changeset 158:0bd6096d06e7

8079166: Update API to DIO 1.1 Summary: Merge with DIO spec repo Reviewed-by: alkonsta
author snazarki
date Thu, 30 Apr 2015 21:58:05 +0300
parents c20b78e3144c
children 5d161bfcaf7a
files src/se/native/com/oracle/dio/gpio/impl/jni_gpio.cpp src/share/classes/com/oracle/dio/gpio/impl/GPIOPortImpl.java src/share/classes/com/oracle/dio/i2cbus/impl/I2CSlaveImpl.java src/share/classes/com/oracle/dio/impl/AbstractPeripheral.java src/share/classes/com/oracle/dio/power/impl/PowerManagedBase.java src/share/classes/com/oracle/dio/spibus/impl/SPISlaveImpl.java src/share/classes/com/oracle/dio/uart/impl/UARTImpl.java src/share/classes/jdk/dio/AsyncErrorHandler.java src/share/classes/jdk/dio/BufferAccess.java src/share/classes/jdk/dio/ClosedDeviceException.java src/share/classes/jdk/dio/Device.java src/share/classes/jdk/dio/DeviceAlreadyExistsException.java src/share/classes/jdk/dio/DeviceConfig.java src/share/classes/jdk/dio/DeviceDescriptor.java src/share/classes/jdk/dio/DeviceEvent.java src/share/classes/jdk/dio/DeviceEventListener.java src/share/classes/jdk/dio/DeviceException.java src/share/classes/jdk/dio/DeviceManager.java src/share/classes/jdk/dio/DeviceMgmtPermission.java src/share/classes/jdk/dio/DeviceNotFoundException.java src/share/classes/jdk/dio/DevicePermission.java src/share/classes/jdk/dio/InputRoundListener.java src/share/classes/jdk/dio/InvalidDeviceConfigException.java src/share/classes/jdk/dio/OutputRoundListener.java src/share/classes/jdk/dio/RegistrationEvent.java src/share/classes/jdk/dio/RegistrationListener.java src/share/classes/jdk/dio/RoundCompletionEvent.java src/share/classes/jdk/dio/Transactional.java src/share/classes/jdk/dio/UnavailableDeviceException.java src/share/classes/jdk/dio/UnsupportedAccessModeException.java src/share/classes/jdk/dio/UnsupportedDeviceTypeException.java src/share/classes/jdk/dio/adc/ADCChannel.java src/share/classes/jdk/dio/adc/ADCChannelConfig.java src/share/classes/jdk/dio/adc/ADCPermission.java src/share/classes/jdk/dio/adc/AcquisitionRoundListener.java src/share/classes/jdk/dio/adc/InvalidInputSamplingRateException.java src/share/classes/jdk/dio/adc/MonitoringEvent.java src/share/classes/jdk/dio/adc/MonitoringListener.java src/share/classes/jdk/dio/adc/package-info.java src/share/classes/jdk/dio/atcmd/ATDevice.java src/share/classes/jdk/dio/atcmd/ATDeviceConfig.java src/share/classes/jdk/dio/atcmd/ATPermission.java src/share/classes/jdk/dio/atcmd/CommandResponseHandler.java src/share/classes/jdk/dio/atcmd/DataConnection.java src/share/classes/jdk/dio/atcmd/DataConnectionHandler.java src/share/classes/jdk/dio/atcmd/UnsolicitedResponseHandler.java src/share/classes/jdk/dio/atcmd/package-info.java src/share/classes/jdk/dio/counter/CounterPermission.java src/share/classes/jdk/dio/counter/CountingEvent.java src/share/classes/jdk/dio/counter/CountingListener.java src/share/classes/jdk/dio/counter/PulseCounter.java src/share/classes/jdk/dio/counter/PulseCounterConfig.java src/share/classes/jdk/dio/counter/package-info.java src/share/classes/jdk/dio/dac/DACChannel.java src/share/classes/jdk/dio/dac/DACChannelConfig.java src/share/classes/jdk/dio/dac/DACPermission.java src/share/classes/jdk/dio/dac/GenerationRoundListener.java src/share/classes/jdk/dio/dac/InvalidOutputSamplingRateException.java src/share/classes/jdk/dio/dac/package-info.java src/share/classes/jdk/dio/generic/GenericBufferIODevice.java src/share/classes/jdk/dio/generic/GenericDevice.java src/share/classes/jdk/dio/generic/GenericDeviceConfig.java src/share/classes/jdk/dio/generic/GenericDeviceControl.java src/share/classes/jdk/dio/generic/GenericEvent.java src/share/classes/jdk/dio/generic/GenericEventListener.java src/share/classes/jdk/dio/generic/GenericPermission.java src/share/classes/jdk/dio/generic/package-info.java src/share/classes/jdk/dio/gpio/GPIOPin.java src/share/classes/jdk/dio/gpio/GPIOPinConfig.java src/share/classes/jdk/dio/gpio/GPIOPinPermission.java src/share/classes/jdk/dio/gpio/GPIOPort.java src/share/classes/jdk/dio/gpio/GPIOPortConfig.java src/share/classes/jdk/dio/gpio/GPIOPortPermission.java src/share/classes/jdk/dio/gpio/PinEvent.java src/share/classes/jdk/dio/gpio/PinListener.java src/share/classes/jdk/dio/gpio/PortEvent.java src/share/classes/jdk/dio/gpio/PortListener.java src/share/classes/jdk/dio/gpio/package-info.java src/share/classes/jdk/dio/i2cbus/I2CCombinedMessage.java src/share/classes/jdk/dio/i2cbus/I2CDevice.java src/share/classes/jdk/dio/i2cbus/I2CDeviceConfig.java src/share/classes/jdk/dio/i2cbus/I2CPermission.java src/share/classes/jdk/dio/i2cbus/package-info.java src/share/classes/jdk/dio/modem/ModemSignalEvent.java src/share/classes/jdk/dio/modem/ModemSignalListener.java src/share/classes/jdk/dio/modem/ModemSignalsControl.java src/share/classes/jdk/dio/modem/package-info.java src/share/classes/jdk/dio/package-info.java src/share/classes/jdk/dio/power/PowerManaged.java src/share/classes/jdk/dio/power/PowerSavingHandler.java src/share/classes/jdk/dio/power/package-info.java src/share/classes/jdk/dio/pwm/GenerationEvent.java src/share/classes/jdk/dio/pwm/GenerationListener.java src/share/classes/jdk/dio/pwm/GenerationRoundListener.java src/share/classes/jdk/dio/pwm/InvalidPulseRateException.java src/share/classes/jdk/dio/pwm/PWMChannel.java src/share/classes/jdk/dio/pwm/PWMChannelConfig.java src/share/classes/jdk/dio/pwm/PWMPermission.java src/share/classes/jdk/dio/pwm/package-info.java src/share/classes/jdk/dio/spi/AbstractDevice.java src/share/classes/jdk/dio/spi/DeviceProvider.java src/share/classes/jdk/dio/spi/package-info.java src/share/classes/jdk/dio/spibus/InvalidWordLengthException.java src/share/classes/jdk/dio/spibus/SPICompositeMessage.java src/share/classes/jdk/dio/spibus/SPIDevice.java src/share/classes/jdk/dio/spibus/SPIDeviceConfig.java src/share/classes/jdk/dio/spibus/SPIPermission.java src/share/classes/jdk/dio/spibus/package-info.java src/share/classes/jdk/dio/uart/ModemUART.java src/share/classes/jdk/dio/uart/UART.java src/share/classes/jdk/dio/uart/UARTConfig.java src/share/classes/jdk/dio/uart/UARTEvent.java src/share/classes/jdk/dio/uart/UARTEventListener.java src/share/classes/jdk/dio/uart/UARTPermission.java src/share/classes/jdk/dio/uart/package-info.java src/share/classes/jdk/dio/watchdog/WatchdogTimer.java src/share/classes/jdk/dio/watchdog/WatchdogTimerConfig.java src/share/classes/jdk/dio/watchdog/WatchdogTimerPermission.java src/share/classes/jdk/dio/watchdog/WindowedWatchdogTimer.java src/share/classes/jdk/dio/watchdog/package-info.java
diffstat 120 files changed, 4376 insertions(+), 1338 deletions(-) [+]
line wrap: on
line diff
--- a/src/se/native/com/oracle/dio/gpio/impl/jni_gpio.cpp	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/se/native/com/oracle/dio/gpio/impl/jni_gpio.cpp	Thu Apr 30 21:58:05 2015 +0300
@@ -357,21 +357,6 @@
     return (jint)value;
 }
 
-/*
- * Sets the GPIOPortConfig.pins private field.
- * Class:     com_oracle_dio_gpio_impl_GPIOPortImpl
- * Method:    assignPins0
- */
-JNIEXPORT void JNICALL Java_com_oracle_dio_gpio_impl_GPIOPortImpl_assignPins0
-  (JNIEnv* env, jobject obj, jobject cfg, jobjectArray pins) {
-    jclass cfgClass = env->GetObjectClass(cfg);
-    jfieldID pinsField = cfgClass ? env->GetFieldID(cfgClass, "pins", "[Ljdk/dio/gpio/GPIOPin;") :
-                                    NULL;
-    if (pinsField) {
-        env->SetObjectField(cfg, pinsField, pins);
-    }
-}
-
 
 /* Entities required for sending GPIO pin notifications */
 static jobject pinEventBuffer = NULL;
--- a/src/share/classes/com/oracle/dio/gpio/impl/GPIOPortImpl.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/com/oracle/dio/gpio/impl/GPIOPortImpl.java	Thu Apr 30 21:58:05 2015 +0300
@@ -88,7 +88,6 @@
             pins[i] = new GPIOPinFake(pinCfgs[i]);
         }
 
-        assignPins0(cfg, pins);
     }
 
     @Override
@@ -218,11 +217,15 @@
                 ((GPIOPinFake)pin).closeInternal();
             }
             // for DM.register: nullifying to remove redundant information from serialized class
-            assignPins0(cfg, null);
             super.close();
         }
     }
 
+    @Override
+    public GPIOPin[] getPins() {
+        return null;
+    }
+
     @Local(DontRemoveFields = {
         "com.oracle.dio.impl.Handle.unlock_func_ptr",
         "com.oracle.dio.impl.Handle.native_handle",
@@ -268,9 +271,5 @@
     })
     private native void stopNoti0() throws IOException;
 
-    @Local(DontRemoveFields = {
-        "jdk.dio.gpio.GPIOPortConfig.pins",
-    })
-    private native void assignPins0(GPIOPortConfig cfg, GPIOPin[] pins);
 }
 
--- a/src/share/classes/com/oracle/dio/i2cbus/impl/I2CSlaveImpl.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/com/oracle/dio/i2cbus/impl/I2CSlaveImpl.java	Thu Apr 30 21:58:05 2015 +0300
@@ -273,6 +273,11 @@
         return getGrpID0();
     }
 
+    @Override
+    public ByteBuffer prepareBuffer(ByteBuffer buffer, int size) throws IOException, ClosedDeviceException {
+        throw new java.lang.UnsupportedOperationException();
+    }
+
     @Local(DontRemoveFields = {
         "jdk.dio.i2cbus.I2CDeviceConfig.controllerNumber",
         "jdk.dio.i2cbus.I2CDeviceConfig.clockFrequency",
--- a/src/share/classes/com/oracle/dio/impl/AbstractPeripheral.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/com/oracle/dio/impl/AbstractPeripheral.java	Thu Apr 30 21:58:05 2015 +0300
@@ -202,6 +202,7 @@
      */
     protected  void unlock0() { handle.unlock(); }
 
+    @Override
     public ByteOrder getByteOrder() throws IOException, UnavailableDeviceException, ClosedDeviceException {
         return ByteOrder.LITTLE_ENDIAN;
     }
--- a/src/share/classes/com/oracle/dio/power/impl/PowerManagedBase.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/com/oracle/dio/power/impl/PowerManagedBase.java	Thu Apr 30 21:58:05 2015 +0300
@@ -47,15 +47,7 @@
     final protected void clearPowerManagement() {
     }
 
-    protected abstract void checkPowerPermission();
-
-    protected void checkPowerState() throws IOException, ClosedDeviceException {
+    final protected void checkPowerState() throws IOException, ClosedDeviceException {
         checkOpen();
     }
-
-    public synchronized void close() throws IOException {
-        if (isOpen()) {
-            super.close();
-        }
-    }
 }
--- a/src/share/classes/com/oracle/dio/spibus/impl/SPISlaveImpl.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/com/oracle/dio/spibus/impl/SPISlaveImpl.java	Thu Apr 30 21:58:05 2015 +0300
@@ -139,6 +139,11 @@
         return getWordLength0();
     }
 
+    @Override
+    public ByteBuffer prepareBuffer(ByteBuffer buffer, int size) throws IOException, ClosedDeviceException {
+        throw new java.lang.UnsupportedOperationException();
+    }
+
     /**
      * Reads one data word of up to 32 bits from this slave device.
      *
--- a/src/share/classes/com/oracle/dio/uart/impl/UARTImpl.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/com/oracle/dio/uart/impl/UARTImpl.java	Thu Apr 30 21:58:05 2015 +0300
@@ -800,16 +800,24 @@
         return getUartId0();
     }
 
+    @Override
     public synchronized ByteBuffer getInputBuffer() throws ClosedDeviceException,
             IOException {
         throw new java.lang.UnsupportedOperationException();
     }
 
+    @Override
     public synchronized ByteBuffer getOutputBuffer() throws ClosedDeviceException,
             IOException {
         throw new java.lang.UnsupportedOperationException();
     }
 
+    @Override
+    public ByteBuffer prepareBuffer(ByteBuffer buffer, int size) throws IOException, ClosedDeviceException {
+        throw new java.lang.UnsupportedOperationException();
+    }
+
+
     @Local(DontRemoveFields = {
         "com.oracle.dio.impl.Handle.native_handle",
         "com.oracle.dio.impl.AbstractPeripheral.handle",
--- a/src/share/classes/jdk/dio/AsyncErrorHandler.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/AsyncErrorHandler.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,16 +22,16 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio;
 
 /**
  * The {@code AsyncErrorHandler} interface defines methods for getting notified of errors of
  * asynchronous I/O operations.
- * <p />
+ * <p>
  * Note though that contrarily to how classes implementing sub-interfaces of
- * {@link DeviceEventListener} handle events handling of I/O errors reported through this
+ * {@link DeviceEventListener} handle events, handling of I/O errors reported through this
  * interface is not subject to the same time-sensitivity constrains.
+ * </p>
  *
  * @param <P>
  *            the device type that generates the error.
--- a/src/share/classes/jdk/dio/BufferAccess.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/BufferAccess.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,68 +22,172 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio;
 
 import java.io.*;
 import java.nio.*;
 
 /**
- * The {@code BufferAccess} interface provides methods for getting access to the device
- * (or the driver thereof) I/O buffers, if any.
+ * The {@code BufferAccess} interface provides methods for getting access to the
+ * device (or the driver thereof) I/O buffers, if any. A device driver may through
+ * this interface provide access to direct buffers that are suitable for efficient
+ * direct I/O operations such as using Direct Memory Access (DMA). This interface
+ * additionally provides a method that wraps an application-provided direct buffer
+ * into a buffer suitable for efficient direct I/O operations.
+ * <p>
+ * The following sample code illustrates how the internal device's buffer might be used
+ * to perform efficient I/O operations (assuming the feature is supported):</p>
+ * <blockquote>
+ * <pre>
+ * <i>// Iterativelly creates a series of samples according to some requirement...</i>
+ * private boolean createSamples(IntBuffer buffer) { ... }
  *
- * @param <B>
- *            the I/O buffer type.
+ * <i>// Generates the sampled output signal; this code is more efficient if all the
+ * // samples to generate fit within the device's output buffer.</i>
+ * try (DACChannel dac = DeviceManager.open(channelID)) {
+ *   IntBuffer buffer = dac.getOutputBuffer();
+ *   while (createSamples(buffer)) { <i>// Directly creates the samples in the driver's internal buffer</i>
+ *     dac.generate(buffer);
+ *     buffer.clear();
+ *   }
+ * } catch (IOException ex) {
+ *   <i>// ...</i>
+ * }
+ * </pre>
+ * </blockquote>
+ * <p>
+ * The following sample code illustrates how an application may use a (pre-allocated) direct buffer to
+ * to perform efficient I/O operations (assuming the feature is supported):</p>
+ * <blockquote>
+ * <pre>
+ *   ByteBuffer someBuffer = ... <i>// Some already allocated buffer</i>
+ *   try (DACChannel dac = DeviceManager.open(channelID)) {
+ *     someBuffer.clear(); <i>// Clear the buffer to make sure its full capacity can be used</i>
+ *     IntBuffer buffer = dac.prepareBuffer(someBuffer, 128);
+ *     if (buffer == null) { <i>// The provided buffer is not direct and/or is not suitable for efficient transfer</i>
+ *       buffer = someBuffer.asIntBuffer(); <i>// The device will default to less efficient transfer mode</i>
+ *     }
+ *     while (createSamples(buffer)) {
+ *       dac.generate(buffer);
+ *       buffer.clear();
+ *     }
+ *   } catch (IOException ex) {
+ *     <i>// ...</i>
+ *   }
+ * }
+ * </pre>
+ * </blockquote>
+ * <p>
+ * Buffers are not safe for use by multiple concurrent threads so care should be
+ * taken to not access the device I/O buffers until any on-going operation has
+ * completed. Interfering with an on-going I/O operation by accessing and
+ * modifying a device I/O buffer concurrently may yield unpredictable results.
+ * </p>
+ *
+ * @param <B> the I/O buffer type.
  * @since 1.0
  */
 @apimarker.API("device-io_1.1")
 public interface BufferAccess<B extends Buffer> {
 
-    /**
-     * Gets the <em>direct</em> input buffer of this device <i>(optional operation)</i>.
-     * <p />
-     * The input buffer will get allocated on a per-application basis to avoid conflicts;
-     * but only one such buffer will be allocated per application. The capacity of the buffer
-     * will be determined based on the property of the underlying device.
-     * <p />
-     * When the returned {@code Buffer} instance is invalidated because the device is either
-     * closed or in exclusive use by some other application then an attempt to access the
-     * {@code Buffer} instance will not change the buffer's content and will cause a
-     * {@code ClosedDeviceException} or some other unspecified exception to be thrown either at
-     * the time of the access or at some later time.
-     *
-     * @return the direct input buffer of this device.
-     * @throws UnsupportedOperationException
-     *             if this device (or driver thereof) does not have or does not allow direct access
-     *             to its input buffer.
-     * @throws ClosedDeviceException
-     *             if the device has been closed.
-     * @throws IOException
-     *             if an I/O error occurred such as the device is not readable.
-     */
-    B getInputBuffer() throws ClosedDeviceException, IOException;
+  /**
+   * Gets the <em>direct</em> input buffer of this device <i>(optional
+   * operation)</i>.
+   * <p>
+   * The input buffer will get allocated on a per-application basis to avoid
+   * conflicts; but only one such buffer will be allocated per application. The
+   * capacity of the buffer will be determined based on the property of the
+   * underlying device.
+   * </p><p>
+   * When the returned {@code Buffer} instance is invalidated because the device
+   * is either closed or in exclusive use by some other application then an
+   * attempt to access the {@code Buffer} instance will not change the buffer's
+   * content and will cause a {@code ClosedDeviceException} or some other
+   * unspecified exception to be thrown either at the time of the access or at
+   * some later time.
+   * </p>
+   *
+   * @return the direct input buffer of this device.
+   * @throws UnsupportedOperationException if this device (or driver thereof)
+   * does not have or does not allow direct access to its input buffer.
+   * @throws ClosedDeviceException if the device has been closed.
+   * @throws IOException if an I/O error occurred such as the device is not
+   * readable.
+   */
+  B getInputBuffer() throws ClosedDeviceException, IOException;
 
-    /**
-     * Gets the <em>direct</em> output buffer of this device <i>(optional operation)</i>.
-     * <p />
-     * The output buffer will get allocated on a per-application basis to avoid conflicts;
-     * but only one such buffer will be allocated per application. The capacity of the buffer
-     * will be determined based on the property of the underlying device.
-     * <p />
-     * When the returned {@code Buffer} instance is invalidated because the device is either
-     * closed or in exclusive use by some other application then an attempt to access the
-     * {@code Buffer} instance will not change the buffer's content and will cause a
-     * {@code ClosedDeviceException} or some other unspecified exception to be thrown either at
-     * the time of the access or at some later time.
-     *
-     * @return the direct output buffer of this device.
-     * @throws UnsupportedOperationException
-     *             if this device (or driver thereof) does not have or does not allow direct access
-     *             to its output buffer.
-     * @throws ClosedDeviceException
-     *             if the device has been closed.
-     * @throws IOException
-     *             if an I/O error occurred such as the device is not writable.
-     */
-    B getOutputBuffer() throws ClosedDeviceException, IOException;
+  /**
+   * Gets the <em>direct</em> output buffer of this device <i>(optional
+   * operation)</i>.
+   * <p>
+   * The output buffer will get allocated on a per-application basis to avoid
+   * conflicts; but only one such buffer will be allocated per application. The
+   * capacity of the buffer will be determined based on the property of the
+   * underlying device.
+   * </p><p>
+   * When the returned {@code Buffer} instance is invalidated because the device
+   * is either closed or in exclusive use by some other application then an
+   * attempt to access the {@code Buffer} instance will not change the buffer's
+   * content and will cause a {@code ClosedDeviceException} or some other
+   * unspecified exception to be thrown either at the time of the access or at
+   * some later time.
+   * </p>
+   *
+   * @return the direct output buffer of this device.
+   * @throws UnsupportedOperationException if this device (or driver thereof)
+   * does not have or does not allow direct access to its output buffer.
+   * @throws ClosedDeviceException if the device has been closed.
+   * @throws IOException if an I/O error occurred such as the device is not
+   * writable.
+   */
+  B getOutputBuffer() throws ClosedDeviceException, IOException;
+
+  /**
+   * Creates a view of the provided {@code ByteBuffer} suitable for efficient
+   * direct I/O transfers of the specified size and of the type required by this
+   * device. If the provided buffer is a direct buffer then the alignment of its current
+   * position, and its limit are checked; if eligible for direct I/O operation, a
+   * new buffer - of the required type - whose content is a shared subsequence of the provided
+   * buffer's content is created as follows:
+   * <ul>
+   * <li>
+   * The content of the new buffer will start at the provided buffer's current
+   * position - adjusted (incremented) for alignment, if necessary.
+   * </li>
+   * <li>
+   * The new buffer's position will be zero, its capacity and its limit will be
+   * be set to the most optimal value lesser or equal to the requested size that
+   * can fit in the number of bytes remaining in the provided buffer - after
+   * adjustment for alignment; its mark will be undefined.
+   * </li>
+   * </ul>
+   * Changes to the provided buffer's content will be visible in the new buffer,
+   * and vice versa; the two buffers' position, limit, and mark values will be
+   * independent. <br>
+   * This device's driver will make a best effort to perform native (e.g. DMA)
+   * I/O operations directly upon the new buffer. If the remaining elements in
+   * the new buffer is less than the requested size then the application will
+   * have to submit the whole I/O operation in several rounds. If the new buffer
+   * is not at its full capacity when submitted for transfer - such as upon the very
+   * last round - then this device's driver may not be able to use efficient
+   * transfer and may resort to a less efficient mode of transfer.
+   * <p>
+   * If the provided buffer is not direct or is not eligible for direct I/O (or
+   * if direct I/O is not supported) then {@code null} is returned. The
+   * provided buffer may still be used for the intended I/O operation but in
+   * this case, the device's driver may resort to less efficient procedures
+   * to perform the I/O operation.
+   * </p>
+   *
+   * @param buffer the buffer to prepare for efficient I/O transfer.
+   * @param size the size of the intended data to transfer.
+   * @return a new buffer suitable for efficient I/O operations mapped onto the
+   * provided buffer, if one can be created; {@code null} otherwise.
+   * @throws IllegalArgumentException if {@code size} is negative.
+   * @throws ClosedDeviceException if the device has been closed.
+   * @throws IOException if some other I/O error occurs.
+   *
+   * @since 1.1
+   */
+  B prepareBuffer(ByteBuffer buffer, int size) throws IOException, ClosedDeviceException;
 }
--- a/src/share/classes/jdk/dio/ClosedDeviceException.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/ClosedDeviceException.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio;
 
 import java.nio.channels.ClosedChannelException;
--- a/src/share/classes/jdk/dio/Device.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/Device.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio;
 
 import java.io.IOException;
@@ -31,15 +30,15 @@
 
 /**
  * The {@code Device} interface represents devices in the system. This interface
- * provides generic methods for handling devices. <br />
+ * provides generic methods for handling devices. <br>
  * All <i>devices</i> must implement the {@code Device} interface.
- * <p />
+ * <p>
  * When a device is open in shared mode then access synchronization may be performed by
  * invoking {@link #tryLock tryLock} and {@link #unlock unlock}. Device locks are held on a per
  * {@code Device} instance basis. When the same device is open twice in shared access
  * mode by the same application, locking one of the {@code Device} instances will prevent the
  * other form being accessed/used.
- *
+ * </p>
  * <h3><a name="byte_order">Device Byte Order</a></h3>
  * Devices that perform multi-byte value I/O operations have a "native" byte order
  * (see {@link #getByteOrder getByteOrder}).
@@ -74,9 +73,10 @@
      * resource. This method will block until the designated device resource becomes
      * available for exclusive access by this {@code Device} instance or the specified amount of
      * real time has elapsed. A {@code timeout} of {@code 0} means to wait forever.
-     * <p />
+     * <p>
      * This method returns silently if the underlying device resource is open in
      * exclusive access mode or is already acquired for exclusive access (locked).
+     * </p>
      *
      * @param timeout
      *            the timeout in milliseconds.
@@ -96,11 +96,12 @@
      * making it available to other applications. Upon closing the underlying device
      * resource MUST be set to the state (power state and configuration) it was in prior to opening
      * it.
-     * <p />
+     * <p>
      * Once closed, subsequent operations on that very same {@code Device} instance will result
      * in a {@link ClosedDeviceException} being thrown.
-     * <p />
+     * </p><p>
      * This method has no effects if the device has already been closed.
+     * </p>
      *
      * @throws IOException
      *             if an I/O error occurs.
@@ -118,10 +119,11 @@
 
     /**
      * Releases from (platform-wide) exclusive access the underlying device resource.
-     * <p />
+     * <p>
      * This method returns silently if the underlying device resource is either open in
      * exclusive access mode or is not currently acquired for exclusive access (locked) or has
      * already been closed.
+     * </p>
      *
      * @throws IOException
      *             if any other I/O error occurred.
@@ -142,10 +144,9 @@
 
     /**
      * Retrieves this device's byte order.
-     * <p />
-     * The byte order is used when performing multi-byte value I/O operations. The byte
-     * order of a device that only performs single-byte value I/O operations
-     * is always {@link java.nio.ByteOrder#BIG_ENDIAN BIG_ENDIAN}.
+     * <p>
+     * The byte order is used when performing multi-byte value I/O operations.
+     * </p>
      *
      * @return this buffer's byte order.
      *
--- a/src/share/classes/jdk/dio/DeviceAlreadyExistsException.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/DeviceAlreadyExistsException.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio;
 
 /**
--- a/src/share/classes/jdk/dio/DeviceConfig.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/DeviceConfig.java	Thu Apr 30 21:58:05 2015 +0300
@@ -24,77 +24,206 @@
  */
 
 package jdk.dio;
+import java.io.IOException;
+import java.io.OutputStream;
 
 /**
- * The {@code DeviceConfig} class is a tagging interface for all device configuration
- * classes.
- * <p />
- * A device configuration contains the following elements:
+ * The {@code DeviceConfig} class is the base interface for all device
+ * configuration classes.
+ * <p>
+ * A device's configuration consists of the following elements:
+ * </p>
  * <dl>
  * <dt><b>Hardware Addressing Information</b></dt>
- * <dd>Information required to address the device. Examples are an I2C bus number and an
- * I2C slave device address or a GPIO controller number and pin index.</dd>
+ * <dd>Information required to address the device. Examples are an I2C bus
+ * number and an I2C slave device address or a GPIO controller number and pin
+ * index.</dd>
  * <dt><b>Static Configuration Parameters</b></dt>
- * <dd>Configuration parameters that must be set before the device is opened and which
- * may not be changed afterwards. Examples are an SPI slave device clock mode or word length.</dd>
+ * <dd>Configuration parameters that must be set upon opening the device and
+ * which may not be changed afterwards. Examples are an SPI slave device clock
+ * mode or word length.</dd>
  * <dt><b>Dynamic Configuration Parameters</b></dt>
- * <dd>Configuration parameters for which a default value may be set before the device is
- * opened and which may still be changed while the device is open. Dynamic configuration
- * parameters can be changed after the device is open through methods of
- * {@link Device} sub-interfaces. Examples are a UART baud rate or the current direction of a
- * bidirectional GPIO pin.</dd>
+ * <dd>Configuration parameters for which an initial value is set upon opening the
+ * device and that an application may change while the device is still open.
+ * Dynamic configuration parameters can be changed after the device is open
+ * through methods of {@link Device} sub-interfaces. Examples are a UART baud
+ * rate or the current direction of a bidirectional GPIO pin.
+ * The initial values
+ * of dynamic configuration parameters are initial <em>default</em> values from
+ * the point of view of the application accessing the device. Runtime changes
+ * to the values of dynamic configuration parameters are not reflected in the
+ * {@code DeviceConfig} object of that device, which retains its initial values.
+ * </dd>
  * </dl>
- * {@code DeviceConfig} instances should be immutable. <br />
- * A compliant implementation of this specification MUST ensure that information encapsulated in a
- * {@code DeviceConfig} instance cannot be altered while it is handling it and SHOULD either
- * create its own private copy of the instance or of the information it contains.
- * <p />
- * Some hardware addressing parameter, and static and dynamic configuration parameters may be set to
- * {@link #DEFAULT}. Whether such default settings are supported is platform- as well as device
- * driver-dependent.
- * <p />
- * An instance of {@code DeviceConfig} can be passed to the
- * {@link DeviceManager#open(DeviceConfig)} or
- * {@link DeviceManager#open(Class, DeviceConfig)} method to open the designated device
- * device with the specified configuration. A {@link InvalidDeviceConfigException} is thrown
- * when attempting to open a device with an invalid or unsupported configuration.
+ * The {@link DeviceManager#open(DeviceConfig) open(DeviceConfig, ...)} and
+ * {@link DeviceManager#open(Class, DeviceConfig) open(Class, DeviceConfig, ...)}
+ * methods of the {@link DeviceManager} can be used to open a device and obtain
+ * a {@code Device} instance to access it. The device to open is designated by
+ * the hardware addressing information encapsulated in the provided {@code DeviceConfig} object;
+ * it is then configured according to the static and runtime configuration parameters
+ * encapsulated in the same provided {@code DeviceConfig} object. If the device
+ * designated by the provided hardware addressing information cannot be found a
+ * {@link DeviceNotFoundException} is thrown. If a static or runtime configuration
+ * parameter or a combination thereof is not valid or not supported a
+ * {@link InvalidDeviceConfigException}.
+ * <h3><a name="immutability">Immutability of {@code DeviceConfig} Objects</a></h3>
+ * {@code DeviceConfig} objects should be immutable. If a
+ * {@code DeviceConfig}-implementing class is not immutable it should implement
+ * the {@link java.lang.Cloneable} interface. A compliant implementation of this
+ * specification MUST do its best to ensure that information encapsulated in a
+ * {@code DeviceConfig} instance cannot be altered while it is handling it and
+ * SHOULD, when necessary (that is when an instance is not considered
+ * immutable), create its own private copy either of the instance (such as by
+ * cloning it) or of the information it contains. If a
+ * {@code DeviceConfig}-implementing class does not implement the
+ * {@code Cloneable} interface then it SHALL - for that purpose - be considered
+ * immutable.<br>
+ * As per the above requirements, a compliant implementation of this specification
+ * may return the same (immutable) {@code DeviceConfig} instance over several calls;
+ * an application must therefore not synchronize on {@code DeviceConfig} objects.
+ * <h3><a name="persistency">Persistency of {@code DeviceConfig} Objects</a></h3>
+ * A compliant implementation of this specification MUST support the persistence
+ * of the device configuration registry across platform reboots; it MUST guarantee
+ * in particular that a device configuration registered by an application remains
+ * registered after the application has terminated and across platform reboots
+ * until it is explictly unregistered by an application (possibly the same)
+ * that has been granted the necessary permissions.<br>
+ * To allow for persistency of the device configuration registry, {@code DeviceConfig}
+ * objects must support saving their states to an {@code OutputStream}
+ * and restoring their states from an {@code InputStream}. The
+ * {@code DeviceManager} saves the state of an {@code DeviceConfig} object by invoking
+ * its {@link #serialize(java.io.OutputStream) serialize} method. The
+ * {@code DeviceManager} restores the state of an {@code DeviceConfig} object by invoking
+ * the {@link jdk.dio.spi.DeviceProvider#deserialize(java.io.InputStream) deserialize}
+ * on its associated {@link jdk.dio.spi.DeviceProvider DeviceProvider}.<br>
+ * On the Java Platform Standard Edition, these methods may delegate to the Object Serialization
+ * framework.
+ * In order to facilitate the implementation of compound or layered device abstractions,
+ * on the Java Platform Micro Edition, which does not support Object Serialization,
+ * {@code DeviceConfig}-implementing classes should provide methods for creating new instances
+ * initialized from an {@code InputStream}; see example below:
+ * <blockquote>
+ *   <pre>
+ * public class RealTimeClockConfig implements DeviceConfig&lt;RealTimeClock&gt;, HardwareAddressing {
  *
- * @param <P>
- *            the device type the configuration is defined for.
+ *   private MMIODeviceConfig mmioConfig;
+ *
+ *   public RealTimeClockConfig(MMIODeviceConfig mmioConfig) {
+ *     this.mmioConfig = mmioConfig;
+ *   }
+ *
+ *   <em>public static RealTimeClockConfig deserialize(InputStream in) throws IOException {
+ *     return new RealTimeClockConfig(MMIODeviceConfig.deserialize(in));
+ *   }</em>
+ *
+ *   ...
+ *
+ *   public MMIODeviceConfig getMmioConfig() {
+ *     return mmioConfig;
+ *   }
+ *
+ *   &#64;Override
+ *   public int serialize(OutputStream out) throws IOException {
+ *     return mmioConfig.serialize(out);
+ *   }
+ * }
+ *   </pre>
+ * </blockquote>
+ * <h3><a name="default_unassigned">Unassigned, Default or Unused Parameter Values</a></h3>
+ * Some hardware addressing, static or dynamic configuration parameters may be
+ * set to {@link #UNASSIGNED} (or {@code null}) when opening or registering a
+ * device configuration. Device drivers may substitute hardware addressing parameters
+ * and static and dynamic configuration parameters
+ * set to {@link #UNASSIGNED} (or {@code null}) with actual default values;
+ * whether such default settings are supported is platform- as well as device driver-dependent;
+ * if a required parameter is set to {@link #UNASSIGNED} (or {@code null}) the device driver
+ * MUST reject the configuration and throw an {@link InvalidDeviceConfigException}.
+ * When querying the configuration of an open device using the
+ * {@link DeviceDescriptor#getConfiguration DeviceDescriptor.getConfiguration}
+ * method the actual settings are returned; parameters that are neither supported
+ * nor required by the underlying hardware or driver are still set to {@link #UNASSIGNED}
+ * (or {@code null}); whether or not this is the case when listing registered
+ * device configuration using the {@link DeviceManager#list DeviceManager.list}
+ * methods depends on whether the device could be probed upon registration
+ * of the configuration (see <a href="{@docRoot}/jdk/dio/DeviceManager.html#probing">Device Probing</a>).
+ *
+ * @param <P> the device type the configuration is defined for.
  * @see DeviceManager#open(DeviceConfig)
+ * @see DeviceManager#open(DeviceConfig, int)
  * @see DeviceManager#open(Class, DeviceConfig)
+ * @see DeviceManager#open(Class, DeviceConfig, int)
+ * @see DeviceManager#list
+ * @see DeviceDescriptor#getConfiguration
  * @see InvalidDeviceConfigException
  * @since 1.0
  */
 @apimarker.API("device-io_1.1")
 public interface DeviceConfig<P extends Device<? super P>> {
 
-    /**
-     * Used to indicate that the default value of a configuration parameter should be used.
-     */
-    int DEFAULT = -1;
+  /**
+   * Used to indicate that the default value of a hardware addressing or
+   * configuration parameter is requested upon opening or registering a device
+   * configuration or to indicate that a configuration parameter is unassigned
+   * (such as when it is not supported).
+   * @deprecated As of 1.1 replaced by {@link #UNASSIGNED}.
+   */
+  int DEFAULT = -1;
+  /**
+   * Used to indicate that the default value of a hardware addressing or
+   * configuration parameter is requested upon opening or registering a device
+   * configuration or to indicate that a configuration parameter is unused
+   * (such as when it is neither supported nor required by the underlying hardware or driver).
+   */
+  int UNASSIGNED = -1;
+
+  /**
+   * The {@code HardwareAddressing} interface defines an abstraction of an
+   * hardware addressing information common on different platforms.
+   * <p />
+   * When a device's {@code HardwareAddressing} contains both a specific controller number
+   * (see {@link #getControllerNumber getControllerNumber}) and a specific controller name (see {@link #getControllerName getControllerName})
+   * a compliant implementation of this specification MUST only use the controller number
+   * for addressing the device and for permission checks.
+   *
+   * @since 1.0
+   */
+  @apimarker.API("device-io_1.1")
+  public interface HardwareAddressing {
 
     /**
-     * The {@code HardwareAddressing} interface defines an abstraction of an hardware addressing
-     * information common on different platforms.
+     * Gets the controller number.
      *
-     * @since 1.0
+     * @return the controller number (a positive or zero integer) or
+     * {@link #UNASSIGNED} if no specific value is requested or no actual value is
+     * assigned (see
+     * <a href="{@docRoot}/jdk/dio/DeviceConfig.html#default_unassigned">Unassigned, Default or Unused Parameter Values</a>).
      */
-    @apimarker.API("device-io_1.1")
-    public interface HardwareAddressing {
+    int getControllerNumber();
 
-        /**
-         * Gets the controller number.
-         *
-         * @return the controller number (a positive or zero integer) or {@link #DEFAULT}.
-         */
-        int getControllerNumber();
+    /**
+     * Gets the controller name (such as a <em>device file</em> name on UNIX
+     * systems).
+     *
+     * @return the controller name or {@code null} if no specific value is
+     * requested or no actual value is assigned (see
+     * <a href="{@docRoot}/jdk/dio/DeviceConfig.html#default_unassigned">Unassigned, Default or Unused Parameter Values</a>).
+     */
+    String getControllerName();
+  }
 
-        /**
-         * Gets the controller name (such as a <em>device file</em> name on UNIX systems).
-         *
-         * @return the controller name or {@code null}.
-         */
-        String getControllerName();
-    }
+  /**
+   * Serializes the state of this {@code DeviceConfig} object to the specified
+   * {@code OutputStream}. This method may be invoked by the
+   * {@link jdk.dio.DeviceManager DeviceManager} to save the state of a
+   * {@code DeviceConfig} object to a persistent store in order to support
+   * persistence of device configuration registration.
+   *
+   * @param out the stream to write to.
+   * @return the number of bytes written to the stream.
+   * @throws IOException if an I/O error occurs.
+   *
+   * @see jdk.dio.spi.DeviceProvider#deserialize(java.io.InputStream)
+   * @since 1.1
+   */
+  int serialize(OutputStream out) throws IOException;
 }
--- a/src/share/classes/jdk/dio/DeviceDescriptor.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/DeviceDescriptor.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio;
 
 /**
@@ -77,7 +76,10 @@
     Class<P> getInterface();
 
     /**
-     * Returns the registered configuration of the device.
+     * Returns the actual configuration of the device. The actual settings are returned;
+     * {@link DeviceConfig#UNASSIGNED} (or {@code null}) may still be returned for a
+     * hardware addressing, static or dynamic configuration parameter
+     * to indicate that it is unassigned (such as when it is not supported).
      *
      * @param <C>
      *            the device configuration type.
--- a/src/share/classes/jdk/dio/DeviceEvent.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/DeviceEvent.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,15 +22,15 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio;
 
 /**
  * The {@code DeviceEvent} class encapsulates events fired by or on behalf of a
  * device. An event may correspond to an hardware interrupt or to some software signal.
- * <p />
+ * <p>
  * When an event burst occurs - that is more events occurred than can be handled - events may be
  * coalesced. Coalescing of events is platform and device-dependent.
+ * </p>
  *
  * @param <P>
  *            the device type the event is defined for.
@@ -52,9 +52,10 @@
     /**
      * The additional microseconds to the timestamp for when the last coalesced event occurred. If
      * events were not coalesced then this is the same as that of the first event.
-     * <p />
+     * <p>
      * The actual last timestamp in microseconds is equal to: <i>(lastTimeStamp * 1000) +
      * lastTimeStampMicros</i>.
+     * </p>
      */
     protected int lastTimeStampMicros;
     /**
@@ -69,9 +70,10 @@
     /**
      * The additional microseconds to the timestamp for when this event (first) occurred. If events
      * were coalesced then this is that of the first event.
-     * <p />
+     * <p>
      * The actual timestamp in microseconds is equal to: <i>(timeStamp * 1000) +
      * timeStampMicros</i>.
+     * </p>
      */
     protected int timeStampMicros;
 
--- a/src/share/classes/jdk/dio/DeviceEventListener.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/DeviceEventListener.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,22 +22,26 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio;
 
 /**
  * The {@code DeviceEventListener} interface is a tagging interface that all event listeners
  * must implement. Event listeners provide methods for notifying applications of the occurrence of
  * events (hardware interrupts or software signals) on devices.
- * <p />
- * An event listener should implement the following requirements:
+ * <p>
+ * An event listener should implement the following requirements:</p>
  * <ul>
  * <li>it should be implemented to be as fast as possible; for example it should not call any
  * operations that may block, nor pause the current thread.</li>
  * <li>it should not throw any unchecked exception.</li>
  * </ul>
+ * <p>
  * A compliant implementation of this specification MUST catch unchecked exceptions that may be
  * thrown by a listener.
+ * </p><p>
+ * A compliant implementation of this specification MUST serialize the notifications
+ * to the same {@code DeviceEventListener} instance.
+ * </p>
  *
  * @since 1.0
  */
--- a/src/share/classes/jdk/dio/DeviceException.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/DeviceException.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio;
 
 import java.io.IOException;
--- a/src/share/classes/jdk/dio/DeviceManager.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/DeviceManager.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio;
 
 import java.io.IOException;
@@ -49,53 +48,54 @@
 
 /**
  * The {@code DeviceManager} class provides methods for opening and registering
- * devices that can then be handled as {@link Device} instances. A {@code Device} instance
+ * devices that can then be handled as {@link Device} instances. A device
  * of a particular type can be opened using its platform-specific numeric ID or name as well as
  * its properties or using an ad-hoc configuration (in which case, its hardware addressing
  * information must be explicitly provided).
- * <p />
- * A {@code Device} instance may be identified by a numeric ID. This ID is unrelated to the
+ * <p>
+ * A device may be identified by a numeric ID. This ID is unrelated to the
  * hardware number (hardware addressing information) that may be used to identify a device such as a
  * GPIO pin number or an I2C slave device address. A device ID typically corresponds to a
  * registered configuration for a device. The numeric ID of a device must be
  * greater than or equal to {@code 0} and must be unique. Yet the same device may be
  * directly and indirectly mapped through several IDs; each ID may correspond to a different
  * configuration, representation or abstraction for the same underlying device hardware
- * resource. <br />
- * A {@code Device} instance opened with an ad-hoc configuration - that is: not
+ * resource.<br>
+ * A device opened with an ad-hoc configuration - that is: not
  * through one of its registered configurations - is not assigned a numeric ID nor a name. Its
  * numeric ID and name are both undefined and set respectively to
  * {@link DeviceDescriptor#UNDEFINED_ID UNDEFINED_ID} and {@code null}.
- * <p />
+ * </p><p>
  * Devices may be opened in either <a href="{@docRoot}/overview-summary.html#access-model">
  * <em>exclusive</em> or <em>shared</em> mode</a>. By default,
  * devices are opened in exclusive mode. Whether a device can be opened in
  * shared mode depends on the underlying device hardware as well as on the underlying
  * device driver. It also depends on whether the provided {@code Device} implementation is a
  * <em>dedicated</em>, <em>virtualized</em> or <em>shared</em> abstraction of the underlying
- * device resource. <br />
+ * device resource. <br>
  * When a device is open with an ad-hoc configuration in shared mode then the
  * {@code Device} implementation (or driver) may throw a
  * {@link InvalidDeviceConfigException} if the device is already open and the
- * requested adhoc configuration is incompatible with the current configuration of the device
- * device. <br />
+ * requested adhoc configuration is incompatible with the current configuration of the
+ * device. <br>
  * When a device is open in shared mode then some explicit means of access
  * synchronization may have to be used such as by invoking {@link Device#tryLock Device.tryLock} and
  * {@link Device#unlock Device.unlock}. Device locks are held on a per {@code Device} instance basis.
  * When the same device is open twice in shared access mode by the same application,
  * locking one of the {@code Device} instances will prevent the other from being accessed/used.
- * <p />
- * Opening a {@code Device} instance of a specific type with a registered configuration is
- * subject to permission checks (see {@link DeviceMgmtPermission#OPEN}). <br />
- * Opening a {@code Device} instance of a specific type with an ad-hoc configuration is subject
+ * </p><p>
+ * Opening a device of a specific type with a registered configuration is
+ * subject to permission checks (see {@link DeviceMgmtPermission#OPEN}).<br>
+ * Opening a device of a specific type with an ad-hoc configuration is subject
  * to permission checks specific for that type (for example see
  * {@link jdk.dio.gpio.GPIOPinPermission GPIOPinPermission.OPEN}). This permission check
  * should be implemented by the {@link jdk.dio.spi.DeviceProvider#open
- * DeviceProvider.open} method. <br />
+ * DeviceProvider.open} method. <br>
  * Registration and unregistration of devices are subject to permission checks (see
  * {@link DeviceMgmtPermission#REGISTER} and {@link DeviceMgmtPermission#UNREGISTER}).
- * <br />
+ * <br>
  * For more details see <a href="{@docRoot}/overview-summary.html#security-model">Security Model</a>.
+ * </p>
  * <h3><a name="probing">Device Probing</a></h3>
  * For some peripheral hardware such as I2C bus or SPI bus, opening (or registering) a device
  * such as a slave device on a bus does not necessarily entail immediately
@@ -122,14 +122,16 @@
 public class DeviceManager {
     /**
      * Exclusive access mode.
-     * <p />
+     * <p>
      * This bit flag can be bitwise-combined (OR) with other access mode bit flags.
+     * </p>
      */
     public static final int EXCLUSIVE = 1;
     /**
      * Shared access mode.
-     * <p />
+     * <p>
      * This bit flag can be bitwise-combined (OR) with other access mode bit flags.
+     * </p>
      */
     public static final int SHARED = 2;
 
@@ -178,30 +180,28 @@
     }
 
     /**
-     * Opens a {@code Device} instance of the specified type with the specified hardware
-     * addressing information and configuration. The specified device type and specified
-     * configuration type must be compatible. An instance of the first <em>available</em>
-     * matching {@code Device} is returned. If a matching {@code Device} is already open
-     * (therefore <em>not available</em>) the next matching {@code Device} is considered.
-     * <p />
-     * Opening a {@code Device} instance with hardware addressing information and configuration
+     * Opens a device, returning a {@code Device} instance of the specified type to access it.
+     * The device to open is designated by the provided hardware addressing information and is
+     * initially set-up according to the specified configuration. The specified device type and specified
+     * configuration type must be compatible.
+     * <p>
+     * Opening a device from its hardware addressing information and with an ad-hoc configuration
      * may be subject to <a href="#probing">device probing limitations </a>.
-     * <p />
+     * </p><p>
      * The device is opened in exclusive access mode.
-     * <p />
+     * </p><p>
      * The returned {@code Device} instance's ID and name are undefined.
-     * <p />
      * A new instance is returned upon each call.
+     * </p>
      *
      * @param <P>
      *            the type of the device to open.
      * @param intf
-     *            the interface (sub-interface of {@code Device}) of the device being looked
-     *            up.
+     *            the interface (sub-interface of {@code Device}) of the device to open.
      * @param config
      *            the device configuration (which includes hardware addressing information as
      *            well as configuration parameters).
-     * @return a {@code Device} instance for the specified configuration.
+     * @return a new {@code Device} instance to access the designated device.
      * @throws UnsupportedDeviceTypeException
      *             if the designated device type is not supported.
      * @throws InvalidDeviceConfigException
@@ -230,35 +230,33 @@
     }
 
     /**
-     * Opens a {@code Device} instance of the specified type with the specified hardware
-     * addressing information and configuration. The specified device type and specified
-     * configuration type must be compatible. An instance of the first <em>available</em> matching {@code Device}
-     * is returned. If a matching {@code Device} is already open in a mode that is not
-     * compatible with the requested mode the next matching {@code Device} is considered.
-     * <p />
-     * Opening a {@code Device} instance with hardware addressing information and configuration
+     * Opens a device, returning a {@code Device} instance of the specified type to access it.
+     * The device to open is designated by the provided hardware addressing information and is
+     * initially set-up according to the specified configuration. The specified device type and specified
+     * configuration type must be compatible.
+     * <p>
+     * Opening a device from its hardware addressing information and with an ad-hoc configuration
      * may be subject to <a href="#probing">device probing limitations </a>.
-     * <p />
+     * </p><p>
      * The device is opened in the designated access mode. A device may be
      * opened in shared mode if supported by the underlying driver and hardware and if it is not
      * already opened in exclusive mode. A device may be opened in exclusive mode if
      * supported by the underlying driver and hardware and if it is not already opened.
-     * <p />
+     * </p><p>
      * The returned {@code Device} instance's ID and name are undefined.
-     * <p />
      * A new instance is returned upon each call.
+     * </p>
      *
      * @param <P>
      *            the type of the device to open.
      * @param intf
-     *            the interface (sub-interface of {@code Device}) of the device being looked
-     *            up.
+     *            the interface (sub-interface of {@code Device}) of the device to open.
      * @param config
      *            the device configuration (which includes hardware addressing information as
      *            well as configuration parameters).
      * @param mode
      *            the access mode, one of: {@link #EXCLUSIVE} or {@link #SHARED}.
-     * @return a {@code Device} instance for the specified configuration.
+     * @return a new {@code Device} instance to access the designated device.
      * @throws UnsupportedDeviceTypeException
      *             if the designated device type is not supported.
      * @throws InvalidDeviceConfigException
@@ -285,7 +283,7 @@
      *             is not applicable to the device type specified by {@code intf}.
      */
     public static <P extends Device<? super P>> P open(Class<P> intf, DeviceConfig<? super P> config, int mode)
-    throws IOException, InvalidDeviceConfigException, UnsupportedDeviceTypeException,
+            throws IOException, InvalidDeviceConfigException, UnsupportedDeviceTypeException,
             DeviceNotFoundException, UnavailableDeviceException, UnsupportedAccessModeException {
 
         if (null == intf) {
@@ -330,17 +328,21 @@
     }
 
     /**
-     * Looks up and opens a {@code Device} instance for the provided numeric ID.
-     * <p />
+     * Looks up then opens the device designated by the provided numeric ID,
+     * returning a {@code Device} instance to access it.
+     * The device configuration registered for the provided ID is first looked up;
+     * the device designated by the retrieved hardware addressing information is open and is
+     * initially set-up according to the registered configuration.
+     * <p>
      * The device is opened in exclusive access mode.
-     * <p />
      * A new instance is returned upon each call.
+     * </p>
      *
      * @param <P>
      *            the type of the device to open.
      * @param id
      *            the numeric device id.
-     * @return a {@code Device} instance for the given numeric ID.
+     * @return a new {@code Device} instance to access the designated device.
      * @throws DeviceNotFoundException
      *             if the designated device is not found.
      * @throws UnavailableDeviceException
@@ -366,11 +368,16 @@
     }
 
     /**
-     * Looks up and opens a {@code Device} instance for the provided numeric ID and type.
-     * <p />
+     * Looks up then opens the device designated by the provided numeric ID and type,
+     * returning a {@code Device} instance of the specified type to access it.
+     * The device configuration registered for the provided ID is first looked up;
+     * the device designated by the retrieved hardware addressing information is open and is
+     * initially set-up according to the registered configuration. The specified device type and retrieved
+     * configuration type must be compatible.
+     * <p>
      * The device is opened in exclusive access mode.
-     * <p />
      * A new instance is returned upon each call.
+     * </p>
      *
      * @param <P>
      *            the type of the device to open.
@@ -379,7 +386,7 @@
      * @param intf
      *            the interface (sub-interface of {@code Device}) of the device being looked
      *            up.
-     * @return a {@code Device} instance for the given numeric ID.
+     * @return a new {@code Device} instance to access the designated device.
      * @throws DeviceNotFoundException
      *             if the designated device is not found.
      * @throws UnsupportedDeviceTypeException
@@ -409,14 +416,20 @@
     }
 
     /**
-     * Looks up and opens a {@code Device} instance for the provided numeric ID and type.
-     * <p />
+     * Looks up then opens the device designated by the provided numeric ID and type,
+     * returning a {@code Device} instance of the specified type to access it.
+     * The device configuration registered for the provided ID is first looked up;
+     * the device designated by the retrieved hardware addressing information is open and is
+     * initially set-up according to the registered configuration. The specified device type and retrieved
+     * configuration type must be compatible.
+     * <p>
      * The device is opened in the designated access mode. A device may be
      * opened in shared mode if supported by the underlying driver and hardware and if it is not
      * already opened in exclusive mode. A device may be opened in exclusive mode if
      * supported by the underlying driver and hardware and if it is not already opened.
-     * <p />
+     * </p><p>
      * A new instance is returned upon each call.
+     * </p>
      *
      * @param <P>
      *            the type of the device to open.
@@ -427,7 +440,7 @@
      *            up.
      * @param mode
      *            the access mode, one of: {@link #EXCLUSIVE} or {@link #SHARED}.
-     * @return a {@code Device} instance for the given numeric ID.
+     * @return a new {@code Device} instance to access the designated device.
      * @throws UnsupportedDeviceTypeException
      *             if the designated device type is not supported.
      * @throws DeviceNotFoundException
@@ -497,14 +510,20 @@
     }
 
     /**
-     * Looks up and opens a {@code Device} instance for the provided numeric ID.
-     * <p />
+     * Looks up then opens the device designated by the provided numeric ID,
+     * returning a {@code Device} instance to access it.
+     * The device configuration registered for the provided ID is first looked up;
+     * the device designated by the retrieved hardware addressing information is open and is
+     * initially set-up according to the registered configuration.
+     * <p>
      * The device is opened in the designated access mode. A device may be
      * opened in shared mode if supported by the underlying driver and hardware and if it is not
      * already opened in exclusive mode. A device may be opened in exclusive mode if
      * supported by the underlying driver and hardware and if it is not already opened.
-     * <p />
+     * </p><p>
+     * The device is opened in exclusive access mode.
      * A new instance is returned upon each call.
+     * </p>
      *
      * @param <P>
      *            the type of the device to open.
@@ -512,7 +531,7 @@
      *            the numeric device id.
      * @param mode
      *            the access mode, one of: {@link #EXCLUSIVE} or {@link #SHARED}.
-     * @return a {@code Device} instance for the given numeric ID.
+     * @return a new {@code Device} instance to access the designated device.
      * @throws DeviceNotFoundException
      *             if the designated device is not found.
      * @throws UnavailableDeviceException
@@ -540,27 +559,26 @@
     }
 
     /**
-     * Opens a {@code Device} instance with the specified hardware addressing information and
-     * configuration. The type of the device is inferred from the configuration type. An
-     * instance of the first <em>available</em> matching {@code Device}. If a matching
-     * {@code Device} is already open (therefore <em>not available</em>) the next matching
-     * {@code Device} is considered.
-     * <p />
-     * Opening a {@code Device} instance with hardware addressing information and configuration
+     * Opens a device, returning a {@code Device} instance of the specified type to access it.
+     * The device to open is designated by the provided hardware addressing information and is
+     * initially set-up according to the specified configuration.
+     * The type of the device is inferred from the configuration type.
+     * <p>
+     * Opening a device from its hardware addressing information and with an ad-hoc configuration
      * may be subject to <a href="#probing">device probing limitations </a>.
-     * <p />
+     * </p><p>
      * The device is opened in exclusive access mode.
-     * <p />
+     * </p><p>
      * The returned {@code Device} instance's ID and name are undefined.
-     * <p />
      * A new instance is returned upon each call.
+     * </p>
      *
      * @param <P>
      *            the type of the device to open.
      * @param config
      *            the device configuration (which includes hardware addressing information as
      *            well as configuration parameters).
-     * @return a {@code Device} instance for the specified configuration.
+     * @return a new {@code Device} instance to access the designated device.
      * @throws UnsupportedDeviceTypeException
      *             if the designated device type is not supported.
      * @throws InvalidDeviceConfigException
@@ -586,23 +604,22 @@
     }
 
     /**
-     * Opens a {@code Device} instance with the specified hardware addressing information and
-     * configuration. The type of the device is inferred from the configuration type. An
-     * instance of the first <em>available</em> matching {@code Device} is returned. If a
-     * matching {@code Device} is already open in a mode that is not compatible with the
-     * requested mode the next matching {@code Device} is considered.
-     * <p />
-     * Opening a {@code Device} instance with hardware addressing information and configuration
-     * may be subject to <a href="#probing">device probing limitations </a>.
-     * <p />
+     * Opens a device, returning a {@code Device} instance of the specified type to access it.
+     * The device to open is designated by the provided hardware addressing information and is
+     * initially set-up according to the specified configuration.
+     * The type of the device is inferred from the configuration type.
+     * <p>
+     * Opening a device from its hardware addressing information and with an ad-hoc configuration
+     * may be subject to <a href="#probing">device probing limitations</a>.
+     * </p><p>
      * The device is opened in the designated access mode. A device may be
      * opened in shared mode if supported by the underlying driver and hardware and if it is not
      * already opened in exclusive mode. A device may be opened in exclusive mode if
      * supported by the underlying driver and hardware and if it is not already opened.
-     * <p />
+     * </p><p>
      * The returned {@code Device} instance's ID and name are undefined.
-     * <p />
      * A new instance is returned upon each call.
+     * </p>
      *
      * @param <P>
      *            the type of the device to open.
@@ -611,7 +628,7 @@
      *            well as configuration parameters).
      * @param mode
      *            the access mode, one of: {@link #EXCLUSIVE} or {@link #SHARED}.
-     * @return a {@code Device} instance for the specified configuration.
+     * @return a new {@code Device} instance to access the designated device.
      * @throws UnsupportedDeviceTypeException
      *             if the designated device type is not supported.
      * @throws InvalidDeviceConfigException
@@ -641,20 +658,24 @@
     }
 
     /**
-     * Looks up and opens a {@code Device} instance for the specified name, type and/or
-     * properties. An instance of the first <em>available</em> matching {@code Device} is
-     * returned. If a matching {@code Device} is already open in a mode that is not compatible
-     * with the requested mode the next matching {@code Device} is considered.
-     * <p />
+     * Looks up then opens a device designated by the provided name, type and properties,
+     * returning a {@code Device} instance of the specified type to access it.
+     * A registered device configuration matching the provided name, type and properties is first looked up;
+     * if the device designated by the retrieved hardware addressing information is <em>available</em>
+     * it is open and initially set-up according to the matching configuration;
+     * if the device is already open in a mode that is not compatible
+     * with the requested mode the next matching registered device configuration is considered.
+     * <p>
      * The device is opened in the designated access mode. A device may be
      * opened in shared mode if supported by the underlying driver and hardware and if it is not
      * already opened in exclusive mode. A device may be opened in exclusive mode if
      * supported by the underlying driver and hardware and if it is not already opened.
-     * <p />
+     * </p><p>
      * A new instance is returned upon each call.
-     * <p />
+     * </p><p>
      * Property-based lookup only uses exact (case-insensitive) matching and does not perform any
      * semantic interpretation.
+     * </p>
      *
      * @param <P>
      *            the type of the device to open.
@@ -667,7 +688,7 @@
      *            the access mode, one of: {@link #EXCLUSIVE} or {@link #SHARED}.
      * @param properties
      *            the list of required properties; may be {@code null}.
-     * @return a {@code Device} instance for the given name and required properties.
+     * @return a new {@code Device} instance to access the designated device.
      * @throws UnsupportedDeviceTypeException
      *             if the designated device type is not supported.
      * @throws DeviceNotFoundException
@@ -767,17 +788,21 @@
     }
 
     /**
-     * Looks up and opens a {@code Device} instance for the specified name, type and/or
-     * properties. An instance of the first <em>available</em> matching {@code Device} is
-     * returned. If a matching {@code Device} is already open (therefore <em>not available</em>)
-     * the next matching {@code Device} is considered.
-     * <p />
+     * Looks up then opens a device designated by the provided name, type and properties,
+     * returning a {@code Device} instance of the specified type to access it.
+     * A registered device configuration matching the provided name, type and properties is first looked up;
+     * if the device designated by the retrieved hardware addressing information is <em>available</em>
+     * it is open and initially set-up according to the matching configuration;
+     * if the device is already open (therefore <em>not available</em>)
+     * the next matching registered device configuration is considered.
+     * <p>
      * The device is opened in exclusive access mode.
-     * <p />
+     * </p><p>
      * A new instance is returned upon each call.
-     * <p />
+     * </p><p>
      * Property-based lookup only uses exact (case-insensitive) matching and does not perform any
      * semantic interpretation.
+     * </p>
      *
      * @param <P>
      *            the type of the device to open.
@@ -788,7 +813,7 @@
      *            up.
      * @param properties
      *            the list of required properties; may be {@code null}.
-     * @return a {@code Device} instance for the given name and required properties.
+     * @return a new {@code Device} instance to access the designated device.
      * @throws UnsupportedDeviceTypeException
      *             if the designated device type is not supported.
      * @throws DeviceNotFoundException
@@ -822,38 +847,41 @@
      * supporting the provided configuration. Upon successful registration all
      * {@link RegistrationListener} instances registered for the type of the registered device
      * are notified.
-     * <p />
-     * An implementation of the {@code DeviceManager} must guarantee that an application
+     * <p>
+     * An implementation of the {@code DeviceManager} MUST guarantee that an application
      * registering a device is the first one to get notified (in the event it has registered a
      * {@code RegistrationListener} for that type of devices).
-     * <p />
+     * </p><p>
      * The designated device may be probed to check if the provided configuration is valid
      * (see <a href="#probing">device probing limitations </a>).
-     * <p />
+     * </p><p>
      * Prior to registering a new device of a certain type the
      * {@link DeviceMgmtPermission} is checked with the action
-     * {@link DeviceMgmtPermission#REGISTER DeviceMgmtPermission.REGISTER}. <br />
+     * {@link DeviceMgmtPermission#REGISTER DeviceMgmtPermission.REGISTER}. <br>
      * For example, if a device of type {@link jdk.dio.gpio.GPIOPin
      * GPIOPin} is to be registered the {@code DeviceMgmtPermission} is checked with a target
      * name composed of the requested device name and ID and with the action
-     * {@code DeviceMgmtPermission#REGISTER DeviceMgmtPermission.REGISTER}.
-     * <p />
+     * {@link DeviceMgmtPermission#REGISTER DeviceMgmtPermission.REGISTER}.
+     * </p><p>
      * The following is an example of how this method may be used to register a new UART with Modem
-     * control lines: <blockquote>
-     *
+     * control lines:</p><blockquote>
      * <pre>
-     * DeviceManager.register(10, // the device ID
-     *         ModemUART.class, // the device type/interface
-     *         new UARTConfig(0, 2400, UARTConfig.DATABITS_8, UARTConfig.PARITY_EVEN, UARTConfig.STOPBITS_1,
-     *                 UARTConfig.FLOWCONTROL_NONE), // the device configuration
-     *         &quot;MODEM&quot;, // the device name
-     *         &quot;com.foobar.modem.xxx=true&quot;, &quot;com.foobar.modem.yyy=true&quot; // the device capabilities
+     * DeviceManager.register(10, <i>// the device ID</i>
+     *         ModemUART.class, <i>// the device type/interface</i>
+     *         new UARTConfig.Builder()
+     *             .setControllerNumber(0)
+     *             .setChannelNumber(0)
+     *             .setBaudRate(2400)
+     *             .setDataBits(UARTConfig.DATABITS_8)
+     *             .setParity(UARTConfig.PARITY_EVEN)
+     *             .setStopBits(UARTConfig.STOPBITS_1)
+     *             .setFlowControlMode(UARTConfig.FLOWCONTROL_NONE)
+     *             .build(), <i>// the device configuration</i>
+     *         &quot;MODEM&quot;, <i>// the device name</i>
+     *         &quot;com.foobar.modem.xxx=true&quot;, &quot;com.foobar.modem.yyy=true&quot; <i>// the device capabilities</i>
      * );
      * </pre>
      * </blockquote>
-     * This method cannot be used to register a device of a
-     * custom type. If an attempt is made to register a custom implementation of
-     * {@link DeviceConfig} a {@code UnsupportedDeviceTypeException} will be thrown.
      *
      * @param <P>
      *            the type of the device to be registered.
@@ -983,15 +1011,16 @@
      * Unregisters the device associated with the specified ID. Upon successful
      * unregistration all {@link RegistrationListener} instances registered for the type of the
      * device that has been unregistered are notified.
-     * <p />
+     * <p>
      * Some devices are registered by the underlying platform and cannot be unregistered.
-     * <p />
+     * </p><p>
      * Unregistration of a device has no side effect on its currently open
      * {@code Device} instances. These {@code Device} instances especially retain the
      * device ID that was assigned to them at the time they were open.
-     * <p />
+     * </p><p>
      * This method returns silently if the provided ID does not correspond to a registered
      * device.
+     * </p>
      *
      * @param id
      *            the ID of the device to unregister.
--- a/src/share/classes/jdk/dio/DeviceMgmtPermission.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/DeviceMgmtPermission.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio;
 
 import java.security.Permission;
@@ -35,11 +34,11 @@
 /**
  * The {@code DeviceMgmtPermission} class defines permissions for registering and unregistering devices as
  * well as opening devices using their registered configurations.
- * <p />
+ * <p>
  * Device management permissions have a target name and actions.
- * <p />
+ * </p><p>
  * The target name is a combination of a device name and of a device ID or range of device IDs.
- * It takes the following form:
+ * It takes the following form:</p>
  * <blockquote>
  * <code>{device-name-spec} [ ":"{device-id-spec} ]</code>
  * </blockquote>
@@ -51,7 +50,8 @@
  * <code>{device-name} | "*" | ""</code>
  * </blockquote>
  * The <code>{device-name}</code>string is a device name as may be returned by a call to {@link DeviceDescriptor#getName() DeviceDescriptor.getName}.
- * <br />
+ * Occurrences of the semicolon character ({@code ":"}) must be escaped with a backslash ({@code "\"}).
+ * <br>
  * A <code>{device-name-spec}</code> specification consisting of the asterisk ("*") matches all device names.
  * A <code>{device-name-spec}</code> specification consisting of the empty string ("") designates an undefined device name
  * that may only be matched by an empty string or an asterisk.
@@ -64,25 +64,28 @@
  * </blockquote>
  * The <code>{device-id}</code> string is a device ID as may be returned by a call to {@link DeviceDescriptor#getID() DeviceDescriptor.getID}.
  * The characters in the string must all be decimal digits.
- * <br />
+ * <br>
+ * A <code>{device-id-spec}</code> specification of the form "N-M" (where N and M are device IDs) designates
+ * a range of device IDs from N (inclusive) to M (inclusive), where M is greater or equal to N.
  * A <code>{device-id-spec}</code> specification of the form "N-" (where N is a device ID) signifies all device IDs
  * numbered N and above, while a specification of the form "-N" indicates all device IDs numbered N and below.
  * A single asterisk in the place of the <code>{device-id-spec}</code> field matches all device IDs.
- * <p />
+ * <br>
  * The target name {@code "*:*"} matches all device names and all device IDs as is the target name {@code "*"}.
  * </dd>
  * </dl>
+ * <p>
  * The actions to be granted are passed to the constructor in a string containing a list of one or more comma-separated
- * keywords. The possible keywords are {@code register} and {@code unregister}. Their
- * meaning is defined as follows:
+ * keywords. The supported actions are {@code open}, {@code register} and {@code unregister}. Their
+ * meaning is defined as follows:</p>
  * <dl>
  * <dt>{@code open}</dt>
  * <dd>open a device using its device ID or name (see {@link DeviceManager#open(int) DeviceManager.open(id, ...)}
  * and {@link DeviceManager#open(java.lang.String, java.lang.Class, java.lang.String[]) DeviceManager.open(name, ...)} methods)</dd>
  * <dt>{@code register}</dt>
- * <dd>register a new device</dd>
+ * <dd>register a new device (see {@link DeviceManager#register DeviceManager.register})</dd>
  * <dt>{@code unregister}</dt>
- * <dd>unregister a device</dd>
+ * <dd>unregister a device (see {@link DeviceManager#unregister DeviceManager.unregister})</dd>
  * </dl>
  *
  * @see DeviceManager#open DeviceManager.open
@@ -113,6 +116,10 @@
 
     /**
      * Constructs a new {@code DeviceMgmtPermission} instance with the specified target name and action list.
+     * The target name is normalized so that leading and trailing spaces are removed
+     * and each occurrence of <code>{device-id}</code> is represented in its canonical
+     * decimal representation form (no leading zeros).
+     *
      *
      * @param name
      *            the target name (as defined above).
@@ -122,8 +129,11 @@
      * @throws NullPointerException
      *             if {@code name} is {@code null}.
      * @throws IllegalArgumentException
-     *             if actions is {@code null}, empty or contains an action other than the
-     *             specified possible actions.
+     *             <ul>
+     *             <li>if {@code actions} is {@code null}, empty or contains an action other than the
+     *             specified possible actions,</li>
+     *             <li>if {@code name} is not properly formatted.</li>
+     *             </ul>
      */
     public DeviceMgmtPermission(String name, String actions) {
         super(name.toString());
@@ -137,12 +147,13 @@
 
     /**
      * Checks two {@code DeviceMgmtPermission} objects for equality.
+     * Checks that {@code obj}'s class is the same as this object's class and has the
+     * same name (as returned by {@link Permission#getName Permission.getName}) and same actions (sorted as per {@link #getActions getActions}) as this object.
      *
      * @param obj
-     *            the object to test for equality with this object.
-     *
-     * @return {@code true} if {@code obj} is a {@code DeviceMgmtPermission} and has the same target name and
-     *         actions as this {@code DeviceMgmtPermission} object.
+     *         the object to test for equality with this object.
+     * @return {@code true} if {@code obj}'s class is the same as this object's class and has the same target
+     *         name and actions as this object; {@code false} otherwise.
      */
     @Override
     public boolean equals(Object obj) {
@@ -161,7 +172,12 @@
     }
 
     /**
-     * Returns the hash code value for this object.
+     * Returns the hash code value for this object. The hash code is calculated
+     * from this permission's name (as returned by {@link Permission#getName Permission.getName}) and actions (sorted as per {@link #getActions getActions})
+     * in a way that ensures that {@code permission1.equals(permission2)} implies
+     * that {@code permission1.hashCode()==permission2.hashCode()} for any two permissions,
+     * {@code permission1} and {@code permission2}, as required by the general contract of {@link Object#hashCode Object.hashCode}
+     * and the contract of {@link Permission#hashCode Permission.hashCode}.
      *
      * @return a hash code value for this object.
      */
@@ -171,12 +187,12 @@
     }
 
     /**
-     * Checks if this {@code DeviceMgmtPermission} object "implies" the specified permission.
-     * <p />
-     * More specifically, this method returns {@code true} if:
+     * Checks if this object "implies" the specified permission.
+     * <p>
+     * More specifically, this method returns {@code true} if:</p>
      * <ul>
-     * <li>{@code permission} is an instance of {@code DeviceMgmtPermission}, and
-     * <li>{@code permission}'s actions are a proper subset of this action list, and</li>
+     * <li>{@code permission}'s class is the same as this object's class, and</li>
+     * <li>{@code permission}'s actions (as returned by {@link #getActions getActions}) are a proper subset of this object's action list, and</li>
      * <li>{@code permission}'s device name, ID or range thereof
      * is included in this device name or ID range, whichever is defined.
      * </ul>
@@ -184,8 +200,8 @@
      * @param permission
      *            the permission to check against.
      *
-     * @return {@code true} if the specified permission is not {@code null} and is implied by this object, {@code false}
-     *         otherwise.
+     * @return {@code true} if the specified permission is not {@code null} and is implied by this
+     *         object, {@code false} otherwise.
      */
     @Override
     public boolean implies(Permission permission) {
@@ -307,15 +323,10 @@
      * Returns a new {@code PermissionCollection} for storing {@code DeviceMgmtPermission} objects.
      * <p>
      * {@code DeviceMgmtPermission} objects must be stored in a manner that allows them to be inserted into the
-     * collection in any order, but that also enables the {@code PermissionCollection} implies method to be implemented
+     * collection in any order, but that also enables the {@link PermissionCollection#implies PermissionCollection.implies} method to be implemented
      * in an efficient (and consistent) manner.
      *
-     * <p>
-     * If {@code null} is returned, then the caller of this method is free to store permissions of this type in any
-     * PermissionCollection they choose (one that uses a {@code Hashtable}, one that uses a {@code Vector}, etc).
-     *
-     * @return a new {@code PermissionCollection} suitable for storing {@code DeviceMgmtPermission} objects, or
-     *         {@code null} if one is not defined.
+     * @return a new {@code PermissionCollection} suitable for storing {@code DeviceMgmtPermission} objects.
      */
     @Override
     public PermissionCollection newPermissionCollection() {
--- a/src/share/classes/jdk/dio/DeviceNotFoundException.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/DeviceNotFoundException.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio;
 
 /**
--- a/src/share/classes/jdk/dio/DevicePermission.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/DevicePermission.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio;
 
 import java.security.Permission;
@@ -35,10 +34,10 @@
 
 /**
  * The {@code DevicePermission} abstract class is the superclass of all device permissions.
- * <p />
+ * <p>
  * A {@code DevicePermission} permission has a target name and, optionally, a list of actions.
- * <p />
- * The target name contains hardware addressing information. It takes the following form:
+ * </p><p>
+ * The target name contains hardware addressing information. It takes the following form:</p>
  * <blockquote> <code>( {controller-spec} ) [ ":" {channel-spec}]</code> </blockquote>
  * <dl>
  * <dt><code>{controller-spec}</code></dt>
@@ -74,14 +73,19 @@
  * </dl>
  * A <code>{channel-spec}</code> specification consisting of the asterisk ({@code "*"}) matches all
  * channels. A <code>{channel-spec}</code> specification consisting of the empty string ({@code ""})
- * designates an undefined channel that may only be matched by an empty string or an asterisk.</dd>
+ * designates an undefined channel that may only be matched by an empty string or an asterisk.
+ * <br>
+ * The {@code DevicePermission} abstract class treats the <code>{channel-desc}</code> string
+ * as an opaque string: a <code>{channel-spec}</code> string may therefore only be matched
+ * by the exact same <code>{channel-spec}</code> string or by the asterisk ({@code "*"}).
+ * </dd>
  * </dl>
  * Subclasses of {@code DevicePermission} may defined additional specific target name formats to
  * designate devices using their specific hardware addressing information.
- * <p />
+ * <p>
  * The actions to be granted are passed to the constructor in a string containing a list of one or
  * more comma-separated keywords. The supported common actions are {@code open} and
- * {@code powermanage}. Their meaning is defined as follows:
+ * {@code powermanage}. Their meaning is defined as follows:</p>
  * <dl>
  * <dt>{@code open}</dt>
  * <dd>open a device (see {@link DeviceManager#open DeviceManager.open})</dd>
@@ -98,7 +102,6 @@
  */
 @apimarker.API("device-io_1.1")
 public abstract class DevicePermission extends Permission {
-
     /**
      * The {@code open} action.
      */
@@ -116,13 +119,18 @@
     private String myActions;
 
     /**
-     * Constructs a new {@code DevicePermission} with the specified
-     * target name and the implicit {@code open} action.
+     * Constructs a new {@code DevicePermission} with the specified target name and the implicit
+     * {@code open} action.
+     * The target name is normalized so that leading and trailing spaces are removed
+     * and each occurrence of <code>{controller-number}</code> is represented in its canonical
+     * decimal representation form (without leading zeros).
      *
      * @param name
      *            the target name (as defined above).
      * @throws NullPointerException
      *             if {@code name} is {@code null}.
+     * @throws IllegalArgumentException
+     *             if {@code name} is not properly formatted.
      * @see #getName getName
      */
     public DevicePermission(String name) {
@@ -143,6 +151,9 @@
     /**
      * Constructs a new {@code DevicePermission} instance with the specified target name and
      * action list.
+     * The target name is normalized so that leading and trailing spaces are removed
+     * and each occurrence of <code>{controller-number}</code> is represented in its canonical
+     * decimal representation form (without leading zeros).
      *
      * @param name
      *            the target name (as defined above).
@@ -152,8 +163,11 @@
      * @throws NullPointerException
      *             if {@code name} is {@code null}.
      * @throws IllegalArgumentException
-     *             if actions is {@code null}, empty or contains an
-     *             action other than the specified possible actions.
+     *             <ul>
+     *             <li>if {@code actions} is {@code null}, empty or contains an action other than the
+     *             specified possible actions,</li>
+     *             <li>if {@code name} is not properly formatted.</li>
+     *             </ul>
      * @see #getName getName
      */
     public DevicePermission(String name, String actions) {
@@ -163,11 +177,13 @@
 
     /**
      * Checks two {@code DevicePermission} objects for equality.
+     * Checks that {@code obj}'s class is the same as this object's class and has the
+     * same name (as returned by {@link Permission#getName Permission.getName}) and same actions (sorted as per {@link #getActions getActions}) as this object.
      *
      * @param obj
-     *            the object to test for equality with this object.
-     * @return {@code true} if {@code obj} is a {@code DevicePermission} and has the same target
-     *         name and actions as this {@code DevicePermission} object.
+     *         the object to test for equality with this object.
+     * @return {@code true} if {@code obj}'s class is the same as this object's class and has the same target
+     *         name and actions as this object; {@code false} otherwise.
      */
     @Override
     public boolean equals(Object obj) {
@@ -209,7 +225,12 @@
     }
 
     /**
-     * Returns the hash code value for this object.
+     * Returns the hash code value for this object. The hash code is calculated
+     * from this permission's name (as returned by {@link Permission#getName Permission.getName}) and actions (sorted as per {@link #getActions getActions})
+     * in a way that ensures that {@code permission1.equals(permission2)} implies
+     * that {@code permission1.hashCode()==permission2.hashCode()} for any two permissions,
+     * {@code permission1} and {@code permission2}, as required by the general contract of {@link Object#hashCode() Object.hashCode}
+     * and the contract of {@link Permission#hashCode Permission.hashCode}.
      *
      * @return a hash code value for this object.
      */
@@ -218,16 +239,18 @@
         return (getName() + myActions).hashCode();
     }
 
-
     /**
-     * Checks if this {@code DevicePermission} object "implies" the specified permission.
-     * <p />
-     * More specifically, this method returns {@code true} if:
+     * Checks if this object "implies" the specified permission.
+     * <p>
+     * More specifically, this method returns {@code true} if:</p>
      * <ul>
-     * <li>{@code permission} is an instance of {@code DevicePermission}, and</li>
-     * <li>{@code permission}'s actions are a proper subset of this object's action list, and</li>
+     * <li>{@code permission}'s class is the same as this object's class, and</li>
+     * <li>{@code permission}'s actions (as returned by {@link #getActions getActions}) are a proper subset of this object's action list, and</li>
      * <li>{@code permission}'s hardware addressing information or range thereof is included in this
-     * {@code DevicePermission}'s hardware addressing information range.</li>
+     * object's hardware addressing information range; the implementation of this method by
+     * the {@code DevicePermission} abstract class treats the channel description (<code>{channel-desc}</code>) string
+     * as an opaque string: a channel specification (<code>{channel-spec}</code>) string may therefore only be matched
+     * by the exact same a channel specification string or by the asterisk ({@code "*"}).</li>
      * </ul>
      *
      * @param permission
@@ -317,15 +340,31 @@
      * <p>
      * {@code DevicePermission} objects must be stored in a manner that allows them to be
      * inserted into the collection in any order, but that also enables the
-     * {@code PermissionCollection} implies method to be implemented in an efficient (and
+     * {@link PermissionCollection#implies PermissionCollection.implies} method to be implemented in an efficient (and
      * consistent) manner.
+     * </p><p>
+     * For example, assuming a {@code PermissionCollection} object containing
+     * the two following {@code DevicePermission}s:</p>
+     * <ol>
+     * <li>  <code>"adc:1", "powermanage"</code></li>
+     * <li>  <code>"adc:*", "open"</code></li>
+     * </ol>
      * <p>
-     * If {@code null} is returned, then the caller of this method is free to store permissions of
-     * this type in any PermissionCollection they choose (one that uses a {@code Hashtable}, one
-     * that uses a {@code Vector}, etc).
+     * when calling the {@code implies} method on that
+     * {@code PermissionCollection} object with the {@code DevicePermission}:
+     * </p><pre>
+     *   "adc:1", "open,powermanage",
+     * </pre>
+     * <p>the {@code implies} method must take into account both the "adc:*"
+     * and "adc:1" permissions, so the effective permission is
+     * "open,powermanage", and {@code implies} returns {@code true}. The
+     * "implies" semantics for {@code DevicePermission}s are handled properly by
+     * the {@code PermissionCollection} object returned by this method. If a device-specific subclass
+     * of {@code DevicePermission} defines a different "implies" semantics then
+     * that subclass must re-implement this method accordingly.
+     * </p>
      *
-     * @return a new {@code PermissionCollection} suitable for storing {@code DevicePermission}
-     *         objects, or {@code null} if one is not defined.
+     * @return a new {@code PermissionCollection} suitable for storing {@code DevicePermission}.
      */
     @Override
     public PermissionCollection newPermissionCollection() {
--- a/src/share/classes/jdk/dio/InputRoundListener.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/InputRoundListener.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio;
 
 import java.nio.Buffer;
@@ -32,9 +31,10 @@
  * of an input round. An {@code InputRoundListener} gets invoked for each of the successive rounds
  * of an input operation when the input buffer has been filled in and input data is available for
  * processing.
- * <p />
+ * <p>
  * This interface also extends the {@link AsyncErrorHandler} interface for getting notified of
  * asynchronous I/O errors.
+ * </p>
  *
  * @param <P>
  *            the device type that generates the event to listener for.
--- a/src/share/classes/jdk/dio/InvalidDeviceConfigException.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/InvalidDeviceConfigException.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio;
 
 /**
--- a/src/share/classes/jdk/dio/OutputRoundListener.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/OutputRoundListener.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio;
 
 import java.nio.Buffer;
@@ -32,9 +31,10 @@
  * of an output round. An {@code OutputRoundListener} gets invoked for each of the successive rounds
  * of an output operation when the data has been output and the output buffer is available for
  * copying more data to output.
- * <p />
+ * <p>
  * This interface also extends the {@link AsyncErrorHandler} interface for getting notified of
  * asynchronous I/O errors.
+ * </p>
  *
  * @param <P>
  *            the device type that generates the event to listener for.
--- a/src/share/classes/jdk/dio/RegistrationEvent.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/RegistrationEvent.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio;
 
 import java.util.EventObject;
--- a/src/share/classes/jdk/dio/RegistrationListener.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/RegistrationListener.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,14 +22,13 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio;
 
 import java.util.EventListener;
 
 /**
  * The {@code RegistrationListener} interface defines methods for getting notified of the
- * registration and unregistration of devices. <br />
+ * registration and unregistration of devices. <br>
  * A {@code RegistrationListener} can be registered using the
  * {@link DeviceManager#addRegistrationListener DeviceManager.addRegistrationListener}
  * method.
--- a/src/share/classes/jdk/dio/RoundCompletionEvent.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/RoundCompletionEvent.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,14 +22,13 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio;
 
 import java.nio.*;
 
 /**
  * The {@code RoundCompletionEvent} class encapsulates the completion condition of a round of I/O
- * operation. <br />
+ * operation. <br>
  * {@code RoundCompletionEvent}s are <em>never coalesced</em>.
  *
  * @param <P>
@@ -183,7 +182,7 @@
      * Indicates whether an input buffer overrun or output buffer underrun condition occurred and
      * the I/O operation had to be suspended temporarily.
      *
-     * @return {@code true} if an input buffer overrun or output buffer underrun condition occurred.
+     * @return {@code true} if an input buffer overrun or output buffer underrun condition occurred; {@code false} otherwise.
      */
     public boolean isOnError() {
         return onError;
--- a/src/share/classes/jdk/dio/Transactional.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/Transactional.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio;
 
 import java.io.*;
@@ -37,14 +36,13 @@
  * the same I2C slave device as a combined message. An SPI driver will treat the sequence of read
  * and write operations to the same SPI slave device as a single transaction and will assert the
  * Slave Select line during the whole transaction.
- * <p />
+ * <p>
  * In order to ensure that the {@link #end end} method is always invoked, these methods should be
- * used within a {@code try ... finally} block: <blockquote>
- *
+ * used within a {@code try ... finally} block:</p><blockquote>
  * <pre>
  * try {
  *     device.begin();
- *     // read and write operations
+ *     <i>// read and write operations</i>
  * } finally {
  *     device.end();
  * }
--- a/src/share/classes/jdk/dio/UnavailableDeviceException.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/UnavailableDeviceException.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio;
 
 /**
--- a/src/share/classes/jdk/dio/UnsupportedAccessModeException.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/UnsupportedAccessModeException.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio;
 
 /**
--- a/src/share/classes/jdk/dio/UnsupportedDeviceTypeException.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/UnsupportedDeviceTypeException.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio;
 
 /**
--- a/src/share/classes/jdk/dio/adc/ADCChannel.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/adc/ADCChannel.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.adc;
 
 import jdk.dio.BufferAccess;
@@ -38,12 +37,12 @@
 /**
  * The {@code ADCChannel} interface provides methods for controlling an ADC (Analog to Digital
  * Converter) channel.
- * <p />
+ * <p>
  * One ADC device can have several channels. Analog input are sampled and converted according to the
  * ADC device resolution to raw digital values between {@link #getMinValue getMinValue} and
  * {@link #getMaxValue getMaxValue}. Actual input voltage values can be calculated from raw digital
  * values and the <em>Reference Voltage</em> value as returned by {@link #getVRefValue getVRefValue}.
- * <p />
+ * </p><p>
  * An ADC channel may be identified by the numeric ID and by the name (if any defined) that
  * correspond to its registered configuration. An {@code ADCChannel} instance can be opened by a
  * call to one of the {@link DeviceManager#open(int) DeviceManager.open(id,...)} methods
@@ -53,37 +52,56 @@
  * opened with an ad-hoc {@link ADCChannelConfig} configuration (which includes its hardware
  * addressing information) using one of the
  * {@link DeviceManager#open(jdk.dio.DeviceConfig)
- * DeviceManager.open(config,...)} it is not assigned any ID nor name.
- * <p />
+ * DeviceManager.open(config,...)} methods it is not assigned any ID nor name.
+ * </p><p>
  * Once opened, an application can read the current sampled input value of an ADC channel by calling
- * the {@link #acquire() acquire} method or can acquire the input values sampled over a period of time by
+ * the {@link #acquire() acquire()} method or can acquire the input values sampled over a period of time by
  * calling the {@link #acquire(IntBuffer)} method.
- * <p />
+ * </p><p>
  * An application can also asynchronously acquire the input values sampled at a certain rate by
  * calling the {@link #startAcquisition(IntBuffer, AcquisitionRoundListener) startAcquisition}
  * methods with a {@link AcquisitionRoundListener} instance which will get cyclicly and
  * asynchronously notified when the desired number of samples have been acquired. The analog input
  * acquisition can be stopped by calling the {@link #stopAcquisition() stopAcquisition} method.
- * <p />
+ * </p><p>
  * An application can monitor the input value by calling the
  * {@link #startMonitoring(int, int, MonitoringListener) startMonitoring} method with a low and a
  * high threshold value and {@link MonitoringListener} instance which will get asynchronously
  * notified when the input value gets out of or back in the defined range. The monitoring can be
  * stopped by calling the {@link #stopMonitoring() stopMonitoring} method.
- * <p />
+ * </p><p>
  * At most one acquisition (synchronous or asynchronous) and/or (depending on the platform) at most
  * one monitoring can be going on at any time. If an acquisition and a monitoring can be performed
  * concurrently, they will be performed at the same sampling rate (see
- * {@link #getSamplingInterval() getSamplingInterval}). They therefore respectively acquire and
+ * {@link #getSamplingInterval() getSamplingInterval}).
+ * They therefore respectively acquire and
  * monitor the same sampled input values.
- * <p />
+ * </p><p>
  * When an application is no longer using an ADC channel it should call the {@link #close() close}
  * method to close the ADC channel. Any further attempt to set or get the value of a ADC channel
  * which has been closed will result in a {@link ClosedDeviceException} been thrown.
- * <p />
+ * </p><p>
  * Asynchronous notification of range conditions or input acquisition is only loosely tied
  * to hardware-level interrupt requests. The platform does not guarantee notification in a
- * deterministic/timely manner.
+ * deterministic/timely manner.</p>
+ * <h3><a name="iomodes">Buffered I/O and Direct I/O Transfers</a></h3>
+ * A ADC channel may support buffered I/O or direct I/O operations depending on
+ * the capabilities of the underlying device hardware and driver. <br>
+ * Buffered input - input in buffering mode - may be requested by setting the
+ * input buffer size parameter of the {@link ADCChannelConfig} configuration to
+ * a value greater than {@code 0} ; whether or not the channel will indeed work
+ * in buffering mode and will use an internal input buffer of the size requested
+ * is up to the device driver. An application may check whether a channel is
+ * working in buffering mode by calling the
+ * {@link ADCChannelConfig#getInputBufferSize ADCChannelConfig.getInputBufferSize} method. <br>
+ * When a ADC channel is not working in buffering mode, direct I/O may be
+ * enabled by providing direct {@code Buffer}s to the input methods; whether
+ * efficient direct input transfers will be used depends on the underlying
+ * hardware and driver capabilities and on whether the provided buffers are
+ * suitable for such operations (see
+ * {@link BufferAccess#prepareBuffer BufferAccess.prepareBuffer}). Input methods
+ * using double buffering may only support efficient direct operations if both
+ * buffers are suitable for such operations.
  *
  * @see AcquisitionRoundListener
  * @see MonitoringListener
@@ -117,10 +135,12 @@
     int getMaxValue() throws IOException, UnavailableDeviceException, ClosedDeviceException;
 
     /**
-     * Gets the minimum input sampling interval (in microseconds) that can be set using
-     * {@link #setSamplingInterval setSamplingInterval}.
+     * Gets the minimum <em>scaled</em> input sampling interval (in microseconds) that can be set using
+     * {@link #setSamplingInterval setSamplingInterval}. The minimum <em>effective</em> sampling interval
+     * can be calculated from the currently set <em>scale factor</em> as can be retrieved using
+     * {@link #getScaleFactor getScaleFactor}.
      *
-     * @return the minimum input sampling interval (in microseconds).
+     * @return the minimum scaled input sampling interval (in microseconds).
      * @throws IOException
      *             if some other I/O error occurs.
      * @throws UnavailableDeviceException
@@ -132,6 +152,24 @@
     int getMinSamplingInterval() throws IOException, UnavailableDeviceException, ClosedDeviceException;
 
     /**
+     * Gets the maximum <em>scaled</em> input sampling interval (in microseconds) that can be set using
+     * {@link #setSamplingInterval setSamplingInterval}. The maximum <em>effective</em> sampling interval
+     * can be calculated from the currently set <em>scale factor</em> as can be retrieved using
+     * {@link #getScaleFactor getScaleFactor}.
+     *
+     * @return the maximum scaled input sampling interval (in microseconds).
+     * @throws IOException
+     *             if some other I/O error occurs.
+     * @throws UnavailableDeviceException
+     *             if this device is not currently available - such as it is locked by another
+     *             application.
+     * @throws ClosedDeviceException
+     *             if the device has been closed.
+     * @since 1.1
+     */
+    int getMaxSamplingInterval() throws IOException, UnavailableDeviceException, ClosedDeviceException;
+
+    /**
      * Returns the minimum raw value this channel can convert to. If the ADC device resolution is
      * {@code n} then the {@code min} value returned by {@link #getMinValue getMinValue} and the
      * {@code max} value returned by {@link #getMaxValue getMaxValue} are such that: <blockquote>
@@ -154,13 +192,16 @@
     int getMinValue() throws IOException, UnavailableDeviceException, ClosedDeviceException;
 
     /**
-     * Gets the input sampling interval (in microseconds). If the sampling interval was not set
-     * previously using {@link #setSamplingInterval setSamplingInterval} the device
-     * configuration-specific default value is returned.  Additionally, the value returned may differ
+     * Gets the <em>scaled</em> input sampling interval (in microseconds). The
+     * <em>effective</em> sampling interval can then be calculated from the
+     * currently set <em>scale factor</em> as can be retrieved using {@link #getScaleFactor getScaleFactor}.
+     * If the sampling interval was not
+     * set previously using {@link #setSamplingInterval setSamplingInterval}, the device
+     * configuration-specific default value is returned. Additionally, the value returned may differ
      * from the previously set or configured value as it may have been adjusted to account
-     * for the resolution or discrete sampling interval values supported by the underlying platform or driver.
+     * for the timer resolution or discrete sampling interval values supported by the underlying platform or driver.
      *
-     * @return the input sampling interval (in microseconds).
+     * @return the scaled input sampling interval (in microseconds).
      * @throws IOException
      *             if some other I/O error occurs.
      * @throws UnavailableDeviceException
@@ -172,13 +213,78 @@
     int getSamplingInterval() throws IOException, UnavailableDeviceException, ClosedDeviceException;
 
     /**
+     * Sets the sampling interval scale factor of this ADC channel.
+     * <p>
+     * If the underlying platform or driver does not support the
+     * requested scale factor value then {@code factor} will be <em>rounded
+     * down</em> to aligned to the closest lower supported discrete factor value. The resulting factor can
+     * be retrieved by a call to {@link #getScaleFactor getScaleFactor}.
+     * </p><p>
+     * If the scale factor - after adjustment - is {@code scale} and the scaled
+     * sampling interval value as returned by
+     * {@link #getSamplingInterval getSamplingInterval} is {@code sInterval}
+     * then the effective sampling interval is re-calculated as follows:</p>
+     * <blockquote>
+     * <pre>
+     * {@code eInterval = (sInterval / scale)}
+     * </pre>
+     * </blockquote>
+     *
+     * @param factor the scale factor.
+     * @throws IOException if some other I/O error occurs.
+     * @throws UnavailableDeviceException if this device is not currently
+     * available - such as it is locked by another application.
+     * @throws ClosedDeviceException if the device has been closed.
+     *
+     * @see #getScaleFactor
+     */
+    void setScaleFactor(double factor) throws IOException, UnavailableDeviceException, ClosedDeviceException;
+
+    /**
+     * Gets the sampling interval scale factor of this ADC channel. If the scale
+     * factor is {@code scale} and the scaled sampling interval value as
+     * returned by {@link #getSamplingInterval getSamplingInterval} is {@code sInterval} then the
+     * effective sampling interval is calculated as follows: <blockquote>
+     * <pre>
+     * {@code eInterval = (sInterval / scale)}
+     * </pre>
+     * </blockquote>
+     * Conversely, the scaled sampling interval value to set using
+     * {@link #setSamplingInterval} to obtain the effective sampling
+     * interval {@code eInterval} is calculated as follows: <blockquote>
+     * <pre>
+     * {@code sInterval = (eInterval * scale)}
+     * </pre>
+     * </blockquote>
+     * The scale factor also applies to the minimum and maximum scaled sampling intervals
+     * as respectively returned by {@link #getMinSamplingInterval getMinSamplingInterval}
+     * and {@link #getMaxSamplingInterval getMaxSamplingInterval}.
+     * <p>
+     * If the sampling interval scale factor was not set previously using
+     * {@link #setScaleFactor setScaleFactor}, the device configuration-specific
+     * default value is returned.
+     * </p>
+     *
+     * @return the scale factor.
+     * @throws IOException
+     *             if some other I/O error occurs.
+     * @throws UnavailableDeviceException
+     *             if this device is not currently available - such as it is locked by another
+     *             application.
+     * @throws ClosedDeviceException
+     *             if the device has been closed.
+     */
+    double getScaleFactor() throws IOException, UnavailableDeviceException, ClosedDeviceException;
+
+    /**
      * Reads the current raw sampled input value of this channel.
-     * <p />
+     * <p>
      * This method may be invoked at any time. If another thread has already initiated a synchronous
      * input acquisition upon this channel, however, then an invocation of this method will block
      * until the first operation is complete.
-     * <p />
+     * </p><p>
      * Only one acquisition (synchronous or asynchronous) can be going on at any time.
+     * </p>
      *
      * @return this channel's current raw sampled input value.
      * @throws IOException
@@ -196,57 +302,64 @@
     /**
      * Reads a sequence of raw sampled input values from this channel and copies them into the
      * provided buffer.
-     * <p />
-     * The input will be sampled according to the current input sampling interval as returned by
-     * {@link #getSamplingInterval getSamplingInterval}.
-     * <p />
+     * <p>
+     * The input will be sampled according to the current effective input sampling interval
+     * as determined by the current scaled sampling interval (see {@link #getSamplingInterval getSamplingInterval})
+     * and the current scale factor {@link #getScaleFactor getScaleFactor}.
+     * </p><p>
      * <i>r</i> {@code int} integers will be read from this channel, where <i>r</i> is the number of
      * integers remaining in the buffer, that is, {@code dst.remaining()}, at the moment this method
      * is invoked.
-     * <p />
+     * </p><p>
      * Suppose that an integer sequence of length <i>n</i> is read, where <i>{@code 0 <= n <= r}
      * </i>. This integer sequence will be transferred into the buffer so that the first integer in
      * the sequence is at index <i>p</i> and the last integer is at index <i>{@code p + n - 1}</i>,
      * where <i>p</i> is the buffer's position at the moment this method is invoked. Upon return the
      * buffer's position will be equal to <i>{@code p + n}</i>; its limit will not have changed.
-     * <p />
-     * This operation will block until the requested <i>r</i> integers are read or an error occurs.
-     * <p />
+     * <br>
+     * This operation will block until the requested <i>r</i> raw input values
+     * have been read or otherwise transferred from the driver/hardware. If this
+     * channel uses an internal input buffer and is therefore
+     * working in <a href="#iomodes">buffering mode</a> this method will block
+     * until all the <i>r</i> raw input values have been copied from the internal
+     * input buffer.
+     * </p><p>
      * This method may be invoked at any time. If another thread has already initiated a synchronous
      * input acquisition upon this channel, however, then an invocation of this method will block
      * until the first operation is complete.
-     * <p />
+     * </p><p>
      * Only one acquisition (synchronous or asynchronous) can be going on at any time.
+     * </p>
      *
      * @param dst
      *            The buffer into which integer raw sampled input values are to be transferred
      * @throws NullPointerException
      *             If {@code dst} is {@code null}.
+     * @throws IllegalStateException
+     *             if an asynchronous acquisition is already active.
      * @throws UnavailableDeviceException
      *             if this device is not currently available - such as it is locked by another
      *             application.
+     * @throws UnsupportedByteOrderException
+     *             if the byte ordering of the provided buffer is not supported (see <a href="{@docRoot}/jdk/dio/Device.html#byte_order">Device Byte Order</a>).
      * @throws ClosedDeviceException
      *             if the device has been closed.
      * @throws IOException
      *             if some other I/O error occurs.
-     * @throws IllegalStateException
-     *             if an asynchronous acquisition is already active.
      * @throws UnsupportedOperationException
      *             if an asynchronous monitoring is already active and acquisition and monitoring
      *             cannot be performed concurrently.
      */
-    void acquire(IntBuffer dst) throws IOException, UnavailableDeviceException, ClosedDeviceException;
+    void acquire(IntBuffer dst) throws IOException, UnavailableDeviceException, UnsupportedByteOrderException, ClosedDeviceException;
 
     /**
      * Returns the <em>Reference Voltage</em> value of this ADC channel. If the reference voltage is
      * {@code vRef} and the ADC device resolution is {@code n} then the actual input voltage value
      * corresponding to a raw sampled value {@code value} read on this channel can be calculated as
      * follows: <blockquote>
-     *
      * <pre>
      * {@code vInput = (value * vRef) / (2^n)}
      * </pre>
-     *
      * </blockquote>
      *
      * @return the <em>Reference Voltage</em> value of this channel.
@@ -261,24 +374,25 @@
     double getVRefValue() throws IOException, UnavailableDeviceException, ClosedDeviceException;
 
     /**
-     * Sets the input sampling interval (in microseconds). Whether changing the sampling interval
-     * has an immediate effect or not on an active (synchronous or asynchronous) acquisition is
+     * Sets the <em>scaled</em> input sampling interval (in microseconds). The
+     * <em>effective</em> sampling interval is calculated from the
+     * currently set <em>scale factor</em> as can be retrieved using {@link #getScaleFactor getScaleFactor}.
+     * Whether changing the sampling interval
+     * has an immediate effect or not on an active (synchronous or asynchronous) generation is
      * device- as well as platform-dependent.
-     * <p />
-     * The sampling time interval is expressed in microseconds; if the underlying platform or driver
-     * does not support a microsecond resolution or does not support the requested interval value
-     * then {@code interval} will be <em>rounded down</em> to accommodate the supported timer resolution
-     * or respectively aligned to the closest lower supported discrete interval value. The resulting, actual
-     * sampling interval can be retrieved by a call to {@link #getSamplingInterval() getSamplingInterval}.
+     * <p>
+     * If the underlying platform or driver does not support the requested interval value
+     * then {@code interval} will be aligned to the closest lower supported discrete interval value. The resulting, actual
+     * scaled sampling interval can be retrieved by a call to {@link #getSamplingInterval getSamplingInterval}.
+     * </p>
      *
      * @param interval
-     *            the input sampling interval (in microseconds).
+     *            the scaled input sampling interval (in microseconds).
      * @throws IOException
      *             if some other I/O error occurs.
      * @throws InvalidInputSamplingRateException
-     *             if the resulting sampling rate (i.e.: <i>(1 / {@code interval}</i>)) is higher
-     *             than the maximum supported sampling rate (i.e.: <i>(1 /
-     *             {@link #getMinSamplingInterval getMinSamplingInterval} )</i>).
+     *             if {@code interval} is greater than the maximum sampling interval (see {@link #getMaxSamplingInterval getMaxSamplingInterval})
+     *             or lower than the minimum sampling interval (see {@link #getMinSamplingInterval getMinSamplingInterval}).
      * @throws UnavailableDeviceException
      *             if this device is not currently available - such as it is locked by another
      *             application.
@@ -299,27 +413,32 @@
      * subsequent sampled input values may be lost. Reading into the buffer and notification will
      * only resume once the event has been handled. Reading and notification will immediately start
      * and will repeat until it is stopped by a call to {@link #stopAcquisition() stopAcquisition}.
-     * <p />
+     * <p>
      * <i>r</i> {@code int} integers will be read from this channel, where <i>r</i> is the number of
      * integers remaining in the buffer (possibly {@code 0}), that is, {@code dst.remaining()}, at
      * the moment this method is initially invoked and then subsequently when the listener is
      * returning.
-     * <p />
+     * </p><p>
      * Suppose that an integer sequence of length <i>n</i> is read, where <i>{@code 0 <= n <= r}
      * </i>. This integer sequence will be transferred into the buffer so that the first integer in
      * the sequence is at index <i>p</i> and the last integer is at index <i>{@code p + n - 1}</i>,
      * where <i>p</i> is the buffer's position at the moment this method is invoked and then
      * subsequently when the listener is returning. Upon invocation of the listener to fetch more
      * values to convert the buffer's position will be equal to <i>{@code p + n}</i>; its limit will
-     * not have changed. <br />
+     * not have changed. <br>
+     * If this channel
+     * uses an internal input buffer and is therefore working in <a href="#iomodes">buffering mode</a> the listener will only be
+     * invoked after all the <i>r</i> raw input values have been copied from the
+     * internal input buffer; otherwise the listener will only be invoked after all the
+     * <i>r</i> raw input values have been transferred from the driver/hardware.<br>
      * The buffer's position upon stopping this asynchronous operation by a call to
      * {@link #stopAcquisition stopAcquisition} is not predictable unless called from within the
      * listener.
-     * <p />
+     * </p><p>
      * Upon notification of the provided {@code AcquisitionRoundListener}
      * the reference to the provided {@code dst} buffer can be retrieved from the
      * {@code RoundCompletionEvent} using the {@link jdk.dio.RoundCompletionEvent#getBuffer() getBuffer} method.
-     * <br />
+     * <br>
      * A buffer with {@code 0} integers remaining to be read (that is a buffer already
      * full) at the moment this method is initially invoked or then subsequently when the listener
      * is returning will not stop the asynchronous operation; the listener is guaranteed to be
@@ -327,16 +446,18 @@
      * notification have been dispatched. The overrun condition resulting from the listener notification
      * returning with an already-full buffer will be reported on the subsequent notifications through
      * the {@link jdk.dio.RoundCompletionEvent#isOnError() RoundCompletionEvent.isOnError} method.
-     * <p />
-     * The input will be sampled according to the current input sampling interval as returned by
-     * {@link #getSamplingInterval getSamplingInterval}.
-     * <p />
+     * </p><p>
+     * The input will be sampled according to the current effective input sampling interval
+     * as determined by the current scaled sampling interval (see {@link #getSamplingInterval getSamplingInterval})
+     * and the current scale factor {@link #getScaleFactor getScaleFactor}.
+     * </p><p>
      * Only one acquisition (synchronous or asynchronous) can be going on at any time.
-     * <p />
+     * </p><p>
      * Buffers are not safe for use by multiple concurrent threads so care should
      * be taken to not access the provided buffer until the operation (or a round thereof) has completed.
      * Interfering with the asynchronous operation by accessing and modifying the provided buffer
      * concurrently may yield unpredictable results.
+     * </p>
      *
      * @param dst
      *            The buffer into which integer raw sampled input values are to be transferred.
@@ -366,7 +487,7 @@
     /**
      * Starts asynchronous analog input acquisition on this channel and reads a series of raw
      * sampled input values.
-     * <p />
+     * <p>
      * This method behaves identically to
      * {@link #startAcquisition(IntBuffer, AcquisitionRoundListener)} excepts that it uses
      * double-buffering - the provided buffers must not have a zero-capacity and must not overlap
@@ -379,11 +500,11 @@
      * the position of the current working buffer upon stopping this asynchronous operation by a call to
      * {@link #stopAcquisition stopAcquisition} is not predictable even if called from within the
      * listener.
-     * <p />
+     * </p><p>
      * Upon notification of the provided {@code AcquisitionRoundListener}
      * the reference to the  current working buffer (initially {@code dst1}) can be retrieved from the
      * {@code RoundCompletionEvent} using the {@link jdk.dio.RoundCompletionEvent#getBuffer() getBuffer} method.
-     * <br />
+     * <br>
      * A working buffer with {@code 0} integers remaining to be read (that is a buffer
      * already full) at the moment this method is initially invoked or then subsequently when the
      * listener is returning will not stop the asynchronous operation; the listener is guaranteed to
@@ -391,13 +512,14 @@
      * notification have been dispatched. The overrun condition resulting from the listener notification
      * returning with an already-full buffer will be reported on the subsequent notifications through
      * the {@link jdk.dio.RoundCompletionEvent#isOnError() RoundCompletionEvent.isOnError} method.
-     * <p />
+     * </p><p>
      * Only one acquisition (synchronous or asynchronous) can be going on at any time.
-     * <p />
+     * </p><p>
      * Buffers are not safe for use by multiple concurrent threads so care should
      * be taken to not access the provided buffers until the operation (or a round thereof) has completed.
      * Interfering with the asynchronous operation by accessing and modifying the provided buffers
      * concurrently may yield unpredictable results.
+     * </p>
      *
      * @param dst1
      *            The first buffer into which integer raw sampled input values are to be
@@ -439,21 +561,23 @@
      * {@link #stopMonitoring stopMonitoring}. Range notification operates in toggle mode: once
      * notified of an out-of-range condition the application will next only get notified of a
      * back-in-range condition and so on...
-     * <p />
-     * The sampled input value will be monitored according to the current input sampling interval as
-     * returned by {@link #getSamplingInterval getSamplingInterval}.
-     * <p />
+     * <p>
+     * The input will be sampled according to the current effective input sampling interval
+     * as determined by the current scaled sampling interval (see {@link #getSamplingInterval getSamplingInterval})
+     * and the current scale factor {@link #getScaleFactor getScaleFactor}.
+     * </p><p>
      * To only get notified when the input value gets over some threshold one may call this method
      * with the {@code low} parameter set to the value of {@link #getMinValue getMinValue}.
      * Conversely, to only get notified when the input value gets under some threshold one may call
      * this method with the {@code high} parameter set to the value of {@link #getMaxValue
      * getMaxValue}.
-     * <p />
+     * </p><p>
      * If {@code low} is lower than the minimum value returned by {@link #getMinValue getMinValue}
      * then the minimum value is assumed. If {@code high} is higher the maximum value returned by
      * {@link #getMaxValue getMaxValue}, then the maximum value is assumed.
-     * <p />
+     * </p><p>
      * Only one monitoring can be going on at any time.
+     * </p>
      *
      * @param listener
      *            the {@link MonitoringListener} instance to be notified when a range condition
@@ -485,8 +609,9 @@
     /**
      * Stops the asynchronous analog input acquisition on this channel as started by a call to one
      * of the {@link #startAcquisition startAcquisition} methods.
-     * <p />
+     * <p>
      * This method return silently if no asynchronous analog input acquisition is currently active.
+     * </p>
      *
      * @throws IOException
      *             if some other I/O error occurs.
@@ -501,8 +626,9 @@
     /**
      * Stops the range monitoring of this channel analog input as started by a call to the
      * {@link #startMonitoring startMonitoring} method.
-     * <p />
+     * <p>
      * This method return silently if no range monitoring is currently active.
+     * </p>
      *
      * @throws IOException
      *             if some other I/O error occurs.
--- a/src/share/classes/jdk/dio/adc/ADCChannelConfig.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/adc/ADCChannelConfig.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,73 +22,251 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.adc;
 
-import jdk.dio.DeviceConfig;
-import jdk.dio.InvalidDeviceConfigException;
-import jdk.dio.DeviceManager;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.util.Objects;
 
-import serializator.*;
+import jdk.dio.DeviceConfig;
+import jdk.dio.DeviceManager;
+import jdk.dio.InvalidDeviceConfigException;
+
 import romizer.DontRenameMethod;
 
+import serializator.*;
+
 /**
- * The {@code ADCChannelConfig} class encapsulates the hardware addressing information, and static
- * and dynamic configuration parameters of an ADC channel.
+ * The {@code ADCChannelConfig} class encapsulates the hardware addressing
+ * information, and static and dynamic configuration parameters of an ADC
+ * channel.
  * <p />
- * Some hardware addressing parameter, and static and dynamic configuration parameters may be set to
- * {@link #DEFAULT}. Whether such default settings are supported is platform- as well as device
- * driver-dependent.
+ * Some hardware addressing, static or dynamic configuration parameters may be
+ * set to {@link #UNASSIGNED} or {@code null} (see
+ * <a href="{@docRoot}/jdk/dio/DeviceConfig.html#default_unassigned">Unassigned,
+ * Default or Unused Parameter Values</a>).
  * <p />
  * An instance of {@code ADCChannelConfig} can be passed to the
- * {@link DeviceManager#open(DeviceConfig)} or
- * {@link DeviceManager#open(Class, DeviceConfig)} method to open the designated ADC channel
- * with the specified configuration. A {@link InvalidDeviceConfigException} is thrown when
- * attempting to open a device with an invalid or unsupported configuration.
+ * {@link DeviceManager#open(DeviceConfig) open(DeviceConfig, ...)} and
+ * {@link DeviceManager#open(Class, DeviceConfig) open(Class, DeviceConfig, ...)}
+ * methods of the {@link DeviceManager} to open the designated ADC channel with
+ * the specified configuration. A {@link InvalidDeviceConfigException} is thrown
+ * when attempting to open a device with an invalid or unsupported
+ * configuration.
  *
  * @see DeviceManager#open(DeviceConfig)
+ * @see DeviceManager#open(DeviceConfig, int)
  * @see DeviceManager#open(Class, DeviceConfig)
+ * @see DeviceManager#open(Class, DeviceConfig, int)
  * @since 1.0
  */
 @SerializeMe
 @apimarker.API("device-io_1.1_adc")
 public final class ADCChannelConfig implements DeviceConfig<ADCChannel>, DeviceConfig.HardwareAddressing {
     private String controllerName;
-    private int channelNumber = DEFAULT;
-    private int controllerNumber = DEFAULT;
-    private int resolution = DEFAULT;
-    private int samplingInterval = DEFAULT;
-    private int samplingTime = DEFAULT;
+    private int channelNumber = UNASSIGNED;
+    private int controllerNumber = UNASSIGNED;
+    private int resolution = UNASSIGNED;
+    private int samplingInterval = UNASSIGNED;
+    private int samplingTime = UNASSIGNED;
+    private double scaleFactor = 1.0;
+    private int inputBufferSize = UNASSIGNED;
 
-    // hidden constructor for serializer
+    /**
+     * The {@code Builder} class allows for creating and initializing {@code ADCChannelConfig} objects.
+     * Calls can be chained in the following manner:
+     * <blockquote>
+     * <pre>
+     *   ADCChannelConfig config = new ADCChannelConfig.Builder()
+     *           .setControllerNumber(1)
+     *           .setChannelNumber(1)
+     *           .setResolution(256)
+     *           .setScaleFactor(1.0)
+     *           .setSamplingTime(1)
+     *           .setSamplingInterval(10)
+     *           .setInputBufferSize(0)
+     *           .build();
+     * </pre>
+     * </blockquote>
+     *
+     * @since 1.1
+     */
+    @apimarker.API("device-io_1.1_adc")
+    public static final class Builder {
+        private  final ADCChannelConfig instance = new ADCChannelConfig();
+
+        /**
+         * Creates a new {@code Builder} instance.
+         */
+        public Builder() {
+
+        }
+
+        /**
+         * Creates a new {@code ADCChannelConfig} instance initialized with the
+         * values set for each configuration parameters. If a configuration parameter
+         * was not explictly set its default value will be used.
+         *
+         * @return a new initialized {@code ADCChannelConfig} instance.
+         */
+        public ADCChannelConfig build() {
+            instance.checkValues();
+            return instance;
+        }
+
+        /**
+         * Sets the controller name (default value is {@code null} if not set).
+         *
+         * @param controllerName the controller name (such as its <em>device
+         * file</em> name on UNIX systems) or {@code null}.
+         * @return this {@code Builder} instance.
+         */
+        public Builder setControllerName(String controllerName) {
+            instance.controllerName = controllerName;
+            return this;
+        }
+
+        /**
+         * Sets the channel number (default value is {@code UNASSIGNED} if not set).
+         *
+         * @param channelNumber the channel number (a positive or zero integer)
+         * or {@code DeviceConfig.UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code channelNumber} is not in
+         * the defined range.
+         */
+        public Builder setChannelNumber(int channelNumber) {
+            instance.channelNumber = channelNumber;
+            return this;
+        }
+
+        /**
+         * Sets the controller number (default value is {@code UNASSIGNED} if not set).
+         *
+         * @param controllerNumber the hardware converter's number (a positive
+         * or zero integer) or {@link #UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code controllerNumber} is not
+         * in the defined range.
+         */
+        public Builder setControllerNumber(int controllerNumber) {
+            instance.controllerNumber = controllerNumber;
+            return this;
+        }
+
+        /**
+         * Sets the resolution (default value is {@code UNASSIGNED} if not set).
+         *
+         * @param resolution the resolution in bits (a positive integer) or
+         * {@code DeviceConfig.UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code resolution} is not in the
+         * defined range.
+         */
+        public Builder setResolution(int resolution) {
+            instance.resolution = resolution;
+            return this;
+        }
+
+        /**
+         * Sets the initial <em>scaled</em> input sampling interval (default value is {@code UNASSIGNED} if not
+         * set).
+         *
+         * @param samplingInterval the initial scaled input sampling interval
+         * (the amount of time between two samples) in microseconds (a positive
+         * integer) or {@code DeviceConfig.UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code samplingInterval} is not
+         * in the defined range.
+         *
+         * @see #setScaleFactor
+         */
+        public Builder setSamplingInterval(int samplingInterval) {
+            instance.samplingInterval = samplingInterval;
+            return this;
+        }
+
+        /**
+         * Sets the <em>scaled</em> input sampling time (default value is {@code UNASSIGNED} if not set).
+         *
+         * @param samplingTime the scaled sampling time (the amount of time to
+         * take the sample) in microseconds (a positive integer) or
+         * {@code DeviceConfig.UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code samplingTime} is not in
+         * the defined range.
+         *
+         * @see #setScaleFactor
+         */
+        public Builder setSamplingTime(int samplingTime) {
+            instance.samplingTime = samplingTime;
+            return this;
+        }
+
+        /**
+         * Sets the initial input sampling interval and input
+         * sampling time scale factor (default value is {@code 1.0} if not set).
+         *
+         * @param scaleFactor the sampling time and sampling interval scale
+         * factor (a positive number).
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code scaleFactor} is not in the
+         * defined range.
+         */
+        public Builder setScaleFactor(double scaleFactor) {
+            instance.scaleFactor = scaleFactor;
+            return this;
+        }
+
+        /**
+         * Sets the requested input buffer size (default value is {@code UNASSIGNED} if not set).
+         *
+         * @param inputBufferSize the requested input buffer size in number of
+         * samples (a positive or zero integer) or
+         * {@code DeviceConfig.UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code inputBufferSize} is not in
+         * the defined range.
+         */
+        public Builder setInputBufferSize(int inputBufferSize) {
+            instance.inputBufferSize = inputBufferSize;
+            return this;
+        }
+    }
+
+        // hidden constructor for serializer
     @DontRenameMethod
-    ADCChannelConfig() {}
+    ADCChannelConfig(){}
+
     /**
-     * Creates a new {@code ADCChannelConfig} with the specified hardware addressing information and
-     * configuration parameters.
+     * Creates a new {@code ADCChannelConfig} with the specified hardware
+     * addressing information and configuration parameters.
+     * <p />
+     * The sampling interval and sampling time scale factor is set to
+     * {@code 1.0}.
      *
-     * @param controllerNumber
-     *            the hardware converter's number (a positive or zero integer) or {@link #DEFAULT}.
-     * @param channelNumber
-     *            the hardware channel's number (a positive or zero integer) or {@code DeviceConfig.DEFAULT}.
-     * @param resolution
-     *            the resolution in bits (a positive integer) or {@code DeviceConfig.DEFAULT}.
-     * @param samplingInterval
-     *            the initial input sampling interval (the amount of time between two samples) in
-     *            microseconds (a positive integer) or {@code DeviceConfig.DEFAULT}.
-     * @param samplingTime
-     *            the sampling time (the amount of time to take the sample) in microseconds (a
-     *            positive integer) or {@code DeviceConfig.DEFAULT}.
-     * @throws IllegalArgumentException
-     *             if any of the following is true:
-     *             <ul>
-     *             <li>{@code controllerNumber} is not in the defined range;</li>
-     *             <li>{@code channelNumber} is not in the defined range;</li>
-     *             <li>{@code resolution} is not in the defined range;</li>
-     *             <li>{@code samplingInterval} is not in the defined range;</li>
-     *             <li>{@code samplingTime} is not in the defined range.</li>
-     *             </ul>
+     * @param controllerNumber the hardware converter's number (a positive or
+     * zero integer) or {@link #UNASSIGNED}.
+     * @param channelNumber the hardware channel's number (a positive or zero
+     * integer) or {@code DeviceConfig.UNASSIGNED}.
+     * @param resolution the resolution in bits (a positive integer) or
+     * {@code DeviceConfig.UNASSIGNED}.
+     * @param samplingInterval the initial input sampling interval (the amount
+     * of time between two samples) in microseconds (a positive integer) or
+     * {@code DeviceConfig.UNASSIGNED}.
+     * @param samplingTime the sampling time (the amount of time to take the
+     * sample) in microseconds (a positive integer) or
+     * {@code DeviceConfig.UNASSIGNED}.
+     * @throws IllegalArgumentException if any of the following is true:
+     * <ul>
+     * <li>{@code controllerNumber} is not in the defined range;</li>
+     * <li>{@code channelNumber} is not in the defined range;</li>
+     * <li>{@code resolution} is not in the defined range;</li>
+     * <li>{@code samplingInterval} is not in the defined range;</li>
+     * <li>{@code samplingTime} is not in the defined range.</li>
+     * </ul>
+     * @deprecated As of 1.1, use {@link Builder} instead.
      */
     public ADCChannelConfig(int controllerNumber, int channelNumber, int resolution, int samplingInterval, int samplingTime) {
         this.controllerNumber = controllerNumber;
@@ -100,31 +278,33 @@
     }
 
     /**
-     * Creates a new {@code ADCChannelConfig} with the specified hardware addressing information and
-     * configuration parameters.
+     * Creates a new {@code ADCChannelConfig} with the specified hardware
+     * addressing information and configuration parameters.
+     * <p />
+     * The sampling interval and sampling time scale factor is set to
+     * {@code 1.0}.
      *
-     * @param controllerName
-     *            the controller name (such as its <em>device file</em> name on UNIX systems).
-     * @param channelNumber
-     *            the hardware channel's number (a positive or zero integer) or {@link #DEFAULT}.
-     * @param resolution
-     *            the resolution in bits (a positive integer) or {@code DeviceConfig.DEFAULT}.
-     * @param samplingInterval
-     *            the initial input sampling interval (the amount of time between two samples) in
-     *            microseconds (a positive integer) or {@code DeviceConfig.DEFAULT}.
-     * @param samplingTime
-     *            the sampling time (the amount of time to take the sample) in microseconds (a
-     *            positive integer) or {@code DeviceConfig.DEFAULT}.
-     * @throws IllegalArgumentException
-     *             if any of the following is true:
-     *             <ul>
-     *             <li>{@code channelNumber} is not in the defined range;</li>
-     *             <li>{@code resolution} is not in the defined range;</li>
-     *             <li>{@code samplingInterval} is not in the defined range;</li>
-     *             <li>{@code samplingTime} is not in the defined range.</li>
-     *             </ul>
-     * @throws NullPointerException
-     *             if {@code controllerName} is {@code null}.
+     * @param controllerName the hardware controller's name (such as its
+     * <em>device file</em> name on UNIX systems).
+     * @param channelNumber the hardware channel's number (a positive or zero
+     * integer) or {@link #UNASSIGNED}.
+     * @param resolution the resolution in bits (a positive integer) or
+     * {@code DeviceConfig.UNASSIGNED}.
+     * @param samplingInterval the initial input sampling interval (the amount
+     * of time between two samples) in microseconds (a positive integer) or
+     * {@code DeviceConfig.UNASSIGNED}.
+     * @param samplingTime the sampling time (the amount of time to take the
+     * sample) in microseconds (a positive integer) or
+     * {@code DeviceConfig.UNASSIGNED}.
+     * @throws IllegalArgumentException if any of the following is true:
+     * <ul>
+     * <li>{@code channelNumber} is not in the defined range;</li>
+     * <li>{@code resolution} is not in the defined range;</li>
+     * <li>{@code samplingInterval} is not in the defined range;</li>
+     * <li>{@code samplingTime} is not in the defined range.</li>
+     * </ul>
+     * @throws NullPointerException if {@code controllerName} is {@code null}.
+     * @deprecated As of 1.1, use {@link Builder} instead.
      */
     public ADCChannelConfig(String controllerName, int channelNumber, int resolution, int samplingInterval, int samplingTime) {
         this.controllerName = controllerName;
@@ -138,9 +318,42 @@
     }
 
     /**
+     * Creates a new {@code ADCChannelConfig} whose state is deserialized from
+     * the specified {@code InputStream}. This method may be invoked to restore
+     * the state of a {@code ADCChannelConfig} object from a persistent store.
+     *
+     * @param in the stream to read from.
+     * @return a new {@code ADCChannelConfig} instance.
+     * @throws IOException if an I/O error occurs or if the provided stream does
+     * not contain a representation of a {@code ADCChannelConfig} object.
+     *
+     * @since 1.1
+     */
+    public static ADCChannelConfig deserialize(InputStream in) throws IOException {
+        throw new IOException("Unsupported Operation");
+    }
+
+    /**
+     * Serializes the state of this {@code ADCChannelConfig} object to the
+     * specified {@code OutputStream}. This method may be invoked by the
+     * {@link jdk.dio.DeviceManager DeviceManager} to save the state of this
+     * {@code ADCChannelConfig} object to a persistent store.
+     *
+     * @param out the stream to write to.
+     * @throws IOException if an I/O error occurs.
+     *
+     * @since 1.1
+     */
+    @Override
+    public int serialize(OutputStream out) throws IOException {
+        throw new IOException("Unsupported Operation");
+    }
+
+    /**
      * Gets the configured channel number.
      *
-     * @return the hardware channel's number (a positive or zero integer) or {@link #DEFAULT}.
+     * @return the hardware channel's number (a positive or zero integer) or
+     * {@link #UNASSIGNED}.
      */
     public int getChannelNumber() {
         return channelNumber;
@@ -149,7 +362,8 @@
     /**
      * Gets the configured device number (such as the ADC converter number).
      *
-     * @return the device number (a positive or zero integer) or {@link #DEFAULT}.
+     * @return the device number (a positive or zero integer) or
+     * {@link #UNASSIGNED}.
      */
     @Override
     public int getControllerNumber() {
@@ -157,7 +371,8 @@
     }
 
     /**
-     * Gets the configured controller name (such as its <em>device file</em> name on UNIX systems).
+     * Gets the configured controller name (such as its <em>device file</em>
+     * name on UNIX systems).
      *
      * @return the controller name or {@code null}.
      */
@@ -167,60 +382,95 @@
     }
 
     /**
+     * Gets the requested or allocated input buffer size. The
+     * platform/underlying driver may or may not allocate the requested size for
+     * the input buffer. When querying the configuration of an opened or
+     * registered device the allocated buffer size is returned.
+     *
+     * @return the requested or allocated input buffer size in number of samples
+     * (a positive or zero integer).
+     *
+     * @since 1.1
+     */
+    public int getInputBufferSize() {
+        return inputBufferSize;
+    }
+
+    /**
      * Gets the configured resolution.
      *
-     * @return the resolution in bits (a positive integer) or {@link #DEFAULT}.
+     * @return the resolution in bits (a positive integer) or
+     * {@link #UNASSIGNED}.
      */
     public int getResolution() {
         return resolution;
     }
 
     /**
-     * Gets the configured default/initial input sampling interval - the amount of time between two
-     * samples (in microseconds).
+     * Gets the configured default/initial <em>scaled</em> input sampling
+     * interval - the amount of time between two samples (in microseconds).
      *
-     * @return the default/initial input sampling interval in microseconds (a positive integer) or
-     *         {@link #DEFAULT}.
+     * @return the default/initial input sampling interval in microseconds (a
+     * positive integer) or {@link #UNASSIGNED}.
+     *
+     * @see #getScaleFactor
      */
     public int getSamplingInterval() {
         return samplingInterval;
     }
 
     /**
-     * Gets the configured input sampling time - the amount of time to take the sample (in
-     * microseconds).
+     * Gets the configured <em>scaled</em> input sampling time - the amount of
+     * time to take the sample (in microseconds).
      *
-     * @return the input sampling time in microseconds (a positive integer) or {@link #DEFAULT}.
+     * @return the input sampling time in microseconds (a positive integer) or
+     * {@link #UNASSIGNED}.
+     *
+     * @see #getScaleFactor
      */
     public int getSamplingTime() {
         return samplingTime;
     }
 
     /**
+     * Gets the default/initial configured input sampling interval and input
+     * sampling time scale factor.
+     *
+     * @return the default/initial input sampling interval scale factor (a
+     * positive number).
+     *
+     * @since 1.1
+     */
+    public double getScaleFactor() {
+        return scaleFactor;
+    }
+
+    /**
      * Returns the hash code value for this object.
      *
      * @return a hash code value for this object.
      */
     @Override
     public int hashCode() {
-        int hash = 5;
-        hash = 37 * hash + Objects.hashCode(this.controllerName);
-        hash = 37 * hash + this.channelNumber;
-        hash = 37 * hash + this.controllerNumber;
-        hash = 37 * hash + this.resolution;
-        hash = 37 * hash + this.samplingInterval;
-        hash = 37 * hash + this.samplingTime;
+        int hash = 7;
+        hash = 97 * hash + Objects.hashCode(this.controllerName);
+        hash = 97 * hash + this.channelNumber;
+        hash = 97 * hash + this.controllerNumber;
+        hash = 97 * hash + this.resolution;
+        hash = 97 * hash + this.samplingInterval;
+        hash = 97 * hash + this.samplingTime;
+        hash = 97 * hash + (int) (Double.doubleToLongBits(this.scaleFactor) ^ (Double.doubleToLongBits(this.scaleFactor) >>> 32));
+        hash = 97 * hash + this.inputBufferSize;
         return hash;
     }
 
     /**
      * Checks two {@code ADCChannelConfig} objects for equality.
      *
-     * @param obj
-     *            the object to test for equality with this object.
-     * @return {@code true} if {@code obj} is a {@code ADCChannelConfig} and has the same hardware
-     *         addressing information and configuration parameter values as this
-     *         {@code ADCChannelConfig} object.
+     * @param obj the object to test for equality with this object.
+     * @return {@code true} if {@code obj} is a {@code ADCChannelConfig} and has
+     * the same hardware addressing information and configuration parameter
+     * values as this {@code ADCChannelConfig} object; {@code false} otherwise.
      */
     @Override
     public boolean equals(Object obj) {
@@ -249,8 +499,12 @@
         if (this.samplingTime != other.samplingTime) {
             return false;
         }
-        return true;
+        if (Double.doubleToLongBits(this.scaleFactor) != Double.doubleToLongBits(other.scaleFactor)) {
+            return false;
+        }
+        return this.inputBufferSize == other.inputBufferSize;
     }
+
     private void checkValues() throws IllegalArgumentException {
         if ((null == controllerName && DEFAULT > controllerNumber) ||
             DEFAULT > channelNumber ||
--- a/src/share/classes/jdk/dio/adc/ADCPermission.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/adc/ADCPermission.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.adc;
 
 import jdk.dio.DeviceManager;
@@ -45,16 +44,7 @@
  * {@link ADCChannelConfig#getChannelNumber ADCChannelConfig.getChannelNumber}. The characters in
  * the string must all be decimal digits.</dd>
  * </dl>
- * The supported actions are {@code open} and {@code powermanage}. Their meaning is defined as
- * follows:
- * <dl>
- * <dt>{@code open}</dt>
- * <dd>open and access an ADC channel functions (see {@link DeviceManager#open
- * DeviceManager.open})</dd>
- * <dt>{@code powermanage}</dt>
- * <dd>manage the power saving mode of a device (see
- * {@link jdk.dio.power.PowerManaged})</dd>
- * </dl>
+ * The supported actions are {@code open} and {@code powermanage} as defined in {@link DevicePermission}.
  *
  * @see DeviceManager#open DeviceManager.open
  * @see jdk.dio.power.PowerManaged
@@ -66,11 +56,16 @@
     /**
      * Constructs a new {@code ADCPermission} with the specified target name and the implicit
      * {@code open} action.
+     * The target name is normalized so that leading and trailing spaces are removed
+     * and each occurrence of <code>{controller-number}</code> and <code>{channel-desc}</code> is represented in its canonical
+     * decimal representation form (without leading zeros).
      *
      * @param name
      *            the target name (as defined above).
      * @throws NullPointerException
      *             if {@code name} is {@code null}.
+     * @throws IllegalArgumentException
+     *             if {@code name} is not properly formatted.
      * @see #getName getName
      */
     public ADCPermission(String name) {
@@ -80,6 +75,9 @@
     /**
      * Constructs a new {@code ADCPermission} instance with the specified target name and action
      * list.
+     * The target name is normalized so that leading and trailing spaces are removed
+     * and each occurrence of <code>{controller-number}</code> and <code>{channel-desc}</code> is represented in its canonical
+     * decimal representation form (without leading zeros).
      *
      * @param name
      *            the target name (as defined above).
@@ -89,8 +87,11 @@
      * @throws NullPointerException
      *             if {@code name} is {@code null}.
      * @throws IllegalArgumentException
-     *             if actions is {@code null}, empty or contains an
-     *             action other than the specified possible actions.
+     *             <ul>
+     *             <li>if {@code actions} is {@code null}, empty or contains an action other than the
+     *             specified possible actions,</li>
+     *             <li>if {@code name} is not properly formatted.</li>
+     *             </ul>
      * @see #getName getName
      */
     public ADCPermission(String name, String actions) {
--- a/src/share/classes/jdk/dio/adc/AcquisitionRoundListener.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/adc/AcquisitionRoundListener.java	Thu Apr 30 21:58:05 2015 +0300
@@ -31,12 +31,13 @@
 
 /**
  * The {@code AcquisitionRoundListener} interface defines methods for getting notified of the
- * availability of sampled input values. <br />
+ * availability of sampled input values. <br>
  * This interface also indirectly extends the {@link jdk.dio.AsyncErrorHandler
  * AsyncErrorHandler} interface for getting notified of asynchronous I/O errors.
- * <p />
+ * <p>
  * An {@code AcquisitionRoundListener} can be registered using one of the
  * {@link ADCChannel#startAcquisition ADCChannel.startAcquisition} methods.
+ * </p>
  *
  * @see ADCChannel#startAcquisition ADCChannel.startAcquisition
  * @since 1.0
--- a/src/share/classes/jdk/dio/adc/InvalidInputSamplingRateException.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/adc/InvalidInputSamplingRateException.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,12 +22,12 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.adc;
 
 /**
- * Thrown by an instance of {@link ADCChannel} in case the requested sampling rate is higher than
- * the maximum sampling rate the ADC device can support.
+ * Thrown by an instance of {@link ADCChannel} in case the requested sampling interval results
+ * in a sampling rate higher or lower than
+ * the maximum, respectively minimum, sampling rate/interval the ADC device can support.
  *
  * @since 1.0
  */
--- a/src/share/classes/jdk/dio/adc/MonitoringEvent.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/adc/MonitoringEvent.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.adc;
 
 import jdk.dio.DeviceEvent;
--- a/src/share/classes/jdk/dio/adc/MonitoringListener.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/adc/MonitoringListener.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.adc;
 
 import jdk.dio.AsyncErrorHandler;
--- a/src/share/classes/jdk/dio/adc/package-info.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/adc/package-info.java	Thu Apr 30 21:58:05 2015 +0300
@@ -75,7 +75,7 @@
  *
  *     public void start(int channelID) throws IOException, NonAvailableDeviceException, DeviceNotFoundException {
  *         channel = (ADCChannel) DeviceManager.open(channelID);
- *         channel.setSamplingInterval(100); // every 100 milliseconds
+ *         channel.setSamplingInterval(100); <i>// every 100 milliseconds</i>
  *         int[] values = new int[10];
  *         channel.startAcquisition(IntBuffer.wrap(values), this);
  *     }
@@ -84,7 +84,7 @@
  *         IntBuffer buffer = event.getBuffer();
  *         while (buffer.hasRemaining()) {
  *             int value = buffer.get();
- *             // Handle value...
+ *             <i>// Handle value...</i>
  *         }
  *     }
  *
@@ -96,7 +96,7 @@
  *     }
  *
  *     public void failed(Throwable exception, ADCChannel source) {
- *          // Ignored
+ *          <i>// Ignored</i>
  *     }
  * }
  * </pre>
@@ -111,14 +111,14 @@
  *     public void start(int channelID, int low, int high) throws IOException, NonAvailableDeviceException,
  *             DeviceNotFoundException {
  *         channel = (ADCChannel) DeviceManager.open(channelID);
- *         channel.setSamplingInterval(100); // every 100 milliseconds
+ *         channel.setSamplingInterval(100); <i>// every 100 milliseconds</i>
  *         channel.startMonitoring(low, high, this);
  *     }
  *
  *     public void thresholdReached(MonitoringEvent event) {
  *         if (event.getType() == MonitoringEvent.OUT_OF_RANGE) {
  *             int value = event.acquire();
- *             // Handle condition...
+ *             <i>// Handle condition...</i>
  *         }
  *     }
  *
@@ -130,7 +130,7 @@
  *     }
  *
  *     public void failed(Throwable exception, ADCChannel source) {
- *          // Ignored
+ *          <i>// Ignored</i>
  *     }
  * }
  * </pre>
--- a/src/share/classes/jdk/dio/atcmd/ATDevice.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/atcmd/ATDevice.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.atcmd;
 
 import jdk.dio.Device;
@@ -144,11 +143,38 @@
      *             application.
      * @throws ClosedDeviceException
      *             if the device has been closed.
+     * @deprecated As of 1.1, replaced by {@link #tryAbortCommand tryAbortCommand}.
      */
     void abortCommand(String abortSequence) throws IOException, UnavailableDeviceException,
             ClosedDeviceException;
 
     /**
+     * Aborts the currently executing command by sending the provided {@code abortSequence}.
+     * Abortion depends on the command's definition (abortability). Calling this method does NOT
+     * guarantee abortion of the currently executing command. It only aborts if the command supports
+     * abortion and it is currently in a proper state for abortion. The response from the AT device
+     * is returned; the application should use this response to determine if the command was
+     * successfully aborted or not. An {@code OK} result code is typically returned upon success
+     * but the response may vary.
+     *
+     * @param abortSequence
+     *            the character sequence for aborting; if {@code null} the {@code ESC} (abort)
+     *            character is sent out by default.
+     * @return the response.
+     * @throws IOException
+     *             if some other I/O error occurs.
+     * @throws UnavailableDeviceException
+     *             if this device is not currently available - such as it is locked by another
+     *             application.
+     * @throws ClosedDeviceException
+     *             if the device has been closed.
+     *
+     * @since 1.1
+     */
+    String tryAbortCommand(String abortSequence) throws IOException, UnavailableDeviceException,
+            ClosedDeviceException;
+
+    /**
      * When in data mode, calling this method will try to switch to command mode such as (depending
      * on the underlying AT device) by sending {@code "+++"} escape sequence.
      *
@@ -159,10 +185,32 @@
      *             application.
      * @throws ClosedDeviceException
      *             if the device has been closed.
+     *
+     * @deprecated As of 1.1, replaced by {@link #tryEscapeToCommandMode tryEscapeToCommandMode}.
      */
     void escapeToCommandMode() throws IOException, UnavailableDeviceException, ClosedDeviceException;
 
     /**
+     * When in data mode, calling this method will try to switch to command mode such as (depending
+     * on the underlying AT device) by sending {@code "+++"} escape sequence. The response from the AT device
+     * is returned; the application should use this response to determine if the AT device
+     * successfully escaped to command mode. An {@code OK} result code is typically returned upon success
+     * but the response may vary.
+     *
+     * @return the response.
+     * @throws IOException
+     *             if some other I/O error occurs.
+     * @throws UnavailableDeviceException
+     *             if this device is not currently available - such as it is locked by another
+     *             application.
+     * @throws ClosedDeviceException
+     *             if the device has been closed.
+     *
+     * @since 1.1
+     */
+    String tryEscapeToCommandMode() throws IOException, UnavailableDeviceException, ClosedDeviceException;
+
+    /**
      * Returns the maximum length of the command string that can be processed by the underlying AT
      * parser. Command string exceeding this value may be cut off without warning as this is a
      * default behavior of modems.
--- a/src/share/classes/jdk/dio/atcmd/ATDeviceConfig.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/atcmd/ATDeviceConfig.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,33 +22,40 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.atcmd;
 
-import jdk.dio.DeviceConfig;
-import jdk.dio.InvalidDeviceConfigException;
-import jdk.dio.DeviceManager;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.util.Objects;
 
+import jdk.dio.DeviceConfig;
+import jdk.dio.DeviceManager;
+import jdk.dio.InvalidDeviceConfigException;
+
+import romizer.DontRenameMethod;
+
 import serializator.*;
-import romizer.DontRenameMethod;
 
 /**
  * The {@code ATDeviceConfig} class encapsulates the hardware addressing information, and static and
  * dynamic configuration parameters of an AT device.
  * <p />
- * Some hardware addressing parameter, and static and dynamic configuration parameters may be set to
- * {@link #DEFAULT}. Whether such default settings are supported is platform- as well as device
- * driver-dependent.
+ * Some hardware addressing, static or dynamic configuration parameters may be
+ * set to {@link #UNASSIGNED} or {@code null} (see
+ * <a href="{@docRoot}/jdk/dio/DeviceConfig.html#default_unassigned">Unassigned, Default or Unused Parameter Values</a>).
  * <p />
  * An instance of {@code ATDeviceConfig} can be passed to the
- * {@link DeviceManager#open(DeviceConfig)} or
- * {@link DeviceManager#open(Class, DeviceConfig)} method to open the designated AT device
+ * {@link DeviceManager#open(DeviceConfig) open(DeviceConfig, ...)} and
+ * {@link DeviceManager#open(Class, DeviceConfig) open(Class, DeviceConfig, ...)}
+ * methods of the {@link DeviceManager} to open the designated AT device
  * with the specified configuration. A {@link InvalidDeviceConfigException} is thrown when
  * attempting to open a device with an invalid or unsupported configuration.
  *
  * @see DeviceManager#open(DeviceConfig)
+ * @see DeviceManager#open(DeviceConfig, int)
  * @see DeviceManager#open(Class, DeviceConfig)
+ * @see DeviceManager#open(Class, DeviceConfig, int)
  * @since 1.0
  */
 @SerializeMe
@@ -57,9 +64,9 @@
 
     private String controllerName;
 
-    private int controllerNumber = DEFAULT;
+    private int controllerNumber = UNASSIGNED;
 
-    private int channelNumber = DEFAULT;
+    private int channelNumber = UNASSIGNED;
 
     // hidden constructor for serializer
     @DontRenameMethod
@@ -71,7 +78,7 @@
      * @param controllerName
      *            the controller name (such as its <em>device file</em> name on UNIX systems).
      * @param channelNumber
-     *            the hardware channel's number (a positive or zero integer) or {@link #DEFAULT}.
+     *            the hardware channel's number (a positive or zero integer) or {@link #UNASSIGNED}.
      * @throws IllegalArgumentException
      *             if {@code channelNumber} is not in the defined range.
      * @throws NullPointerException
@@ -91,9 +98,9 @@
      * Creates a new {@code ATDeviceConfig} with the specified hardware addressing information.
      *
      * @param controllerNumber
-     *            the controller number (a positive or zero integer) or {@link #DEFAULT}.
+     *            the controller number (a positive or zero integer) or {@link #UNASSIGNED}.
      * @param channelNumber
-     *            the hardware channel's number (a positive or zero integer) or {@link #DEFAULT}.
+     *            the hardware channel's number (a positive or zero integer) or {@link #UNASSIGNED}.
      * @throws IllegalArgumentException
      *             if {@code channelNumber} is not in the defined range.
      */
@@ -106,9 +113,41 @@
     }
 
     /**
+     * Creates a new {@code ATDeviceConfig} whose state is deserialized from the specified {@code InputStream}.
+     * This method may be invoked to restore the state of a {@code ATDeviceConfig}
+     * object from a persistent store.
+     *
+     * @param in the stream to read from.
+     * @return a new {@code ATDeviceConfig} instance.
+     * @throws IOException if an I/O error occurs or if the provided stream does not
+     * contain a representation of a {@code ATDeviceConfig} object.
+     *
+     * @since 1.1
+     */
+    public static ATDeviceConfig deserialize(InputStream in) throws IOException {
+      throw new IOException("Unsupported Operation");
+    }
+
+
+    /**
+     * Serializes the state of this {@code ATDeviceConfig} object to the specified {@code OutputStream}.
+     * This method may be invoked by the {@link jdk.dio.DeviceManager DeviceManager}
+     * to save the state of this {@code ATDeviceConfig} object to a persistent store.
+     *
+     * @param out the stream to write to.
+     * @throws IOException if an I/O error occurs.
+     *
+     * @since 1.1
+     */
+    @Override
+    public int serialize(OutputStream out) throws IOException {
+      throw new IOException("Unsupported Operation");
+    }
+
+    /**
      * Gets the configured channel number.
      *
-     * @return the channel number (a positive or zero integer); or {@link #DEFAULT}.
+     * @return the channel number (a positive or zero integer); or {@link #UNASSIGNED}.
      */
     public int getChannelNumber() {
         return channelNumber;
@@ -117,7 +156,7 @@
     /**
      * Gets the configured controller number.
      *
-     * @return the controller number (a positive or zero integer) or {@link #DEFAULT}.
+     * @return the controller number (a positive or zero integer) or {@link #UNASSIGNED}.
      */
     @Override
     public int getControllerNumber() {
@@ -155,7 +194,7 @@
      *            the object to test for equality with this object.
      * @return {@code true} if {@code obj} is a {@code ATDeviceConfig} and has the same hardware
      *         addressing information and configuration parameter values as this
-     *         {@code ATDeviceConfig} object.
+     *         {@code ATDeviceConfig} object; {@code false} otherwise.
      */
     @Override
     public boolean equals(Object obj) {
@@ -172,9 +211,6 @@
         if (this.controllerNumber != other.controllerNumber) {
             return false;
         }
-        if (this.channelNumber != other.channelNumber) {
-            return false;
-        }
-        return true;
+        return this.channelNumber == other.channelNumber;
     }
 }
--- a/src/share/classes/jdk/dio/atcmd/ATPermission.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/atcmd/ATPermission.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.atcmd;
 
 import jdk.dio.DeviceManager;
@@ -46,15 +45,10 @@
  * {@link ATDeviceConfig#getChannelNumber ATDeviceConfig.getChannelNumber}. The characters in the string must all be decimal digits.
  * </dd>
  * </dl>
- * The actions to be granted are passed to the constructor in a string containing a list of one or more comma-separated
- * keywords. The supported keywords are {@code open}, {@code data} and {@code powermanage}. Their meaning is defined as follows:
+ * The supported actions are {@code open} and {@code powermanage} as defined in {@link DevicePermission}, and {@code data} defined as follows:
  * <dl>
- * <dt>{@code open}</dt>
- * <dd>open and access an AT device functions (see {@link DeviceManager#open})</dd>
  * <dt>{@code data}</dt>
  * <dd>open data connections (see {@link ATDevice#openDataConnection})</dd>
- * <dt>{@code powermanage}</dt>
- * <dd>manage the power saving mode of a device (see {@link jdk.dio.power.PowerManaged})</dd>
  * </dl>
  *
  * @see DeviceManager#open DeviceManager.open
@@ -72,12 +66,17 @@
 
     /**
      * Constructs a new {@code ATPermission} with the specified target name and implicit {@code open} action.
+     * The target name is normalized so that leading and trailing spaces are removed
+     * and each occurrence of <code>{controller-number}</code> and <code>{channel-desc}</code> is represented in its canonical
+     * decimal representation form (without leading zeros).
      *
      * @param name
      *            the target name (as defined above).
      *
      * @throws NullPointerException
      *             if {@code name} is {@code null}.
+     * @throws IllegalArgumentException
+     *             if {@code name} is not properly formatted.
      *
      * @see #getName getName
      */
@@ -87,6 +86,9 @@
 
     /**
      * Constructs a new {@code ATPermission} instance with the specified target name and action list.
+     * The target name is normalized so that leading and trailing spaces are removed
+     * and each occurrence of <code>{controller-number}</code> and <code>{channel-desc}</code> is represented in its canonical
+     * decimal representation form (without leading zeros).
      *
      * @param name
      *            the target name (as defined above).
@@ -95,8 +97,11 @@
      * @throws NullPointerException
      *             if {@code name} is {@code null}.
      * @throws IllegalArgumentException
-     *             if actions is {@code null}, empty or contains an action other than the
-     *             specified possible actions.
+     *             <ul>
+     *             <li>if {@code actions} is {@code null}, empty or contains an action other than the
+     *             specified possible actions,</li>
+     *             <li>if {@code name} is not properly formatted.</li>
+     *             </ul>
      */
     public ATPermission(String name, String actions) {
         super(name, ActionFactory.verifyAndOrderActions(actions, DevicePermission.OPEN + "," + DATA + "," + DevicePermission.POWER_MANAGE));
--- a/src/share/classes/jdk/dio/atcmd/CommandResponseHandler.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/atcmd/CommandResponseHandler.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.atcmd;
 
 /**
@@ -53,8 +52,14 @@
      *            the {@code ATDevice} instance issuing the response.
      * @param response
      *            the response to handle or {@code null} if the response was too long or in case of an un-handled error.
-     * @return complementary input if an intermediate result code requiring input (such as a prompt) was provided; or
-     *         {@code null} if no additional input is required (such as final result code was received).
+     * @return
+     * <ul>
+     * <li>complementary input if an intermediate result code requiring input (such as a prompt) was provided;</li>
+     * <li>an empty string if no additional input is required, still no final result code was received yet;</li>
+     * <li>or {@code null} if a final result code was received.</li>
+     * </ul>
+     *
+     * @since 1.1 Clarified the use of empty string return values.
      */
     String processResponse(ATDevice atDevice, String response);
 }
--- a/src/share/classes/jdk/dio/atcmd/DataConnection.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/atcmd/DataConnection.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.atcmd;
 
 import java.nio.channels.ByteChannel;
--- a/src/share/classes/jdk/dio/atcmd/DataConnectionHandler.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/atcmd/DataConnectionHandler.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.atcmd;
 
 /**
--- a/src/share/classes/jdk/dio/atcmd/UnsolicitedResponseHandler.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/atcmd/UnsolicitedResponseHandler.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.atcmd;
 
 /**
--- a/src/share/classes/jdk/dio/atcmd/package-info.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/atcmd/package-info.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 /**
  * Interfaces and classes for controlling a Data Communication Equipment such as a modem or a
  * cellular module using AT commands.
@@ -95,32 +94,32 @@
  *     }
  *
  *     public String processResponse(ATDevice modem, String response) {
- *         // Assume that command echo has been previously disabled (such as with an {@code ATE0} command).
+ *         <i>// Assume that command echo has been previously disabled (such as with an {@code ATE0} command).</i>
  *
- *         if (response.equals(&quot;&gt; \n&quot;)) { // Prompt for text
+ *         if (response.equals(&quot;&gt; \n&quot;)) { <i>// Prompt for text</i>
  *             return text;
  *         } else if (response.equals(&quot;OK\n&quot;)) {
- *             status = SENT;  // Sent successfully
+ *             status = SENT;  <i>// Sent successfully</i>
  *         } else if (response.contains(&quot;ERROR&quot;)) {
- *             status = ERROR; // Failed to send
+ *             status = ERROR; <i>// Failed to send</i>
  *         }
  *         return null;
  *     }
  * }
  *
  * public boolean sendSMS(final String number, final String text) {
- *     // Acquire a modem with &quot;sms&quot; properties
+ *     <i>// Acquire a modem with &quot;sms&quot; properties</i>
  *     try {
  *         if (modem == null) {
  *             modem = DeviceManager.open(null, ATDevice.class, &quot;jdk.dio.atcmd.sms=true&quot;);
  *         }
- *         // Send SMS command
+ *         <i>// Send SMS command</i>
  *         SMSHandler sh = new SMSHandler(text);
  *         modem.sendCommand(&quot;AT+CMGS=\&quot;&quot; + number + &quot;\&quot;\n&quot;, sh);
  *         status = SUBMITTED;
- *         return true; // Submitted successfully
+ *         return true; <i>// Submitted successfully</i>
  *     } catch (IOException ioe) {
- *         return false; // Failed to submit
+ *         return false; <i>// Failed to submit</i>
  *     }
  * }
  *
@@ -133,7 +132,7 @@
  *         try {
  *             modem.close();
  *         } catch (IOException ex) {
- *             // Ignored
+ *             <i>// Ignored</i>
  *         }
  *     }
  * }
--- a/src/share/classes/jdk/dio/counter/CounterPermission.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/counter/CounterPermission.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.counter;
 
 import jdk.dio.DeviceManager;
@@ -45,16 +44,7 @@
  * {@code PulseCounterConfig#getChannelNumber}. The characters in the string must all be decimal
  * digits.</dd>
  * </dl>
- * The supported actions are {@code open} and {@code powermanage}. Their meaning is defined as
- * follows:
- * <dl>
- * <dt>{@code open}</dt>
- * <dd>open and access a pulse counter functions (see {@link DeviceManager#open
- * DeviceManager.open})</dd>
- * <dt>{@code powermanage}</dt>
- * <dd>manage the power saving mode of a device (see
- * {@link jdk.dio.power.PowerManaged})</dd>
- * </dl>
+ * The supported actions are {@code open} and {@code powermanage} as defined in {@link DevicePermission}.
  *
  * @see DeviceManager#open DeviceManager.open
  * @see jdk.dio.power.PowerManaged
@@ -66,11 +56,16 @@
     /**
      * Constructs a new {@code CounterPermission} with the specified target name and the implicit
      * {@code open} action.
+     * The target name is normalized so that leading and trailing spaces are removed
+     * and each occurrence of <code>{controller-number}</code> and <code>{channel-desc}</code> is represented in its canonical
+     * decimal representation form (without leading zeros).
      *
      * @param name
      *            the target name (as defined above).
      * @throws NullPointerException
      *             if {@code name} is {@code null}.
+     * @throws IllegalArgumentException
+     *             if {@code name} is not properly formatted.
      * @see #getName getName
      */
     public CounterPermission(String name) {
@@ -80,6 +75,9 @@
     /**
      * Constructs a new {@code CounterPermission} instance with the specified target name and action
      * list.
+     * The target name is normalized so that leading and trailing spaces are removed
+     * and each occurrence of <code>{controller-number}</code> and <code>{channel-desc}</code> is represented in its canonical
+     * decimal representation form (without leading zeros).
      *
      * @param name
      *            the target name (as defined above).
@@ -89,8 +87,11 @@
      * @throws NullPointerException
      *             if {@code name} is {@code null}.
      * @throws IllegalArgumentException
-     *             if actions is {@code null}, empty or contains an
-     *             action other than the specified possible actions.
+     *             <ul>
+     *             <li>if {@code actions} is {@code null}, empty or contains an action other than the
+     *             specified possible actions,</li>
+     *             <li>if {@code name} is not properly formatted.</li>
+     *             </ul>
      * @see #getName getName
      */
     public CounterPermission(String name, String actions) {
--- a/src/share/classes/jdk/dio/counter/CountingEvent.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/counter/CountingEvent.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.counter;
 
 import jdk.dio.DeviceEvent;
--- a/src/share/classes/jdk/dio/counter/CountingListener.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/counter/CountingListener.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.counter;
 
 import jdk.dio.AsyncErrorHandler;
--- a/src/share/classes/jdk/dio/counter/PulseCounter.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/counter/PulseCounter.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,14 +22,16 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.counter;
 
+import java.io.IOException;
+
+import jdk.dio.ClosedDeviceException;
 import jdk.dio.Device;
 import jdk.dio.DeviceManager;
-import jdk.dio.ClosedDeviceException;
 import jdk.dio.UnavailableDeviceException;
-import java.io.IOException;
+import jdk.dio.gpio.GPIOPin;
+
 import romizer.WeakDontRenameClass;
 
 /**
@@ -45,7 +47,7 @@
  * opened with an ad-hoc {@link PulseCounterConfig} configuration (which includes its hardware
  * addressing information) using one of the
  * {@link DeviceManager#open(jdk.dio.DeviceConfig)
- * DeviceManager.open(config,...)} it is not assigned any ID nor name.
+ * DeviceManager.open(config,...)} methods it is not assigned any ID nor name.
  * <p />
  * Once opened, an application can either start a pulse counting session using the
  * {@link #startCounting() startCounting} method and retrieve the current pulse count on-the-fly
@@ -73,9 +75,17 @@
  * Asynchronous notification of pulse counting conditions is only loosely tied to
  * hardware-level interrupt requests. The platform does not guarantee notification in a
  * deterministic/timely manner.
+ * <h3><a name="permission">Permission Requirement For Pulse Counters Configured with an Explicit GPIO Input Pin</a></h3>
+ * Opening a {@code PulseCounter} instance with an ad-hoc configuration requires
+ * the {@link jdk.dio.counter.CounterPermission CounterPermission.OPEN} to be granted;
+ * opening an instance of a {@code PulseCounter} configured with an explicit {@code GPIOPin} input
+ * on which the pulses are to be counted requires, in addition, the
+ * {@link jdk.dio.gpio.GPIOPinPermission GPIOPinPermission.OPEN} permission to be granted
+ * on the designated GPIO pin.
  *
  * @see CountingListener
  * @see CounterPermission
+ * @see jdk.dio.gpio.GPIOPinPermission
  * @since 1.0
  */
 @apimarker.API("device-io_1.1_counter")
@@ -226,4 +236,17 @@
      *             if counting is not active.
      */
     void suspendCounting() throws IOException, UnavailableDeviceException, ClosedDeviceException;
+
+    /**
+     * Gets the input source on which the pulses are counted/measured.
+     * <p />
+     * A concurrent runtime change of the dynamic configuration parameters of
+     * the source (such as of its direction) may result in {@code IOException}
+     * being thrown by counting operations.
+     *
+     * @return the source on which the pulses are to counted/measured; or {@code null} if the source is implicit.
+     *
+     * @since 1.1
+     */
+    GPIOPin getSource();
 }
--- a/src/share/classes/jdk/dio/counter/PulseCounterConfig.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/counter/PulseCounterConfig.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,11 +22,15 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.counter;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.util.Objects;
 
+import com.oracle.dio.utils.ExceptionMessage;
+
 import jdk.dio.DeviceConfig;
 import jdk.dio.DeviceDescriptor;
 import jdk.dio.DeviceManager;
@@ -34,27 +38,29 @@
 import jdk.dio.gpio.GPIOPin;
 import jdk.dio.gpio.GPIOPinConfig;
 
-import com.oracle.dio.utils.ExceptionMessage;
+import romizer.*;
 
-import romizer.*;
 import serializator.*;
 
 /**
  * The {@code PulseCounterConfig} class encapsulates the hardware addressing information, and static
  * and dynamic configuration parameters of a pulse counter.
  * <p />
- * Some hardware addressing parameter, and static and dynamic configuration parameters may be set to
- * {@link #DEFAULT}. Whether such default settings are supported is platform- as well as device
- * driver-dependent.
+ * Some hardware addressing, static or dynamic configuration parameters may be
+ * set to {@link #UNASSIGNED} or {@code null} (see
+ * <a href="{@docRoot}/jdk/dio/DeviceConfig.html#default_unassigned">Unassigned, Default or Unused Parameter Values</a>).
  * <p />
  * An instance of {@code PulseCounterConfig} can be passed to the
- * {@link DeviceManager#open(DeviceConfig)} or
- * {@link DeviceManager#open(Class, DeviceConfig)} method to open the designated counter
+ * {@link DeviceManager#open(DeviceConfig) open(DeviceConfig, ...)} and
+ * {@link DeviceManager#open(Class, DeviceConfig) open(Class, DeviceConfig, ...)}
+ * methods of the {@link DeviceManager} to open the designated counter
  * with the specified configuration. A {@link InvalidDeviceConfigException} is thrown when
  * attempting to open a device with an invalid or unsupported configuration.
  *
  * @see DeviceManager#open(DeviceConfig)
+ * @see DeviceManager#open(DeviceConfig, int)
  * @see DeviceManager#open(Class, DeviceConfig)
+ * @see DeviceManager#open(Class, DeviceConfig, int)
  * @since 1.0
  */
 @SerializeMe
@@ -90,16 +96,142 @@
 
     private String controllerName;
 
-    private int controllerNumber = DEFAULT;
+    private int controllerNumber = UNASSIGNED;
 
-    private int channelNumber = DEFAULT;
+    private int channelNumber = UNASSIGNED;
 
     private GPIOPinConfig sourceConfig;
 
-    private GPIOPin source;
 
     private int type;
 
+    /**
+     * The {@code Builder} class allows for creating and initializing
+     * {@code PulseCounterConfig} objects. Calls can be chained in the following
+     * manner:
+     * <blockquote>
+     * <pre>
+     *   PulseCounterConfig config = new PulseCounterConfig.Builder()
+     *           .setControllerNumber(1)
+     *           .setChannelNumber(1)
+     *           .setType(TYPE_NEGATIVE_PULSE)
+     *           .build();
+     * </pre>
+     * </blockquote>
+     *
+     * @since 1.1
+     */
+    @apimarker.API("device-io_1.1_counter")
+    public static final class Builder {
+
+        private final PulseCounterConfig instance = new PulseCounterConfig();
+
+        /**
+         * Creates a new {@code Builder} instance.
+         */
+        public Builder() {
+
+        }
+
+        /**
+         * Creates a new {@code PulseCounterConfig} instance initialized with
+         * the values set for each configuration parameters. If a configuration
+         * parameter was not explictly set its default value will be used.
+         *
+         * @return a new initialized {@code PulseCounterConfig} instance.
+         * @throws IllegalStateException if any of the following is true:
+         * <ul>
+         * <li>the pulse or pulse edge type is not set.</li>
+         * </ul>
+         */
+        public PulseCounterConfig build() {
+            instance.checkValues();
+            return instance;
+        }
+
+        /**
+         * Sets the controller name (default value is {@code null} if not set).
+         *
+         * @param controllerName the controller name (such as its <em>device
+         * file</em> name on UNIX systems) or {@code null}.
+         * @return this {@code Builder} instance.
+         */
+        public Builder setControllerName(String controllerName) {
+            instance.controllerName = controllerName;
+            return this;
+        }
+
+        /**
+         * Sets the channel/counter number (default value is {@code UNASSIGNED} if not
+         * set).
+         *
+         * @param channelNumber the channel/counter number (a positive or zero integer)
+         * or {@code DeviceConfig.UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code channelNumber} is not in
+         * the defined range.
+         */
+        public Builder setChannelNumber(int channelNumber) {
+            instance.channelNumber = channelNumber;
+            return this;
+        }
+
+        /**
+         * Sets the controller number (default value is {@code UNASSIGNED} if
+         * not set).
+         *
+         * @param controllerNumber the controller number (a positive
+         * or zero integer) or {@link #UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code controllerNumber} is not
+         * in the defined range.
+         */
+        public Builder setControllerNumber(int controllerNumber) {
+            instance.controllerNumber = controllerNumber;
+            return this;
+        }
+
+        /**
+         * Sets the configuration of the source (a GPIO input pin) on which the pulses are to be
+         * counted (default value is {@code null} if not set).
+         *
+         * @param source the configuration of the source (a GPIO input pin); or {@code null} if the source is
+         * implicit.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code source} is not
+         * {@code null} and is not configured for input.
+         */
+        public Builder setSourceConfig(GPIOPinConfig source) {
+            instance.sourceConfig = source;
+            return this;
+        }
+
+        /**
+         * Sets the pulse or pulse edge type.
+         *
+         * @param type the pulse or pulse edge type: {@link #TYPE_FALLING_EDGE_ONLY},
+         *            {@link #TYPE_RISING_EDGE_ONLY}, {@link #TYPE_NEGATIVE_PULSE} or
+         * {@link #TYPE_POSITIVE_PULSE}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code type} is not in the
+         * defined range.
+         */
+        public Builder setType(int type) {
+            instance.type = type;
+            return this;
+        }
+    }
+
+    private PulseCounterConfig(PulseCounterConfig prototype) {
+        if (prototype != null) {
+            this.controllerName = prototype.controllerName;
+            this.channelNumber = prototype.channelNumber;
+            this.controllerNumber = prototype.controllerNumber;
+            this.sourceConfig = prototype.sourceConfig;
+            this.type = prototype.type;
+        }
+    }
+
     // hidden constructor for serializer
     @DontRenameMethod
     PulseCounterConfig(){}
@@ -109,9 +241,9 @@
      * and type. The source of the pulse counter is implicit (such as a dedicated input pin).
      *
      * @param controllerNumber
-     *            the hardware controller's number (a positive or zero integer) or {@link #DEFAULT}.
+     *            the hardware controller's number (a positive or zero integer) or {@link #UNASSIGNED}.
      * @param channelNumber
-     *            the hardware counter's number (a positive or zero integer) or {@link #DEFAULT}.
+     *            the hardware counter's number (a positive or zero integer) or {@link #UNASSIGNED}.
      * @param type
      *            the pulse or pulse edge type: {@link #TYPE_FALLING_EDGE_ONLY},
      *            {@link #TYPE_RISING_EDGE_ONLY}, {@link #TYPE_NEGATIVE_PULSE} or
@@ -123,6 +255,8 @@
      *             <li>{@code channelNumber} is not in the defined range;</li>
      *             <li>{@code type} is not one of the defined values.</li>
      *             </ul>
+     *
+     * @deprecated As of 1.1, use {@link Builder} instead.
      */
     public PulseCounterConfig(int controllerNumber, int channelNumber, int type) {
         this.controllerNumber = controllerNumber;
@@ -136,9 +270,9 @@
      * and GPIO pin source.
      *
      * @param controllerNumber
-     *            the hardware controller's number (a positive or zero integer) or {@link #DEFAULT}.
+     *            the hardware controller's number (a positive or zero integer) or {@link #UNASSIGNED}.
      * @param channelNumber
-     *            the hardware counter's number (a positive or zero integer) or {@link #DEFAULT}.
+     *            the hardware counter's number (a positive or zero integer) or {@link #UNASSIGNED}.
      * @param type
      *            the pulse or pulse edge type: {@link #TYPE_FALLING_EDGE_ONLY},
      *            {@link #TYPE_RISING_EDGE_ONLY}, {@link #TYPE_NEGATIVE_PULSE} or
@@ -158,6 +292,8 @@
      *             </ul>
      * @throws NullPointerException
      *             if {@code source} is {@code null}.
+     *
+     * @deprecated As of 1.1, use {@link Builder} instead.
      */
     public PulseCounterConfig(int controllerNumber, int channelNumber, int type, GPIOPinConfig source) {
         this.controllerNumber = controllerNumber;
@@ -176,7 +312,7 @@
      * @param controllerName
      *            the controller name (such as its <em>device file</em> name on UNIX systems).
      * @param channelNumber
-     *            the hardware counter's number (a positive or zero integer) or {@link #DEFAULT}.
+     *            the hardware counter's number (a positive or zero integer) or {@link #UNASSIGNED}.
      * @param type
      *            the pulse or pulse edge type: {@link #TYPE_FALLING_EDGE_ONLY},
      *            {@link #TYPE_RISING_EDGE_ONLY}, {@link #TYPE_NEGATIVE_PULSE} or
@@ -189,6 +325,8 @@
      *             <li>{@code channelNumber} is not in the defined range;</li>
      *             <li>{@code type} is not one of the defined values.</li>
      *             </ul>
+     *
+     * @deprecated As of 1.1, use {@link Builder} instead.
      */
     public PulseCounterConfig(String controllerName, int channelNumber, int type) {
         // checks for null
@@ -206,7 +344,7 @@
      * @param controllerName
      *            the controller name (such as its <em>device file</em> name on UNIX systems).
      * @param channelNumber
-     *            the hardware counter's number (a positive or zero integer) or {@link #DEFAULT}.
+     *            the hardware counter's number (a positive or zero integer) or {@link #UNASSIGNED}.
      * @param type
      *            the pulse or pulse edge type: {@link #TYPE_FALLING_EDGE_ONLY},
      *            {@link #TYPE_RISING_EDGE_ONLY}, {@link #TYPE_NEGATIVE_PULSE} or
@@ -225,6 +363,8 @@
      *             </ul>
      * @throws NullPointerException
      *             if {@code controllerName} or {@code source} is {@code null}.
+     *
+     * @deprecated As of 1.1, use {@link Builder} instead.
      */
     public PulseCounterConfig(String controllerName, int channelNumber, int type, GPIOPinConfig source) {
         // checks for null
@@ -239,9 +379,41 @@
     }
 
     /**
+     * Creates a new {@code PulseCounterConfig} whose state is deserialized from the specified {@code InputStream}.
+     * This method may be invoked to restore the state of a {@code PulseCounterConfig}
+     * object from a persistent store.
+     *
+     * @param in the stream to read from.
+     * @return a new {@code PulseCounterConfig} instance.
+     * @throws IOException if an I/O error occurs or if the provided stream does not
+     * contain a representation of a {@code PulseCounterConfig} object.
+     *
+     * @since 1.1
+     */
+    public static PulseCounterConfig deserialize(InputStream in) throws IOException {
+      throw new IOException("Unsupported Operation");
+    }
+
+
+    /**
+     * Serializes the state of this {@code PulseCounterConfig} object to the specified {@code OutputStream}.
+     * This method may be invoked by the {@link jdk.dio.DeviceManager DeviceManager}
+     * to save the state of this {@code PulseCounterConfig} object to a persistent store.
+     *
+     * @param out the stream to write to.
+     * @throws IOException if an I/O error occurs.
+     *
+     * @since 1.1
+     */
+    @Override
+    public int serialize(OutputStream out) throws IOException {
+      throw new IOException("Unsupported Operation");
+    }
+
+    /**
      * Gets the configured controller number.
      *
-     * @return the controller number (a positive or zero integer); or {@link #DEFAULT}.
+     * @return the controller number (a positive or zero integer); or {@link #UNASSIGNED}.
      */
     @Override
     public int getControllerNumber() {
@@ -251,7 +423,7 @@
     /**
      * Gets the configured counter number.
      *
-     * @return the counter number (a positive or zero integer); or {@link #DEFAULT}.
+     * @return the counter number (a positive or zero integer); or {@link #UNASSIGNED}.
      */
     public int getChannelNumber() {
         return channelNumber;
@@ -260,7 +432,7 @@
     /**
      * Gets the configured controller name (such as its <em>device file</em> name on UNIX systems).
      *
-     * @return the controllerName or {@code null}.
+     * @return the controller name or {@code null}.
      */
     @Override
     public String getControllerName() {
@@ -276,9 +448,11 @@
      *
      * @return the source on which the pulses are to be counted/measured; or {@code null} if the source is implicit
      * or if this {@code PusleCounterConfig} instance is not associated to an actual {@code PulseCounter} instance.
+     *
+     * @deprecated As of 1.1, replaced by {@link PulseCounter#getSource PulseCounter.getSource}.
      */
     public GPIOPin getSource() {
-        return source;
+        return null;
     }
 
     /**
@@ -315,7 +489,6 @@
         hash = 83 * hash + this.controllerNumber;
         hash = 83 * hash + this.channelNumber;
         hash = 83 * hash + Objects.hashCode(this.sourceConfig);
-        hash = 83 * hash + Objects.hashCode(this.source);
         hash = 83 * hash + this.type;
         return hash;
     }
@@ -327,7 +500,7 @@
      *            the object to test for equality with this object.
      * @return {@code true} if {@code obj} is a {@code PulseCounterConfig} and has the same hardware
      *         addressing information and configuration parameter values as this
-     *         {@code PulseCounterConfig} object.
+     *         {@code PulseCounterConfig} object; {@code false} otherwise.
      */
     @Override
     public boolean equals(Object obj) {
@@ -350,13 +523,7 @@
         if (!Objects.equals(this.sourceConfig, other.sourceConfig)) {
             return false;
         }
-        if (!Objects.equals(this.source, other.source)) {
-            return false;
-        }
-        if (this.type != other.type) {
-            return false;
-        }
-        return true;
+        return this.type == other.type;
     }
 
     private void checkValues() throws IllegalArgumentException {
--- a/src/share/classes/jdk/dio/counter/package-info.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/counter/package-info.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 /**
  * Interfaces and classes for counting pulses (or events) on a digital input line.
  * <p />
@@ -57,10 +56,10 @@
  * value at any time (on-the-fly) by calling the {@code getCount}. <blockquote>
  *
  * <pre>
- * counter.startCounting(); // Start counting pulses
- * // Perform some task...
- * int count = counter.getCount(); // Retrieve the number of pulses that occurred while performing the task
- * counter.stopCounting(); // Stop counting pulses
+ * counter.startCounting(); <i>// Start counting pulses</i>
+ * <i>// Perform some task...</i>
+ * int count = counter.getCount(); <i>// Retrieve the number of pulses that occurred while performing the task</i>
+ * counter.stopCounting(); <i>// Stop counting pulses</i>
  * </pre>
  * </blockquote> When done, the application should call the
  * {@link jdk.dio.counter.PulseCounter#close close} method to close Pulse counter.
@@ -79,12 +78,12 @@
  *
  *     public void start(int counterID) throws IOException, NonAvailableDeviceException, DeviceNotFoundException {
  *         counter = (PulseCounter) DeviceManager.open(counterID);
- *         counter.startCounting(-1, 1000, this); // Count events occuring during 1 second (without terminal count value)
+ *         counter.startCounting(-1, 1000, this); <i>// Count events occuring during 1 second (without terminal count value)</i>
  *     }
  *
  *     public void countValueAvailable(CountingEvent event) {
  *         int count = event.getValue();
- *         // Handle pulse count...
+ *         <i>// Handle pulse count...</i>
  *     }
  *
  *     public void stop() throws IOException {
--- a/src/share/classes/jdk/dio/dac/DACChannel.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/dac/DACChannel.java	Thu Apr 30 21:58:05 2015 +0300
@@ -50,7 +50,7 @@
  * opened with an ad-hoc {@link DACChannelConfig} configuration (which includes its hardware
  * addressing information) using one of the
  * {@link DeviceManager#open(jdk.dio.DeviceConfig)
- * DeviceManager.open(config,...)} it is not assigned any ID nor name.
+ * DeviceManager.open(config,...)} methods it is not assigned any ID nor name.
  * <p />
  * Once opened, an application can write an output value to a DAC channel by calling the
  * {@link #generate(int) generate(int)} method or can write a series of output values to be
@@ -72,7 +72,25 @@
  * Asynchronous notification of output generation completion is only loosely tied to
  * hardware-level interrupt requests. The platform does not guarantee notification in a
  * deterministic/timely manner.
- *
+ * <h3><a name="iomodes">Buffered I/O and Direct I/O Transfers</a></h3>
+ * A DAC channel may support buffered I/O or direct I/O operations depending on
+ * the capabilities of the underlying device hardware and driver. <br />
+ * Buffered output - output in buffering mode - may be requested by setting the
+ * output buffer size parameter of the {@link DACChannelConfig} configuration to
+ * a value greater than {@code 0} ; whether or not the channel will indeed work
+ * in buffering mode and will use an internal output buffer of the size requested
+ * is up to the device driver. An application may check whether a channel is
+ * working in buffering mode by calling the
+ * {@link DACChannelConfig#getOutputBufferSize DACChannelConfig.getOutputBufferSize} method. <br />
+ * When a DAC channel is not working in buffering mode, direct I/O may be
+ * enabled by providing direct {@code Buffer}s to the output methods; whether
+ * efficient direct output transfers will be used depends on the underlying
+ * hardware and driver capabilities and on whether the provided buffers are
+ * suitable for such operations (see
+ * {@link BufferAccess#prepareBuffer BufferAccess.prepareBuffer}). Output methods
+ * using double buffering may only support efficient direct operations if both
+ * buffers are suitable for such operations.
+  *
  * @see GenerationRoundListener
  * @since 1.0
  */
@@ -103,10 +121,12 @@
     int getMaxValue() throws IOException, UnavailableDeviceException, ClosedDeviceException;
 
     /**
-     * Gets the minimum output sampling interval (in microseconds) that can be set using
-     * {@link #setSamplingInterval setSamplingInterval}.
+     * Gets the minimum <em>scaled</em> output sampling interval (in microseconds) that can be set using
+     * {@link #setSamplingInterval setSamplingInterval}. The minimum <em>effective</em> sampling interval
+     * can be calculated from the currently set <em>scale factor</em> as can be retrieved using
+     * {@link #getScaleFactor getScaleFactor}.
      *
-     * @return the minimum output sampling interval (in microseconds).
+     * @return the minimum scaled output sampling interval (in microseconds).
      * @throws IOException
      *             if some other I/O error occurs.
      * @throws UnavailableDeviceException
@@ -118,6 +138,24 @@
     int getMinSamplingInterval() throws IOException, UnavailableDeviceException, ClosedDeviceException;
 
     /**
+     * Gets the maximum <em>scaled</em> output sampling interval (in microseconds) that can be set using
+     * {@link #setSamplingInterval setSamplingInterval}. The maximum <em>effective</em> sampling interval
+     * can be calculated from the currently set <em>scale factor</em> as can be retrieved using
+     * {@link #getScaleFactor getScaleFactor}.
+     *
+     * @return the maximum scaled output sampling interval (in microseconds).
+     * @throws IOException
+     *             if some other I/O error occurs.
+     * @throws UnavailableDeviceException
+     *             if this device is not currently available - such as it is locked by another
+     *             application.
+     * @throws ClosedDeviceException
+     *             if the device has been closed.
+     * @since 1.1
+     */
+    int getMaxSamplingInterval() throws IOException, UnavailableDeviceException, ClosedDeviceException;
+
+    /**
      * Returns the minimum raw value this channel can convert. If the DAC device resolution is
      * {@code n} then the {@code min} value returned by {@link #getMinValue getMinValue} and the
      * {@code max} value returned by {@link #getMaxValue getMaxValue} are such that: <blockquote>
@@ -140,13 +178,16 @@
     int getMinValue() throws IOException, UnavailableDeviceException, ClosedDeviceException;
 
     /**
-     * Gets the output sampling interval (in microseconds). If the output sampling interval was not
-     * set previously using {@link #setSamplingInterval setSamplingInterval} the device
+     * Gets the <em>scaled</em> output sampling interval (in microseconds). The
+     * <em>effective</em> sampling interval can then be calculated from the
+     * currently set <em>scale factor</em> as can be retrieved using {@link #getScaleFactor getScaleFactor}.
+     * If the sampling interval was not
+     * set previously using {@link #setSamplingInterval setSamplingInterval}, the device
      * configuration-specific default value is returned. Additionally, the value returned may differ
      * from the previously set or configured value as it may have been adjusted to account
-     * for the resolution or discrete sampling interval values supported by the underlying platform or driver.
+     * for the timer resolution or discrete sampling interval values supported by the underlying platform or driver.
      *
-     * @return the output sampling interval (in microseconds).
+     * @return the scaled output sampling interval (in microseconds).
      * @throws IOException
      *             if some other I/O error occurs.
      * @throws UnavailableDeviceException
@@ -181,24 +222,87 @@
     double getVRefValue() throws IOException, UnavailableDeviceException, ClosedDeviceException;
 
     /**
-     * Sets the output sampling interval (in microseconds). Whether changing the sampling interval
+     * Sets the sampling interval scale factor of this DAC channel.
+     * <p />
+     * If the underlying platform or driver does not support the
+     * requested scale factor value then {@code factor} will be <em>rounded
+     * down</em> to aligned to the closest lower supported discrete factor value. The resulting factor can
+     * be retrieved by a call to {@link #getScaleFactor getScaleFactor}.
+     * <p />
+     * If the scale factor - after adjustment - is {@code scale} and the scaled
+     * sampling interval value as returned by
+     * {@link #getSamplingInterval getSamplingInterval} is {@code sInterval}
+     * then the effective sampling interval is re-calculated as follows:
+     * <blockquote>
+     * <pre>
+     * {@code eInterval = (sInterval / scale)}
+     * </pre>
+     * </blockquote>
+     *
+     * @param factor the scale factor.
+     * @throws IOException if some other I/O error occurs.
+     * @throws UnavailableDeviceException if this device is not currently
+     * available - such as it is locked by another application.
+     * @throws ClosedDeviceException if the device has been closed.
+     *
+     * @see #getScaleFactor
+     */
+    void setScaleFactor(double factor) throws IOException, UnavailableDeviceException, ClosedDeviceException;
+
+    /**
+     * Gets the sampling interval scale factor of this DAC channel. If the scale
+     * factor is {@code scale} and the scaled sampling interval value as
+     * returned by {@link #getSamplingInterval getSamplingInterval} is {@code sInterval} then the
+     * effective sampling interval is calculated as follows: <blockquote>
+     * <pre>
+     * {@code eInterval = (sInterval / scale)}
+     * </pre>
+     * </blockquote>
+     * Conversely, the scaled sampling interval value to set using
+     * {@link #setSamplingInterval} to obtain the effective sampling
+     * interval {@code eInterval} is calculated as follows: <blockquote>
+     * <pre>
+     * {@code sInterval = (eInterval * scale)}
+     * </pre>
+     * </blockquote>
+     * The scale factor also applies to the minimum and maximum scaled sampling intervals
+     * as respectively returned by {@link #getMinSamplingInterval getMinSamplingInterval}
+     * and {@link #getMaxSamplingInterval getMaxSamplingInterval}.
+     * <p />
+     * If the sampling interval scale factor was not set previously using
+     * {@link #setScaleFactor setScaleFactor}, the device configuration-specific
+     * default value is returned.
+     *
+     * @return the scale factor.
+     * @throws IOException
+     *             if some other I/O error occurs.
+     * @throws UnavailableDeviceException
+     *             if this device is not currently available - such as it is locked by another
+     *             application.
+     * @throws ClosedDeviceException
+     *             if the device has been closed.
+     */
+    double getScaleFactor() throws IOException, UnavailableDeviceException, ClosedDeviceException;
+
+    /**
+     * Sets the <em>scaled</em> output sampling interval (in microseconds). The
+     * <em>effective</em> sampling interval is calculated from the
+     * currently set <em>scale factor</em> as can be retrieved using {@link #getScaleFactor getScaleFactor}.
+     * Whether changing the sampling interval
      * has an immediate effect or not on an active (synchronous or asynchronous) generation is
      * device- as well as platform-dependent.
      * <p />
-     * The sampling time interval is expressed in microseconds; if the underlying platform or driver
-     * does not support a microsecond resolution or does not support the requested interval value
-     * then {@code interval} will be <em>rounded down</em> to accommodate the supported timer resolution
-     * or respectively aligned to the closest lower supported discrete interval value. The resulting, actual
-     * sampling interval can be retrieved by a call to {@link #getSamplingInterval() getSamplingInterval}.
+     * If the underlying platform or driver does not support the requested interval value
+     * then {@code interval} will be aligned to the closest lower supported discrete interval value. The resulting, actual
+     * scaled sampling interval can be retrieved by a call to {@link #getSamplingInterval getSamplingInterval}.
      *
      * @param interval
-     *            the output sampling interval (in microseconds).
+     *            the scaled output sampling interval (in microseconds).
      * @throws IOException
      *             if some other I/O error occurs.
      * @throws InvalidOutputSamplingRateException
-     *             if the resulting sampling rate (i.e.: <i>(1 / {@code interval}</i>)) is higher
-     *             than the maximum supported sampling rate (i.e.: <i>(1 /
-     *             {@link #getMinSamplingInterval getMinSamplingInterval} )</i>).
+     *             if {@code interval} is greater than the maximum sampling interval (see {@link #getMaxSamplingInterval getMaxSamplingInterval})
+     *             or lower than the minimum sampling interval (see {@link #getMinSamplingInterval getMinSamplingInterval}).
      * @throws UnavailableDeviceException
      *             if this device is not currently available - such as it is locked by another
      *             application.
@@ -241,21 +345,27 @@
      * Writes a sequence of raw output values from the provided buffer to this channel for
      * conversion.
      * <p />
-     * The raw output values will be converted according to the current output sampling interval as
-     * returned by {@link #getSamplingInterval getSamplingInterval}.
+     * The raw output values will be converted according to the current effective output sampling interval
+     * as determined by the current scaled sampling interval (see {@link #getSamplingInterval getSamplingInterval})
+     * and the current scale factor {@link #getScaleFactor getScaleFactor}.
      * <p />
      * <i>r</i> integers will be written to this channel, where <i>r</i> is the number of integers
      * remaining in the buffer, that is, {@code src.remaining()}, at the moment this method is
      * invoked.
      * <p />
-     * <p />
      * Suppose that an integer sequence of length <i>n</i> is written, where <i>{@code 0 <= n <= r}
      * </i>. This integer sequence will be transferred from the buffer starting at index <i>p</i>,
      * where <i>p</i> is the buffer's position at the moment this method is invoked; the index of
      * the last integer written will be <i>{@code p + n - 1}</i>. Upon return the buffer's position
-     * will be equal to <i>{@code p + n}</i>; its limit will not have changed.
-     * <p />
-     * The operation will return only after writing all of the <i>r</i> requested integers.
+     * will be equal to <i>{@code p + n}</i>; its limit will not have changed. <br />
+     * This operation will return only after all of the <i>r</i> raw output values
+     * remaining in the provided {@code src} buffer have been written or otherwise
+     * transferred to the driver/hardware. If this channel uses an internal output buffer and
+     * is therefore working in <a href="#iomodes">buffering mode</a> this method will block until all the
+     * <i>r</i> raw output values have been copied to the internal output buffer.
+     * <br />
+     * The buffer's position upon stopping this asynchronous operation by a call
+     * to {@link #stopGeneration()  stopGeneration} is not predictable unless called from within the listener.
      * <p />
      * This method may be invoked at any time. If another thread has already initiated a synchronous
      * output generation upon this channel, however, then an invocation of this method will block
@@ -285,7 +395,7 @@
      *             if the device has been closed.
      * @throws IOException
      *             if some other I/O error occurs.
-     */
+      */
     void generate(IntBuffer src) throws IOException, UnavailableDeviceException, UnsupportedByteOrderException, ClosedDeviceException;
 
     /**
@@ -309,17 +419,15 @@
      * The buffer's position upon stopping this asynchronous operation by a call to
      * {@link #stopGeneration stopGeneration} is not predictable unless called from within the
      * listener. <br />
-     * If the provided {@code src} buffer is a direct buffer fulfilling the direct
-     * I/O requirements of this device (see {@link #prepareBuffer(java.nio.Buffer, int) prepareBuffer}) then the listener will only
-     * be invoked after all the <i>r</i> raw output values remaining in the provided
-     * {@code src} buffer have been consumed by the driver/hardware. If this channel
-     * uses an output buffer and is therefore working in buffering mode the listener will only be
+     * If this channel
+     * uses an internal output buffer and is therefore working in <a href="#iomodes">buffering mode</a> the listener will only be
      * invoked after all the <i>r</i> raw output values have been copied to the
-     * output buffer; otherwise the listener will only be invoked after all the
-     * <i>r</i> raw output values have been consumed by the driver/hardware.
+     * internal output buffer; otherwise the listener will only be invoked after all the
+     * <i>r</i> raw output values have been transferred to the driver/hardware.
      * <p />
-     * The raw output values (samples) will be converted according to the current output sampling
-     * interval as returned by {@link #getSamplingRate getSamplingRate}.
+     * The raw output values will be converted according to the current effective output sampling interval
+     * as determined by the current scaled sampling interval (see {@link #getSamplingInterval getSamplingInterval})
+     * and the current scale factor {@link #getScaleFactor getScaleFactor}.
      * <p />
      * Upon notification of the provided {@code GenerationRoundListener}
      * the reference to the provided {@code src} buffer can be retrieved from the
@@ -383,15 +491,7 @@
      * will only be suspended if the previous event has not yet been handled. Also,
      * the position of the current working buffer upon stopping this asynchronous operation by a call to
      * {@link #stopGeneration stopGeneration} is not predictable even if called from within the
-     * listener. <br />
-     * If both buffers are direct buffer fulfilling the direct I/O requirements of
-     * this device (see {@link #prepareBuffer(java.nio.Buffer, int) prepareBuffer} ) then the
-     * listener will only be invoked after all the raw output values remaining in
-     * the current working buffer are consumed by the driver/hardware; otherwise if this
-     * channel uses an output buffer and is therefore working in buffering mode
-     * the listener will only
-     * be invoked after all the raw output values remaining in the current working
-     * buffer have been copied to the output buffer.
+     * listener.
      * <p />
      * Upon notification of the provided {@code GenerationRoundListener}
      * the reference to the  current working buffer (initially {@code src1}) can be retrieved from the
--- a/src/share/classes/jdk/dio/dac/DACChannelConfig.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/dac/DACChannelConfig.java	Thu Apr 30 21:58:05 2015 +0300
@@ -25,41 +25,196 @@
 
 package jdk.dio.dac;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Objects;
+
 import jdk.dio.DeviceConfig;
 import jdk.dio.DeviceManager;
 import jdk.dio.InvalidDeviceConfigException;
-import java.util.Objects;
+
+import romizer.DontRenameMethod;
+
 import serializator.*;
-import romizer.DontRenameMethod;
 
 
 /**
  * The {@code DACChannelConfig} class encapsulates the hardware addressing information, and static
  * and dynamic configuration parameters of an DAC channel.
  * <p />
- * Some hardware addressing parameter, and static and dynamic configuration parameters may be set to
- * {@link #DEFAULT}. Whether such default settings are supported is platform- as well as device
- * driver-dependent.
+ * Some hardware addressing, static or dynamic configuration parameters may be
+ * set to {@link #UNASSIGNED} or {@code null} (see
+ * <a href="{@docRoot}/jdk/dio/DeviceConfig.html#default_unassigned">Unassigned, Default or Unused Parameter Values</a>).
  * <p />
  * An instance of {@code DACChannelConfig} can be passed to the
- * {@link DeviceManager#open(DeviceConfig)} or
- * {@link DeviceManager#open(Class, DeviceConfig)} method to open the designated DAC channel
+ * {@link DeviceManager#open(DeviceConfig) open(DeviceConfig, ...)} and
+ * {@link DeviceManager#open(Class, DeviceConfig) open(Class, DeviceConfig, ...)}
+ * methods of the {@link DeviceManager} to open the designated DAC channel
  * with the specified configuration. A {@link InvalidDeviceConfigException} is thrown when
  * attempting to open a device with an invalid or unsupported configuration.
  *
  * @see DeviceManager#open(DeviceConfig)
+ * @see DeviceManager#open(DeviceConfig, int)
  * @see DeviceManager#open(Class, DeviceConfig)
+ * @see DeviceManager#open(Class, DeviceConfig, int)
  * @since 1.0
  */
 @SerializeMe
 @apimarker.API("device-io_1.1_dac")
 public final class DACChannelConfig implements DeviceConfig<DACChannel>, DeviceConfig.HardwareAddressing  {
     private String controllerName;
-    private int channelNumber = DEFAULT;
-    private int controllerNumber = DEFAULT;
-    private int resolution = DEFAULT;
-    private int samplingInterval = DEFAULT;
+    private int channelNumber = UNASSIGNED;
+    private int controllerNumber = UNASSIGNED;
+    private int resolution = UNASSIGNED;
+    private int samplingInterval = UNASSIGNED;
+    private double scaleFactor = 1.0;
+    private int outputBufferSize = UNASSIGNED;
 
+    /**
+     * The {@code Builder} class allows for creating and initializing {@code DACChannelConfig} objects.
+     * Calls can be chained in the following manner:
+     * <blockquote>
+     * <pre>
+     *   DACChannelConfig config = new DACChannelConfig.Builder()
+     *           .setControllerNumber(1)
+     *           .setChannelNumber(1)
+     *           .setResolution(256)
+     *           .setScaleFactor(1.0)
+     *           .setSamplingInterval(10)
+     *           .setOutputBufferSize(0)
+     *           .build();
+     * </pre>
+     * </blockquote>
+     *
+     * @since 1.1
+     */
+    @apimarker.API("device-io_1.1_dac")
+    public static final class Builder {
+
+        private final  DACChannelConfig instance = new DACChannelConfig();
+
+        /**
+         * Creates a new {@code Builder} instance.
+         */
+        public Builder() {
+
+        }
+
+        /**
+         * Creates a new {@code DACChannelConfig} instance initialized with the
+         * values set for each configuration parameters. If a configuration parameter
+         * was not explictly set its default value will be used.
+         *
+         * @return a new initialized {@code DACChannelConfig} instance.
+         */
+        public DACChannelConfig build() {
+            instance.checkValues();
+            return instance;
+        }
+
+        /**
+         * Sets the controller name (default value is {@code null} if not set).
+         *
+         * @param controllerName the controller name (such as its <em>device
+         * file</em> name on UNIX systems) or {@code null}.
+         * @return this {@code Builder} instance.
+         */
+        public Builder setControllerName(String controllerName) {
+            instance.controllerName = controllerName;
+            return this;
+        }
+
+        /**
+         * Sets the channel number (default value is {@code UNASSIGNED} if not set).
+         *
+         * @param channelNumber the channel number (a positive or zero integer)
+         * or {@code DeviceConfig.UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code channelNumber} is not in
+         * the defined range.
+         */
+        public Builder setChannelNumber(int channelNumber) {
+            instance.channelNumber = channelNumber;
+            return this;
+        }
+
+        /**
+         * Sets the controller number (default value is {@code UNASSIGNED} if not set).
+         *
+         * @param controllerNumber the hardware converter's number (a positive
+         * or zero integer) or {@link #UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code controllerNumber} is not
+         * in the defined range.
+         */
+        public Builder setControllerNumber(int controllerNumber) {
+            instance.controllerNumber = controllerNumber;
+            return this;
+        }
+
+        /**
+         * Sets the resolution (default value is {@code UNASSIGNED} if not set).
+         *
+         * @param resolution the resolution in bits (a positive integer) or
+         * {@code DeviceConfig.UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code resolution} is not in the
+         * defined range.
+         */
+        public Builder setResolution(int resolution) {
+            instance.resolution = resolution;
+            return this;
+        }
+
+        /**
+         * Sets the initial <em>scaled</em> output sampling interval (default value is {@code UNASSIGNED} if not
+         * set).
+         *
+         * @param samplingInterval the initial scaled output sampling interval
+         * (the amount of time between two samples) in microseconds (a positive
+         * integer) or {@code DeviceConfig.UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code samplingInterval} is not
+         * in the defined range.
+         *
+         * @see #setScaleFactor
+         */
+        public Builder setSamplingInterval(int samplingInterval) {
+            instance.samplingInterval = samplingInterval;
+            return this;
+        }
+
+        /**
+         * Sets the initial output sampling interval scale factor
+         * (default value is {@code 1.0} if not set).
+         *
+         * @param scaleFactor the sampling interval scale
+         * factor (a positive number).
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code scaleFactor} is not in the
+         * defined range.
+         */
+        public Builder setScaleFactor(double scaleFactor) {
+            instance.scaleFactor = scaleFactor;
+            return this;
+        }
+
+        /**
+         * Sets the requested output buffer size (default value is {@code UNASSIGNED} if not set).
+         *
+         * @param outputBufferSize the requested output buffer size in number of
+         * samples (a positive or zero integer) or
+         * {@code DeviceConfig.UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code outputBufferSize} is not in
+         * the defined range.
+         */
+        public Builder setOutputBufferSize(int outputBufferSize) {
+            instance.outputBufferSize = outputBufferSize;
+            return this;
+        }
+    }
 
     // hidden constructor for serializer
     @DontRenameMethod
@@ -68,16 +223,18 @@
     /**
      * Creates a new {@code DACChannelConfig} with the specified hardware addressing information and
      * configuration parameters.
+     * <p />
+     * The sampling interval scale factor is set to {@code 1.0}.
      *
      * @param controllerNumber
-     *            the hardware converter's number (a positive or zero integer) or {@link #DEFAULT}.
+     *            the hardware converter's number (a positive or zero integer) or {@link #UNASSIGNED}.
      * @param channelNumber
-     *            the hardware channel's number (a positive or zero integer) or {@link #DEFAULT}.
+     *            the hardware channel's number (a positive or zero integer) or {@link #UNASSIGNED}.
      * @param resolution
-     *            the resolution in bits (a positive integer) or {@link #DEFAULT}.
+     *            the resolution in bits (a positive integer) or {@link #UNASSIGNED}.
      * @param samplingInterval
      *            the initial output sampling interval in microseconds (a positive integer) or
-     *            {@link #DEFAULT}.
+     *            {@link #UNASSIGNED}.
      * @throws IllegalArgumentException
      *             if any of the following is true:
      *             <ul>
@@ -86,6 +243,8 @@
      *             <li>{@code resolution} is not in the defined range;</li>
      *             <li>{@code samplingInterval} is not in the defined range.</li>
      *             </ul>
+     *
+     * @deprecated As of 1.1, use {@link Builder} instead.
      */
     public DACChannelConfig(int controllerNumber, int channelNumber, int resolution, int samplingInterval) {
         this.controllerNumber = controllerNumber;
@@ -98,16 +257,18 @@
     /**
      * Creates a new {@code DACChannelConfig} with the specified hardware addressing information and
      * configuration parameters.
+     * <p />
+     * The sampling interval scale factor is set to {@code 1.0}.
      *
      * @param controllerName
      *            the controller name (such as its <em>device file</em> name on UNIX systems).
      * @param channelNumber
-     *            the hardware channel's number (a positive or zero integer) or {@link #DEFAULT}.
+     *            the hardware channel's number (a positive or zero integer) or {@link #UNASSIGNED}.
      * @param resolution
-     *            the resolution in bits (a positive integer) or {@link #DEFAULT}.
+     *            the resolution in bits (a positive integer) or {@link #UNASSIGNED}.
      * @param samplingInterval
      *            the initial output sampling interval in microseconds (a positive integer) or
-     *            {@link #DEFAULT}.
+     *            {@link #UNASSIGNED}.
      * @throws IllegalArgumentException
      *             if any of the following is true:
      *             <ul>
@@ -117,6 +278,8 @@
      *             </ul>
      * @throws NullPointerException
      *             if {@code controllerName} is {@code null}.
+     *
+     * @deprecated As of 1.1, use {@link Builder} instead.
      */
     public DACChannelConfig(String controllerName, int channelNumber, int resolution, int samplingInterval) {
         this.controllerName = controllerName;
@@ -128,10 +291,43 @@
         checkValues();
     }
 
+
+    /**
+     * Creates a new {@code DACChannelConfig} whose state is deserialized from the specified {@code InputStream}.
+     * This method may be invoked to restore the state of a {@code DACChannelConfig}
+     * object from a persistent store.
+     *
+     * @param in the stream to read from.
+     * @return a new {@code DACChannelConfig} instance.
+     * @throws IOException if an I/O error occurs or if the provided stream does not
+     * contain a representation of a {@code DACChannelConfig} object.
+     *
+     * @since 1.1
+     */
+    public static DACChannelConfig deserialize(InputStream in) throws IOException {
+      throw new IOException("Unsupported Operation");
+    }
+
+
+    /**
+     * Serializes the state of this {@code DACChannelConfig} object to the specified {@code OutputStream}.
+     * This method may be invoked by the {@link jdk.dio.DeviceManager DeviceManager}
+     * to save the state of this {@code DACChannelConfig} object to a persistent store.
+     *
+     * @param out the stream to write to.
+     * @throws IOException if an I/O error occurs.
+     *
+     * @since 1.1
+     */
+    @Override
+    public int serialize(OutputStream out) throws IOException {
+      throw new IOException("Unsupported Operation");
+    }
+
     /**
      * Gets the configured channel number.
      *
-     * @return the hardware channel's number (a positive or zero integer) or {@link #DEFAULT}.
+     * @return the hardware channel's number (a positive or zero integer) or {@link #UNASSIGNED}.
      */
     public int getChannelNumber() {
         return channelNumber;
@@ -140,8 +336,9 @@
     /**
      * Gets the configured controller number.
      *
-     * @return the hardware converter's number (a positive or zero integer) or {@link #DEFAULT}.
+     * @return the hardware converter's number (a positive or zero integer) or {@link #UNASSIGNED}.
      */
+    @Override
     public int getControllerNumber() {
         return controllerNumber;
     }
@@ -149,7 +346,7 @@
     /**
      * Gets the configured controller name (such as its <em>device file</em> name on UNIX systems).
      *
-     * @return the controllerName or {@code null}.
+     * @return the controller name or {@code null}.
      */
     @Override
     public String getControllerName() {
@@ -157,37 +354,68 @@
     }
 
     /**
+     * Gets the requested or allocated output buffer size. The platform/underlying
+     * driver may or may not allocate the requested size
+     * for the output buffer.
+     * When querying the configuration of an opened or registered device the
+     * allocated buffer size is returned.
+     *
+     * @return the requested or allocated output buffer size (a positive or zero integer).
+     *
+     * @since 1.1
+     */
+    public int getOutputBufferSize() {
+        return outputBufferSize;
+    }
+
+    /**
      * Gets the configured resolution.
      *
-     * @return the resolution in bits (a positive integer) or {@link #DEFAULT}.
+     * @return the resolution in bits (a positive integer) or {@link #UNASSIGNED}.
      */
     public int getResolution() {
         return resolution;
     }
 
     /**
-     * Gets the default/initial configured output sampling interval (in microseconds).
+     * Gets the default/initial configured <em>scaled</em> output sampling interval - the amount of time between two
+     * samples (in microseconds).
      *
      * @return the default/initial output sampling interval in microseconds (a positive integer) or
-     *         {@link #DEFAULT}.
+     *         {@link #UNASSIGNED}.
+     *
+     * @see #getScaleFactor
      */
     public int getSamplingInterval() {
         return samplingInterval;
     }
 
     /**
+     * Gets the default/initial configured output sampling interval scale factor.
+     *
+     * @return the default/initial output sampling interval scale factor (a positive number).
+     *
+     * @since 1.1
+     */
+    public double getScaleFactor() {
+        return scaleFactor;
+    }
+
+   /**
      * Returns the hash code value for this object.
      *
      * @return a hash code value for this object.
      */
     @Override
     public int hashCode() {
-        int hash = 7;
-        hash = 67 * hash + Objects.hashCode(this.controllerName);
-        hash = 67 * hash + this.channelNumber;
-        hash = 67 * hash + this.controllerNumber;
-        hash = 67 * hash + this.resolution;
-        hash = 67 * hash + this.samplingInterval;
+        int hash = 5;
+        hash = 13 * hash + Objects.hashCode(this.controllerName);
+        hash = 13 * hash + this.channelNumber;
+        hash = 13 * hash + this.controllerNumber;
+        hash = 13 * hash + this.resolution;
+        hash = 13 * hash + this.samplingInterval;
+        hash = 13 * hash + (int) (Double.doubleToLongBits(this.scaleFactor) ^ (Double.doubleToLongBits(this.scaleFactor) >>> 32));
+        hash = 13 * hash + this.outputBufferSize;
         return hash;
     }
 
@@ -198,7 +426,7 @@
      *            the object to test for equality with this object.
      * @return {@code true} if {@code obj} is a {@code DACChannelConfig} and has the same hardware
      *         addressing information and configuration parameter values as this
-     *         {@code DACChannelConfig} object.
+     *         {@code DACChannelConfig} object; {@code false} otherwise.
      */
     @Override
     public boolean equals(Object obj) {
@@ -224,7 +452,10 @@
         if (this.samplingInterval != other.samplingInterval) {
             return false;
         }
-        return true;
+        if (Double.doubleToLongBits(this.scaleFactor) != Double.doubleToLongBits(other.scaleFactor)) {
+            return false;
+        }
+        return this.outputBufferSize == other.outputBufferSize;
     }
 
     private void checkValues() {
--- a/src/share/classes/jdk/dio/dac/DACPermission.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/dac/DACPermission.java	Thu Apr 30 21:58:05 2015 +0300
@@ -43,16 +43,7 @@
  * {@link DACChannelConfig#getChannelNumber DACChannelConfig.getChannelNumber}. The characters in
  * the string must all be decimal digits.</dd>
  * </dl>
- * The possible actions are {@code open} and {@code powermanage}. Their meaning is defined as
- * follows:
- * <dl>
- * <dt>{@code open}</dt>
- * <dd>open and access an DAC channel functions (see {@link DeviceManager#open
- * DeviceManager.open})</dd>
- * <dt>{@code powermanage}</dt>
- * <dd>manage the power saving mode of a device (see
- * {@link jdk.dio.power.PowerManaged})</dd>
- * </dl>
+ * The supported actions are {@code open} and {@code powermanage} as defined in {@link DevicePermission}.
  *
  * @see DeviceManager#open DeviceManager.open
  * @see jdk.dio.power.PowerManaged
@@ -64,11 +55,16 @@
     /**
      * Constructs a new {@code DACPermission} with the specified target name and the implicit
      * {@code open} action.
+     * The target name is normalized so that leading and trailing spaces are removed
+     * and each occurrence of <code>{controller-number}</code> and <code>{channel-desc}</code> is represented in its canonical
+     * decimal representation form (without leading zeros).
      *
      * @param name
      *            the target name (as defined above).
      * @throws NullPointerException
      *             if {@code name} is {@code null}.
+     * @throws IllegalArgumentException
+     *             if {@code name} is not properly formatted.
      * @see #getName getName
      */
     public DACPermission(String name) {
@@ -78,6 +74,9 @@
     /**
      * Constructs a new {@code DACPermission} instance with the specified target name and action
      * list.
+     * The target name is normalized so that leading and trailing spaces are removed
+     * and each occurrence of <code>{controller-number}</code> and <code>{channel-desc}</code> is represented in its canonical
+     * decimal representation form (without leading zeros).
      *
      * @param name
      *            the target name (as defined above).
@@ -87,8 +86,11 @@
      * @throws NullPointerException
      *             if {@code name} is {@code null}.
      * @throws IllegalArgumentException
-     *             if actions is {@code null}, empty or contains an
-     *             action other than the specified possible actions.
+     *             <ul>
+     *             <li>if {@code actions} is {@code null}, empty or contains an action other than the
+     *             specified possible actions,</li>
+     *             <li>if {@code name} is not properly formatted.</li>
+     *             </ul>
      * @see #getName getName
      */
     public DACPermission(String name, String actions) {
--- a/src/share/classes/jdk/dio/dac/GenerationRoundListener.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/dac/GenerationRoundListener.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.dac;
 
 import jdk.dio.OutputRoundListener;
--- a/src/share/classes/jdk/dio/dac/InvalidOutputSamplingRateException.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/dac/InvalidOutputSamplingRateException.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,12 +22,12 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.dac;
 
 /**
- * Thrown by an instance of {@link DACChannel} in case the requested sampling rate is higher than
- * the maximum sampling rate the DAC device can support.
+ * Thrown by an instance of {@link DACChannel} in case the requested sampling interval results
+ * in a sampling rate higher or lower than
+ * the maximum, respectively minimum, sampling interval/rate the DAC device can support.
  *
  * @since 1.0
  */
--- a/src/share/classes/jdk/dio/dac/package-info.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/dac/package-info.java	Thu Apr 30 21:58:05 2015 +0300
@@ -78,8 +78,8 @@
  *             throw new InvalidStateException();
  *         }
  *         channel = (DACChannel) DeviceManager.open(channelID);
- *         channel.setSamplingInterval(1000); // every 1000 milliseconds
- *         // Creates a series of samples varying from min value to max value
+ *         channel.setSamplingInterval(1000); <i>// every 1000 milliseconds</i>
+ *         <i>// Creates a series of samples varying from min value to max value</i>
  *         int[] values = new int[10];
  *         int min = channel.getMinValue();
  *         int max = channel.getMaxValue();
@@ -90,15 +90,15 @@
  *
  *     public void outputRoundCompleted(RoundCompletionEvent&lt;DACChannel, IntBuffer&gt; event) {
  *         try {
- *             // Replay the same sample series
+ *             <i>// Replay the same sample series</i>
  *             createSamples(event.getBuffer(), event.getDevice().getMinValue(), event.getDevice().getMaxValue(),
  *                     10);
  *         } catch (IOException ioe) {
- *             // Ignored
+ *             <i>// Ignored</i>
  *         }
  *     }
  *
- *     // Creates a series of samples varying from min value to max value
+ *     <i>// Creates a series of samples varying from min value to max value</i>
  *     private void createSamples(IntBuffer buffer, int min, int max, int count) {
  *         for (int i = 0; i &lt; count; i++) {
  *             buffer.put(min + (((max - min) / (count - 1)) * i));
@@ -114,7 +114,7 @@
  *     }
  *
  *     public void failed(Throwable exception, DACChannel source) {
- *          // Ignored
+ *          <i>// Ignored</i>
  *     }
  * }
  * </pre>
--- a/src/share/classes/jdk/dio/generic/GenericBufferIODevice.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/generic/GenericBufferIODevice.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.generic;
 
 import jdk.dio.BufferAccess;
@@ -92,7 +91,7 @@
      * @throws NullPointerException
      *             If {@code dst} is {@code null}.
      * @throws IllegalArgumentException
-     *             If {@code skip} is negative.
+     *              If {@code skip} is negative.
      * @throws UnavailableDeviceException
      *             if this device is not currently available - such as it is locked by another
      *             application.
--- a/src/share/classes/jdk/dio/generic/GenericDevice.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/generic/GenericDevice.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.generic;
 
 import java.io.IOException;
@@ -129,7 +128,7 @@
      * by all the applications sharing the underlying device will get notified of the events they
      * registered for.
      * <p />
-     * If {@code listener} is {@code null} then listener previously registered for the specified
+     * If {@code listener} is {@code null} then the listener previously registered for the specified
      * event type will be removed.
      * <p />
      * Only one listener can be registered at a particular time for a particular event type.
--- a/src/share/classes/jdk/dio/generic/GenericDeviceConfig.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/generic/GenericDeviceConfig.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,15 +22,20 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+package jdk.dio.generic;
 
-package jdk.dio.generic;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Objects;
 
 import jdk.dio.DeviceConfig;
 import jdk.dio.DeviceManager;
 import jdk.dio.InvalidDeviceConfigException;
-import java.util.Objects;
+
+import romizer.DontRenameMethod;
+
 import serializator.*;
-import romizer.DontRenameMethod;
 
 
 /**
@@ -41,22 +46,153 @@
  * configuration parameters should be set using the {@link GenericDevice#setControl
  * GenericDevice.setControl} method.
  * <p />
+ * Some hardware addressing, static or dynamic configuration parameters may be
+ * set to {@link #UNASSIGNED} or {@code null} (see
+ * <a href="{@docRoot}/jdk/dio/DeviceConfig.html#default_unassigned">Unassigned, Default or Unused Parameter Values</a>).
+ * <p />
  * An instance of {@code GenericDeviceConfig} can be passed to the
- * {@link DeviceManager#open(DeviceConfig)} or
- * {@link DeviceManager#open(Class, DeviceConfig)} method to open the designated generic
+ * {@link DeviceManager#open(DeviceConfig) open(DeviceConfig, ...)} and
+ * {@link DeviceManager#open(Class, DeviceConfig) open(Class, DeviceConfig, ...)}
+ * methods of the {@link DeviceManager} to open the designated generic
  * device with the specified configuration. A {@link InvalidDeviceConfigException} is thrown
  * when attempting to open a device with an invalid or unsupported configuration.
  *
  * @see DeviceManager#open(DeviceConfig)
+ * @see DeviceManager#open(DeviceConfig, int)
  * @see DeviceManager#open(Class, DeviceConfig)
+ * @see DeviceManager#open(Class, DeviceConfig, int)
  * @since 1.0
  */
 @SerializeMe
 @apimarker.API("device-io_1.1_generic")
 public final class GenericDeviceConfig implements DeviceConfig<GenericDevice>, DeviceConfig.HardwareAddressing {
     private String controllerName;
-    private int channelNumber = DEFAULT;
-    private int controllerNumber = DEFAULT;
+    private int channelNumber = UNASSIGNED;
+    private int controllerNumber = UNASSIGNED;
+    private int inputBufferSize = UNASSIGNED;
+    private int outputBufferSize = UNASSIGNED;
+
+
+    /**
+     * The {@code Builder} class allows for creating and initializing
+     * {@code GenericDeviceConfig} objects. Calls can be chained in the following manner:
+     * <blockquote>
+     * <pre>
+     *   GenericDeviceConfig config = new GenericDeviceConfig.Builder()
+     *           .setControllerNumber(1)
+     *           .setChannelNumber(1)
+     *           .setInputBufferSize(0)
+     *           .setOutputBufferSize(0)
+     *           .build();
+     * </pre>
+     * </blockquote>
+     *
+     * @since 1.1
+     */
+    @apimarker.API("device-io_1.1_generic")
+    public static final class Builder {
+
+        private GenericDeviceConfig instance = new GenericDeviceConfig();
+
+        public Builder() {
+
+        }
+
+        /**
+         * Creates a new {@code GenericDeviceConfig} instance initialized with the
+         * values set for each configuration parameters. If a configuration
+         * parameter was not explictly set its default value will be used.
+         *
+         * @return a new initialized {@code GenericDeviceConfig} instance.
+         */
+        public GenericDeviceConfig build() {
+            return instance;
+       }
+
+        /**
+         * Sets the controller name (default value is {@code null} if not set).
+         *
+         * @param controllerName the controller name (such as its <em>device
+         * file</em> name on UNIX systems) or {@code null}.
+         * @return this {@code Builder} instance.
+         */
+        public Builder setControllerName(String controllerName) {
+            instance.controllerName = controllerName;
+            return this;
+        }
+
+        /**
+         * Sets the channel number (default value is {@code UNASSIGNED} if not
+         * set).
+         *
+         * @param channelNumber the channel number (a positive or zero integer)
+         * or {@code DeviceConfig.UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code channelNumber} is not in
+         * the defined range.
+         */
+        public Builder setChannelNumber(int channelNumber) {
+            instance.channelNumber = channelNumber;
+            return this;
+        }
+
+        /**
+         * Sets the controller number (default value is {@code UNASSIGNED} if
+         * not set).
+         *
+         * @param controllerNumber the hardware converter's number (a positive
+         * or zero integer) or {@link #UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code controllerNumber} is not
+         * in the defined range.
+         */
+        public Builder setControllerNumber(int controllerNumber) {
+            instance.controllerNumber = controllerNumber;
+            return this;
+        }
+
+        /**
+         * Sets the requested input buffer size (default value is
+         * {@code UNASSIGNED} if not set).
+         *
+         * @param inputBufferSize the requested input buffer size in number of
+         * samples (a positive or zero integer) or
+         * {@code DeviceConfig.UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code inputBufferSize} is not in
+         * the defined range.
+         */
+        public Builder setInputBufferSize(int inputBufferSize) {
+            instance.inputBufferSize = inputBufferSize;
+            return this;
+        }
+
+        /**
+         * Sets the requested output buffer size (default value is
+         * {@code UNASSIGNED} if not set).
+         *
+         * @param outputBufferSize the requested output buffer size in number of
+         * samples (a positive or zero integer) or
+         * {@code DeviceConfig.UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code outputBufferSize} is not
+         * in the defined range.
+         */
+        public Builder setOutputBufferSize(int outputBufferSize) {
+            instance.outputBufferSize = outputBufferSize;
+            return this;
+        }
+    }
+
+    private GenericDeviceConfig(GenericDeviceConfig prototype) {
+        if (prototype != null) {
+            this.controllerName = prototype.controllerName;
+            this.channelNumber = prototype.channelNumber;
+            this.controllerNumber = prototype.controllerNumber;
+            this.inputBufferSize = prototype.inputBufferSize;
+            this.outputBufferSize = prototype.outputBufferSize;
+        }
+    }
 
     // hidden constructor for serializer
     @DontRenameMethod
@@ -67,15 +203,17 @@
      * .
      *
      * @param controllerNumber
-     *            the hardware controller's number (a positive or zero integer) or {@link #DEFAULT}.
+     *            the hardware controller's number (a positive or zero integer) or {@link #UNASSIGNED}.
      * @param channelNumber
-     *            the hardware device's number (a positive or zero integer) or {@link #DEFAULT}.
+     *            the hardware device's number (a positive or zero integer) or {@link #UNASSIGNED}.
      * @throws IllegalArgumentException
      *             if any of the following is true:
      *             <ul>
      *             <li>{@code controllerNumber} is not in the defined range;</li>
      *             <li>{@code channelNumber} is not in the defined range.</li>
      *             </ul>
+     *
+     * @deprecated As of 1.1, use {@link Builder} instead.
      */
     public GenericDeviceConfig(int controllerNumber, int channelNumber) {
         if (controllerNumber< DEFAULT || channelNumber < DEFAULT) {
@@ -90,19 +228,57 @@
      *
      * @param controllerName
      *            the controller name (such as its <em>device file</em> name on UNIX systems).
+     * @param channelNumber
+     *            the hardware device's number (a positive or zero integer) or {@link #UNASSIGNED}.
+     * @throws IllegalArgumentException
+     *             if {@code channelNumber} is not in the defined range.
      * @throws NullPointerException
      *             if {@code controllerName} is {@code null}.
+     *
+     * @deprecated As of 1.1, use {@link Builder} instead.
      */
-    public GenericDeviceConfig(String controllerName) {
+    public GenericDeviceConfig(String controllerName, int channelNumber) {
         this.controllerName = controllerName;
+        this.channelNumber = channelNumber;
         // NPE check
         controllerName.length();
     }
 
     /**
+     * Creates a new {@code GenericDeviceConfig} whose state is deserialized from the specified {@code InputStream}.
+     * This method may be invoked to restore the state of a {@code GenericDeviceConfig}
+     * object from a persistent store.
+     *
+     * @param in the stream to read from.
+     * @return a new {@code GenericDeviceConfig} instance.
+     * @throws IOException if an I/O error occurs or if the provided stream does not
+     * contain a representation of a {@code GenericDeviceConfig} object.
+     *
+     * @since 1.1
+     */
+    public static GenericDeviceConfig deserialize(InputStream in) throws IOException {
+      throw new IOException("Unsupported Operation");
+    }
+
+    /**
+     * Serializes the state of this {@code GenericDeviceConfig} object to the specified {@code OutputStream}.
+     * This method may be invoked by the {@link jdk.dio.DeviceManager DeviceManager}
+     * to save the state of this {@code GenericDeviceConfig} object to a persistent store.
+     *
+     * @param out the stream to write to.
+     * @throws IOException if an I/O error occurs.
+     *
+     * @since 1.1
+     */
+    @Override
+    public int serialize(OutputStream out) throws IOException {
+      throw new IOException("Unsupported Operation");
+    }
+
+    /**
      * Gets the configured channel number.
      *
-     * @return the hardware device channel's number (a positive or zero integer) or {@link #DEFAULT}
+     * @return the hardware device channel's number (a positive or zero integer) or {@link #UNASSIGNED}
      *         .
      */
     public int getChannelNumber() {
@@ -113,7 +289,7 @@
      * Gets the configured controller number.
      *
      * @return the hardware device controller's number (a positive or zero integer) or
-     *         {@link #DEFAULT}.
+     *         {@link #UNASSIGNED}.
      */
     @Override
     public int getControllerNumber() {
@@ -131,6 +307,36 @@
     }
 
     /**
+     * Gets the requested or allocated input buffer size. The platform/underlying
+     * driver may or may not allocate the requested size
+     * for the input buffer.
+     * When querying the configuration of an opened or registered device the
+     * allocated buffer size is returned.
+     *
+     * @return the requested or allocated input buffer size (a positive or zero integer).
+     *
+     * @since 1.1
+     */
+    public int getInputBufferSize() {
+        return inputBufferSize;
+    }
+
+    /**
+     * Gets the requested or allocated output buffer size. The platform/underlying
+     * driver may or may not allocate the requested size
+     * for the output buffer.
+     * When querying the configuration of an opened or registered device the
+     * allocated buffer size is returned.
+     *
+     * @return the requested or allocated output buffer size (a positive or zero integer).
+     *
+     * @since 1.1
+     */
+    public int getOutputBufferSize() {
+        return outputBufferSize;
+    }
+
+    /**
      * Returns the hash code value for this object.
      *
      * @return a hash code value for this object.
@@ -151,7 +357,7 @@
      *            the object to test for equality with this object.
      * @return {@code true} if {@code obj} is a {@code GenericDeviceConfig} and has the same hardware
      *         addressing information and configuration parameter values as this
-     *         {@code GenericDeviceConfig} object.
+     *         {@code GenericDeviceConfig} object; {@code false} otherwise.
      */
     @Override
     public boolean equals(Object obj) {
@@ -168,9 +374,6 @@
         if (this.channelNumber != other.channelNumber) {
             return false;
         }
-        if (this.controllerNumber != other.controllerNumber) {
-            return false;
-        }
-        return true;
+        return this.controllerNumber == other.controllerNumber;
     }
 }
--- a/src/share/classes/jdk/dio/generic/GenericDeviceControl.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/generic/GenericDeviceControl.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,12 +22,11 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.generic;
 
 /**
  * The class {@code GenericDeviceControl} encapsulates a generic device's configuration
- * and access (I/O) controls. A control can be set or gotten using the
+ * and access (I/O) control. A control can be set or gotten using the
  * {@link GenericDevice#setControl GenericDevice.setControl} and {@link GenericDevice#getControl
  * GenericDevice.getControl} methods. Controls can be used to configured a generic device
  * a well as performing basic input/output operations. The list of controls supported by a
--- a/src/share/classes/jdk/dio/generic/GenericEvent.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/generic/GenericEvent.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.generic;
 
 import jdk.dio.DeviceEvent;
--- a/src/share/classes/jdk/dio/generic/GenericEventListener.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/generic/GenericEventListener.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.generic;
 
 import jdk.dio.DeviceEventListener;
--- a/src/share/classes/jdk/dio/generic/GenericPermission.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/generic/GenericPermission.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.generic;
 
 import jdk.dio.DeviceManager;
@@ -43,16 +42,7 @@
  * {@link GenericDeviceConfig#getChannelNumber GenericDeviceConfig.getChannelNumber}. The characters
  * in the string must all be decimal digits.</dd>
  * </dl>
- * The possible actions are {@code open} and {@code powermanage}. Their meaning is defined as
- * follows:
- * <dl>
- * <dt>{@code open}</dt>
- * <dd>open and access an generic device functions (see {@link DeviceManager#open
- * DeviceManager.open})</dd>
- * <dt>{@code powermanage}</dt>
- * <dd>manage the power saving mode of a device (see
- * {@link jdk.dio.power.PowerManaged})</dd>
- * </dl>
+ * The supported actions are {@code open} and {@code powermanage} as defined in {@link DevicePermission}.
  *
  * @see DeviceManager#open DeviceManager.open
  * @see jdk.dio.power.PowerManaged
@@ -64,11 +54,16 @@
     /**
      * Constructs a new {@code GenericPermission} with the specified target name and the implicit
      * {@code open} action.
+     * The target name is normalized so that leading and trailing spaces are removed
+     * and each occurrence of <code>{controller-number}</code> and <code>{channel-desc}</code> is represented in its canonical
+     * decimal representation form (without leading zeros).
      *
      * @param name
      *            the target name (as defined above).
      * @throws NullPointerException
      *             if {@code name} is {@code null}.
+     * @throws IllegalArgumentException
+     *             if {@code name} is not properly formatted.
      * @see #getName getName
      */
     public GenericPermission(String name) {
@@ -78,6 +73,9 @@
     /**
      * Constructs a new {@code GenericPermission} instance with the specified target name and action
      * list.
+     * The target name is normalized so that leading and trailing spaces are removed
+     * and each occurrence of <code>{controller-number}</code> and <code>{channel-desc}</code> is represented in its canonical
+     * decimal representation form (without leading zeros).
      *
      * @param name
      *            the target name (as defined above).
@@ -87,8 +85,11 @@
      * @throws NullPointerException
      *             if {@code name} is {@code null}.
      * @throws IllegalArgumentException
-     *             if actions is {@code null}, empty or contains an
-     *             action other than the specified possible actions.
+     *             <ul>
+     *             <li>if {@code actions} is {@code null}, empty or contains an action other than the
+     *             specified possible actions,</li>
+     *             <li>if {@code name} is not properly formatted.</li>
+     *             </ul>
      * @see #getName getName
      */
     public GenericPermission(String name, String actions) {
--- a/src/share/classes/jdk/dio/generic/package-info.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/generic/package-info.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 /**
  * Interfaces and classes for controlling devices using generic I/O operations.
  * <p />
@@ -38,11 +37,11 @@
  * interface if it does not support any read and write operations.</dd>
  * <dt>{@link jdk.dio.generic.GenericBufferIODevice}</dt>
  * <dd>Device control operations and event listener registration as inherited from
- * {@link jdk.dio.generic.GenericBufferIODevice} and byte buffer read and write
+ * {@code GenericDevice} and byte buffer read and write
  * operations.</dd>
  * </dl>
  * In order to access a device using its generic interface, an application should first open and
- * obtain a {@link jdk.dio.generic.GenericDevice} instance for the device using its
+ * obtain a {@code GenericDevice} instance for the device using its
  * numeric ID, name, type (interface) and/or properties:
  * <dl>
  * <dt>Using its ID</dt>
@@ -61,8 +60,8 @@
  * </blockquote></dd>
  * </dl>
  * Once the device opened, the application can set and get controls, read and write data using
- * methods of the {@link jdk.dio.generic.GenericDevice} or
- * {@link jdk.dio.generic.GenericBufferIODevice} interfaces. <blockquote>
+ * methods of the {@code GenericDevice} or
+ * {@code GenericBufferIODevice} interfaces. <blockquote>
  *
  * <pre>
  * device.read(buffer, 0, buffer.length);
@@ -74,8 +73,8 @@
  * <pre>
  * device.close();
  * </pre>
- * </blockquote> The following sample codes give examples of using the Generic API to communicate
- * Real Time Clock device: <blockquote>
+ * </blockquote> The following sample code gives an example of using the Generic API to access
+ * a Real Time Clock device: <blockquote>
  *
  * <pre>
  * public static final int EVT_ALARM = 0;
@@ -87,7 +86,7 @@
  * public static final GenericDeviceControl&lt;Byte&gt; HOURS = new GenericDeviceControl&lt;&gt;(5, Byte.class);
  * public static final GenericDeviceControl&lt;Boolean&gt; ALARM_ENABLED = new GenericDeviceControl&lt;&gt;(6, Boolean.class);
  *
- * // Sets the daily alarm for after some delay
+ * <i>// Sets the daily alarm for after some delay</i>
  * public void setAlarm(byte delaySeconds, byte delayMinutes, byte delayHours) throws IOException, DeviceException {
  *     try (GenericDevice rtc = DeviceManager.open(&quot;RTC&quot;, GenericDevice.class, (String) null)) {
  *         byte currentSeconds = rtc.getControl(SECONDS);
@@ -106,17 +105,16 @@
  *
  *             public void eventDispatched(GenericEvent event) {
  *                 GenericDevice rtc = event.getDevice();
- *                 // Notify application of alarm
+ *                 <i>// Notify application of alarm</i>
  *             }
  *         });
- *         // Enable alarm.
+ *         <i>// Enable alarm.</i>
  *         rtc.setControl(ALARM_ENABLED, true);
  *     }
  * }
  * </pre>
- * </blockquote> The preceding example is using a <em>try-with-resources</em> statement;
- * the {@link jdk.dio.generic.GenericDevice#close GenericDevice.close}
- * method is automatically invoked by the platform at the end of the statement. <blockquote>
+ * </blockquote>The following sample code gives an example of using the Generic API to control
+ * and capture audio input from a microphone such a USB microphone exposed as a {@code GenericDevice}:<blockquote>
  *
  * <pre>
  * public static final int EVT_VOLUME_CHANGED = 0;
@@ -137,7 +135,7 @@
  *                 GenericDevice mic = event.getDevice();
  *                 try {
  *                     float currentVolume = mic.getControl(MIC_VOLUME);
- *                     // ...
+ *                     <i>// ...</i>
  *                 } catch (ClosedDeviceException ex) {
  *                     ex.printStackTrace();
  *                 } catch (IOException ex) {
@@ -150,6 +148,9 @@
  * }
  * </pre>
  * </blockquote>
+ * The preceding examples are using a <em>try-with-resources</em> statement;
+ * the {@link jdk.dio.generic.GenericDevice#close GenericDevice.close}
+ * method is automatically invoked by the platform at the end of the statement
  * <p />
  * Unless otherwise noted, passing a {@code null} argument to a constructor or method in any class
  * or interface in this package will cause a {@link java.lang.NullPointerException
--- a/src/share/classes/jdk/dio/gpio/GPIOPin.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/gpio/GPIOPin.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.gpio;
 
 import jdk.dio.ClosedDeviceException;
@@ -44,7 +43,7 @@
  * opened with an ad-hoc {@link GPIOPinConfig} configuration (which includes its hardware addressing
  * information) using one of the
  * {@link DeviceManager#open(jdk.dio.DeviceConfig)
- * DeviceManager.open(config,...)} it is not assigned any ID nor name.
+ * DeviceManager.open(config,...)} methods it is not assigned any ID nor name.
  * <p />
  * A GPIO pin may be configured for output or input. Output pins are both writable and readable
  * while input pins are only readable.
@@ -120,7 +119,8 @@
      * @return the current pin interrupt trigger, one of: {@link GPIOPinConfig#TRIGGER_NONE},
      *         {@link GPIOPinConfig#TRIGGER_FALLING_EDGE}, {@link GPIOPinConfig#TRIGGER_RISING_EDGE}
      *         , {@link GPIOPinConfig#TRIGGER_BOTH_EDGES}, {@link GPIOPinConfig#TRIGGER_HIGH_LEVEL},
-     *         {@link GPIOPinConfig#TRIGGER_LOW_LEVEL}, {@link GPIOPinConfig#TRIGGER_BOTH_LEVELS}.
+     *         {@link GPIOPinConfig#TRIGGER_LOW_LEVEL}, {@link GPIOPinConfig#TRIGGER_BOTH_LEVELS};
+     *         {@code GPIOPinConfig.TRIGGER_NONE} if this GPIO pin is currently configured for output.
      * @throws IOException
      *             if some other I/O error occurs.
      * @throws UnavailableDeviceException
@@ -186,11 +186,10 @@
      * @throws IOException
      *             if an IO error occurred.
      * @throws UnsupportedOperationException
-     *             if this GPIO pin cannot be configured with the desired trigger mode.
+     *             if this GPIO pin is currently configured for output or cannot otherwise
+     *             be configured with the desired trigger mode.
      * @throws IllegalArgumentException
      *             if {@code trigger} is not one of the defined values.
-     * @throws SecurityException
-     *             if the caller does not have the required permission.
      * @throws UnavailableDeviceException
      *             if this device is not currently available - such as it is locked by another
      *             application.
--- a/src/share/classes/jdk/dio/gpio/GPIOPinConfig.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/gpio/GPIOPinConfig.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,32 +22,41 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.gpio;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Objects;
+
+import com.oracle.dio.utils.ExceptionMessage;
+
 import jdk.dio.DeviceConfig;
+import jdk.dio.DeviceManager;
 import jdk.dio.InvalidDeviceConfigException;
-import jdk.dio.DeviceManager;
-import java.util.Objects;
-import com.oracle.dio.utils.ExceptionMessage;
+
+import romizer.*;
+
 import serializator.*;
-import romizer.*;
 /**
  * The {@code GPIOPinConfig} class encapsulates the hardware addressing information, and static and
  * dynamic configuration parameters of a GPIO pin.
  * <p />
- * Some hardware addressing parameter, and static and dynamic configuration parameters may be set to
- * {@link #DEFAULT}. Whether such default settings are supported is platform- as well as device
- * driver-dependent.
+ * Some hardware addressing, static or dynamic configuration parameters may be
+ * set to {@link #UNASSIGNED} or {@code null} (see
+ * <a href="{@docRoot}/jdk/dio/DeviceConfig.html#default_unassigned">Unassigned, Default or Unused Parameter Values</a>).
  * <p />
  * An instance of {@code GPIOPinConfig} can be passed to the
- * {@link DeviceManager#open(DeviceConfig)} or
- * {@link DeviceManager#open(Class, DeviceConfig)} method to open the designated GPIO pin
+ * {@link DeviceManager#open(DeviceConfig) open(DeviceConfig, ...)} and
+ * {@link DeviceManager#open(Class, DeviceConfig) open(Class, DeviceConfig, ...)}
+ * methods of the {@link DeviceManager} to open the designated GPIO pin
  * with the specified configuration. A {@link InvalidDeviceConfigException} is thrown when
  * attempting to open a device with an invalid or unsupported configuration.
  *
  * @see DeviceManager#open(DeviceConfig)
+ * @see DeviceManager#open(DeviceConfig, int)
  * @see DeviceManager#open(Class, DeviceConfig)
+ * @see DeviceManager#open(Class, DeviceConfig, int)
  * @since 1.0
  */
 @SerializeMe
@@ -126,11 +135,181 @@
     private String controllerName;
     private int direction;
     private boolean initValue;
-    private int mode;
-    private int pinNumber = DEFAULT;
-    private int controllerNumber = DEFAULT;
+    private int mode = UNASSIGNED;
+    private int pinNumber = UNASSIGNED;
+    private int controllerNumber = UNASSIGNED;
     private int trigger;
 
+    /**
+     * The {@code Builder} class allows for creating and initializing
+     * {@code GPIOPinConfig} objects. Calls can be chained in the following
+     * manner:
+     * <blockquote>
+     * <pre>
+     *   GPIOPinConfig config = new GPIOPinConfig.Builder()
+     *           .setControllerNumber(1)
+     *           .setPinNumber(1)
+     *           .setDirection(DIR_OUTPUT_ONLY)
+     *           .setDriveMode(MODE_OUTPUT_PUSH_PULL)
+     *           .setInitValue(true)
+     *           .build();
+     * </pre>
+     * </blockquote>
+     *
+     * @since 1.1
+     */
+    @apimarker.API("device-io_1.1_gpio")
+    public static final class Builder {
+
+        private GPIOPinConfig instance = new GPIOPinConfig();
+
+        /**
+         * Creates a new {@code Builder} instance.
+         */
+        public Builder() {
+
+        }
+
+        /**
+         * Creates a new {@code GPIOPinConfig} instance initialized with the
+         * values set for each configuration parameters. If a configuration
+         * parameter was not explictly set its default value will be used.
+         *
+         * @return a new initialized {@code GPIOPinConfig} instance.
+         * @throws IllegalArgumentException if any of the following is true:
+         * <ul>
+         * <li>{@code trigger} is incompatible with the direction(s) designated
+         * by {@code direction};</li>
+         * <li>{@code mode} does not designates a drive mode for or designates a
+         * drive mode incompatible (as specified by {@link #setDriveMode setDriveMode})
+         * with the direction(s) designated by
+         * {@code direction}.</li>
+         * </ul>
+         * @throws IllegalStateException if any of the following is true:
+         * <ul>
+         * <li>the allowed and initial pin direction is not set.</li>
+         * </ul>
+         */
+        public GPIOPinConfig build() {
+            instance.checkValues();
+            return instance;
+        }
+
+        /**
+         * Sets the controller name (default value is {@code null} if not set).
+         *
+         * @param controllerName the controller name (such as its <em>device
+         * file</em> name on UNIX systems) or {@code null}.
+         * @return this {@code Builder} instance.
+         */
+        public Builder setControllerName(String controllerName) {
+            instance.controllerName = controllerName;
+            return this;
+        }
+
+        /**
+         * Sets the pin number (default value is {@code UNASSIGNED} if not set).
+         *
+         * @param pinNumber the pin number (a positive or zero integer) or
+         * {@code DeviceConfig.UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code pinNumber} is not in the
+         * defined range.
+         */
+        public Builder setPinNumber(int pinNumber) {
+            instance.pinNumber = pinNumber;
+            return this;
+        }
+
+        /**
+         * Sets the controller number (default value is {@code UNASSIGNED} if
+         * not set).
+         *
+         * @param controllerNumber the controller number (a positive or zero
+         * integer) or {@link #UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code controllerNumber} is not
+         * in the defined range.
+         */
+        public Builder setControllerNumber(int controllerNumber) {
+            instance.controllerNumber = controllerNumber;
+            return this;
+        }
+
+        /**
+         * Sets the allowed and initial pin direction.
+         *
+         * @param direction the allowed and initial direction of the pin, one
+         * of: {@link #DIR_INPUT_ONLY},
+         *            {@link #DIR_OUTPUT_ONLY}, {@link #DIR_BOTH_INIT_INPUT},
+         *            {@link #DIR_BOTH_INIT_OUTPUT}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code direction} is not in the
+         * defined range.
+         */
+        public Builder setDirection(int direction) {
+            instance.direction = direction;
+            return this;
+        }
+
+        /**
+         * Sets the initial value of the pin when initially set for output
+         * (default value is {@code false} if not set).
+         *
+         * @param initValue the initial value of the pin when initially set for
+         * output.
+         * @return this {@code Builder} instance.
+         */
+        public Builder setInitValue(boolean initValue) {
+            instance.initValue = initValue;
+            return this;
+        }
+
+        /**
+         * Sets the pin drive mode (default value is {@code UNASSIGNED} if not
+         * set).
+         *
+         * @param mode the pin drive mode: either {@link #UNASSIGNED} or a
+         * bitwise OR of at least one of: {@link #MODE_INPUT_PULL_UP}, {@link #MODE_INPUT_PULL_DOWN} ,
+         *            {@link #MODE_OUTPUT_PUSH_PULL}, {@link #MODE_OUTPUT_OPEN_DRAIN}; if
+         * the pin can be set in both input and output direction then the mode
+         * must specify both an input drive mode and an output drive mode (bit
+         * mask).
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if any of the following is true:
+         * <ul>
+         * <li>{@code mode} does not designate any mode (i.e. equals
+         * {@code 0});</li>
+         * <li>{@code mode} designates more than one input or output drive
+         * mode.</li>
+         * </ul>
+         */
+        public Builder setDriveMode(int mode) {
+            instance.mode = mode;
+            return this;
+        }
+
+        /**
+         * Sets the initial interrupt trigger events (default value is
+         * {@code TRIGGER_NONE} if not set).
+         *
+         * @param trigger the initial interrupt trigger events, one of: {@link #TRIGGER_NONE},
+         *            {@link #TRIGGER_FALLING_EDGE}, {@link #TRIGGER_RISING_EDGE},
+         *            {@link #TRIGGER_BOTH_EDGES}, {@link #TRIGGER_HIGH_LEVEL},
+         *            {@link #TRIGGER_LOW_LEVEL}, {@link #TRIGGER_BOTH_LEVELS}; if the pin
+         * is set for output-only then {@code trigger} must be
+         * {@link #TRIGGER_NONE}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code trigger} is not in the
+         * defined range.
+         */
+        public Builder setTrigger(int trigger) {
+            instance.trigger = trigger;
+            return this;
+        }
+    }
+
+
     // hidden constructor for serializer
     @DontRenameMethod
     GPIOPinConfig() {}
@@ -140,15 +319,15 @@
      * configuration parameters.
      *
      * @param controllerNumber
-     *            the hardware port's number (a positive or zero integer) or {@link #DEFAULT}.
+     *            the hardware port's number (a positive or zero integer) or {@link #UNASSIGNED}.
      * @param pinNumber
-     *            the hardware pin's number (a positive or zero integer) or {@link #DEFAULT}.
+     *            the hardware pin's number (a positive or zero integer) or {@link #UNASSIGNED}.
      * @param direction
      *            the allowed and initial direction of the pin, one of: {@link #DIR_INPUT_ONLY},
      *            {@link #DIR_OUTPUT_ONLY}, {@link #DIR_BOTH_INIT_INPUT},
      *            {@link #DIR_BOTH_INIT_OUTPUT}.
      * @param mode
-     *            the drive mode of the pin: either {@link #DEFAULT} or a bitwise OR of at least one
+     *            the drive mode of the pin: either {@link #UNASSIGNED} or a bitwise OR of at least one
      *            of: {@link #MODE_INPUT_PULL_UP}, {@link #MODE_INPUT_PULL_DOWN} ,
      *            {@link #MODE_OUTPUT_PUSH_PULL}, {@link #MODE_OUTPUT_OPEN_DRAIN}; if the pin can be
      *            set in both input and output direction then the mode must specify both an input
@@ -157,7 +336,8 @@
      *            the initial interrupt trigger events, one of: {@link #TRIGGER_NONE},
      *            {@link #TRIGGER_FALLING_EDGE}, {@link #TRIGGER_RISING_EDGE},
      *            {@link #TRIGGER_BOTH_EDGES}, {@link #TRIGGER_HIGH_LEVEL},
-     *            {@link #TRIGGER_LOW_LEVEL}, {@link #TRIGGER_BOTH_LEVELS}.
+     *            {@link #TRIGGER_LOW_LEVEL}, {@link #TRIGGER_BOTH_LEVELS}; if the pin is
+     *            set for output-only then {@code trigger} must be {@link #TRIGGER_NONE}.
      * @param initValue
      *            the initial value of the pin when initially set for output; ignored otherwise.
      * @throws IllegalArgumentException
@@ -167,11 +347,14 @@
      *             <li>{@code pinNumber} is not in the defined range;</li>
      *             <li>{@code direction} is not one of the defined values;</li>
      *             <li>{@code trigger} is not one of the defined values;</li>
+     *             <li>{@code trigger} is incompatible with the direction(s) designated by {@code direction};</li>
      *             <li>{@code mode} does not designate any mode (i.e. equals {@code 0});</li>
      *             <li>{@code mode} designates more than one input or output drive mode;</li>
      *             <li>{@code mode} does not designates a drive mode for or designates a drive mode
      *             incompatible with the direction(s) designated by {@code direction}.</li>
      *             </ul>
+     *
+     * @deprecated As of 1.1, use {@link Builder} instead.
      */
     public GPIOPinConfig(int controllerNumber, int pinNumber, int direction, int mode, int trigger, boolean initValue) {
         this.controllerNumber = controllerNumber;
@@ -183,7 +366,7 @@
         this.trigger = trigger;
         this.mode = mode;
         this.initValue = initValue;
-        checkValues(direction, mode, trigger);
+        checkValues();
     }
 
     /**
@@ -193,13 +376,13 @@
      * @param controllerName
      *            the controller name (such as its <em>device file</em> name on UNIX systems).
      * @param pinNumber
-     *            the hardware pin's number (a positive or zero integer) or {@link #DEFAULT}.
+     *            the hardware pin's number (a positive or zero integer) or {@link #UNASSIGNED}.
      * @param direction
      *            the allowed and initial direction of the pin, one of: {@link #DIR_INPUT_ONLY},
      *            {@link #DIR_OUTPUT_ONLY}, {@link #DIR_BOTH_INIT_INPUT},
      *            {@link #DIR_BOTH_INIT_OUTPUT}.
      * @param mode
-     *            the drive mode of the pin: either {@link #DEFAULT} or a bitwise OR of at least one
+     *            the drive mode of the pin: either {@link #UNASSIGNED} or a bitwise OR of at least one
      *            of: {@link #MODE_INPUT_PULL_UP}, {@link #MODE_INPUT_PULL_DOWN} ,
      *            {@link #MODE_OUTPUT_PUSH_PULL}, {@link #MODE_OUTPUT_OPEN_DRAIN}; if the pin can be
      *            set in both input and output direction then the mode must specify both an input
@@ -208,7 +391,8 @@
      *            the initial interrupt trigger events, one of: {@link #TRIGGER_NONE},
      *            {@link #TRIGGER_FALLING_EDGE}, {@link #TRIGGER_RISING_EDGE},
      *            {@link #TRIGGER_BOTH_EDGES}, {@link #TRIGGER_HIGH_LEVEL},
-     *            {@link #TRIGGER_LOW_LEVEL}, {@link #TRIGGER_BOTH_LEVELS}.
+     *            {@link #TRIGGER_LOW_LEVEL}, {@link #TRIGGER_BOTH_LEVELS}; if the pin is
+     *            set for output-only then {@code trigger} must be {@link #TRIGGER_NONE}.
      * @param initValue
      *            the initial value of the pin when initially set for output; ignored otherwise.
      * @throws IllegalArgumentException
@@ -217,6 +401,7 @@
      *             <li>{@code pinNumber} is not in the defined range;</li>
      *             <li>{@code direction} is not one of the defined values;</li>
      *             <li>{@code trigger} is not one of the defined values;</li>
+     *             <li>{@code trigger} is incompatible with the direction(s) designated by {@code direction};</li>
      *             <li>{@code mode} does not designate any mode (i.e. equals {@code 0});</li>
      *             <li>{@code mode} designates more than one input or output drive mode;</li>
      *             <li>{@code mode} does not designates a drive mode for or designates a drive mode
@@ -224,6 +409,8 @@
      *             </ul>
      * @throws NullPointerException
      *             if {@code controllerName} is {@code null}.
+     *
+     * @deprecated As of 1.1, use {@link Builder} instead.
      */
     public GPIOPinConfig(String controllerName, int pinNumber, int direction, int mode, int trigger, boolean initValue) {
         this.controllerName = controllerName;
@@ -236,7 +423,39 @@
         this.trigger = trigger;
         this.mode = mode;
         this.initValue = initValue;
-        checkValues(direction, mode, trigger);
+        checkValues();
+    }
+
+    /**
+     * Creates a new {@code GPIOPinConfig} whose state is deserialized from the specified {@code InputStream}.
+     * This method may be invoked to restore the state of a {@code GPIOPinConfig}
+     * object from a persistent store.
+     *
+     * @param in the stream to read from.
+     * @return a new {@code GPIOPinConfig} instance.
+     * @throws IOException if an I/O error occurs or if the provided stream does not
+     * contain a representation of a {@code GPIOPinConfig} object.
+     *
+     * @since 1.1
+     */
+    public static GPIOPinConfig deserialize(InputStream in) throws IOException {
+      throw new IOException("Unsupported Operation");
+    }
+
+
+    /**
+     * Serializes the state of this {@code GPIOPinConfig} object to the specified {@code OutputStream}.
+     * This method may be invoked by the {@link jdk.dio.DeviceManager DeviceManager}
+     * to save the state of this {@code GPIOPinConfig} object to a persistent store.
+     *
+     * @param out the stream to write to.
+     * @throws IOException if an I/O error occurs.
+     *
+     * @since 1.1
+     */
+    @Override
+    public int serialize(OutputStream out) throws IOException {
+      throw new IOException("Unsupported Operation");
     }
 
     /**
@@ -252,7 +471,7 @@
     /**
      * Gets the configured pin drive mode.
      *
-     * @return the pin drive mode: either {@link #DEFAULT} or a bitwise OR of at least one of :
+     * @return the pin drive mode: either {@link #UNASSIGNED} or a bitwise OR of at least one of :
      *         {@link #MODE_INPUT_PULL_UP}, {@link #MODE_INPUT_PULL_DOWN},
      *         {@link #MODE_OUTPUT_PUSH_PULL}, {@link #MODE_OUTPUT_OPEN_DRAIN}.
      */
@@ -272,7 +491,7 @@
     /**
      * Gets the configured pin number.
      *
-     * @return the hardware pin's number (a positive or zero integer) or {@link #DEFAULT}.
+     * @return the hardware pin's number (a positive or zero integer) or {@link #UNASSIGNED}.
      */
     public int getPinNumber() {
         return pinNumber;
@@ -281,7 +500,7 @@
     /**
      * Gets the configured controller number for the pin.
      *
-     * @return the hardware port's number (a positive or zero integer) or {@link #DEFAULT}.
+     * @return the hardware port's number (a positive or zero integer) or {@link #UNASSIGNED}.
      */
     @Override
     public int getControllerNumber() {
@@ -335,7 +554,7 @@
      *            the object to test for equality with this object.
      * @return {@code true} if {@code obj} is a {@code GPIOPinConfig} and has the same hardware
      *         addressing information and configuration parameter values as this
-     *         {@code GPIOPinConfig} object.
+     *         {@code GPIOPinConfig} object; {@code false} otherwise.
      */
     @Override
     public boolean equals(Object obj) {
@@ -364,13 +583,10 @@
         if (this.controllerNumber != other.controllerNumber) {
             return false;
         }
-        if (this.trigger != other.trigger) {
-            return false;
-        }
-        return true;
+        return this.trigger == other.trigger;
     }
 
-    private void checkValues(int direction, int mode, int trigger) {
+    private void checkValues() {
         if ( GPIOPinConfig.TRIGGER_NONE > trigger || GPIOPinConfig.TRIGGER_BOTH_LEVELS < trigger || 0 == mode ) {
             throw new IllegalArgumentException(
                 ExceptionMessage.format(ExceptionMessage.GPIO_TRIGGER_OR_MODE)
--- a/src/share/classes/jdk/dio/gpio/GPIOPinPermission.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/gpio/GPIOPinPermission.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.gpio;
 
 import jdk.dio.DeviceManager;
@@ -45,17 +44,10 @@
  * {@link GPIOPinConfig#getPinNumber GPIOPinConfig.getPinNumber}. The characters in the string must
  * all be decimal digits.</dd>
  * </dl>
- * The supported actions are {@code open}, {@code powermanage} or {@code setdirection}. Their
- * meaning is defined as follows:
+ * The supported actions are {@code open} and {@code powermanage} as defined in {@link DevicePermission}, and {@code setdirection} defined as follows:
  * <dl>
- * <dt>{@code open}</dt>
- * <dd>open and access a GPIO pin functions (see {@link DeviceManager#open
- * DeviceManager.open})</dd>
  * <dt>{@code setdirection}</dt>
  * <dd>change GPIO pin direction (see {@link GPIOPin#setDirection GPIOPin.setDirection})</dd>
- * <dt>{@code powermanage}</dt>
- * <dd>manage the power saving mode of a device (see
- * {@link jdk.dio.power.PowerManaged})</dd>
  * </dl>
  *
  * @see DeviceManager#open DeviceManager.open
@@ -73,11 +65,16 @@
     /**
      * Constructs a new {@code GPIOPinPermission} with the specified target name and the implicit
      * {@code open} action.
+     * The target name is normalized so that leading and trailing spaces are removed
+     * and each occurrence of <code>{controller-number}</code> and <code>{channel-desc}</code> is represented in its canonical
+     * decimal representation form (without leading zeros).
      *
      * @param name
      *            the target name (as defined above).
      * @throws NullPointerException
      *             if {@code name} is {@code null}.
+     * @throws IllegalArgumentException
+     *             if {@code name} is not properly formatted.
      * @see #getName getName
      */
     public GPIOPinPermission(String name) {
@@ -87,6 +84,9 @@
     /**
      * Constructs a new {@code GPIOPinPermission} instance with the specified target name and action
      * list.
+     * The target name is normalized so that leading and trailing spaces are removed
+     * and each occurrence of <code>{controller-number}</code> and <code>{channel-desc}</code> is represented in its canonical
+     * decimal representation form (without leading zeros).
      *
      * @param name
      *            the target name (as defined above).
@@ -96,8 +96,11 @@
      * @throws NullPointerException
      *             if {@code name} is {@code null}.
      * @throws IllegalArgumentException
-     *             if actions is {@code null}, empty or contains an
-     *             action other than the specified possible actions.
+     *             <ul>
+     *             <li>if {@code actions} is {@code null}, empty or contains an action other than the
+     *             specified possible actions,</li>
+     *             <li>if {@code name} is not properly formatted.</li>
+     *             </ul>
      * @see #getName getName
      */
     public GPIOPinPermission(String name, String actions) {
--- a/src/share/classes/jdk/dio/gpio/GPIOPort.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/gpio/GPIOPort.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.gpio;
 
 import jdk.dio.ClosedDeviceException;
@@ -52,7 +51,7 @@
  * opened with an ad-hoc {@link GPIOPortConfig} configuration (which includes its hardware
  * addressing information) using one of the
  * {@link DeviceManager#open(jdk.dio.DeviceConfig)
- * DeviceManager.open(config,...)} it is not assigned any ID nor name.
+ * DeviceManager.open(config,...)} methods it is not assigned any ID nor name.
  * <p />
  * Once opened, an application can obtain the current value of a GPIO port by calling the
  * {@link #getValue getValue} method and set its value by calling the {@link #setValue setValue}
@@ -84,9 +83,18 @@
  * be changed by an application. Asynchronous notification of port value changes is
  * only loosely tied to hardware-level interrupt requests. The platform does not guarantee
  * notification in a deterministic/timely manner.
+ * <h3><a name="permission">Permission Requirement For Ad Hoc GPIO Ports</a></h3>
+ * Opening a {@code GPIOPort} instance with an ad-hoc configuration is subject
+ * to {@link jdk.dio.gpio.GPIOPortPermission GPIOPortPermission.OPEN} permission checks. <br />
+ * When opening an instance of {@code GPIOPort} defined as an ad-hoc grouping of GPIO pins
+ * the target of the {@link jdk.dio.gpio.GPIOPortPermission GPIOPortPermission.OPEN} permissions
+ * designate the controller or controllers of the GPIO pins that compose the port.
+ * Opening such an ad-hoc grouping of GPIO pins is, in addition, subject to {@link jdk.dio.gpio.GPIOPinPermission GPIOPinPermission.OPEN} permission checks
+ * on all the GPIO pins that compose the port.
  *
  * @see PortListener
  * @see GPIOPortPermission
+ * @see GPIOPinPermission
  * @since 1.0
  */
 @apimarker.API("device-io_1.1_gpio")
@@ -228,4 +236,18 @@
      *             if the device has been closed.
      */
     void setValue(int value) throws IOException, UnavailableDeviceException, ClosedDeviceException;
+
+    /**
+     * Gets the pins composing the port (in the exact same order they compose the port).
+     * <p />
+     * A concurrent runtime change of the
+     * dynamic configuration parameters of any of the pins composing the port (such as of its direction) may result in
+     * {@code IOException} being thrown by port operations.
+     *
+     * @return the pins composing the port (a defensive copy is returned); or {@code null} if
+     * the composing pins cannot be individually retrieved.
+     *
+     * @since 1.1
+     */
+    GPIOPin[] getPins();
 }
--- a/src/share/classes/jdk/dio/gpio/GPIOPortConfig.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/gpio/GPIOPortConfig.java	Thu Apr 30 21:58:05 2015 +0300
@@ -24,24 +24,34 @@
  */
 package jdk.dio.gpio;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.Objects;
+
+import com.oracle.dio.utils.ExceptionMessage;
+
+import jdk.dio.DeviceConfig;
 import jdk.dio.DeviceManager;
-import jdk.dio.DeviceConfig;
 import jdk.dio.InvalidDeviceConfigException;
-import com.oracle.dio.utils.ExceptionMessage;
+
+import romizer.DontRenameMethod;
+
 import serializator.*;
-import romizer.DontRenameMethod;
 
 /**
  * The {@code GPIOPortConfig} class encapsulates the hardware addressing information, and static and
  * dynamic configuration parameters of a GPIO port.
  * <p />
- * Some hardware addressing parameter, and static and dynamic configuration parameters may be set to
- * {@link #DEFAULT}. Whether such default settings are supported is platform- as well as device
- * driver-dependent.
+ * Some hardware addressing, static or dynamic configuration parameters may be
+ * set to {@link #UNASSIGNED} or {@code null} (see
+ * <a href="{@docRoot}/jdk/dio/DeviceConfig.html#default_unassigned">Unassigned, Default or Unused Parameter Values</a>).
  * <p />
  * An instance of {@code GPIOPortConfig} can be passed to the
- * {@link DeviceManager#open(DeviceConfig)} or
- * {@link DeviceManager#open(Class, DeviceConfig)} method to open the designated GPIO port
+ * {@link DeviceManager#open(DeviceConfig) open(DeviceConfig, ...)} and
+ * {@link DeviceManager#open(Class, DeviceConfig) open(Class, DeviceConfig, ...)}
+ * methods of the {@link DeviceManager} to open the designated GPIO port
  * with the specified configuration. A {@link InvalidDeviceConfigException} is thrown when
  * attempting to open a device with an invalid or unsupported configuration.
  * <p />
@@ -51,7 +61,9 @@
  * that compose a {@code GPIOPort} may trigger a notification for that {@code GPIOPort}.
  *
  * @see DeviceManager#open(DeviceConfig)
+ * @see DeviceManager#open(DeviceConfig, int)
  * @see DeviceManager#open(Class, DeviceConfig)
+ * @see DeviceManager#open(Class, DeviceConfig, int)
  * @since 1.0
  */
 @SerializeMe
@@ -74,11 +86,11 @@
      * Output port direction.
      */
     public static final int DIR_OUTPUT_ONLY = 1;
-    // private int portNumber = DEFAULT;
+
     private int direction;
     private int initValue;
     private GPIOPinConfig[] pinConfigs;
-    private GPIOPin[] pins;
+
 
     // hidden constructor for serializer
     @DontRenameMethod
@@ -114,24 +126,24 @@
      * @throws NullPointerException
      *             if {@code pins} is {@code null}.
      */
-    public GPIOPortConfig(int direction, int initValue, GPIOPinConfig[] pins) {
-        checkValues(direction, initValue, pins);
+    public GPIOPortConfig(int direction, int initValue, GPIOPinConfig... pins) {
         this.direction = direction;
         this.initValue = initValue;
         this.pinConfigs = new GPIOPinConfig[pins.length];
         System.arraycopy(pins, 0, this.pinConfigs, 0, pins.length);
+        checkValues();
     }
 
-    private void checkValues(int direction, int initValue, GPIOPinConfig[] pins) {
+    private void checkValues() {
         if (DIR_INPUT_ONLY > direction ||
             DIR_BOTH_INIT_OUTPUT < direction ||
-            pins.length == 0 ) {
+            pinConfigs.length == 0 ) {
             throw new IllegalArgumentException(
                 ExceptionMessage.format(ExceptionMessage.GPIO_ILLEGAL_DIRECTION_OR_INIT_VALUE)
             );
         }
 
-        for (GPIOPinConfig pin : pins) {
+        for (GPIOPinConfig pin : pinConfigs) {
             if (pin.getDirection() != direction &&
                 pin.getDirection() < DIR_BOTH_INIT_INPUT) {
                 throw new IllegalArgumentException(
@@ -142,14 +154,36 @@
     }
 
     /**
-     * Gets the configured port number.
+     * Creates a new {@code GPIOPortConfig} whose state is deserialized from the specified {@code InputStream}.
+     * This method may be invoked to restore the state of a {@code GPIOPortConfig}
+     * object from a persistent store.
      *
-     * @return the hardware port's number (a positive or zero integer) or {@link #DEFAULT} if no
-     *         port number was specified.
+     * @param in the stream to read from.
+     * @return a new {@code GPIOPortConfig} instance.
+     * @throws IOException if an I/O error occurs or if the provided stream does not
+     * contain a representation of a {@code GPIOPortConfig} object.
+     *
+     * @since 1.1
      */
-    // public int getPortNumber() {
-    // return portNumber;
-    // }
+    public static GPIOPortConfig deserialize(InputStream in) throws IOException {
+      throw new IOException("Unsupported Operation");
+    }
+
+
+    /**
+     * Serializes the state of this {@code GPIOPortConfig} object to the specified {@code OutputStream}.
+     * This method may be invoked by the {@link jdk.dio.DeviceManager DeviceManager}
+     * to save the state of this {@code GPIOPortConfig} object to a persistent store.
+     *
+     * @param out the stream to write to.
+     * @throws IOException if an I/O error occurs.
+     *
+     * @since 1.1
+     */
+    @Override
+    public int serialize(OutputStream out) throws IOException {
+      throw new IOException("Unsupported Operation");
+    }
 
     /**
      * Gets the configured port direction.
@@ -196,13 +230,53 @@
      * if this {@code GPIOPortConfig} instance is not associated to an actual {@code GPIOPort} instance -
      * that is the {@code GPIOPortConfig} instance was not retrieved from a call to
      * {@code getDescriptor().getConfiguration()} on the {@code GPIOPort} instance.
+     *
+     * @deprecated As of 1.1, replaced by {@link GPIOPort#getPins GPIOPort.getPins}.
      */
     public GPIOPin[] getPins() {
-        if (pins != null) {
-            GPIOPin[] clone = new GPIOPin[pins.length];
-            System.arraycopy(pins, 0, clone, 0, pins.length);
-            return clone;
-        }
         return null;
     }
+
+    /**
+     * Returns the hash code value for this object.
+     *
+     * @return a hash code value for this object.
+     */
+    @Override
+    public int hashCode() {
+        int hash = 3;
+        hash = 97 * hash + this.direction;
+        hash = 97 * hash + this.initValue;
+        for (GPIOPinConfig pinConfig : this.pinConfigs) {
+            hash = 97 * hash + Objects.hashCode(pinConfig);       }
+        return hash;
+    }
+
+    /**
+     * Checks two {@code GPIOPortConfig} objects for equality.
+     *
+     * @param obj
+     *            the object to test for equality with this object.
+     *
+     * @return {@code true} if {@code obj} is a {@code GPIOPortConfig} and has
+     * the same configuration parameter values as this {@code GPIOPortConfig} object; {@code false} otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final GPIOPortConfig other = (GPIOPortConfig) obj;
+        if (this.direction != other.direction) {
+            return false;
+        }
+        if (this.initValue != other.initValue) {
+            return false;
+        }
+        return Arrays.equals(this.pinConfigs, other.pinConfigs);
+    }
+
 }
--- a/src/share/classes/jdk/dio/gpio/GPIOPortPermission.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/gpio/GPIOPortPermission.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.gpio;
 
 import jdk.dio.DeviceManager;
@@ -41,19 +40,12 @@
  * <dl>
  * <dt><code>{channel-desc}</code></dt>
  * <dd>The <code>{channel-desc}</code> string (described in {@link DevicePermission}) must be
- * the empty string ({@code ("")}).</dd>
+ * the empty string ({@code ""}).</dd>
  * </dl>
- * The possible actions are {@code open}, {@code powermanage} or {@code setdirection}. Their meaning
- * is defined as follows:
+ * The supported actions are {@code open} and {@code powermanage} as defined in {@link DevicePermission}, and {@code setdirection} defined as follows:
  * <dl>
- * <dt>{@code open}</dt>
- * <dd>open and access a GPIO port functions (see {@link DeviceManager#open
- * DeviceManager.open})</dd>
  * <dt>{@code setdirection}</dt>
  * <dd>change GPIO port direction (see {@link GPIOPort#setDirection GPIOPort.setDirection})</dd>
- * <dt>{@code powermanage}</dt>
- * <dd>manage the power saving mode of a device (see
- * {@link jdk.dio.power.PowerManaged})</dd>
  * </dl>
  *
  * @see DeviceManager#open DeviceManager.open
@@ -71,11 +63,16 @@
     /**
      * Constructs a new {@code GPIOPortPermission} with the specified target name and the implicit
      * {@code open} action.
+     * The target name is normalized so that leading and trailing spaces are removed
+     * and each occurrence of <code>{controller-number}</code> is represented in its canonical
+     * decimal representation form (without leading zeros).
      *
      * @param name
      *            the target name (as defined above).
      * @throws NullPointerException
      *             if {@code name} is {@code null}.
+     * @throws IllegalArgumentException
+     *             if {@code name} is not properly formatted.
      * @see #getName getName
      */
     public GPIOPortPermission(String name) {
@@ -85,6 +82,9 @@
     /**
      * Constructs a new {@code GPIOPortPermission} instance with the specified target name and
      * action list.
+     * The target name is normalized so that leading and trailing spaces are removed
+     * and each occurrence of <code>{controller-number}</code> is represented in its canonical
+     * decimal representation form (without leading zeros).
      *
      * @param name
      *            the target name (as defined above).
@@ -94,8 +94,11 @@
      * @throws NullPointerException
      *             if {@code name} is {@code null}.
      * @throws IllegalArgumentException
-     *             if actions is {@code null}, empty or contains an
-     *             action other than the specified possible actions.
+     *             <ul>
+     *             <li>if {@code actions} is {@code null}, empty or contains an action other than the
+     *             specified possible actions,</li>
+     *             <li>if {@code name} is not properly formatted.</li>
+     *             </ul>
      * @see #getName getName
      */
     public GPIOPortPermission(String name, String actions) {
--- a/src/share/classes/jdk/dio/gpio/PinEvent.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/gpio/PinEvent.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.gpio;
 
 import jdk.dio.DeviceEvent;
--- a/src/share/classes/jdk/dio/gpio/PinListener.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/gpio/PinListener.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.gpio;
 
 import jdk.dio.DeviceEventListener;
--- a/src/share/classes/jdk/dio/gpio/PortEvent.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/gpio/PortEvent.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.gpio;
 
 import jdk.dio.DeviceEvent;
--- a/src/share/classes/jdk/dio/gpio/PortListener.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/gpio/PortListener.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.gpio;
 
 /**
--- a/src/share/classes/jdk/dio/gpio/package-info.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/gpio/package-info.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 /**
  * Interfaces and classes for reading and writing from/to GPIO (General Purpose Input Output) pins
  * and ports of the device.
@@ -32,7 +31,7 @@
  * {@code GPIOPin} instances depends on the hardware and platform configuration (and especially
  * whether the GPIO pins can be shared through different abstractions).
  * <p/>
- * In order to use a specific pin or port, an application should first open and obtain and obtain a
+ * In order to use a specific pin or port, an application should first open and obtain a
  * {@link jdk.dio.gpio.GPIOPin} instance or
  * {@link jdk.dio.gpio.GPIOPort} instance, respectively, for the pin or port it
  * wants to use using its numeric ID, name, type (interface) and/or properties:
@@ -83,15 +82,15 @@
  *
  *         public void valueChanged(PinEvent event) {
  *             try {
- *                 ledPin.setValue(event.getValue()); // turn LED on or off
+ *                 ledPin.setValue(event.getValue()); <i>// turn LED on or off</i>
  *             } catch (IOException ioe) {
- *                 // handle exception
+ *                 <i>// handle exception</i>
  *             }
  *         }
  *     });
- *     // perform some other computation
+ *     <i>// perform some other computation</i>
  * } catch (IOException ioe) {
- *     // handle exception
+ *     <i>// handle exception</i>
  * }
  * </pre>
  * </blockquote> The preceding example is using a <em>try-with-resources</em> statement;
--- a/src/share/classes/jdk/dio/i2cbus/I2CCombinedMessage.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/i2cbus/I2CCombinedMessage.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.i2cbus;
 
 import jdk.dio.ClosedDeviceException;
@@ -46,12 +45,12 @@
  *     ByteBuffer temp = ByteBuffer.allocateDirect(4);
  *     byte[] addr = new byte[]{...};
  *     int bytesRead = slave1.getBus().createCombinedMessage()
- *             .appendRead(slave1, temp) // Reads the temperature from TEMP sensor
- *             .appendWrite(slave2, ByteBuffer.wrap(addr)) // Writes the address to EEPROM to select the location
- *             .appendWrite(slave2, temp) // Writes the temperature at the selected EEPROM address
+ *             .appendRead(slave1, temp) <i>// Reads the temperature from TEMP sensor</i>
+ *             .appendWrite(slave2, ByteBuffer.wrap(addr)) <i>// Writes the address to EEPROM to select the location</i>
+ *             .appendWrite(slave2, temp) <i>// Writes the temperature at the selected EEPROM address</i>
  *             .transfer()[0];
  * } catch (IOException ioe) {
- *     // Handle exception
+ *     <i>// Handle exception</i>
  * }
  * </pre>
  * </blockquote> The preceding example is using a
@@ -171,7 +170,7 @@
      * Buffers are not safe for use by multiple concurrent threads so care should
      * be taken to not access the provided buffers until the transfer has completed.
      *
-     * @return an array containing the number of bytes read for each of the read
+     * @return an array (possibly empty) containing the number of bytes read for each of the read
      * operations of this combined message; the results of each read operations
      * appear in the very same order the read operations have been appended to
      * this combined message.
--- a/src/share/classes/jdk/dio/i2cbus/I2CDevice.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/i2cbus/I2CDevice.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.i2cbus;
 
 import jdk.dio.BufferAccess;
@@ -49,7 +48,7 @@
  * opened with an ad-hoc {@link I2CDeviceConfig} configuration (which includes its hardware
  * addressing information) using one of the
  * {@link DeviceManager#open(jdk.dio.DeviceConfig)
- * DeviceManager.open(config,...)} it is not assigned any ID nor name.
+ * DeviceManager.open(config,...)} methods it is not assigned any ID nor name.
  * <p />
  * On an I2C bus, data is transferred between the I2C master device and an I2C slave device through
  * single or combined messages:
@@ -96,8 +95,8 @@
  *             (byte) ((subaddress &gt;&gt; 8) &amp; 0xFF), (byte) ((subaddress &gt;&gt; 0) &amp; 0xFF), };
  *     try {
  *         ((Transactional) device).begin();
- *         device.write(ByteBuffer.wrap(subaddr, subaddr.length - subaddressSize, subaddressSize)); // Writes the subaddress
- *         device.read(dstBuf); // Read the data at that subaddress
+ *         device.write(ByteBuffer.wrap(subaddr, subaddr.length - subaddressSize, subaddressSize)); <i>// Writes the subaddress</i>
+ *         device.read(dstBuf); <i>// Read the data at that subaddress</i>
  *     } finally {
  *         ((Transactional) device).end();
  *     }
--- a/src/share/classes/jdk/dio/i2cbus/I2CDeviceConfig.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/i2cbus/I2CDeviceConfig.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,32 +22,40 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.i2cbus;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Objects;
+
 import jdk.dio.DeviceConfig;
+import jdk.dio.DeviceManager;
 import jdk.dio.InvalidDeviceConfigException;
-import jdk.dio.DeviceManager;
-import java.util.Objects;
+
+import romizer.DontRenameMethod;
+
 import serializator.*;
-import romizer.DontRenameMethod;
 
 /**
  * The {@code I2CDeviceConfig} class encapsulates the hardware addressing information, and static
  * and dynamic configuration parameters of an I2C slave device.
  * <p />
- * Some hardware addressing parameter, and static and dynamic configuration parameters may be set to
- * {@link #DEFAULT}. Whether such default settings are supported is platform- as well as device
- * driver-dependent.
+ * Some hardware addressing, static or dynamic configuration parameters may be
+ * set to {@link #UNASSIGNED} or {@code null} (see
+ * <a href="{@docRoot}/jdk/dio/DeviceConfig.html#default_unassigned">Unassigned, Default or Unused Parameter Values</a>).
  * <p />
  * An instance of {@code I2CDeviceConfig} can be passed to the
- * {@link DeviceManager#open(DeviceConfig)} or
- * {@link DeviceManager#open(Class, DeviceConfig)} method to open the designated I2C slave
+ * {@link DeviceManager#open(DeviceConfig) open(DeviceConfig, ...)} and
+ * {@link DeviceManager#open(Class, DeviceConfig) open(Class, DeviceConfig, ...)}
+ * methods of the {@link DeviceManager} to open the designated I2C slave
  * device with the specified configuration. A {@link InvalidDeviceConfigException} is thrown
  * when attempting to open a device with an invalid or unsupported configuration.
  *
  * @see DeviceManager#open(DeviceConfig)
+ * @see DeviceManager#open(DeviceConfig, int)
  * @see DeviceManager#open(Class, DeviceConfig)
+ * @see DeviceManager#open(Class, DeviceConfig, int)
  * @since 1.0
  */
 @SerializeMe
@@ -65,9 +73,152 @@
 
     private String controllerName;
     private int address;
-    private int addressSize;
-    private int controllerNumber = DEFAULT;
-    private int clockFrequency = DEFAULT;
+    private int addressSize = UNASSIGNED;
+    private int controllerNumber = UNASSIGNED;
+    private int clockFrequency = UNASSIGNED;
+    private int inputBufferSize = UNASSIGNED;
+    private int outputBufferSize = UNASSIGNED;
+
+    /**
+     * The {@code Builder} class allows for creating and initializing
+     * {@code I2CDeviceConfig} objects. Calls can be chained in the following
+     * manner:
+     * <blockquote>
+     * <pre>
+     *   I2CDeviceConfig config = new I2CDeviceConfig.Builder()
+     *           .setControllerNumber(1)
+     *           .setAddress(0x300, ADDR_SIZE_10)
+     *           .setClockFrequency(8000000)
+     *           .build();
+     * </pre>
+     * </blockquote>
+     *
+     * @since 1.1
+     */
+    @apimarker.API("device-io_1.1_i2cbus")
+    public static final  class Builder {
+
+        private  final I2CDeviceConfig instance = new I2CDeviceConfig();
+
+        /**
+         * Creates a new {@code Builder} instance.
+         */
+        public Builder() {
+
+        }
+
+        /**
+         * Creates a new {@code I2CDeviceConfig} instance initialized with the
+         * values set for each configuration parameters. If a configuration
+         * parameter was not explictly set its default value will be used.
+         *
+         * @return a new initialized {@code I2CDeviceConfig} instance.
+         * @throws IllegalStateException if any of the following is true:
+         * <ul>
+         * <li>the address of the slave device on the bus is not set.</li>
+         * </ul>
+         */
+        public I2CDeviceConfig build() {
+            instance.checkValues();
+            return instance;
+        }
+
+        /**
+         * Sets the name of the bus the slave device is connected to (default value is {@code null} if not set).
+         *
+         * @param controllerName the name of the bus the slave device is connected to (such as its <em>device
+         * file</em> name on UNIX systems) or {@code null}.
+         * @return this {@code Builder} instance.
+         */
+        public Builder setControllerName(String controllerName) {
+            instance.controllerName = controllerName;
+            return this;
+        }
+
+        /**
+         * Sets the address of the slave device on the bus.
+         *
+         * @param address the address of the slave device on the bus (a positive
+         * or zero integer).
+         * @param addressSize the address size: {@link #ADDR_SIZE_7} bits,
+         * {@link #ADDR_SIZE_10} bits or {@link #UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if any of the following is true:
+         * <ul>
+         * <li>{@code address} is not in the defined range;</li>
+         * <li>{@code addressSize} is not in the defined range;</li>
+         * </ul>
+         */
+        public Builder setAddress(int address, int addressSize) {
+            instance.address = address;
+            instance.addressSize = addressSize;
+            return this;
+        }
+
+        /**
+         * Sets the number of the bus the slave device is connected to (default
+         * value is {@code UNASSIGNED} if not set).
+         *
+         * @param controllerNumber the number of the bus the slave device is
+         * connected to (a positive or zero integer) or {@link #UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code controllerNumber} is not
+         * in the defined range.
+         */
+        public Builder setControllerNumber(int controllerNumber) {
+            instance.controllerNumber = controllerNumber;
+            return this;
+        }
+
+        /**
+         * Sets the requested input buffer size (default value is
+         * {@code UNASSIGNED} if not set).
+         *
+         * @param inputBufferSize the requested input buffer size in number of
+         * samples (a positive or zero integer) or
+         * {@code DeviceConfig.UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code inputBufferSize} is not in
+         * the defined range.
+         */
+        public Builder setInputBufferSize(int inputBufferSize) {
+            instance.inputBufferSize = inputBufferSize;
+            return this;
+        }
+
+        /**
+         * Sets the requested output buffer size (default value is
+         * {@code UNASSIGNED} if not set).
+         *
+         * @param outputBufferSize the requested output buffer size in number of
+         * samples (a positive or zero integer) or
+         * {@code DeviceConfig.UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code outputBufferSize} is not
+         * in the defined range.
+         */
+        public Builder setOutputBufferSize(int outputBufferSize) {
+            instance.outputBufferSize = outputBufferSize;
+            return this;
+        }
+
+        /**
+         * Sets the clock frequency of the slave device in Hz (default value is
+         * {@code UNASSIGNED} if not set).
+         *
+         * @param clockFrequency the clock frequency of the slave device in Hz
+         * (a positive integer) or {@link #UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code clockFrequency} is not in
+         * the defined range.
+         */
+        public Builder setClockFrequency(int clockFrequency) {
+            instance.clockFrequency = clockFrequency;
+            return this;
+        }
+    }
+
+
 
 
     // hidden constructor for serializer
@@ -80,15 +231,15 @@
      *
      * @param controllerNumber
      *            the number of the bus the slave device is connected to (a positive or zero
-     *            integer) or {@link #DEFAULT}.
+     *            integer) or {@link #UNASSIGNED}.
      * @param address
      *            the address of the slave device on the bus (a positive or zero integer).
      * @param addressSize
      *            the address size: {@link #ADDR_SIZE_7} bits, {@link #ADDR_SIZE_10} bits or
-     *            {@link #DEFAULT}.
+     *            {@link #UNASSIGNED}.
      * @param clockFrequency
      *            the clock frequency of the slave device in Hz (a positive integer) or
-     *            {@link #DEFAULT}.
+     *            {@link #UNASSIGNED}.
      * @throws IllegalArgumentException
      *             if any of the following is true:
      *             <ul>
@@ -97,6 +248,8 @@
      *             <li>{@code addressSize} is not in the defined range;</li>
      *             <li>{@code clockFrequency} is not in the defined range.</li>
      *             </ul>
+     *
+     * @deprecated As of 1.1, use {@link Builder} instead.
      */
     public I2CDeviceConfig(int controllerNumber, int address, int addressSize, int clockFrequency) {
         this.controllerNumber = controllerNumber;
@@ -111,15 +264,15 @@
      * configuration parameters.
      *
      * @param controllerName
-     *            the controller name (such as its <em>device file</em> name on UNIX systems).
+     *            the name of the bus the slave device is connected to (such as its <em>device file</em> name on UNIX systems).
      * @param address
      *            the address of the slave device on the bus (a positive or zero integer).
      * @param addressSize
      *            the address size: {@link #ADDR_SIZE_7} bits, {@link #ADDR_SIZE_10} bits or
-     *            {@link #DEFAULT}.
+     *            {@link #UNASSIGNED}.
      * @param clockFrequency
      *            the clock frequency of the slave device in Hz (a positive integer) or
-     *            {@link #DEFAULT}.
+     *            {@link #UNASSIGNED}.
      * @throws IllegalArgumentException
      *             if any of the following is true:
      *             <ul>
@@ -129,6 +282,8 @@
      *             </ul>
      * @throws NullPointerException
      *             if {@code controllerName} is {@code null}.
+     *
+     * @deprecated As of 1.1, use {@link Builder} instead.
      */
     public I2CDeviceConfig(String controllerName, int address, int addressSize, int clockFrequency) {
         this.controllerName = controllerName;
@@ -141,6 +296,37 @@
     }
 
     /**
+     * Creates a new {@code I2CDeviceConfig} whose state is deserialized from the specified {@code InputStream}.
+     * This method may be invoked to restore the state of a {@code I2CDeviceConfig}
+     * object from a persistent store.
+     *
+     * @param in the stream to read from.
+     * @return a new {@code I2CDeviceConfig} instance.
+     * @throws IOException if an I/O error occurs or if the provided stream does not
+     * contain a representation of a {@code I2CDeviceConfig} object.
+     *
+     * @since 1.1
+     */
+    public static I2CDeviceConfig deserialize(InputStream in) throws IOException {
+      throw new IOException("Unsupported Operation");
+    }
+
+    /**
+     * Serializes the state of this {@code I2CDeviceConfig} object to the specified {@code OutputStream}.
+     * This method may be invoked by the {@link jdk.dio.DeviceManager DeviceManager}
+     * to save the state of this {@code I2CDeviceConfig} object to a persistent store.
+     *
+     * @param out the stream to write to.
+     * @throws IOException if an I/O error occurs.
+     *
+     * @since 1.1
+     */
+    @Override
+    public int serialize(OutputStream out) throws IOException {
+      throw new IOException("Unsupported Operation");
+    }
+
+    /**
      * Gets the configured address of the I2C slave device.
      *
      * @return the address of the slave device on the bus (a positive or zero integer).
@@ -153,7 +339,7 @@
      * Gets the configured address size of the I2C slave device.
      *
      * @return the address size: {@link #ADDR_SIZE_7} bits, {@link #ADDR_SIZE_10} bits or
-     *         {@link #DEFAULT}.
+     *         {@link #UNASSIGNED}.
      */
     public int getAddressSize() {
         return addressSize;
@@ -163,8 +349,9 @@
      * Gets the configured controller number (the controller number the I2C bus adapter the I2C slave device
      * is connected to).
      *
-     * @return the controller number (a positive or zero integer) or {@link #DEFAULT}.
+     * @return the controller number (a positive or zero integer) or {@link #UNASSIGNED}.
      */
+    @Override
     public int getControllerNumber() {
         return controllerNumber;
     }
@@ -180,10 +367,39 @@
     }
 
     /**
+     * Gets the requested input buffer size. The platform/underlying driver may or may not allocate the requested size
+     * for the input buffer.
+     * When querying the configuration of an opened or registered device the
+     * allocated buffer size is returned.
+     *
+     * @return the requested or allocated input buffer size (a positive or zero integer).
+     *
+     * @since 1.1
+     */
+    public int getInputBufferSize() {
+        return inputBufferSize;
+    }
+
+    /**
+     * Gets the requested or allocated output buffer size. The platform/underlying
+     * driver may or may not allocate the requested size
+     * for the output buffer.
+     * When querying the configuration of an opened or registered device the
+     * allocated buffer size is returned.
+     *
+     * @return the requested or allocated output buffer size (a positive or zero integer).
+     *
+     * @since 1.1
+     */
+    public int getOutputBufferSize() {
+        return outputBufferSize;
+    }
+
+    /**
      * Gets the configured clock frequency (in Hz) supported by the I2C slave device.
      *
      * @return the clock frequency of the slave device in Hz (a positive integer) or
-     *         {@link #DEFAULT}.
+     *         {@link #UNASSIGNED}.
      */
     public int getClockFrequency() {
         return clockFrequency;
@@ -212,7 +428,7 @@
      *            the object to test for equality with this object.
      * @return {@code true} if {@code obj} is a {@code I2CDeviceConfig} and has the same hardware
      *         addressing information and configuration parameter values as this
-     *         {@code I2CDeviceConfig} object.
+     *         {@code I2CDeviceConfig} object; {@code false} otherwise.
      */
     @Override
     public boolean equals(Object obj) {
@@ -235,10 +451,7 @@
         if (this.controllerNumber != other.controllerNumber) {
             return false;
         }
-        if (this.clockFrequency != other.clockFrequency) {
-            return false;
-        }
-        return true;
+        return this.clockFrequency == other.clockFrequency;
     }
 
     private void checkValues() {
--- a/src/share/classes/jdk/dio/i2cbus/I2CPermission.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/i2cbus/I2CPermission.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.i2cbus;
 
 import jdk.dio.DeviceManager;
@@ -45,16 +44,7 @@
  * to {@link I2CDeviceConfig#getAddress I2CDeviceConfig.getAddress}. The characters in the string
  * must all be hexadecimal digits.</dd>
  * </dl>
- * The possible actions are {@code open} and {@code powermanage}. Their meaning is defined as
- * follows:
- * <dl>
- * <dt>{@code open}</dt>
- * <dd>open and access an I2C slave device functions (see {@link DeviceManager#open
- * DeviceManager.open})</dd>
- * <dt>{@code powermanage}</dt>
- * <dd>manage the power saving mode of a device (see
- * {@link jdk.dio.power.PowerManaged})</dd>
- * </dl>
+ * The supported actions are {@code open} and {@code powermanage} as defined in {@link DevicePermission}.
  *
  * @see DeviceManager#open DeviceManager.open
  * @see jdk.dio.power.PowerManaged
@@ -66,11 +56,16 @@
     /**
      * Constructs a new {@code ADCPermission} with the specified target name and the implicit
      * {@code open} action.
+     * The target name is normalized so that leading and trailing spaces are removed
+     * and each occurrence of <code>{controller-number}</code> and <code>{channel-desc}</code> is respectively represented in its canonical
+     * decimal and hexadecimal representation form (without leading zeros).
      *
      * @param name
      *            the target name (as defined above).
      * @throws NullPointerException
      *             if {@code name} is {@code null}.
+     * @throws IllegalArgumentException
+     *             if {@code name} is not properly formatted.
      * @see #getName getName
      */
     public I2CPermission(String name) {
@@ -80,6 +75,9 @@
     /**
      * Constructs a new {@code I2CPermission} instance with the specified target name and action
      * list.
+     * The target name is normalized so that leading and trailing spaces are removed
+     * and each occurrence of <code>{controller-number}</code> and <code>{channel-desc}</code> is respectively represented in its canonical
+     * decimal and hexadecimal representation form (without leading zeros).
      *
      * @param name
      *            the target name (as defined above).
@@ -89,8 +87,11 @@
      * @throws NullPointerException
      *             if {@code name} is {@code null}.
      * @throws IllegalArgumentException
-     *             if actions is {@code null}, empty or contains an
-     *             action other than the specified possible actions.
+     *             <ul>
+     *             <li>if {@code actions} is {@code null}, empty or contains an action other than the
+     *             specified possible actions,</li>
+     *             <li>if {@code name} is not properly formatted.</li>
+     *             </ul>
      * @see #getName getName
      */
     public I2CPermission(String name, String actions) {
--- a/src/share/classes/jdk/dio/i2cbus/package-info.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/i2cbus/package-info.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 /**
  * Interfaces and classes for I2C (Inter-Integrated Circuit Bus) device access.
  * <p />
@@ -70,19 +69,19 @@
  *     ByteBuffer stopCmd = ByteBuffer.wrap(LED_STOP_COMMAND);
  *     ByteBuffer offCmd = ByteBuffer.wrap(LED_OFF_COMMAND);
  *     ByteBuffer onCmd = ByteBuffer.wrap(LED_ON_COMMAND);
- *     // Clear all status of the 'LED' slave device
+ *     <i>// Clear all status of the 'LED' slave device</i>
  *     slave.write(ByteBuffer.wrap(stopCmd));
  *     slave.write(ByteBuffer.wrap(offCmd));
  *
  *     for (int i = 0; i &lt; LED_LOOP_COUNT; i++) {
- *         // turning 'LED' on and keeping it on for 1500ms
+ *         <i>// turning 'LED' on and keeping it on for 1500ms</i>
  *         slave.write(ByteBuffer.wrap(onCmd));
  *         try {
  *             Thread.sleep(LED_BLINK_TIME);
  *         } catch (InterruptedException ex) {
  *         }
  *
- *         // turning 'LED' off keeping it off for 1500ms
+ *         <i>// turning 'LED' off keeping it off for 1500ms</i>
  *         slave.write(ByteBuffer.wrap(offCmd));
  *         try {
  *             Thread.sleep(LED_BLINK_TIME);
@@ -90,7 +89,7 @@
  *         }
  *     }
  * } catch (IOException ioe) {
- *     // handle exception
+ *     <i>// handle exception</i>
  * }
  * </pre>
  * </blockquote> The preceding example is using a <em>try-with-resources</em> statement;
--- a/src/share/classes/jdk/dio/modem/ModemSignalEvent.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/modem/ModemSignalEvent.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.modem;
 
 import jdk.dio.Device;
--- a/src/share/classes/jdk/dio/modem/ModemSignalListener.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/modem/ModemSignalListener.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.modem;
 
 import jdk.dio.Device;
--- a/src/share/classes/jdk/dio/modem/ModemSignalsControl.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/modem/ModemSignalsControl.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.modem;
 
 import jdk.dio.ClosedDeviceException;
--- a/src/share/classes/jdk/dio/modem/package-info.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/modem/package-info.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 /**
  * Interfaces and classes for controlling MODEM signals.
  * <p />
--- a/src/share/classes/jdk/dio/package-info.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/package-info.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 /**
  * Provides interfaces and classes for device I/O access and control. Devices are of
  * defined types and can be accessed and control by the means of
--- a/src/share/classes/jdk/dio/power/PowerManaged.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/power/PowerManaged.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.power;
 
 import jdk.dio.ClosedDeviceException;
@@ -125,7 +124,7 @@
      */
 
     /*
-     * Note: the power states below are freely adapted from the Device Power Sates defined by the Device power management
+     * Note: the power sates below are freely adapted from the Device Power Sates defined by the Device power management
      * in the ACPI spec (http://www.acpi.info/DOWNLOADS/ACPIspec30a.pdf).
      */
 
--- a/src/share/classes/jdk/dio/power/PowerSavingHandler.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/power/PowerSavingHandler.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.power;
 
 import jdk.dio.Device;
--- a/src/share/classes/jdk/dio/power/package-info.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/power/package-info.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 /**
  * Interfaces and classes for power management of devices.
  * <p />
@@ -41,10 +40,10 @@
  *     public void start(int channelID, int low, int high) throws IOException, UnavailableDeviceException,
  *             DeviceNotFoundException {
  *         channel = (ADCChannel) DeviceManager.open(channelID);
- *         channel.setSamplingInterval(1000); // every 1 seconds
+ *         channel.setSamplingInterval(1000); <i>// every 1 seconds</i>
  *         channel.startMonitoring(low, high, this);
  *         if (channel instanceof PowerManaged) {
- *             ((PowerManaged) channel).enablePowerSaving(PowerManaged.LOW_POWER, this); // Only enable LOW_POWER saving mode (POWER_ON is implicit)
+ *             ((PowerManaged) channel).enablePowerSaving(PowerManaged.LOW_POWER, this); <i>// Only enable LOW_POWER saving mode (POWER_ON is implicit)</i>
  *         }
  *     }
  *
@@ -57,15 +56,15 @@
  *     public &lt;P extends Device&lt;? super P&gt;&gt; long handlePowerStateChangeRequest(P device,
  *             PowerManaged.Group group, int currentState, int requestedState, long duration) {
  *         if (requestedState == PowerManaged.LOW_POWER) {
- *             return inRange ? duration : 0; // Only accept to change to LOW_POWER if signal is back in range
+ *             return inRange ? duration : 0; <i>// Only accept to change to LOW_POWER if signal is back in range</i>
  *         }
- *         return duration; // Accept returning to POWER_ON
+ *         return duration; <i>// Accept returning to POWER_ON</i>
  *     }
  *
  *     &#64;Override
  *     public &lt;P extends Device&lt;? super P&gt;&gt; void handlePowerStateChange(P device,
  *             PowerManaged.Group group, int currentState, int requestedState, long duration) {
- *         // Do nothing
+ *         <i>// Do nothing</i>
  *     }
  *
  *     public void stop() throws IOException {
--- a/src/share/classes/jdk/dio/pwm/GenerationEvent.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/pwm/GenerationEvent.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.pwm;
 
 import jdk.dio.DeviceEvent;
--- a/src/share/classes/jdk/dio/pwm/GenerationListener.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/pwm/GenerationListener.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.pwm;
 
 import jdk.dio.AsyncErrorHandler;
--- a/src/share/classes/jdk/dio/pwm/GenerationRoundListener.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/pwm/GenerationRoundListener.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.pwm;
 
 import jdk.dio.OutputRoundListener;
--- a/src/share/classes/jdk/dio/pwm/InvalidPulseRateException.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/pwm/InvalidPulseRateException.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,12 +22,12 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.pwm;
 
 /**
- * Thrown by an instance of {@link PWMChannel} in case the requested pulse rate/frequency is higher than the maximum
- * rate/frequency the PWM device can support.
+ * Thrown by an instance of {@link PWMChannel} in case the requested pulse period results
+ * in a pulse rate higher or lower
+ * than the maximum, respectively minimum, rate/frequency the PWM device can support.
  *
  * @since 1.0
  */
--- a/src/share/classes/jdk/dio/pwm/PWMChannel.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/pwm/PWMChannel.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,8 +22,10 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+package jdk.dio.pwm;
 
-package jdk.dio.pwm;
+import java.io.IOException;
+import java.nio.IntBuffer;
 
 import jdk.dio.BufferAccess;
 import jdk.dio.ClosedDeviceException;
@@ -31,8 +33,8 @@
 import jdk.dio.DeviceManager;
 import jdk.dio.UnavailableDeviceException;
 import jdk.dio.UnsupportedByteOrderException;
-import java.io.IOException;
-import java.nio.IntBuffer;
+import jdk.dio.gpio.GPIOPin;
+
 import romizer.WeakDontRenameClass;
 
 /**
@@ -48,11 +50,11 @@
  * {@link DeviceManager#open(java.lang.String, java.lang.Class, java.lang.String[])
  * DeviceManager.open(name,...)} methods using its name. When a {@code PWMChannel} instance is opened with an ad-hoc
  * {@link PWMChannelConfig} configuration (which includes its hardware addressing information) using one of the
- * {@link DeviceManager#open(jdk.dio.DeviceConfig) DeviceManager.open(config,...)} it is not
+ * {@link DeviceManager#open(jdk.dio.DeviceConfig) DeviceManager.open(config,...)} methods it is not
  * assigned any ID nor name.
  * <p />
- * Once opened, an application can set the pulse period using the {@link #setPulsePeriod} and then generate a certain
- * number of pulses of a specified width by calling one of the {@link #generate} methods.
+ * Once opened, an application can set the pulse period using the {@link #setPulsePeriod setPulsePeriod} and then generate a certain
+ * number of pulses of a specified width by calling one of the {@link #generate generate} methods.
  * <p />
  * An application can also asynchronously generate a train of pulses either of a specified width up to a specified
  * maximum count or from widths specified in a buffer by calling one of the
@@ -68,9 +70,35 @@
  * <p />
  * Upon opening a PWM channel the default pulse width and duty cycle are always {@code 0}; the idle
  * state is platform or configuration-specific.
+ * <h3><a name="iomodes">Buffered I/O and Direct I/O Transfers</a></h3>
+ * A PWM channel may support buffered I/O or direct I/O operations depending on
+ * the capabilities of the underlying device hardware and driver. <br />
+ * Buffered output - output in buffering mode - may be requested by setting the
+ * output buffer size parameter of the {@link PWMChannelConfig} configuration to
+ * a value greater than {@code 0} ; whether or not the channel will indeed work
+ * in buffering mode and will use an internal output buffer of the size requested
+ * is up to the device driver. An application may check whether a channel is
+ * working in buffering mode by calling the
+ * {@link PWMChannelConfig#getOutputBufferSize PWMChannelConfig.getOutputBufferSize} method. <br />
+ * When a PWM channel is not working in buffering mode, direct I/O may be
+ * enabled by providing direct {@code Buffer}s to the output methods; whether
+ * efficient direct output transfers will be used depends on the underlying
+ * hardware and driver capabilities and on whether the provided buffers are
+ * suitable for such operations (see
+ * {@link BufferAccess#prepareBuffer BufferAccess.prepareBuffer}). Output methods
+ * using double buffering may only support efficient direct operations if both
+ * buffers are suitable for such operations.
+ * <h3><a name="permission">Permission Requirement For PWM Channels Configured with an Explicit GPIO Output Pin</a></h3>
+ * Opening a {@code PWMChannel} instance with an ad-hoc configuration requires
+ * the {@link jdk.dio.pwm.PWMPermission PWMPermission.OPEN} to be granted;
+ * opening an instance of a {@code PWMChannel} configured with an explicit {@code GPIOPin} output
+ * on which the pulses are to be generated requires, in addition, the
+ * {@link jdk.dio.gpio.GPIOPinPermission GPIOPinPermission.OPEN} permission to be granted
+ * on the designated GPIO pin.
  *
  * @see GenerationListener
  * @see PWMPermission
+ * @see jdk.dio.gpio.GPIOPinPermission
  * @since 1.0
  */
 @apimarker.API("device-io_1.1_pwm")
@@ -78,16 +106,20 @@
 public interface PWMChannel extends Device<PWMChannel>, BufferAccess<IntBuffer> {
 
     /**
-     * Sets the pulse period of this PWM channel.
+     * Sets the <em>scaled</em> pulse period of this PWM channel. The
+     * <em>effective</em> pulse period is calculated from the
+     * currently set <em>scale factor</em> as can be retrieved using {@link #getScaleFactor getScaleFactor}.
+     * Whether changing the pulse period
+     * has an immediate effect or not on an active (synchronous or asynchronous) generation is
+     * device- as well as platform-dependent.
      * <p />
-     * The pulse period is expressed in microseconds; if the underlying platform or driver
-     * does not support a microsecond resolution or does not support the requested pulse period value
-     * then {@code period} will be <em>rounded down</em> to accommodate the supported timer resolution
-     * or respectively aligned to the closest lower supported discrete period value. The resulting, actual
+     * If the underlying platform or driver
+     * does not support the requested pulse period value
+     * then {@code period} will be aligned to the closest lower supported discrete period value. The resulting, actual
      * pulse period can be retrieved by a call to {@link #getPulsePeriod() getPulsePeriod}.
      *
      * @param period
-     *            the pulse period as a period in microseconds.
+     *            the scaled pulse period as a period in microseconds.
      * @throws IOException
      *             if some other I/O error occurs.
      * @throws UnavailableDeviceException
@@ -95,21 +127,23 @@
      * @throws ClosedDeviceException
      *             if the device has been closed.
      * @throws InvalidPulseRateException
-     *             if the resulting pulse rate/frequency (i.e.: <i>1/period</i>) is either higher than the maximum supported
-     *             pulse rate/frequency (i.e.: <i>1/{@link #getMinPulsePeriod getMinPulsePeriod}</i>) or lower than the minimum supported
-     *             pulse rate/frequency (i.e.: <i>1/{@link #getMaxPulsePeriod getMaxPulsePeriod}</i>)
+     *             if {@code period} is greater than the maximum pulse period (see {@link #getMaxPulsePeriod getMaxPulsePeriod})
+     *             or lower than the minimum pulse period (see {@link #getMinPulsePeriod getMinPulsePeriod}).
      * @throws IllegalArgumentException
      *             if {@code period} is negative or zero.
      */
     void setPulsePeriod(int period) throws IOException, UnavailableDeviceException, ClosedDeviceException;
 
     /**
-     * Gets the pulse period of this PWM channel (in microseconds). If the pulse period was not set previously using
+     * Gets the <em>scaled</em> pulse period of this PWM channel (in microseconds). The
+     * <em>effective</em> pulse period can then be calculated from the
+     * currently set <em>scale factor</em> as can be retrieved using {@link #getScaleFactor getScaleFactor}.
+     * If the pulse period was not set previously using
      * {@link #setPulsePeriod setPulsePeriod} the device configuration-specific default value is returned.
      * Additionally, the value returned may differ from the previously set or configured value as it may have
-     * been adjusted to account for the resolution or discrete pulse period values supported by the underlying platform or driver.
+     * been adjusted to account for the timer resolution or discrete pulse period values supported by the underlying platform or driver.
      *
-     * @return the pulse period (in microseconds).
+     * @return the scaled pulse period (in microseconds).
      * @throws IOException
      *             if some other I/O error occurs.
      * @throws UnavailableDeviceException
@@ -120,10 +154,73 @@
     int getPulsePeriod() throws IOException, UnavailableDeviceException, ClosedDeviceException;
 
     /**
-     * Gets the maximum pulse period of this PWM channel (in microseconds) that can bet set by a call to
-     * {@link #setPulsePeriod setPulsePeriod}.
+     * Sets the pulse period scale factor of this PWM channel.
+     * <p />
+     * If the underlying platform or driver does not support the
+     * requested scale factor value then {@code factor} will be <em>rounded
+     * down</em> to aligned to the closest lower supported discrete factor value. The resulting factor can
+     * be retrieved by a call to {@link #getScaleFactor getScaleFactor}.
+     * <p />
+     * If the scale factor - after adjustment - is {@code scale} and the scaled pulse period value as
+     * returned by {@link #getPulsePeriod getPulsePeriod} is {@code sPeriod} then the
+     * effective pulse period is calculated as follows: <blockquote>
+     * <pre>
+     * {@code ePeriod = (sPeriod / scale)}
+     * </pre>
+     * </blockquote>
      *
-     * @return the maximum pulse period (in microseconds).
+     * @param factor the scale factor.
+     * @throws IOException if some other I/O error occurs.
+     * @throws UnavailableDeviceException if this device is not currently
+     * available - such as it is locked by another application.
+     * @throws ClosedDeviceException if the device has been closed.
+     *
+     * @see #getScaleFactor
+     */
+    void setScaleFactor(double factor) throws IOException, UnavailableDeviceException, ClosedDeviceException;
+
+    /**
+     * Gets the pulse period scale factor of this PWM channel. If the scale
+     * factor is {@code scale} and the scaled pulse period value as
+     * returned by {@link #getPulsePeriod getPulsePeriod} is {@code sPeriod} then the
+     * effective pulse period is calculated as follows: <blockquote>
+     * <pre>
+     * {@code ePeriod = (sPeriod / scale)}
+     * </pre>
+     * </blockquote>
+     * Conversely, the scaled pulse period value to set using
+     * {@link #setPulsePeriod} to obtain the effective pulse
+     * period {@code ePeriod} is calculated as follows: <blockquote>
+     * <pre>
+     * {@code sPeriod = (ePeriod * scale)}
+     * </pre>
+     * </blockquote>
+     * The scale factor also applies to the minimum and maximum scaled pulse periods
+     * as respectively returned by {@link #getMinPulsePeriod getMinPulsePeriod}
+     * and {@link #getMaxPulsePeriod getMaxPulsePeriod}.
+     * <p />
+     * If the pulse period scale factor was not set previously using
+     * {@link #setScaleFactor setScaleFactor}, the device configuration-specific
+     * default value is returned.
+     *
+     * @return the scale factor.
+     * @throws IOException
+     *             if some other I/O error occurs.
+     * @throws UnavailableDeviceException
+     *             if this device is not currently available - such as it is locked by another
+     *             application.
+     * @throws ClosedDeviceException
+     *             if the device has been closed.
+     */
+    double getScaleFactor() throws IOException, UnavailableDeviceException, ClosedDeviceException;
+
+    /**
+     * Gets the <em>scaled</em> maximum pulse period of this PWM channel (in microseconds) that can bet set by a call to
+     * {@link #setPulsePeriod setPulsePeriod}. The maximum <em>effective</em> pulse period
+     * can be calculated from the currently set <em>scale factor</em> as can be retrieved using
+     * {@link #getScaleFactor getScaleFactor}.
+     *
+     * @return the maximum scaled pulse period (in microseconds).
      * @throws IOException
      *             if some other I/O error occurs.
      * @throws UnavailableDeviceException
@@ -134,10 +231,12 @@
     int getMaxPulsePeriod() throws IOException, UnavailableDeviceException, ClosedDeviceException;
 
     /**
-     * Gets the minimum pulse period of this PWM channel (in microseconds) that can bet set by a call to
-     * {@link #setPulsePeriod setPulsePeriod}.
+     * Gets the minimum <em>scaled</em> pulse period of this PWM channel (in microseconds) that can bet set by a call to
+     * {@link #setPulsePeriod setPulsePeriod}. The minimum <em>effective</em> pulse period
+     * can be calculated from the currently set <em>scale factor</em> as can be retrieved using
+     * {@link #getScaleFactor getScaleFactor}.
      *
-     * @return the minimum pulse period (in microseconds).
+     * @return the minimum scaled pulse period (in microseconds).
      * @throws IOException
      *             if some other I/O error occurs.
      * @throws UnavailableDeviceException
@@ -149,21 +248,23 @@
 
     /**
      * Generates a pulse train containing the specified count of pulses of the specified width.
+     * The pulse width value is <em>scaled</em>; the <em>effective</em> pulse width can be calculated
+     * from the currently set <em>scale factor</em> as can be retrieved using {@link #getScaleFactor getScaleFactor}.
      * <p />
      * To generate pulses of a specific duty cycle {@code dutyCycle}, this method may be called as follows: <br />
-     *
      * <pre>
      * float dutyCycle = 0.5f;
      * pwmChannel.generate((pwmChannel.getPulsePeriod() * dutyCycle), count);
      * </pre>
-     * The pulse width is expressed in microseconds; if the underlying platform or driver
-     * does not support a microsecond resolution or does not support the requested width value
-     * then {@code width} will be <em>rounded down</em> to accommodate the supported timer resolution
-     * or respectively aligned to the closest lower supported discrete width value.
+     * If the underlying platform or driver
+     * does not support the requested width value
+     * then {@code width} will be aligned to the closest lower supported discrete width value.
      * <p />
      * The operation will return only after generating all of the {@code count} requested pulses.
      * <p />
-     * The pulses will be generated according to the current pulse period as returned by {@link #getPulsePeriod getPulsePeriod}.
+     * The pulses will be generated according to the current effective pulse period
+     * as determined by the current scaled pulse period (see {@link #getPulsePeriod getPulsePeriod})
+     * and the current scale factor {@link #getScaleFactor getScaleFactor}.
      * <p />
      * This method may be invoked at any time. If another thread has already initiated a synchronous output operation
      * upon this channel then an invocation of this method will block until the first operation is complete.
@@ -171,7 +272,7 @@
      * Only one output operation (synchronous or asynchronous) can be going on at any time.
      *
      * @param width
-     *            the pulse width (in microseconds).
+     *            the scaled pulse width (in microseconds).
      * @param count
      *            the maximum number of pulses to generate.
      *
@@ -191,7 +292,8 @@
 
     /**
      * Generates a pulse train from the specified sequence of pulse widths. The provided buffer contains the
-     * widths of the pulses to generate.
+     * <em>scaled</em> widths of the pulses to generate; the <em>effective</em> pulse widths can be calculated
+     * from the currently set <em>scale factor</em> as can be retrieved using {@link #getScaleFactor getScaleFactor}.
      * <p />
      * <i>r</i> pulses will be generated by this channel, where <i>r</i> is the number of integers (pulse widths)
      * remaining in the buffer, that is, {@code src.remaining()}, at the moment this method is invoked.
@@ -200,10 +302,16 @@
      * </i>. The sequence starts at index <i>p</i>, where <i>p</i> is the buffer's position at the moment this method is
      * invoked; the index of the last pulse width integer value written will be <i>{@code p + n - 1}</i>. Upon return
      * the buffer's position will be equal to <i>{@code p + n}</i>; its limit will not have changed.
+     * <br />
+     * The operation will block until all of the <i>r</i> pulse width values
+     * remaining in the provided {@code src} buffer have been written or otherwise
+     * transferred to the the driver/hardware. If this channel uses an internal output buffer and
+     * is therefore working in <a href="#iomodes">buffering mode</a> this method will block until all the
+     * <i>r</i> pulse width values have been copied to the internal output buffer.
      * <p />
-     * The operation will return only after generating all of the <i>r</i> requested pulses.
-     * <p />
-     * The pulses will be generated according to the current pulse rate as returned by {@link #getPulseRate getPulseRate}.
+     * The pulses will be generated according to the current effective pulse period
+     * as determined by the current scaled pulse period (see {@link #getPulsePeriod getPulsePeriod})
+     * and the current scale factor {@link #getScaleFactor getScaleFactor}.
      * <p />
      * This method may be invoked at any time. If another thread has already initiated a synchronous pulse generation
      * upon this channel, however, then an invocation of this method will block until the first operation is complete.
@@ -215,14 +323,13 @@
      * the actual width of the pulse generated by the PWM device is hardware- or driver-specific: the pulse width
      * may for example be equal to the set period, corresponding to a 100% duty cycle.
      * <br />
-     * The pulse width is expressed in microseconds; if the underlying platform or driver
-     * does not support a microsecond resolution or does not support the requested width value
+     * If the underlying platform or driver
+     * does not support the requested width value
      * then the actual width of the pulse generated by the PWM device is hardware- or driver-specific: the pulse width
-     * may for example be <em>rounded down</em> to accommodate the supported timer resolution
-     * or respectively aligned to the closest lower supported discrete width value.
+     * may, for example, be aligned to the closest lower supported discrete width value.
      *
      * @param src
-     *            the buffer from which the pulse width integer values can be retrieved.
+     *            the buffer from which the scaled pulse width integer values can be retrieved.
      * @throws NullPointerException
      *             If {@code src} is {@code null}.
      * @throws IllegalStateException
@@ -241,13 +348,15 @@
     /**
      * Starts an asynchronous pulse train generation session - continuously generating pulses of the specified width
      * until explicitly stopped.
+     * The pulse width value is <em>scaled</em>; the <em>effective</em> pulse width can be calculated
+     * from the currently set <em>scale factor</em> as can be retrieved using {@link #getScaleFactor getScaleFactor}.
      * <p />
-     * The pulses will be generated according to the current pulse period as returned by {@link #getPulsePeriod getPulsePeriod}.
+     * The pulses will be generated according to the current effective pulse period
+     * as determined by the current scaled pulse period (see {@link #getPulsePeriod getPulsePeriod})
+     * and the current scale factor {@link #getScaleFactor getScaleFactor}.
      * <p />
-     * The pulse width is expressed in microseconds; if the underlying platform or driver
-     * does not support a microsecond resolution or does not support the requested width value
-     * then {@code width} will be <em>rounded down</em> to accommodate the supported timer resolution
-     * or respectively aligned to the closest lower supported discrete width value.
+     * If the underlying platform or driver does not support the requested width value
+     * then {@code width} will be aligned to the closest lower supported discrete width value.
      * <p/>
      * Pulse generation will immediately start and proceed asynchronously. It may be stopped prior to completion by a
      * call to {@link #stopGeneration stopGeneration}.
@@ -255,7 +364,7 @@
      * Only one pulse generation session can be going on at any time.
      *
      * @param width
-     *            the pulse width (in microseconds).
+     *            the scaled pulse width (in microseconds).
      *
      * @throws IOException
      *             if some other I/O error occurs.
@@ -276,13 +385,15 @@
      * Starts an asynchronous pulse train generation session - generating pulses of the specified width up to the
      * specified count. The provided {@link GenerationListener} instance will be invoked upon completion, that is when
      * the count of generated pulses reaches the specified count value.
+     * The pulse width value is <em>scaled</em>; the <em>effective</em> pulse width can be calculated
+     * from the currently set <em>scale factor</em> as can be retrieved using {@link #getScaleFactor getScaleFactor}.
      * <p />
-     * The pulses will be generated according to the current pulse period as returned by {@link #getPulsePeriod getPulsePeriod}.
+     * The pulses will be generated according to the current effective pulse period
+     * as determined by the current scaled pulse period (see {@link #getPulsePeriod getPulsePeriod})
+     * and the current scale factor {@link #getScaleFactor getScaleFactor}.
      * <p />
-     * The pulse width is expressed in microseconds; if the underlying platform or driver
-     * does not support a microsecond resolution or does not support the requested width value
-     * then {@code width} will be <em>rounded down</em> to accommodate the supported timer resolution
-     * or respectively aligned to the closest lower supported discrete width value.
+     * If the underlying platform or driver does not support the requested width value
+     * then {@code width} will be aligned to the closest lower supported discrete width value.
      * <p/>
      * Pulse generation will immediately start and proceed asynchronously. It may be stopped prior to completion by a
      * call to {@link #stopGeneration stopGeneration}.
@@ -290,7 +401,7 @@
      * Only one pulse generation session can be going on at any time.
      *
      * @param width
-     *            the pulse width (in microseconds).
+     *            the scaled pulse width (in microseconds).
      * @param count
      *            the maximum number of pulses to generate.
      * @param listener
@@ -317,7 +428,10 @@
     /**
      * Starts asynchronous pulse train generation in successive rounds - initially generating pulses of the specified
      * widths up to the specified initial count - as indicated by the number of remaining elements in the provided
-     * buffer. Additional rounds are asynchronously fetched by notifying the provided {@link GenerationRoundListener}
+     * buffer. The provided buffer contains the <em>scaled</em> widths of the pulses to generate; the <em>effective</em>
+     * pulse widths can be calculated from the currently set <em>scale factor</em> as can be retrieved using
+     * {@link #getScaleFactor getScaleFactor}.
+     * Additional rounds are asynchronously fetched by notifying the provided {@link GenerationRoundListener}
      * instance once the initial count of pulses have been generated. The widths of the initial pulses to be generated
      * are read from the provided buffer; the widths of the pulses to generate during the subsequent rounds are read
      * from that very same buffer upon invocation of the provided {@link GenerationRoundListener} instance.
@@ -332,11 +446,18 @@
      * at the moment this method is invoked and then subsequently when the listener is returning; the index of the last integer written will be <i>{@code p + n - 1}</i>.
      * Upon invocation of the listener to fetch the widths of more pulses to generate the buffer's position will be equal to <i>{@code p + n}</i>; its limit will not have changed.
      * <br />
+     * If this channel
+     * uses an internal output buffer and is therefore working in <a href="#iomodes">buffering mode</a> the listener will only be
+     * invoked after all the <i>r</i> pulse width values have been copied to the
+     * internal output buffer; otherwise the listener will only be invoked after all the
+     * <i>r</i> pulse width values have been transferred to the driver/hardware.<br />
      * The buffer's position upon stopping this asynchronous operation by a call to {@link #stopGeneration stopGeneration}
      * is not predictable unless called from within the listener.
      * <p />
-     * The pulses will be generated according to the current pulse rate as returned by {@link #getPulseRate getPulseRate}. The
-     * pulse rate can be changed by the provided {@link GenerationRoundListener} instance upon notification of each
+     * The pulses will be generated according to the current effective pulse period
+     * as determined by the current scaled pulse period (see {@link #getPulsePeriod getPulsePeriod})
+     * and the current scale factor {@link #getScaleFactor getScaleFactor}. The
+     * pulse period can be changed by the provided {@link GenerationRoundListener} instance upon notification of each
      * pulse train subsequence.
      * <p />
      * Upon notification of the provided {@code GenerationRoundListener}
@@ -362,14 +483,12 @@
      * the actual width of the pulse generated by the PWM device is hardware- or driver-specific: the pulse width
      * may for example be equal to the set period, corresponding to a 100% duty cycle.
      * <br />
-     * The pulse width is expressed in microseconds; if the underlying platform or driver
-     * does not support a microsecond resolution or does not support a requested width value
+     * If the underlying platform or driver does not support a requested width value
      * then the actual width of the pulse generated by the PWM device is hardware- or driver-specific: the pulse width
-     * may for example be <em>rounded down</em> to accommodate the supported timer resolution
-     * or respectively aligned to the closest lower supported discrete width value.
+     * may, for example, be aligned to the closest lower supported discrete width value.
      *
      * @param src
-     *            the buffer for the widths (in microseconds) of the pulses to generate.
+     *            the buffer from which the scaled pulse width integer values can be retrieved.
      * @param listener
      *            the {@link GenerationRoundListener} instance to be notified when pulses have been generated for all
      *            the width values remaining in the buffer.
@@ -425,16 +544,14 @@
      * the actual width of the pulse generated by the PWM device is hardware- or driver-specific: the pulse width
      * may for example be equal to the set period, corresponding to a 100% duty cycle.
      * <br />
-     * The pulse width is expressed in microseconds; if the underlying platform or driver
-     * does not support a microsecond resolution or does not support the requested width value
+     * If the underlying platform or driver does not support a requested width value
      * then the actual width of the pulse generated by the PWM device is hardware- or driver-specific: the pulse width
-     * may for example be <em>rounded down</em> to accommodate the supported timer resolution
-     * or respectively aligned to the closest lower supported discrete width value.
+     * may, for example, be aligned to the closest lower supported discrete width value.
      *
      * @param src1
-     *            the first buffer for the widths (in microseconds) of the pulses to generate.
+     *            the first buffer from which the scaled pulse width integer values can be retrieved.
      * @param src2
-     *            the second buffer for the widths (in microseconds) of the pulses to generate.
+     *            the second buffer from which the scaled pulse width integer values can be retrieved.
      * @param listener
      *            the {@link GenerationRoundListener} instance to be notified when pulses have been generated for all
      *            the width values remaining in the working buffer.
@@ -471,4 +588,17 @@
      *             if the device has been closed.
      */
     void stopGeneration() throws IOException, UnavailableDeviceException, ClosedDeviceException;
+
+    /**
+     * Gets the output on which the pulses are generated.
+     * <p />
+     * A concurrent runtime change of the dynamic configuration parameters of the
+     * output (such as of its direction) may result in {@code IOException} being
+     * thrown by PWM operations.
+     *
+     * @return the output on which the pulses are generated; or {@code null} if the output is implicit.
+     *
+     * @since 1.1
+     */
+    GPIOPin getOutput();
 }
--- a/src/share/classes/jdk/dio/pwm/PWMChannelConfig.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/pwm/PWMChannelConfig.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,31 +22,36 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.pwm;
 
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.util.Objects;
 
+import com.oracle.dio.utils.ExceptionMessage;
+
 import jdk.dio.DeviceConfig;
 import jdk.dio.DeviceManager;
 import jdk.dio.InvalidDeviceConfigException;
 import jdk.dio.gpio.GPIOPin;
 import jdk.dio.gpio.GPIOPinConfig;
-import com.oracle.dio.utils.ExceptionMessage;
 
 import romizer.*;
+
 import serializator.*;
 
 /**
  * The {@code PWMChannelConfig} class encapsulates the hardware addressing information, and static and dynamic
  * configuration parameters of a PWM channel.
  * <p />
- * Some hardware addressing parameter, and static and dynamic configuration parameters may be set to {@link #DEFAULT}.
- * Whether such default settings are supported is platform- as well as device driver-dependent.
+ * Some hardware addressing, static or dynamic configuration parameters may be
+ * set to {@link #UNASSIGNED} or {@code null} (see
+ * <a href="{@docRoot}/jdk/dio/DeviceConfig.html#default_unassigned">Unassigned, Default or Unused Parameter Values</a>).
  * <p />
- * An instance of {@code PWMChannelConfig} can be passed to the {@link DeviceManager#open(DeviceConfig)} or
- * {@link DeviceManager#open(Class, DeviceConfig)} method to open the designated PWM channel with the specified
+ * An instance of {@code PWMChannelConfig} can be passed to the {@link DeviceManager#open(DeviceConfig) open(DeviceConfig, ...)} and
+ * {@link DeviceManager#open(Class, DeviceConfig) open(Class, DeviceConfig, ...)}
+ * methods of the {@link DeviceManager} to open the designated PWM channel with the specified
  * configuration. A {@link InvalidDeviceConfigException} is thrown when attempting to open a device with
  * an invalid or unsupported configuration.
  *
@@ -80,33 +85,210 @@
     public static final int ALIGN_RIGHT = 2;
 
     private String controllerName;
-    private int controllerNumber = DEFAULT;
-    private int channelNumber = DEFAULT;
-    private GPIOPinConfig outputConfig ;
-    private GPIOPin output;
-    private int idleState = DEFAULT;
-    private int pulsePeriod = DEFAULT;
-    private int pulseAlignment = DEFAULT;
+    private int channelNumber = UNASSIGNED;
+    private int controllerNumber = UNASSIGNED;
+    private GPIOPinConfig outputConfig;
+    private int idleState = UNASSIGNED;
+    private int pulsePeriod = UNASSIGNED;
+    private double scaleFactor = 1.0;
+    private int pulseAlignment = UNASSIGNED;
+    private int outputBufferSize = UNASSIGNED;
+
+    /**
+     * The {@code Builder} class allows for creating and initializing {@code PWMChannelConfig} objects.
+     * Calls can be chained in the following manner:
+     * <blockquote>
+     * <pre>
+     *   PWMChannelConfig config = new PWMChannelConfig.Builder()
+     *           .setControllerNumber(1)
+     *           .setChannelNumber(1)
+     *           .setScaleFactor(1.0)
+     *           .setPulsePeriod(10)
+     *           .setIdleState(IDLE_STATE_HIGH)
+     *           .setPulseAlignment(ALIGN_CENTER)
+     *           .setOutputBufferSize(0)
+     *           .build();
+     * </pre>
+     * </blockquote>
+     *
+     * @since 1.1
+     */
+    @apimarker.API("device-io_1.1_pwm")
+    public static final class Builder {
+
+        private final PWMChannelConfig instance = new PWMChannelConfig();
+
+        /**
+         * Creates a new {@code Builder} instance.
+         */
+        public Builder() {
+
+        }
+
+        /**
+         * Creates a new {@code PWMChannelConfig} instance initialized with the
+         * values set for each configuration parameters. If a configuration parameter
+         * was not explictly set its default value will be used.
+         *
+         * @return a new initialized {@code PWMChannelConfig} instance.
+         */
+        public PWMChannelConfig build() {
+            instance.checkParameters();
+            return instance;
+        }
+
+        /**
+         * Sets the controller name (default value is {@code null} if not set).
+         *
+         * @param controllerName the controller name (such as its <em>device
+         * file</em> name on UNIX systems) or {@code null}.
+         * @return this {@code Builder} instance.
+         */
+        public Builder setControllerName(String controllerName) {
+            instance.controllerName = controllerName;
+            return this;
+        }
+
+        /**
+         * Sets the channel number (default value is {@code UNASSIGNED} if not set).
+         *
+         * @param channelNumber the channel number (a positive or zero integer)
+         * or {@code DeviceConfig.UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code channelNumber} is not in
+         * the defined range.
+         */
+        public Builder setChannelNumber(int channelNumber) {
+            instance.channelNumber = channelNumber;
+            return this;
+        }
+
+        /**
+         * Sets the controller number (default value is {@code UNASSIGNED} if not set).
+         *
+         * @param controllerNumber the hardware converter's number (a positive
+         * or zero integer) or {@link #UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code controllerNumber} is not
+         * in the defined range.
+         */
+        public Builder setControllerNumber(int controllerNumber) {
+            instance.controllerNumber = controllerNumber;
+            return this;
+        }
+
+        /**
+         * Sets the configuration of the output (a GPIO output pin) on which the
+         * pulses are to be generated. (default value is {@code null} if not set).
+         *
+         * @param outputConfig the configuration of the output (a GPIO output pin);
+         * or {@code null} if the output is implicit.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code outputConfig} is not
+         * {@code null} and is not configured for output.
+         */
+        public Builder setOutputConfig(GPIOPinConfig outputConfig) {
+            instance.outputConfig = outputConfig;
+            return this;
+        }
+
+        /**
+         * Sets the idle output state (default value is {@code UNASSIGNED} if not
+         * set).
+         *
+         * @param idleState the idle output state: : {@link #IDLE_STATE_HIGH}, {@link #IDLE_STATE_LOW} or {@link #UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code idleState} is not in the
+         * defined range.
+         */
+        public Builder setIdleState(int idleState) {
+            instance.idleState = idleState;
+            return this;
+        }
+
+        /**
+         * Sets the initial <em>scaled</em> output sampling interval (default value is {@code UNASSIGNED} if not
+         * set).
+         *
+         * @param pulsePeriod the initial scaled output sampling interval
+         * (the amount of time between two samples) in microseconds (a positive
+         * integer) or {@code DeviceConfig.UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code pulsePeriod} is not
+         * in the defined range.
+         *
+         * @see #setScaleFactor
+         */
+        public Builder setPulsePeriod(int pulsePeriod) {
+            instance.pulsePeriod = pulsePeriod;
+            return this;
+        }
+
+        /**
+         * Sets the initial pulse period scale factor (default value is {@code 1.0} if not set).
+         *
+         * @param scaleFactor the initial pulse period scale factor (a positive number).
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code scaleFactor} is not in the
+         * defined range.
+         */
+        public Builder setScaleFactor(double scaleFactor) {
+            instance.scaleFactor = scaleFactor;
+            return this;
+        }
+
+        /**
+         * Sets the pulse alignment - the alignment of the pulse within the pulse period (default value is {@code UNASSIGNED} if not
+         * set).
+         *
+         * @param pulseAlignment the pulse alignment: {@link #ALIGN_CENTER}, {@link #ALIGN_LEFT}, {@link #ALIGN_RIGHT} or {@link #UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code pulseAlignment} is not in the
+         * defined range.
+         */
+        public Builder setPulseAlignment(int pulseAlignment) {
+            instance.pulseAlignment = pulseAlignment;
+            return this;
+        }
+
+        /**
+         * Sets the requested output buffer size (default value is {@code UNASSIGNED} if not set).
+         *
+         * @param outputBufferSize the requested output buffer size in number of
+         * samples (a positive or zero integer) or
+         * {@code DeviceConfig.UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code outputBufferSize} is not in
+         * the defined range.
+         */
+        public Builder setOutputBufferSize(int outputBufferSize) {
+            instance.outputBufferSize = outputBufferSize;
+            return this;
+        }
+    }
+
 
     // hidden constructor for serializer
     @DontRenameMethod
     PWMChannelConfig() {}
 
     /**
-     * Creates a new {@code PWMChannelConfig} with the specified hardware addressing information and type. The output of
+     * Creates a new {@code PWMChannelConfig} with the specified hardware addressing information and configuration parameters. The output of
      * the PWM channel is implicit (such as a dedicated output pin).
+     * <p />
+     * The pulse period time scale factor is set to {@code 1.0}.
      *
      * @param controllerNumber
-     *            the hardware PWM controller (or generator)'s number (a positive or zero integer) or {@link #DEFAULT}.
+     *            the hardware PWM controller (or generator)'s number (a positive or zero integer) or {@link #UNASSIGNED}.
      * @param channelNumber
-     *            the hardware PWM channel's number (a positive or zero integer) or {@link #DEFAULT}.
+     *            the hardware PWM channel's number (a positive or zero integer) or {@link #UNASSIGNED}.
      * @param idleState
-     *            the output idle state: {@link #IDLE_STATE_HIGH}, {@link #IDLE_STATE_LOW} or {@link #DEFAULT}.
+     *            the output idle state: {@link #IDLE_STATE_HIGH}, {@link #IDLE_STATE_LOW} or {@link #UNASSIGNED}.
      * @param pulsePeriod
-     *            the default pulse period in microseconds (a positive integer) or {@link #DEFAULT}.
+     *            the default pulse period in microseconds (a positive integer) or {@link #UNASSIGNED}.
      * @param pulseAlignment
      *            the pulse alignment: {@link #ALIGN_CENTER}, {@link #ALIGN_LEFT}, {@link #ALIGN_RIGHT} or
-     *            {@link #DEFAULT}.
+     *            {@link #UNASSIGNED}.
      *
      * @throws IllegalArgumentException
      *             if any of the following is true:
@@ -117,6 +299,8 @@
      *             <li>{@code pulsePeriod} is not in the defined range.</li>
      *             <li>{@code pulseAlignment} is not in the defined range.</li>
      *             </ul>
+     *
+     * @deprecated As of 1.1, use {@link Builder} instead.
      */
     public PWMChannelConfig(int controllerNumber, int channelNumber, int idleState, int pulsePeriod, int pulseAlignment) {
         this.controllerNumber = controllerNumber;
@@ -128,7 +312,9 @@
     }
 
     /**
-     * Creates a new {@code PWMChannelConfig} the specified hardware addressing information, type and GPIO pin output.
+     * Creates a new {@code PWMChannelConfig} the specified hardware addressing information, configuration parameters and GPIO pin output.
+     * <p />
+     * The pulse period time scale factor is set to {@code 1.0}.
      * <p />
      * If the access modes (exclusive or shared) supported by the designated
      * GPIO pin output are incompatible with those required by the underlying {@code PWMChannel}
@@ -137,16 +323,16 @@
      * {@link InvalidDeviceConfigException} to be thrown.
      *
      * @param controllerNumber
-     *            the hardware PWM controller (or generator)'s number (a positive or zero integer) or {@link #DEFAULT}.
+     *            the hardware PWM controller (or generator)'s number (a positive or zero integer) or {@link #UNASSIGNED}.
      * @param channelNumber
-     *            the hardware PWM channel's number (a positive or zero integer) or {@link #DEFAULT}.
+     *            the hardware PWM channel's number (a positive or zero integer) or {@link #UNASSIGNED}.
      * @param idleState
-     *            the output idle state: {@link #IDLE_STATE_HIGH}, {@link #IDLE_STATE_LOW} or {@link #DEFAULT}.
+     *            the output idle state: {@link #IDLE_STATE_HIGH}, {@link #IDLE_STATE_LOW} or {@link #UNASSIGNED}.
      * @param pulsePeriod
-     *            the default pulse period in microseconds (a positive integer) or {@link #DEFAULT}.
+     *            the default pulse period in microseconds (a positive integer) or {@link #UNASSIGNED}.
      * @param pulseAlignment
      *            the pulse alignment: {@link #ALIGN_CENTER}, {@link #ALIGN_LEFT}, {@link #ALIGN_RIGHT} or
-     *            {@link #DEFAULT}.
+     *            {@link #UNASSIGNED}.
      * @param output
      *            the configuration of the output (a GPIO output pin) on which the pulses are to be generated.
      *
@@ -162,6 +348,8 @@
      *             </ul>
      * @throws NullPointerException
      *             if {@code output} is {@code null}.
+     *
+     * @deprecated As of 1.1, use {@link Builder} instead.
      */
     public PWMChannelConfig(int controllerNumber, int channelNumber, int idleState, int pulsePeriod,
             int pulseAlignment, GPIOPinConfig output) {
@@ -182,20 +370,22 @@
     }
 
     /**
-     * Creates a new {@code PWMChannelConfig} with the specified hardware addressing information and type. The output of
+     * Creates a new {@code PWMChannelConfig} with the specified hardware addressing information and configuration parameters. The output of
      * the PWM channel is implicit (such as a dedicated output pin).
+     * <p />
+     * The pulse period time scale factor is set to {@code 1.0}.
      *
      * @param controllerName
      *            the controller name (such as its <em>device file</em> name on UNIX systems).
      * @param channelNumber
-     *            the hardware PWM channel's number (a positive or zero integer) or {@link #DEFAULT}.
+     *            the hardware PWM channel's number (a positive or zero integer) or {@link #UNASSIGNED}.
      * @param idleState
-     *            the output idle state: {@link #IDLE_STATE_HIGH}, {@link #IDLE_STATE_LOW} or {@link #DEFAULT}.
+     *            the output idle state: {@link #IDLE_STATE_HIGH}, {@link #IDLE_STATE_LOW} or {@link #UNASSIGNED}.
      * @param pulsePeriod
-     *            the default pulse period in microseconds (a positive integer) or {@link #DEFAULT}.
+     *            the default pulse period in microseconds (a positive integer) or {@link #UNASSIGNED}.
      * @param pulseAlignment
      *            the pulse alignment: {@link #ALIGN_CENTER}, {@link #ALIGN_LEFT}, {@link #ALIGN_RIGHT} or
-     *            {@link #DEFAULT}.
+     *            {@link #UNASSIGNED}.
      *
      * @throws IllegalArgumentException
      *             if any of the following is true:
@@ -207,6 +397,8 @@
      *             </ul>
      * @throws NullPointerException
      *             if {@code controllerName} is {@code null}.
+     *
+     * @deprecated As of 1.1, use {@link Builder} instead.
      */
     public PWMChannelConfig(String controllerName, int channelNumber, int idleState, int pulsePeriod, int pulseAlignment) {
         this(DEFAULT, channelNumber, idleState, pulsePeriod, pulseAlignment);
@@ -216,7 +408,9 @@
     }
 
     /**
-     * Creates a new {@code PWMChannelConfig} the specified hardware addressing information, type and GPIO pin output.
+     * Creates a new {@code PWMChannelConfig} the specified hardware addressing information, configuration parameters and GPIO pin output.
+     * <p />
+     * The pulse period time scale factor is set to {@code 1.0}.
      * <p />
      * If the access modes (exclusive or shared) supported by the designated
      * GPIO pin output are incompatible with those required by the underlying {@code PWMChannel}
@@ -227,14 +421,14 @@
      * @param controllerName
      *            the controller name (such as its <em>device file</em> name on UNIX systems).
      * @param channelNumber
-     *            the hardware PWM channel's number (a positive or zero integer) or {@link #DEFAULT}.
+     *            the hardware PWM channel's number (a positive or zero integer) or {@link #UNASSIGNED}.
      * @param idleState
-     *            the output idle state: {@link #IDLE_STATE_HIGH}, {@link #IDLE_STATE_LOW} or {@link #DEFAULT}.
+     *            the output idle state: {@link #IDLE_STATE_HIGH}, {@link #IDLE_STATE_LOW} or {@link #UNASSIGNED}.
      * @param pulsePeriod
-     *            the default pulse period in microseconds (a positive integer) or {@link #DEFAULT}.
+     *            the default pulse period in microseconds (a positive integer) or {@link #UNASSIGNED}.
      * @param pulseAlignment
      *            the pulse alignment: {@link #ALIGN_CENTER}, {@link #ALIGN_LEFT}, {@link #ALIGN_RIGHT} or
-     *            {@link #DEFAULT}.
+     *            {@link #UNASSIGNED}.
      * @param output
      *            the configuration of the output (a GPIO output pin) on which the pulses are to be generated.
      *
@@ -249,6 +443,8 @@
      *             </ul>
      * @throws NullPointerException
      *             if {@code controllerName} or {@code output} is {@code null}.
+     *
+     * @deprecated As of 1.1, use {@link Builder} instead.
      */
     public PWMChannelConfig(String controllerName, int channelNumber, int idleState, int pulsePeriod,
             int pulseAlignment, GPIOPinConfig output) {
@@ -269,9 +465,40 @@
     }
 
     /**
+     * Creates a new {@code PWMChannelConfig} whose state is deserialized from the specified {@code InputStream}.
+     * This method may be invoked to restore the state of a {@code PWMChannelConfig}
+     * object from a persistent store.
+     *
+     * @param in the stream to read from.
+     * @return a new {@code PWMChannelConfig} instance.
+     * @throws IOException if an I/O error occurs or if the provided stream does not
+     * contain a representation of a {@code PWMChannelConfig} object.
+     *
+     * @since 1.1
+     */
+    public static PWMChannelConfig deserialize(InputStream in) throws IOException {
+      throw new IOException("Unsupported Operation");
+    }
+
+    /**
+     * Serializes the state of this {@code PWMChannelConfig} object to the specified {@code OutputStream}.
+     * This method may be invoked by the {@link jdk.dio.DeviceManager DeviceManager}
+     * to save the state of this {@code PWMChannelConfig} object to a persistent store.
+     *
+     * @param out the stream to write to.
+     * @throws IOException if an I/O error occurs.
+     *
+     * @since 1.1
+     */
+    @Override
+    public int serialize(OutputStream  out) throws IOException {
+      throw new IOException("Unsupported Operation");
+    }
+
+    /**
      * Gets the configured PWM channel number.
      *
-     * @return the hardware channel's number (a positive or zero integer) or {@link #DEFAULT}.
+     * @return the hardware channel's number (a positive or zero integer) or {@link #UNASSIGNED}.
      */
     public int getChannelNumber() {
         return channelNumber;
@@ -280,7 +507,7 @@
     /**
      * Gets the configured controller number (the PWM controller or generator number).
      *
-     * @return the controller number (a positive or zero integer) or {@link #DEFAULT}.
+     * @return the controller number (a positive or zero integer) or {@link #UNASSIGNED}.
      */
     @Override
     public int getControllerNumber() {
@@ -290,7 +517,7 @@
     /**
      * Gets the configured controller name (such as its <em>device file</em> name on UNIX systems).
      *
-     * @return the controllerName or {@code null}.
+     * @return the controller name or {@code null}.
      */
     @Override
     public String getControllerName() {
@@ -298,6 +525,21 @@
     }
 
     /**
+     * Gets the requested or allocated output buffer size. The platform/underlying
+     * driver may or may not allocate the requested size
+     * for the output buffer.
+     * When querying the configuration of an opened or registered device the
+     * allocated buffer size is returned.
+     *
+     * @return the requested or allocated output buffer size (a positive or zero integer).
+     *
+     * @since 1.1
+     */
+    public int getOutputBufferSize() {
+        return outputBufferSize;
+    }
+
+    /**
      * Gets the configured output configuration on which the pulses are to be generated.
      *
      * @return the output on which the pulses are to be generated; or {@code null} if the output is implicit.
@@ -315,15 +557,17 @@
      *
      * @return the output on which the pulses are to be generated; or {@code null} if the output is implicit
      * or if this {@code PWMChannelConfig} instance is not associated to an actual {@code PWMChannel} instance.
+     *
+     * @deprecated As of 1.1, replaced by {@link PWMChannel#getOutput PWMChannel.getOutput}.
      */
     public GPIOPin getOutput() {
-        return output;
+        return null;
     }
 
     /**
-     * Gets the configured default/initial pulse period (in microseconds).
+     * Gets the configured default/initial <em>scaled</em> pulse period (in microseconds).
      *
-     * @return the default/initial pulse period in microseconds (a positive integer) or {@link #DEFAULT}.
+     * @return the default/initial pulse period in microseconds (a positive integer) or {@link #UNASSIGNED}.
      */
     public int getPulsePeriod() {
         return pulsePeriod;
@@ -332,7 +576,7 @@
     /**
      * Gets the configured idle output state.
      *
-     * @return the idle output state: : {@link #IDLE_STATE_HIGH}, {@link #IDLE_STATE_LOW} or {@link #DEFAULT}.
+     * @return the idle output state: : {@link #IDLE_STATE_HIGH}, {@link #IDLE_STATE_LOW} or {@link #UNASSIGNED}.
      */
     public int getIdleState() {
         return idleState;
@@ -341,28 +585,40 @@
     /**
      * Gets the configured pulse alignment. The alignment of the pulse within the pulse period.
      *
-     * @return the pulse alignment: {@link #ALIGN_CENTER}, {@link #ALIGN_LEFT}, {@link #ALIGN_RIGHT} or {@link #DEFAULT}
+     * @return the pulse alignment: {@link #ALIGN_CENTER}, {@link #ALIGN_LEFT}, {@link #ALIGN_RIGHT} or {@link #UNASSIGNED}
      */
     public int getPulseAlignment() {
         return pulseAlignment;
     }
 
     /**
+     * Gets the default/initial configured pulse period scale factor.
+     *
+     * @return the default/initial pulse period scale factor (a positive number).
+     *
+     * @since 1.1
+     */
+    public double getScaleFactor() {
+        return scaleFactor;
+    }
+
+    /**
      * Returns the hash code value for this object.
      *
      * @return a hash code value for this object.
      */
     @Override
     public int hashCode() {
-        int hash = 7;
-        hash = 37 * hash + Objects.hashCode(this.controllerName);
-        hash = 37 * hash + this.controllerNumber;
-        hash = 37 * hash + this.channelNumber;
-        hash = 37 * hash + Objects.hashCode(this.outputConfig);
-        hash = 37 * hash + Objects.hashCode(this.output);
-        hash = 37 * hash + this.idleState;
-        hash = 37 * hash + this.pulsePeriod;
-        hash = 37 * hash + this.pulseAlignment;
+        int hash = 5;
+        hash = 79 * hash + Objects.hashCode(this.controllerName);
+        hash = 79 * hash + this.channelNumber;
+        hash = 79 * hash + this.controllerNumber;
+        hash = 79 * hash + Objects.hashCode(this.outputConfig);
+        hash = 79 * hash + this.idleState;
+        hash = 79 * hash + this.pulsePeriod;
+        hash = 79 * hash + (int) (Double.doubleToLongBits(this.scaleFactor) ^ (Double.doubleToLongBits(this.scaleFactor) >>> 32));
+        hash = 79 * hash + this.pulseAlignment;
+        hash = 79 * hash + this.outputBufferSize;
         return hash;
     }
 
@@ -374,7 +630,7 @@
      *
      * @return {@code true} if {@code obj} is a {@code PWMChannelConfig} and has
      * the same hardware addressing information and configuration parameter values
-     * as this {@code PWMChannelConfig} object.
+     * as this {@code PWMChannelConfig} object; {@code false} otherwise.
      */
     @Override
     public boolean equals(Object obj) {
@@ -388,27 +644,27 @@
         if (!Objects.equals(this.controllerName, other.controllerName)) {
             return false;
         }
+        if (this.channelNumber != other.channelNumber) {
+            return false;
+        }
         if (this.controllerNumber != other.controllerNumber) {
             return false;
         }
-        if (this.channelNumber != other.channelNumber) {
-            return false;
-        }
         if (!Objects.equals(this.outputConfig, other.outputConfig)) {
             return false;
         }
-        if (!Objects.equals(this.output, other.output)) {
-            return false;
-        }
         if (this.idleState != other.idleState) {
             return false;
         }
         if (this.pulsePeriod != other.pulsePeriod) {
             return false;
         }
+        if (Double.doubleToLongBits(this.scaleFactor) != Double.doubleToLongBits(other.scaleFactor)) {
+            return false;
+        }
         if (this.pulseAlignment != other.pulseAlignment) {
             return false;
         }
-        return true;
+        return this.outputBufferSize == other.outputBufferSize;
     }
 }
--- a/src/share/classes/jdk/dio/pwm/PWMPermission.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/pwm/PWMPermission.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.pwm;
 
 import jdk.dio.DeviceManager;
@@ -46,13 +45,7 @@
  * {@link PWMChannelConfig#getChannelNumber PWMChannelConfig.getChannelNumber}. The characters in the string must all be decimal digits.
  * </dd>
  * </dl>
- * The supported actions are {@code open} and {@code powermanage}. Their meaning is defined as follows:
- * <dl>
- * <dt>{@code open}</dt>
- * <dd>open and access an PWM channel functions (see {@link DeviceManager#open DeviceManager.open})</dd>
- * <dt>{@code powermanage}</dt>
- * <dd>manage the power saving mode of a device (see {@link jdk.dio.power.PowerManaged})</dd>
- * </dl>
+ * The supported actions are {@code open} and {@code powermanage} as defined in {@link DevicePermission}.
  *
  * @see DeviceManager#open DeviceManager.open
  * @see jdk.dio.power.PowerManaged
@@ -64,11 +57,16 @@
 
     /**
      * Constructs a new {@code PWMPermission} with the specified target name and the implicit {@code open} action.
+     * The target name is normalized so that leading and trailing spaces are removed
+     * and each occurrence of <code>{controller-number}</code> and <code>{channel-desc}</code> is represented in its canonical
+     * decimal representation form (without leading zeros).
      *
      * @param name
      *            the target name (as defined above).
      * @throws NullPointerException
      *             if {@code name} is {@code null}.
+     * @throws IllegalArgumentException
+     *             if {@code name} is not properly formatted.
      *
      * @see #getName getName
      */
@@ -78,6 +76,9 @@
 
     /**
      * Constructs a new {@code PWMPermission} instance with the specified target name and action list.
+     * The target name is normalized so that leading and trailing spaces are removed
+     * and each occurrence of <code>{controller-number}</code> and <code>{channel-desc}</code> is represented in its canonical
+     * decimal representation form (without leading zeros).
      *
      * @param name
      *            the target name (as defined above).
@@ -86,8 +87,11 @@
      * @throws NullPointerException
      *             if {@code name} is {@code null}.
      * @throws IllegalArgumentException
-     *             if actions is {@code null}, empty or contains an action other than the
-     *             specified possible actions.
+     *             <ul>
+     *             <li>if {@code actions} is {@code null}, empty or contains an action other than the
+     *             specified possible actions,</li>
+     *             <li>if {@code name} is not properly formatted.</li>
+     *             </ul>
      *
      * @see #getName getName
      */
--- a/src/share/classes/jdk/dio/pwm/package-info.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/pwm/package-info.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 /**
  * Interfaces and classes for generating width-modulated pulses - Pulse Width Modulation (PWM) - on a digital output line.
  * <p />
@@ -55,8 +54,8 @@
  * {@link jdk.dio.pwm.PWMChannel#startGeneration}. <blockquote>
  *
  * <pre>
- * channel.setPulsePeriod(1000000); // Pulse period = 1 second
- * channel.generate(500000, 10); // Generate 10 pulses with a width of 0.5 second
+ * channel.setPulsePeriod(1000000); <i>// Pulse period = 1 second</i>
+ * channel.generate(500000, 10); <i>// Generate 10 pulses with a width of 0.5 second</i>
  * </pre>
  *
  * </blockquote> When done, the application should call the {@link jdk.dio.pwm.PWMChannel#close
@@ -81,7 +80,7 @@
  *             try {
  *                 channel.startGeneration((channel.getPulsePeriod() / 10) * --step, 10, this);
  *             } catch (IOException ex) {
- *                 // Iggnored
+ *                 <i>// Ignored</i>
  *             }
  *         }
  *     }
@@ -91,7 +90,7 @@
  *             throw new IllegalStateException();
  *         }
  *         channel = (PWMChannel) DeviceManager.open(channelID);
- *         channel.setPulsePeriod(1000000); // period = 1 second
+ *         channel.setPulsePeriod(1000000); <i>// period = 1 second</i>
  *         channel.startGeneration((channel.getPulsePeriod() / 10) * step, 10, this);
  *     }
  *
@@ -103,7 +102,7 @@
  *     }
  *
  *     public void failed(Throwable exception, PWMChannel source) {
- *          // Ignored
+ *          <i>// Ignored</i>
  *     }
  * }
  * </pre>
--- a/src/share/classes/jdk/dio/spi/AbstractDevice.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/spi/AbstractDevice.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.spi;
 
 import jdk.dio.ClosedDeviceException;
--- a/src/share/classes/jdk/dio/spi/DeviceProvider.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/spi/DeviceProvider.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,16 +22,16 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.spi;
 
 import java.io.IOException;
+import java.io.InputStream;
 
 import jdk.dio.Device;
 import jdk.dio.DeviceConfig;
-import jdk.dio.InvalidDeviceConfigException;
 import jdk.dio.DeviceNotFoundException;
 import jdk.dio.DevicePermission;
+import jdk.dio.InvalidDeviceConfigException;
 import jdk.dio.UnavailableDeviceException;
 import jdk.dio.UnsupportedAccessModeException;
 
@@ -157,4 +157,21 @@
      *         specified properties; {@code false} otherwise.
      */
     boolean matches(String[] properties);
+
+    /**
+     * De-serializes a {@code DeviceConfig} object from the specified {@code InputStream}.
+     * This method may be invoked by the {@link jdk.dio.DeviceManager DeviceManager}
+     * to restore the state of a {@code DeviceConfig} object from a persistent store.
+     *
+     * @param in the stream to read from.
+     * @return the {@code DeviceConfig} object read from the stream.
+     * @throws IOException if an I/O error occurs or if the provided stream does not
+     * contain a representation of a {@code DeviceConfig} object of the type supported
+     * by this {@code DeviceProvider}.
+     *
+     * @see jdk.dio.DeviceConfig#serialize(java.io.OutputStream)
+     * @since 1.1
+     */
+    DeviceConfig<? super P> deserialize(InputStream  in) throws IOException;
+
 }
--- a/src/share/classes/jdk/dio/spi/package-info.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/spi/package-info.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 /**
  * Service-provider classes for the {@link jdk.dio} package.
  *
--- a/src/share/classes/jdk/dio/spibus/InvalidWordLengthException.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/spibus/InvalidWordLengthException.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.spibus;
 
 /**
--- a/src/share/classes/jdk/dio/spibus/SPICompositeMessage.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/spibus/SPICompositeMessage.java	Thu Apr 30 21:58:05 2015 +0300
@@ -46,9 +46,9 @@
  *             .appendwrite(sndBuf1)
  *             .appendDelay(100)
  *             .appendwriteAndRead(sndBuf2, rcvBuf)
- *             .transfer()[2];
+ *             .transfer()[0];
  * } catch (IOException ioe) {
- *     // Handle exception
+ *     <i>// Handle exception</i>
  * }
  * </pre>
  * </blockquote> The preceding example is using a
@@ -158,8 +158,6 @@
      * @return a reference to this {@code SPICompositeMessage} object.
      * @throws NullPointerException
      *             if {@code src} or {@code dst} is {@code null}.
-     * @throws InvalidWordLengthException
-     *             if the number of bytes to receive or send belies word length.
      * @throws IllegalStateException if this message has already been assembled
      * and transferred once.
      * @throws ClosedDeviceException if the device has been closed.
@@ -195,8 +193,6 @@
      *             if {@code src} or {@code dst} is {@code null}.
      * @throws IllegalArgumentException
      *              if {@code skip} is negative.
-     * @throws InvalidWordLengthException
-     *             if the number of bytes to receive or send belies word length.
      * @throws IllegalStateException if this message has already been assembled
      * and transferred once.
      * @throws ClosedDeviceException if the device has been closed.
@@ -221,7 +217,8 @@
      *            the amount (in microseconds) to delay the next operation.
      * @return a reference to this {@code SPICompositeMessage} object.
      * @throws IllegalArgumentException
-     *              if {@code delay} is negative or cannot be accommodated for.
+     *              if {@code delay} is negative or cannot be accommodated for by rounding it up to
+     *              a supported value.
      * @throws IllegalStateException if this message has already been assembled
      * and transferred once.
      * @throws ClosedDeviceException if the device has been closed.
@@ -250,7 +247,7 @@
      * Buffers are not safe for use by multiple concurrent threads so care should
      * be taken to not access the provided buffers until the transfer has completed.
      *
-     * @return an array containing the number of bytes read for each of the read
+     * @return an array (possibly empty) containing the number of bytes read for each of the read
      * operations of this composite message; the results of each read operations
      * appear in the very same order the read operations have been appended to
      * this composite message.
--- a/src/share/classes/jdk/dio/spibus/SPIDevice.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/spibus/SPIDevice.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.spibus;
 
 import jdk.dio.BufferAccess;
@@ -45,7 +44,7 @@
  * {@link DeviceManager#open(java.lang.String, java.lang.Class, java.lang.String[])
  * DeviceManager.open(name,...)} methods using its name. When an {@code SPIDevice} instance is opened with an ad-hoc
  * {@link SPIDeviceConfig} configuration (which includes its hardware addressing information) using one of the
- * {@link DeviceManager#open(jdk.dio.DeviceConfig) DeviceManager.open(config,...)} it is not
+ * {@link DeviceManager#open(jdk.dio.DeviceConfig) DeviceManager.open(config,...)} methods it is not
  * assigned any ID nor name.
  * <p />
  * On an SPI bus, data is transferred between the SPI master device and an SPI slave device in full duplex. That is,
--- a/src/share/classes/jdk/dio/spibus/SPIDeviceConfig.java	Tue Apr 28 12:11:42 2015 +0300
+++ b/src/share/classes/jdk/dio/spibus/SPIDeviceConfig.java	Thu Apr 30 21:58:05 2015 +0300
@@ -22,22 +22,28 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.dio.spibus;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Objects;
+
 import jdk.dio.DeviceConfig;
+import jdk.dio.DeviceManager;
 import jdk.dio.InvalidDeviceConfigException;
-import jdk.dio.DeviceManager;
-import java.util.Objects;
+
+import romizer.DontRenameMethod;
+
 import serializator.*;
-import romizer.DontRenameMethod;
 
 /**
  * The {@code SPIDeviceConfig} class encapsulates the hardware addressing information, and static and dynamic
  * configuration parameters of an SPI slave device.
  * <p />
- * Some hardware addressing parameter, and static and dynamic configuration parameters may be set to {@link #DEFAULT}.
- * Whether such default settings are supported is platform- as well as device driver-dependent.
+ * Some hardware addressing, static or dynamic configuration parameters may be
+ * set to {@link #UNASSIGNED} or {@code null} (see
+ * <a href="{@docRoot}/jdk/dio/DeviceConfig.html#default_unassigned">Unassigned, Default or Unused Parameter Values</a>).
  * <p />
  * <h3><a name="mode">SPI Clock Modes</a></h3>
  * The clock mode is a number from 0 to 3 which represents the combination of the CPOL (SPI Clock Polarity Bit) and CPHA
@@ -70,13 +76,16 @@
  * </tr>
  * </table>
  * <p />
- * An instance of {@code SPIDeviceConfig} can be passed to the {@link DeviceManager#open(DeviceConfig)} or
- * {@link DeviceManager#open(Class, DeviceConfig)} method to open the designated SPI slave device with the
+ * An instance of {@code SPIDeviceConfig} can be passed to the {@link DeviceManager#open(DeviceConfig) open(DeviceConfig, ...)} and
+ * {@link DeviceManager#open(Class, DeviceConfig) open(Class, DeviceConfig, ...)}
+ * methods of the {@link DeviceManager} to open the designated SPI slave device with the
  * specified configuration. A {@link InvalidDeviceConfigException} is thrown when attempting to open a
  * device with an invalid or unsupported configuration.
  *
  * @see DeviceManager#open(DeviceConfig)
+ * @see DeviceManager#open(DeviceConfig, int)
  * @see DeviceManager#open(Class, DeviceConfig)
+ * @see DeviceManager#open(Class, DeviceConfig, int)
  * @since 1.0
  */
 @SerializeMe
@@ -101,12 +110,231 @@
 
     private String controllerName;
     private int address;
-    private int csActive = DEFAULT;
-    private int controllerNumber = DEFAULT;
-    private int bitOrdering = DEFAULT;
-    private int clockFrequency = DEFAULT;
-    private int clockMode = DEFAULT;
-    private int wordLength = DEFAULT;
+    private int csActive = UNASSIGNED;
+    private int controllerNumber = UNASSIGNED;
+    private int bitOrdering = UNASSIGNED;
+    private int clockFrequency = UNASSIGNED;
+    private int clockMode;
+    private int wordLength = UNASSIGNED;
+    private int inputBufferSize = UNASSIGNED;
+    private int outputBufferSize = UNASSIGNED;
+
+    /**
+     * The {@code Builder} class allows for creating and initializing
+     * {@code SPIDeviceConfig} objects. Calls can be chained in the following
+     * manner:
+     * <blockquote>
+     * <pre>
+     *   SPIDeviceConfig config = new SPIDeviceConfig.Builder()
+     *           .setControllerNumber(1)
+     *           .setAddress(0x8)
+     *           .setClockFrequency(8000000)
+     *           .setClockMode(2)
+     *           .setWordLength(10)
+     *           .setBitOrdering(LITTLE_ENDIAN)
+     *           .build();
+     * </pre>
+     * </blockquote>
+     *
+     * @since 1.1
+     */
+    @apimarker.API("device-io_1.1_spibus")
+    public static final  class Builder {
+
+        private final SPIDeviceConfig instance = new SPIDeviceConfig();
+
+        /**
+         * Creates a new {@code Builder} instance.
+         */
+        public Builder() {
+
+        }
+
+        /**
+         * Creates a new {@code SPIDeviceConfig} instance initialized with the
+         * values set for each configuration parameters. If a configuration
+         * parameter was not explictly set its default value will be used.
+         *
+         * @return a new initialized {@code SPIDeviceConfig} instance.
+         * @throws IllegalStateException if any of the following is true:
+         * <ul>
+         * <li>the Chip Select address of the slave device on the bus is not set.</li>
+         * </ul>
+         */
+        public SPIDeviceConfig build() {
+            instance.checkParameters();
+            return instance;
+        }
+
+        /**
+         * Sets the name of the bus the slave device is connected to (default
+         * value is {@code null} if not set).
+         *
+         * @param controllerName the name of the bus the slave device is
+         * connected to (such as its <em>device file</em> name on UNIX systems) or {@code null}.
+         * @return this {@code Builder} instance.
+         */
+        public Builder setControllerName(String controllerName) {
+            instance.controllerName = controllerName;
+            return this;
+        }
+
+        /**
+         * Sets the Chip Select address of the slave device on the bus.
+         *
+         * @param address the Chip Select address of the slave device on the bus
+         * (a positive or zero integer).
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if any of the following is true:
+         * <ul>
+         * <li>{@code address} is not in the defined range;</li>
+         * </ul>
+         */
+        public Builder setAddress(int address) {
+            instance.address = address;
+            return this;
+        }
+
+        /**
+         * Sets the number of the bus the slave device is connected to (default
+         * value is {@code UNASSIGNED} if not set).
+         *
+         * @param controllerNumber the number of the bus the slave device is
+         * connected to (a positive or zero integer) or {@link #UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code controllerNumber} is not
+         * in the defined range.
+         */
+        public Builder setControllerNumber(int controllerNumber) {
+            instance.controllerNumber = controllerNumber;
+            return this;
+        }
+
+        /**
+         * Sets the requested input buffer size (default value is
+         * {@code UNASSIGNED} if not set).
+         *
+         * @param inputBufferSize the requested input buffer size in number of
+         * samples (a positive or zero integer) or
+         * {@code DeviceConfig.UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code inputBufferSize} is not in
+         * the defined range.
+         */
+        public Builder setInputBufferSize(int inputBufferSize) {
+            instance.inputBufferSize = inputBufferSize;
+            return this;
+        }
+
+        /**
+         * Sets the requested output buffer size (default value is
+         * {@code UNASSIGNED} if not set).
+         *
+         * @param outputBufferSize the requested output buffer size in number of
+         * samples (a positive or zero integer) or
+         * {@code DeviceConfig.UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code outputBufferSize} is not
+         * in the defined range.
+         */
+        public Builder setOutputBufferSize(int outputBufferSize) {
+            instance.outputBufferSize = outputBufferSize;
+            return this;
+        }
+
+        /**
+         * Sets the Chip Select active level (default value is
+         * {@code UNASSIGNED} if not set).
+         *
+         * @param csActive the Chip Select active level, one of {@link #CS_ACTIVE_LOW},
+         *            {@link #CS_ACTIVE_HIGH}, {@link #CS_NOT_CONTROLLED} or
+         * {@link #UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code csActive} is not in the
+         * defined range.
+         */
+        public Builder setCSActiveLevel(int csActive) {
+            instance.csActive = csActive;
+            return this;
+        }
+
+        /**
+         * Sets the bit (shifting) ordering of the slave device (default value
+         * is {@code UNASSIGNED} if not set).
+         *
+         * @param bitOrdering the bit (shifting) ordering of the slave device,
+         * one of: {@link SPIDevice#BIG_ENDIAN},
+         *            {@link SPIDevice#LITTLE_ENDIAN}, {@link SPIDevice#MIXED_ENDIAN} or
+         * {@link #UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code bitOrdering} is not in the
+         * defined range.
+         */
+        public Builder setBitOrdering(int bitOrdering) {
+            instance.bitOrdering = bitOrdering;
+            return this;
+        }
+
+        /**
+         * Sets the clock mode (default value is {@code 0} if not set).
+         *
+         * @param clockMode the clock mode, one of:
+         * {@code 0}, {@code 1}, {@code 2} or {@code 4} (see <a href="#mode">SPI
+         * Clock Modes</a>).
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code clockMode} is not in the
+         * defined range.
+         */
+        public Builder setClockMode(int clockMode) {
+            instance.clockMode = clockMode;
+            return this;
+        }
+
+        /**
+         * Sets the word length of the slave device (default value is
+         * {@code UNASSIGNED} if not set).
+         *
+         * @param wordLength the word length of the slave device (a positive
+         * integer) or {@link #UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code wordLength} is not in the
+         * defined range.
+         */
+        public Builder setWordLength(int wordLength) {
+            instance.wordLength = wordLength;
+            return this;
+        }
+
+        /**
+         * Sets the clock frequency of the slave device in Hz (default value is
+         * {@code UNASSIGNED} if not set).
+         *
+         * @param clockFrequency the clock frequency of the slave device in Hz
+         * (a positive integer) or {@link #UNASSIGNED}.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException if {@code clockFrequency} is not in
+         * the defined range.
+         */
+        public Builder setClockFrequency(int clockFrequency) {
+            instance.clockFrequency = clockFrequency;
+            return this;
+        }
+    }
+
+    private SPIDeviceConfig(SPIDeviceConfig prototype) {
+        if (prototype != null) {
+            this.controllerName = prototype.controllerName;
+            this.address = prototype.address;
+            this.controllerNumber = prototype.controllerNumber;
+            this.csActive = prototype.csActive;
+            this.clockFrequency = prototype.clockFrequency;
+            this.clockMode = prototype.clockMode;
+            this.bitOrdering = prototype.bitOrdering;
+            this.wordLength = prototype.wordLength;
+            this.inputBufferSize = prototype.inputBufferSize;
+            this.outputBufferSize = prototype.outputBufferSize;
+        }
+    }
 
     // hidden constructor for serializer
     @DontRenameMethod
@@ -114,23 +342,23 @@
 
     /**
      * Creates a new {@code SPIDeviceConfig} with the specified hardware addressing information and configuration
-     * parameters. The Chip Select active level is platform and/or driver-dependent (i.e. {@link #DEFAULT}).
+     * parameters. The Chip Select active level is platform and/or driver-dependent (i.e. {@link #UNASSIGNED}).
      *
      * @param controllerNumber
      *            the number of the bus the slave device is connected to (a positive or zero integer) or
-     *            {@link #DEFAULT}.
+     *            {@link #UNASSIGNED}.
      * @param address
      *            the Chip Select address of the slave device on the bus (a positive or zero integer).
      * @param clockFrequency
-     *            the clock frequency of the slave device in Hz (a positive integer) or {@link #DEFAULT}.
+     *            the clock frequency of the slave device in Hz (a positive integer) or {@link #UNASSIGNED}.
      * @param clockMode
      *            the clock mode, one of: {@code 0}, {@code 1}, {@code 2} or {@code 4} (see <a href="#mode">SPI Clock
      *            Modes</a>).
      * @param wordLength
-     *            the word length of the slave device (a positive integer) or {@link #DEFAULT}.
+     *            the word length of the slave device (a positive integer) or {@link #UNASSIGNED}.
      * @param bitOrdering
      *            the bit (shifting) ordering of the slave device, one of: {@link SPIDevice#BIG_ENDIAN},
-     *            {@link SPIDevice#LITTLE_ENDIAN}, {@link SPIDevice#MIXED_ENDIAN} or {@link #DEFAULT}.
+     *            {@link SPIDevice#LITTLE_ENDIAN}, {@link SPIDevice#MIXED_ENDIAN} or {@link #UNASSIGNED}.
      * @throws IllegalArgumentException
      *             if any of the following is true:
      *             <ul>
@@ -141,6 +369,8 @@
      *             <li>{@code wordLength} is not in the defined range;</li>
      *             <li>{@code bitOrdering} is not one of the defined values.</li>
      *             </ul>
+     *
+     * @deprecated As of 1.1, use {@link Builder} instead.
      */
     public SPIDeviceConfig(int controllerNumber, int address, int clockFrequency, int clockMode, int wordLength,
             int bitOrdering) {
@@ -153,22 +383,22 @@
      *
      * @param controllerNumber
      *            the number of the bus the slave device is connected to (a positive or zero integer) or
-     *            {@link #DEFAULT}.
+     *            {@link #UNASSIGNED}.
      * @param address
      *            the Chip Select address of the slave device on the bus (a positive or zero integer).
      * @param csActive
      *            the Chip Select active level, one of {@link #CS_ACTIVE_LOW},
-     *            {@link #CS_ACTIVE_HIGH}, {@link #CS_NOT_CONTROLLED} or {@link #DEFAULT}.
+     *            {@link #CS_ACTIVE_HIGH}, {@link #CS_NOT_CONTROLLED} or {@link #UNASSIGNED}.
      * @param clockFrequency
-     *            the clock frequency of the slave device in Hz (a positive integer) or {@link #DEFAULT}.
+     *            the clock frequency of the slave device in Hz (a positive integer) or {@link #UNASSIGNED}.
      * @param clockMode
      *            the clock mode, one of: {@code 0}, {@code 1}, {@code 2} or {@code 4} (see <a href="#mode">SPI Clock
      *            Modes</a>).
      * @param wordLength
-     *            the word length of the slave device (a positive integer) or {@link #DEFAULT}.
+     *            the word length of the slave device (a positive integer) or {@link #UNASSIGNED}.
      * @param bitOrdering
      *            the bit (shifting) ordering of the slave device, one of: {@link SPIDevice#BIG_ENDIAN},
-     *            {@link SPIDevice#LITTLE_ENDIAN}, {@link SPIDevice#MIXED_ENDIAN} or {@link #DEFAULT}.
+     *            {@link SPIDevice#LITTLE_ENDIAN}, {@link SPIDevice#MIXED_ENDIAN} or {@link #UNASSIGNED}.
      * @throws IllegalArgumentException
      *             if any of the following is true:
      *             <ul>
@@ -179,6 +409,8 @@
      *             <li>{@code wordLength} is not in the defined range;</li>
      *             <li>{@code bitOrdering} is not one of the defined values.</li>
      *             </ul>
+     *
+     * @deprecated As of 1.1, use {@link Builder} instead.
      */
     public SPIDeviceConfig(int controllerNumber, int address, int csActive, int clockFrequency, int clockMode, int wordLength,
             int bitOrdering) {
@@ -194,22 +426,22 @@
 
     /**
      * Creates a new {@code SPIDeviceConfig} with the specified hardware addressing information and configuration
-     * parameters. The Chip Select active level is platform and/or driver-dependent (i.e. {@link #DEFAULT}).
+     * parameters. The Chip Select active level is platform and/or driver-dependent (i.e. {@link #UNASSIGNED}).
      *
      * @param controllerName
      *            the controller name (such as its <em>device file</em> name on UNIX systems).
      * @param address
      *            the Chip Select address of the slave device on the bus (a positive or zero integer).
      * @param clockFrequency
-     *            the clock frequency of the slave device in Hz (a positive integer) or {@link #DEFAULT}.
+     *            the clock frequency of the slave device in Hz (a positive integer) or {@link #UNASSIGNED}.
      * @param clockMode
      *            the clock mode, one of: {@code 0}, {@code 1}, {@code 2} or {@code 4} (see <a href="#mode">SPI Clock
      *            Modes</a>).
      * @param wordLength
-     *            the word length of the slave device (a positive integer) or {@link #DEFAULT}.
+     *            the word length of the slave device (a positive integer) or {@link #UNASSIGNED}.
      * @param bitOrdering
      *            the bit (shifting) ordering of the slave device, one of: {@link SPIDevice#BIG_ENDIAN},
-     *            {@link SPIDevice#LITTLE_ENDIAN}, {@link SPIDevice#MIXED_ENDIAN} or {@link #DEFAULT}.
+     *            {@link SPIDevice#LITTLE_ENDIAN}, {@link SPIDevice#MIXED_ENDIAN} or {@link #UNASSIGNED}.
      * @throws IllegalArgumentException
      *             if any of the following is true:
      *             <ul>
@@ -221,6 +453,8 @@
      *             </ul>
      * @throws NullPointerException
      *             if {@code controllerName} is {@code null}.
+     *
+     * @deprecated As of 1.1, use {@link Builder} instead.
      */
     public SPIDeviceConfig(String controllerName, int address, int clockFrequency, int clockMode, int wordLength,
             int bitOrdering) {
@@ -237,17 +471,17 @@
      *            the Chip Select address of the slave device on the bus (a positive or zero integer).
      * @param csActive
      *            the Chip Select active level, one of {@link #CS_ACTIVE_LOW},
-     *            {@link #CS_ACTIVE_HIGH}, {@link #CS_NOT_CONTROLLED} or {@link #DEFAULT}.
+     *            {@link #CS_ACTIVE_HIGH}, {@link #CS_NOT_CONTROLLED} or {@link #UNASSIGNED}.
      * @param clockFrequency
-     *            the clock frequency of the slave device in Hz (a positive integer) or {@link #DEFAULT}.
+     *            the clock frequency of the slave device in Hz (a positive integer) or {@link #UNASSIGNED}.
      * @param clockMode
      *            the clock mode, one of: {@code 0}, {@code 1}, {@code 2} or {@code 4} (see <a href="#mode">SPI Clock
      *            Modes</a>).
      * @param wordLength
-     *            the word length of the slave device (a positive integer) or {@link #DEFAULT}.
+     *            the word length of the slave device (a positive integer) or {@link #UNASSIGNED}.
      * @param bitOrdering
      *            the bit (shifting) ordering of the slave device, one of: {@link SPIDevice#BIG_ENDIAN},
-     *            {@link SPIDevice#LITTLE_ENDIAN}, {@link SPIDevice#MIXED_ENDIAN} or {@link #DEFAULT}.
+     *            {@link SPIDevice#LITTLE_ENDIAN}, {@link SPIDevice#MIXED_ENDIAN} or {@link #UNASSIGNED}.
      * @throws IllegalArgumentException
      *             if any of the following is true:
      *             <ul>
@@ -259,6 +493,8 @@
      *             </ul>
      * @throws NullPointerException
      *             if {@code controllerName} is {@code null}.
+     *
+     * @deprecated As of 1.1, use {@link Builder} instead.
      */
     public SPIDeviceConfig(String controllerName, int address, int csActive, int clockFrequency, int clockMode, int wordLength,
             int bitOrdering) {
@@ -275,6 +511,37 @@
     }
 
     /**
+     * Creates a new {@code SPIDeviceConfig} whose state is deserialized from the specified {@code InputStream}.
+     * This method may be invoked to restore the state of a {@code SPIDeviceConfig}
+     * object from a persistent store.
+     *
+     * @param in the stream to read from.
+     * @return a new {@code SPIDeviceConfig} instance.
+     * @throws IOException if an I/O error occurs or if the provided stream does not
+     * contain a representation of a {@code SPIDeviceConfig} object.
+     *
+     * @since 1.1
+     */
+    public static SPIDeviceConfig deserialize(InputStream  in) throws IOException {
+      throw new IOException("Unsupported Operation");
+    }
+
+    /**
+     * Serializes the state of this {@code SPIDeviceConfig} object to the specified {@code OutputStream}.
+     * This method may be invoked by the {@link jdk.dio.DeviceManager DeviceManager}
+     * to save the state of this {@code SPIDeviceConfig} object to a persistent store.
+     *
+     * @param out the stream to write to.
+     * @throws IOException if an I/O error occurs.
+     *
+     * @since 1.1
+     */
+    @Override
+    public int serialize(OutputStream  out) throws IOException  {
+      throw new IOException("Unsupported Operation");
+    }
+
+    /**
      * Gets the configured address of the SPI slave device.
      *
      * @return the Chip Select address of the slave device on the bus (a positive or zero integer).
@@ -286,7 +553,7 @@
     /**
      * Gets the configured controller number (the controller number of the SPI bus adapter the slave device is connected to).
      *
-     * @return the controller number (a positive or zero integer) or {@link #DEFAULT}.
+     * @return the controller number (a positive or zero integer) or {@link #UNASSIGNED}.
      */
     @Override
     public int getControllerNumber() {
@@ -304,10 +571,40 @@
     }
 
     /**
+     * Gets the requested or allocated input buffer size. The platform/underlying
+     * driver may or may not allocate the requested size
+     * for the input buffer.
+     * When querying the configuration of an opened or registered device the
+     * allocated buffer size is returned.
+     *
+     * @return the requested or allocated input buffer size (a positive or zero integer).
+     *
+     * @since 1.1
+     */
+    public int getInputBufferSize() {
+        return inputBufferSize;
+    }
+
+    /**
+     * Gets the requested or allocated output buffer size. The platform/underlying
+     * driver may or may not allocate the requested size
+     * for the output buffer.
+     * When querying the configuration of an opened or registered device the
+     * allocated buffer size is returned.
+     *
+     * @return the requested or allocated output buffer size (a positive or zero integer).
+     *
+     * @since 1.1
+     */
+    public int getOutputBufferSize() {
+        return outputBufferSize;
+    }
+
+    /**
      * Gets the configured bit (shifting) ordering of the SPI slave device.
      *
      * @return the bit ordering of the slave device, one of: {@link SPIDevice#BIG_ENDIAN},
-     *         {@link SPIDevice#LITTLE_ENDIAN}, {@link SPIDevice#MIXED_ENDIAN} or {@link #DEFAULT}.
+     *         {@link SPIDevice#LITTLE_ENDIAN}, {@link SPIDevice#MIXED_ENDIAN} or {@link #UNASSIGNED}.
      */
     public int getBitOrdering() {
         return bitOrdering;
@@ -316,7 +613,7 @@
     /**
      * Gets the clock frequency (in Hz) supported by the SPI slave device.
      *
-     * @return the clock frequency of the slave device in Hz (a positive integer) or {@link #DEFAULT}.
+     * @return the clock frequency of the slave device in Hz (a positive integer) or {@link #UNASSIGNED}.
      */
     public int getClockFrequency() {
         return clockFrequency;
@@ -336,7 +633,7 @@
      * Gets the configured Chip Select active level for selecting the SPI slave device.
      *
      * @return the Chip Select active level,one of {@link #CS_ACTIVE_LOW},
-     *            {@link #CS_ACTIVE_HIGH}, {@link #CS_NOT_CONTROLLED} or {@link #DEFAULT}.
+     *            {@link #CS_ACTIVE_HIGH}, {@link #CS_NOT_CONTROLLED} or {@link #UNASSIGNED}.
      */
     public int getCSActiveLevel() {
         return csActive;
@@ -345,7 +642,7 @@
     /**
      * Gets the configured word length for communicating with the SPI slave device.
      *
-     * @return the word length of the slave device (a positive integer) or {@link #DEFAULT}.
+     * @return the word length of the slave device (a positive integer) or {@link #UNASSIGNED}.
      */
     public int getWordLength() {
         return wordLength;
@@ -378,7 +675,7 @@
      *
      * @return {@code true} if {@code obj} is a {@code SPIDeviceConfig} and has
      * the same hardware addressing information and configuration parameter values
-     * as this {@code SPIDeviceConfig} object.
+     * as this {@code SPIDeviceConfig} object; {@code false} otherwise.
      */
     @Override
     public boolean equals(Object obj) {
@@ -410,10 +707,7 @@
         if (this.csActive != other.csActive) {
             return false;
         }
-        if (this.wordLength != other.wordLength) {
-            return false;
-        }
-        return true;
+        return this.wordLength == other.wordLength;
     }