Update concurrent module to Harmony r798021.

commit 56bcdc2a3b881883409267c3bd16294d80716859
Merge: 903691a f429dca
Author: Jesse Wilson <jessewilson@google.com>
Date:   Mon Jul 27 17:33:19 2009 -0700

    Merge branch 'concurrent_798021' into concurrent_dalvik

    Conflicts:
    	libcore/concurrent/.classpath
    	libcore/concurrent/build.xml
    	libcore/concurrent/make/run-test.xml
    	libcore/concurrent/src/main/java/java/util/concurrent/ArrayBlockingQueue.java
    	libcore/concurrent/src/main/java/java/util/concurrent/BlockingQueue.java
    	libcore/concurrent/src/main/java/java/util/concurrent/ConcurrentHashMap.java
    	libcore/concurrent/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java
    	libcore/concurrent/src/main/java/java/util/concurrent/ConcurrentMap.java
    	libcore/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArrayList.java
    	libcore/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArraySet.java
    	libcore/concurrent/src/main/java/java/util/concurrent/DelayQueue.java
    	libcore/concurrent/src/main/java/java/util/concurrent/LinkedBlockingQueue.java
    	libcore/concurrent/src/main/java/java/util/concurrent/PriorityBlockingQueue.java
    	libcore/concurrent/src/main/java/java/util/concurrent/ScheduledThreadPoolExecutor.java
    	libcore/concurrent/src/main/java/java/util/concurrent/Semaphore.java
    	libcore/concurrent/src/main/java/java/util/concurrent/SynchronousQueue.java
    	libcore/concurrent/src/main/java/java/util/concurrent/ThreadPoolExecutor.java
    	libcore/concurrent/src/main/java/java/util/concurrent/TimeUnit.java
    	libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicBoolean.java
    	libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicInteger.java
    	libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java
    	libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java
    	libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLong.java
    	libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java
    	libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java
    	libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReference.java
    	libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceArray.java
    	libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java
    	libcore/concurrent/src/main/java/java/util/concurrent/atomic/package.html
    	libcore/concurrent/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
    	libcore/concurrent/src/main/java/java/util/concurrent/locks/LockSupport.java
    	libcore/concurrent/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java
    	libcore/concurrent/src/main/java/java/util/concurrent/locks/package.html
    	libcore/concurrent/src/main/java/java/util/concurrent/package.html
    	libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicLongFieldUpdaterTest.java
    	libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceFieldUpdaterTest.java
    	libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceTest.java
    	libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentHashMapTest.java
    	libcore/concurrent/src/test/java/tests/api/java/util/concurrent/DelayQueueTest.java
    	libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ExecutorsTest.java
    	libcore/concurrent/src/test/java/tests/api/java/util/concurrent/JSR166TestCase.java
    	libcore/concurrent/src/test/java/tests/api/java/util/concurrent/LinkedBlockingQueueTest.java
    	libcore/concurrent/src/test/java/tests/api/java/util/concurrent/LockSupportTest.java
    	libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ReentrantLockTest.java
    	libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ReentrantReadWriteLockTest.java

commit 903691ae71cff640d5487a3d34a20e8767dbfb66
Author: Jesse Wilson <jessewilson@google.com>
Date:   Mon Jul 27 16:09:58 2009 -0700

    Dalvik Concurrent

commit f429dca21c408ee62e688f60d5e110718374e944
Author: Jesse Wilson <jessewilson@google.com>
Date:   Mon Jul 27 16:08:25 2009 -0700

    Concurrent 798021

commit b2c76fdd1056113000140bc4af57300c87469d2d
Author: Jesse Wilson <jessewilson@google.com>
Date:   Mon Jul 27 16:03:45 2009 -0700

    Concurrent 527399
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/AbstractExecutorService.java b/libcore/concurrent/src/main/java/java/util/concurrent/AbstractExecutorService.java
index ed4ce4f..f7ed15c 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/AbstractExecutorService.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/AbstractExecutorService.java
@@ -5,11 +5,10 @@
  */
 
 package java.util.concurrent;
-
 import java.util.*;
 
 /**
- * Provides default implementation of {@link ExecutorService}
+ * Provides default implementations of {@link ExecutorService}
  * execution methods. This class implements the <tt>submit</tt>,
  * <tt>invokeAny</tt> and <tt>invokeAll</tt> methods using the default
  * {@link FutureTask} class provided in this package.  For example,
@@ -24,6 +23,10 @@
  */
 public abstract class AbstractExecutorService implements ExecutorService {
 
+    /**
+     * @throws RejectedExecutionException {@inheritDoc}
+     * @throws NullPointerException       {@inheritDoc}
+     */
     public Future<?> submit(Runnable task) {
         if (task == null) throw new NullPointerException();
         FutureTask<Object> ftask = new FutureTask<Object>(task, null);
@@ -31,6 +34,10 @@
         return ftask;
     }
 
+    /**
+     * @throws RejectedExecutionException {@inheritDoc}
+     * @throws NullPointerException       {@inheritDoc}
+     */
     public <T> Future<T> submit(Runnable task, T result) {
         if (task == null) throw new NullPointerException();
         FutureTask<T> ftask = new FutureTask<T>(task, result);
@@ -38,6 +45,10 @@
         return ftask;
     }
 
+    /**
+     * @throws RejectedExecutionException {@inheritDoc}
+     * @throws NullPointerException       {@inheritDoc}
+     */
     public <T> Future<T> submit(Callable<T> task) {
         if (task == null) throw new NullPointerException();
         FutureTask<T> ftask = new FutureTask<T>(task);
@@ -57,7 +68,7 @@
         if (ntasks == 0)
             throw new IllegalArgumentException();
         List<Future<T>> futures= new ArrayList<Future<T>>(ntasks);
-        ExecutorCompletionService<T> ecs = 
+        ExecutorCompletionService<T> ecs =
             new ExecutorCompletionService<T>(this);
 
         // For efficiency, especially in executors with limited
@@ -79,14 +90,14 @@
             int active = 1;
 
             for (;;) {
-                Future<T> f = ecs.poll(); 
+                Future<T> f = ecs.poll();
                 if (f == null) {
                     if (ntasks > 0) {
                         --ntasks;
                         futures.add(ecs.submit(it.next()));
                         ++active;
                     }
-                    else if (active == 0) 
+                    else if (active == 0)
                         break;
                     else if (timed) {
                         f = ecs.poll(nanos, TimeUnit.NANOSECONDS);
@@ -96,29 +107,29 @@
                         nanos -= now - lastTime;
                         lastTime = now;
                     }
-                    else 
+                    else
                         f = ecs.take();
                 }
                 if (f != null) {
                     --active;
                     try {
                         return f.get();
-                    } catch(InterruptedException ie) {
+                    } catch (InterruptedException ie) {
                         throw ie;
-                    } catch(ExecutionException eex) {
+                    } catch (ExecutionException eex) {
                         ee = eex;
-                    } catch(RuntimeException rex) {
+                    } catch (RuntimeException rex) {
                         ee = new ExecutionException(rex);
                     }
                 }
-            }    
+            }
 
             if (ee == null)
                 ee = new ExecutionException();
             throw ee;
 
         } finally {
-            for (Future<T> f : futures) 
+            for (Future<T> f : futures)
                 f.cancel(true);
         }
     }
@@ -133,8 +144,8 @@
         }
     }
 
-    public <T> T invokeAny(Collection<Callable<T>> tasks, 
-                           long timeout, TimeUnit unit) 
+    public <T> T invokeAny(Collection<Callable<T>> tasks,
+                           long timeout, TimeUnit unit)
         throws InterruptedException, ExecutionException, TimeoutException {
         return doInvokeAny(tasks, true, unit.toNanos(timeout));
     }
@@ -153,10 +164,10 @@
             }
             for (Future<T> f : futures) {
                 if (!f.isDone()) {
-                    try { 
-                        f.get(); 
-                    } catch(CancellationException ignore) {
-                    } catch(ExecutionException ignore) {
+                    try {
+                        f.get();
+                    } catch (CancellationException ignore) {
+                    } catch (ExecutionException ignore) {
                     }
                 }
             }
@@ -164,13 +175,13 @@
             return futures;
         } finally {
             if (!done)
-                for (Future<T> f : futures) 
+                for (Future<T> f : futures)
                     f.cancel(true);
         }
     }
 
-    public <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks, 
-                                         long timeout, TimeUnit unit) 
+    public <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks,
+                                         long timeout, TimeUnit unit)
         throws InterruptedException {
         if (tasks == null || unit == null)
             throw new NullPointerException();
@@ -178,7 +189,7 @@
         List<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
         boolean done = false;
         try {
-            for (Callable<T> t : tasks) 
+            for (Callable<T> t : tasks)
                 futures.add(new FutureTask<T>(t));
 
             long lastTime = System.nanoTime();
@@ -192,18 +203,18 @@
                 nanos -= now - lastTime;
                 lastTime = now;
                 if (nanos <= 0)
-                    return futures; 
+                    return futures;
             }
 
             for (Future<T> f : futures) {
                 if (!f.isDone()) {
-                    if (nanos <= 0) 
-                        return futures; 
-                    try { 
-                        f.get(nanos, TimeUnit.NANOSECONDS); 
-                    } catch(CancellationException ignore) {
-                    } catch(ExecutionException ignore) {
-                    } catch(TimeoutException toe) {
+                    if (nanos <= 0)
+                        return futures;
+                    try {
+                        f.get(nanos, TimeUnit.NANOSECONDS);
+                    } catch (CancellationException ignore) {
+                    } catch (ExecutionException ignore) {
+                    } catch (TimeoutException toe) {
                         return futures;
                     }
                     long now = System.nanoTime();
@@ -215,7 +226,7 @@
             return futures;
         } finally {
             if (!done)
-                for (Future<T> f : futures) 
+                for (Future<T> f : futures)
                     f.cancel(true);
         }
     }
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/ArrayBlockingQueue.java b/libcore/concurrent/src/main/java/java/util/concurrent/ArrayBlockingQueue.java
index 43b9fd0..0082f07 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/ArrayBlockingQueue.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/ArrayBlockingQueue.java
@@ -24,8 +24,8 @@
  * <p>This is a classic &quot;bounded buffer&quot;, in which a
  * fixed-sized array holds elements inserted by producers and
  * extracted by consumers.  Once created, the capacity cannot be
- * increased.  Attempts to offer an element to a full queue will
- * result in the offer operation blocking; attempts to retrieve an
+ * increased.  Attempts to <tt>put</tt> an element into a full queue
+ * will result in the operation blocking; attempts to <tt>take</tt> an
  * element from an empty queue will similarly block.
  *
  * <p> This class supports an optional fairness policy for ordering
@@ -35,8 +35,9 @@
  * generally decreases throughput but reduces variability and avoids
  * starvation.
  *
- * <p>This class implements all of the <em>optional</em> methods
- * of the {@link Collection} and {@link Iterator} interfaces.
+ * <p>This class and its iterator implement all of the
+ * <em>optional</em> methods of the {@link Collection} and {@link
+ * Iterator} interfaces.
  *
  * @since 1.5
  * @author Doug Lea
@@ -56,9 +57,9 @@
     /** The queued items  */
     private final E[] items;
     /** items index for next take, poll or remove */
-    private transient int takeIndex;
+    private int takeIndex;
     /** items index for next put, offer, or add. */
-    private transient int putIndex;
+    private int putIndex;
     /** Number of items in the queue */
     private int count;
 
@@ -84,7 +85,7 @@
     }
 
     /**
-     * Insert element at current put position, advance, and signal.
+     * Inserts element at current put position, advances, and signals.
      * Call only when holding lock.
      */
     private void insert(E x) {
@@ -95,7 +96,7 @@
     }
 
     /**
-     * Extract element at current take position, advance, and signal.
+     * Extracts element at current take position, advances, and signals.
      * Call only when holding lock.
      */
     private E extract() {
@@ -139,6 +140,7 @@
     /**
      * Creates an <tt>ArrayBlockingQueue</tt> with the given (fixed)
      * capacity and default access policy.
+     *
      * @param capacity the capacity of this queue
      * @throws IllegalArgumentException if <tt>capacity</tt> is less than 1
      */
@@ -149,10 +151,11 @@
     /**
      * Creates an <tt>ArrayBlockingQueue</tt> with the given (fixed)
      * capacity and the specified access policy.
+     *
      * @param capacity the capacity of this queue
      * @param fair if <tt>true</tt> then queue accesses for threads blocked
-     * on insertion or removal, are processed in FIFO order; if <tt>false</tt>
-     * the access order is unspecified.
+     *        on insertion or removal, are processed in FIFO order;
+     *        if <tt>false</tt> the access order is unspecified.
      * @throws IllegalArgumentException if <tt>capacity</tt> is less than 1
      */
     public ArrayBlockingQueue(int capacity, boolean fair) {
@@ -169,15 +172,16 @@
      * capacity, the specified access policy and initially containing the
      * elements of the given collection,
      * added in traversal order of the collection's iterator.
+     *
      * @param capacity the capacity of this queue
      * @param fair if <tt>true</tt> then queue accesses for threads blocked
-     * on insertion or removal, are processed in FIFO order; if <tt>false</tt>
-     * the access order is unspecified.
+     *        on insertion or removal, are processed in FIFO order;
+     *        if <tt>false</tt> the access order is unspecified.
      * @param c the collection of elements to initially contain
      * @throws IllegalArgumentException if <tt>capacity</tt> is less than
-     * <tt>c.size()</tt>, or less than 1.
-     * @throws NullPointerException if <tt>c</tt> or any element within it
-     * is <tt>null</tt>
+     *         <tt>c.size()</tt>, or less than 1.
+     * @throws NullPointerException if the specified collection or any
+     *         of its elements are null
      */
     public ArrayBlockingQueue(int capacity, boolean fair,
                               Collection<? extends E> c) {
@@ -190,23 +194,38 @@
     }
 
     /**
-     * Inserts the specified element at the tail of this queue if possible,
-     * returning immediately if this queue is full.
+     * Inserts the specified element at the tail of this queue if it is
+     * possible to do so immediately without exceeding the queue's capacity,
+     * returning <tt>true</tt> upon success and throwing an
+     * <tt>IllegalStateException</tt> if this queue is full.
      *
-     * @param o the element to add.
-     * @return <tt>true</tt> if it was possible to add the element to
-     *         this queue, else <tt>false</tt>
-     * @throws NullPointerException if the specified element is <tt>null</tt>
+     * @param e the element to add
+     * @return <tt>true</tt> (as specified by {@link Collection#add})
+     * @throws IllegalStateException if this queue is full
+     * @throws NullPointerException if the specified element is null
      */
-    public boolean offer(E o) {
-        if (o == null) throw new NullPointerException();
+    public boolean add(E e) {
+        return super.add(e);
+    }
+
+    /**
+     * Inserts the specified element at the tail of this queue if it is
+     * possible to do so immediately without exceeding the queue's capacity,
+     * returning <tt>true</tt> upon success and <tt>false</tt> if this queue
+     * is full.  This method is generally preferable to method {@link #add},
+     * which can fail to insert an element only by throwing an exception.
+     *
+     * @throws NullPointerException if the specified element is null
+     */
+    public boolean offer(E e) {
+        if (e == null) throw new NullPointerException();
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
             if (count == items.length)
                 return false;
             else {
-                insert(o);
+                insert(e);
                 return true;
             }
         } finally {
@@ -215,29 +234,50 @@
     }
 
     /**
-     * Inserts the specified element at the tail of this queue, waiting if
-     * necessary up to the specified wait time for space to become available.
-     * @param o the element to add
-     * @param timeout how long to wait before giving up, in units of
-     * <tt>unit</tt>
-     * @param unit a <tt>TimeUnit</tt> determining how to interpret the
-     * <tt>timeout</tt> parameter
-     * @return <tt>true</tt> if successful, or <tt>false</tt> if
-     * the specified waiting time elapses before space is available.
-     * @throws InterruptedException if interrupted while waiting.
-     * @throws NullPointerException if the specified element is <tt>null</tt>.
+     * Inserts the specified element at the tail of this queue, waiting
+     * for space to become available if the queue is full.
+     *
+     * @throws InterruptedException {@inheritDoc}
+     * @throws NullPointerException {@inheritDoc}
      */
-    public boolean offer(E o, long timeout, TimeUnit unit)
-        throws InterruptedException {
-
-        if (o == null) throw new NullPointerException();
+    public void put(E e) throws InterruptedException {
+        if (e == null) throw new NullPointerException();
+        final E[] items = this.items;
         final ReentrantLock lock = this.lock;
         lock.lockInterruptibly();
         try {
-            long nanos = unit.toNanos(timeout);
+            try {
+                while (count == items.length)
+                    notFull.await();
+            } catch (InterruptedException ie) {
+                notFull.signal(); // propagate to non-interrupted thread
+                throw ie;
+            }
+            insert(e);
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * Inserts the specified element at the tail of this queue, waiting
+     * up to the specified wait time for space to become available if
+     * the queue is full.
+     *
+     * @throws InterruptedException {@inheritDoc}
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public boolean offer(E e, long timeout, TimeUnit unit)
+        throws InterruptedException {
+
+        if (e == null) throw new NullPointerException();
+        long nanos = unit.toNanos(timeout);
+        final ReentrantLock lock = this.lock;
+        lock.lockInterruptibly();
+        try {
             for (;;) {
                 if (count != items.length) {
-                    insert(o);
+                    insert(e);
                     return true;
                 }
                 if (nanos <= 0)
@@ -254,7 +294,6 @@
         }
     }
 
-
     public E poll() {
         final ReentrantLock lock = this.lock;
         lock.lock();
@@ -268,65 +307,6 @@
         }
     }
 
-    public E poll(long timeout, TimeUnit unit) throws InterruptedException {
-        final ReentrantLock lock = this.lock;
-        lock.lockInterruptibly();
-        try {
-            long nanos = unit.toNanos(timeout);
-            for (;;) {
-                if (count != 0) {
-                    E x = extract();
-                    return x;
-                }
-                if (nanos <= 0)
-                    return null;
-                try {
-                    nanos = notEmpty.awaitNanos(nanos);
-                } catch (InterruptedException ie) {
-                    notEmpty.signal(); // propagate to non-interrupted thread
-                    throw ie;
-                }
-
-            }
-        } finally {
-            lock.unlock();
-        }
-    }
-
-
-    public boolean remove(Object o) {
-        if (o == null) return false;
-        final E[] items = this.items;
-        final ReentrantLock lock = this.lock;
-        lock.lock();
-        try {
-            int i = takeIndex;
-            int k = 0;
-            for (;;) {
-                if (k++ >= count)
-                    return false;
-                if (o.equals(items[i])) {
-                    removeAt(i);
-                    return true;
-                }
-                i = inc(i);
-            }
-
-        } finally {
-            lock.unlock();
-        }
-    }
-
-    public E peek() {
-        final ReentrantLock lock = this.lock;
-        lock.lock();
-        try {
-            return (count == 0) ? null : items[takeIndex];
-        } finally {
-            lock.unlock();
-        }
-    }
-
     public E take() throws InterruptedException {
         final ReentrantLock lock = this.lock;
         lock.lockInterruptibly();
@@ -345,27 +325,36 @@
         }
     }
 
-    /**
-     * Adds the specified element to the tail of this queue, waiting if
-     * necessary for space to become available.
-     * @param o the element to add
-     * @throws InterruptedException if interrupted while waiting.
-     * @throws NullPointerException if the specified element is <tt>null</tt>.
-     */
-    public void put(E o) throws InterruptedException {
-        if (o == null) throw new NullPointerException();
-        final E[] items = this.items;
+    public E poll(long timeout, TimeUnit unit) throws InterruptedException {
+        long nanos = unit.toNanos(timeout);
         final ReentrantLock lock = this.lock;
         lock.lockInterruptibly();
         try {
-            try {
-                while (count == items.length)
-                    notFull.await();
-            } catch (InterruptedException ie) {
-                notFull.signal(); // propagate to non-interrupted thread
-                throw ie;
+            for (;;) {
+                if (count != 0) {
+                    E x = extract();
+                    return x;
+                }
+                if (nanos <= 0)
+                    return null;
+                try {
+                    nanos = notEmpty.awaitNanos(nanos);
+                } catch (InterruptedException ie) {
+                    notEmpty.signal(); // propagate to non-interrupted thread
+                    throw ie;
+                }
+
             }
-            insert(o);
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    public E peek() {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            return (count == 0) ? null : items[takeIndex];
         } finally {
             lock.unlock();
         }
@@ -376,7 +365,7 @@
     /**
      * Returns the number of elements in this queue.
      *
-     * @return  the number of elements in this queue.
+     * @return the number of elements in this queue
      */
     public int size() {
         final ReentrantLock lock = this.lock;
@@ -391,17 +380,15 @@
     // this doc comment is a modified copy of the inherited doc comment,
     // without the reference to unlimited queues.
     /**
-     * Returns the number of elements that this queue can ideally (in
-     * the absence of memory or resource constraints) accept without
+     * Returns the number of additional elements that this queue can ideally
+     * (in the absence of memory or resource constraints) accept without
      * blocking. This is always equal to the initial capacity of this queue
      * less the current <tt>size</tt> of this queue.
-     * <p>Note that you <em>cannot</em> always tell if
-     * an attempt to <tt>add</tt> an element will succeed by
-     * inspecting <tt>remainingCapacity</tt> because it may be the
-     * case that a waiting consumer is ready to <tt>take</tt> an
-     * element out of an otherwise full queue.
-     * 
-     * @return the remaining capacity
+     *
+     * <p>Note that you <em>cannot</em> always tell if an attempt to insert
+     * an element will succeed by inspecting <tt>remainingCapacity</tt>
+     * because it may be the case that another thread is about to
+     * insert or remove an element.
      */
     public int remainingCapacity() {
         final ReentrantLock lock = this.lock;
@@ -413,7 +400,48 @@
         }
     }
 
+    /**
+     * Removes a single instance of the specified element from this queue,
+     * if it is present.  More formally, removes an element <tt>e</tt> such
+     * that <tt>o.equals(e)</tt>, if this queue contains one or more such
+     * elements.
+     * Returns <tt>true</tt> if this queue contained the specified element
+     * (or equivalently, if this queue changed as a result of the call).
+     *
+     * @param o element to be removed from this queue, if present
+     * @return <tt>true</tt> if this queue changed as a result of the call
+     */
+    public boolean remove(Object o) {
+        if (o == null) return false;
+        final E[] items = this.items;
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            int i = takeIndex;
+            int k = 0;
+            for (;;) {
+                if (k++ >= count)
+                    return false;
+                if (o.equals(items[i])) {
+                    removeAt(i);
+                    return true;
+                }
+                i = inc(i);
+            }
 
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * Returns <tt>true</tt> if this queue contains the specified element.
+     * More formally, returns <tt>true</tt> if and only if this queue contains
+     * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>.
+     *
+     * @param o object to be checked for containment in this queue
+     * @return <tt>true</tt> if this queue contains the specified element
+     */
     public boolean contains(Object o) {
         if (o == null) return false;
         final E[] items = this.items;
@@ -433,6 +461,19 @@
         }
     }
 
+    /**
+     * Returns an array containing all of the elements in this queue, in
+     * proper sequence.
+     *
+     * <p>The returned array will be "safe" in that no references to it are
+     * maintained by this queue.  (In other words, this method must allocate
+     * a new array).  The caller is thus free to modify the returned array.
+     *
+     * <p>This method acts as bridge between array-based and collection-based
+     * APIs.
+     *
+     * @return an array containing all of the elements in this queue
+     */
     public Object[] toArray() {
         final E[] items = this.items;
         final ReentrantLock lock = this.lock;
@@ -451,6 +492,42 @@
         }
     }
 
+    /**
+     * Returns an array containing all of the elements in this queue, in
+     * proper sequence; the runtime type of the returned array is that of
+     * the specified array.  If the queue fits in the specified array, it
+     * is returned therein.  Otherwise, a new array is allocated with the
+     * runtime type of the specified array and the size of this queue.
+     *
+     * <p>If this queue fits in the specified array with room to spare
+     * (i.e., the array has more elements than this queue), the element in
+     * the array immediately following the end of the queue is set to
+     * <tt>null</tt>.
+     *
+     * <p>Like the {@link #toArray()} method, this method acts as bridge between
+     * array-based and collection-based APIs.  Further, this method allows
+     * precise control over the runtime type of the output array, and may,
+     * under certain circumstances, be used to save allocation costs.
+     *
+     * <p>Suppose <tt>x</tt> is a queue known to contain only strings.
+     * The following code can be used to dump the queue into a newly
+     * allocated array of <tt>String</tt>:
+     *
+     * <pre>
+     *     String[] y = x.toArray(new String[0]);</pre>
+     *
+     * Note that <tt>toArray(new Object[0])</tt> is identical in function to
+     * <tt>toArray()</tt>.
+     *
+     * @param a the array into which the elements of the queue are to
+     *          be stored, if it is big enough; otherwise, a new array of the
+     *          same runtime type is allocated for this purpose
+     * @return an array containing all of the elements in this queue
+     * @throws ArrayStoreException if the runtime type of the specified array
+     *         is not a supertype of the runtime type of every element in
+     *         this queue
+     * @throws NullPointerException if the specified array is null
+     */
     public <T> T[] toArray(T[] a) {
         final E[] items = this.items;
         final ReentrantLock lock = this.lock;
@@ -486,7 +563,10 @@
         }
     }
 
-
+    /**
+     * Atomically removes all of the elements from this queue.
+     * The queue will be empty after this call returns.
+     */
     public void clear() {
         final E[] items = this.items;
         final ReentrantLock lock = this.lock;
@@ -507,6 +587,12 @@
         }
     }
 
+    /**
+     * @throws UnsupportedOperationException {@inheritDoc}
+     * @throws ClassCastException            {@inheritDoc}
+     * @throws NullPointerException          {@inheritDoc}
+     * @throws IllegalArgumentException      {@inheritDoc}
+     */
     public int drainTo(Collection<? super E> c) {
         if (c == null)
             throw new NullPointerException();
@@ -537,7 +623,12 @@
         }
     }
 
-
+    /**
+     * @throws UnsupportedOperationException {@inheritDoc}
+     * @throws ClassCastException            {@inheritDoc}
+     * @throws NullPointerException          {@inheritDoc}
+     * @throws IllegalArgumentException      {@inheritDoc}
+     */
     public int drainTo(Collection<? super E> c, int maxElements) {
         if (c == null)
             throw new NullPointerException();
@@ -574,12 +665,12 @@
     /**
      * Returns an iterator over the elements in this queue in proper sequence.
      * The returned <tt>Iterator</tt> is a "weakly consistent" iterator that
-     * will never throw {@link java.util.ConcurrentModificationException},
+     * will never throw {@link ConcurrentModificationException},
      * and guarantees to traverse elements as they existed upon
      * construction of the iterator, and may (but is not guaranteed to)
      * reflect any modifications subsequent to construction.
      *
-     * @return an iterator over the elements in this queue in proper sequence.
+     * @return an iterator over the elements in this queue in proper sequence
      */
     public Iterator<E> iterator() {
         final ReentrantLock lock = this.lock;
@@ -606,7 +697,7 @@
          * that an element exists in hasNext(), we must return it in
          * the following next() call even if it was in the process of
          * being removed when hasNext() was called.
-         **/
+         */
         private E nextItem;
 
         /**
@@ -635,7 +726,7 @@
         }
 
         /**
-         * Check whether nextIndex is valid; if so setting nextItem.
+         * Checks whether nextIndex is valid; if so setting nextItem.
          * Stops iterator when either hits putIndex or sees null item.
          */
         private void checkNext() {
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/BlockingQueue.java b/libcore/concurrent/src/main/java/java/util/concurrent/BlockingQueue.java
index ddb7d77..85945b9 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/BlockingQueue.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/BlockingQueue.java
@@ -15,9 +15,50 @@
 
 /**
  * A {@link java.util.Queue} that additionally supports operations
- * that wait for the queue to become non-empty when retrieving an element,
- * and wait for space to become available in the queue when storing an 
- * element.
+ * that wait for the queue to become non-empty when retrieving an
+ * element, and wait for space to become available in the queue when
+ * storing an element.
+ *
+ * <p><tt>BlockingQueue</tt> methods come in four forms, with different ways
+ * of handling operations that cannot be satisfied immediately, but may be
+ * satisfied at some point in the future:
+ * one throws an exception, the second returns a special value (either
+ * <tt>null</tt> or <tt>false</tt>, depending on the operation), the third
+ * blocks the current thread indefinitely until the operation can succeed,
+ * and the fourth blocks for only a given maximum time limit before giving
+ * up.  These methods are summarized in the following table:
+ *
+ * <p>
+ * <table BORDER CELLPADDING=3 CELLSPACING=1>
+ *  <tr>
+ *    <td></td>
+ *    <td ALIGN=CENTER><em>Throws exception</em></td>
+ *    <td ALIGN=CENTER><em>Special value</em></td>
+ *    <td ALIGN=CENTER><em>Blocks</em></td>
+ *    <td ALIGN=CENTER><em>Times out</em></td>
+ *  </tr>
+ *  <tr>
+ *    <td><b>Insert</b></td>
+ *    <td>{@link #add add(e)}</td>
+ *    <td>{@link #offer offer(e)}</td>
+ *    <td>{@link #put put(e)}</td>
+ *    <td>{@link #offer(Object, long, TimeUnit) offer(e, time, unit)}</td>
+ *  </tr>
+ *  <tr>
+ *    <td><b>Remove</b></td>
+ *    <td>{@link #remove remove()}</td>
+ *    <td>{@link #poll poll()}</td>
+ *    <td>{@link #take take()}</td>
+ *    <td>{@link #poll(long, TimeUnit) poll(time, unit)}</td>
+ *  </tr>
+ *  <tr>
+ *    <td><b>Examine</b></td>
+ *    <td>{@link #element element()}</td>
+ *    <td>{@link #peek peek()}</td>
+ *    <td><em>not applicable</em></td>
+ *    <td><em>not applicable</em></td>
+ *  </tr>
+ * </table>
  *
  * <p>A <tt>BlockingQueue</tt> does not accept <tt>null</tt> elements.
  * Implementations throw <tt>NullPointerException</tt> on attempts
@@ -31,16 +72,22 @@
  * A <tt>BlockingQueue</tt> without any intrinsic capacity constraints always
  * reports a remaining capacity of <tt>Integer.MAX_VALUE</tt>.
  *
- * <p> While <tt>BlockingQueue</tt> is designed to be used primarily
- * for producer-consumer queues, it additionally supports the {@link
- * java.util.Collection} interface.  So, for example, it is possible
- * to remove an arbitrary element from a queue using
+ * <p> <tt>BlockingQueue</tt> implementations are designed to be used
+ * primarily for producer-consumer queues, but additionally support
+ * the {@link java.util.Collection} interface.  So, for example, it is
+ * possible to remove an arbitrary element from a queue using
  * <tt>remove(x)</tt>. However, such operations are in general
  * <em>not</em> performed very efficiently, and are intended for only
- * occasional use, such as when a queued message is cancelled.  Also,
- * the bulk Collection operations, most notably <tt>addAll</tt>, are
- * <em>not</em> necessarily performed atomically, so it is possible
- * for <tt>addAll(c)</tt> to fail (throwing an exception) after adding
+ * occasional use, such as when a queued message is cancelled.
+ *
+ * <p> <tt>BlockingQueue</tt> implementations are thread-safe.  All
+ * queuing methods achieve their effects atomically using internal
+ * locks or other forms of concurrency control. However, the
+ * <em>bulk</em> Collection operations <tt>addAll</tt>,
+ * <tt>containsAll</tt>, <tt>retainAll</tt> and <tt>removeAll</tt> are
+ * <em>not</em> necessarily performed atomically unless specified
+ * otherwise in an implementation. So it is possible, for example, for
+ * <tt>addAll(c)</tt> to fail (throwing an exception) after adding
  * only some of the elements in <tt>c</tt>.
  *
  * <p>A <tt>BlockingQueue</tt> does <em>not</em> intrinsically support
@@ -61,7 +108,7 @@
  *   Producer(BlockingQueue q) { queue = q; }
  *   public void run() {
  *     try {
- *       while(true) { queue.put(produce()); }
+ *       while (true) { queue.put(produce()); }
  *     } catch (InterruptedException ex) { ... handle ...}
  *   }
  *   Object produce() { ... }
@@ -72,7 +119,7 @@
  *   Consumer(BlockingQueue q) { queue = q; }
  *   public void run() {
  *     try {
- *       while(true) { consume(queue.take()); }
+ *       while (true) { consume(queue.take()); }
  *     } catch (InterruptedException ex) { ... handle ...}
  *   }
  *   void consume(Object x) { ... }
@@ -91,137 +138,207 @@
  * }
  * </pre>
  *
+ * <p>Memory consistency effects: As with other concurrent
+ * collections, actions in a thread prior to placing an object into a
+ * {@code BlockingQueue}
+ * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
+ * actions subsequent to the access or removal of that element from
+ * the {@code BlockingQueue} in another thread.
+ *
  * @since 1.5
  * @author Doug Lea
  * @param <E> the type of elements held in this collection
  */
 public interface BlockingQueue<E> extends Queue<E> {
+    /**
+     * Inserts the specified element into this queue if it is possible to do
+     * so immediately without violating capacity restrictions, returning
+     * <tt>true</tt> upon success and throwing an
+     * <tt>IllegalStateException</tt> if no space is currently available.
+     * When using a capacity-restricted queue, it is generally preferable to
+     * use {@link #offer(Object) offer}.
+     *
+     * @param e the element to add
+     * @return <tt>true</tt> (as specified by {@link Collection#add})
+     * @throws IllegalStateException if the element cannot be added at this
+     *         time due to capacity restrictions
+     * @throws ClassCastException if the class of the specified element
+     *         prevents it from being added to this queue
+     * @throws NullPointerException if the specified element is null
+     * @throws IllegalArgumentException if some property of the specified
+     *         element prevents it from being added to this queue
+     */
+    boolean add(E e);
 
     /**
-     * Inserts the specified element into this queue, if possible.  When
-     * using queues that may impose insertion restrictions (for
-     * example capacity bounds), method <tt>offer</tt> is generally
-     * preferable to method {@link Collection#add}, which can fail to
-     * insert an element only by throwing an exception.
+     * Inserts the specified element into this queue if it is possible to do
+     * so immediately without violating capacity restrictions, returning
+     * <tt>true</tt> upon success and <tt>false</tt> if no space is currently
+     * available.  When using a capacity-restricted queue, this method is
+     * generally preferable to {@link #add}, which can fail to insert an
+     * element only by throwing an exception.
      *
-     * @param o the element to add.
-     * @return <tt>true</tt> if it was possible to add the element to
-     *         this queue, else <tt>false</tt>
-     * @throws NullPointerException if the specified element is <tt>null</tt>
+     * @param e the element to add
+     * @return <tt>true</tt> if the element was added to this queue, else
+     *         <tt>false</tt>
+     * @throws ClassCastException if the class of the specified element
+     *         prevents it from being added to this queue
+     * @throws NullPointerException if the specified element is null
+     * @throws IllegalArgumentException if some property of the specified
+     *         element prevents it from being added to this queue
      */
-    boolean offer(E o);
-    
+    boolean offer(E e);
+
     /**
      * Inserts the specified element into this queue, waiting if necessary
-     * up to the specified wait time for space to become available.
-     * @param o the element to add
-     * @param timeout how long to wait before giving up, in units of
-     * <tt>unit</tt>
-     * @param unit a <tt>TimeUnit</tt> determining how to interpret the
-     * <tt>timeout</tt> parameter
-     * @return <tt>true</tt> if successful, or <tt>false</tt> if
-     * the specified waiting time elapses before space is available.
-     * @throws InterruptedException if interrupted while waiting.
-     * @throws NullPointerException if the specified element is <tt>null</tt>.
+     * for space to become available.
+     *
+     * @param e the element to add
+     * @throws InterruptedException if interrupted while waiting
+     * @throws ClassCastException if the class of the specified element
+     *         prevents it from being added to this queue
+     * @throws NullPointerException if the specified element is null
+     * @throws IllegalArgumentException if some property of the specified
+     *         element prevents it from being added to this queue
      */
-    boolean offer(E o, long timeout, TimeUnit unit)
+    void put(E e) throws InterruptedException;
+
+    /**
+     * Inserts the specified element into this queue, waiting up to the
+     * specified wait time if necessary for space to become available.
+     *
+     * @param e the element to add
+     * @param timeout how long to wait before giving up, in units of
+     *        <tt>unit</tt>
+     * @param unit a <tt>TimeUnit</tt> determining how to interpret the
+     *        <tt>timeout</tt> parameter
+     * @return <tt>true</tt> if successful, or <tt>false</tt> if
+     *         the specified waiting time elapses before space is available
+     * @throws InterruptedException if interrupted while waiting
+     * @throws ClassCastException if the class of the specified element
+     *         prevents it from being added to this queue
+     * @throws NullPointerException if the specified element is null
+     * @throws IllegalArgumentException if some property of the specified
+     *         element prevents it from being added to this queue
+     */
+    boolean offer(E e, long timeout, TimeUnit unit)
         throws InterruptedException;
 
     /**
-     * Retrieves and removes the head of this queue, waiting
-     * if necessary up to the specified wait time if no elements are
-     * present on this queue.
+     * Retrieves and removes the head of this queue, waiting if necessary
+     * until an element becomes available.
+     *
+     * @return the head of this queue
+     * @throws InterruptedException if interrupted while waiting
+     */
+    E take() throws InterruptedException;
+
+    /**
+     * Retrieves and removes the head of this queue, waiting up to the
+     * specified wait time if necessary for an element to become available.
+     *
      * @param timeout how long to wait before giving up, in units of
-     * <tt>unit</tt>
+     *        <tt>unit</tt>
      * @param unit a <tt>TimeUnit</tt> determining how to interpret the
-     * <tt>timeout</tt> parameter
+     *        <tt>timeout</tt> parameter
      * @return the head of this queue, or <tt>null</tt> if the
-     * specified waiting time elapses before an element is present.
-     * @throws InterruptedException if interrupted while waiting.
+     *         specified waiting time elapses before an element is available
+     * @throws InterruptedException if interrupted while waiting
      */
     E poll(long timeout, TimeUnit unit)
         throws InterruptedException;
 
     /**
-     * Retrieves and removes the head of this queue, waiting
-     * if no elements are present on this queue.
-     * @return the head of this queue
-     * @throws InterruptedException if interrupted while waiting.
-     */
-    E take() throws InterruptedException;
-
-    /**
-     * Adds the specified element to this queue, waiting if necessary for
-     * space to become available.
-     * @param o the element to add
-     * @throws InterruptedException if interrupted while waiting.
-     * @throws NullPointerException if the specified element is <tt>null</tt>.
-     */
-    void put(E o) throws InterruptedException;
-
-    /**
-     * Returns the number of elements that this queue can ideally (in
-     * the absence of memory or resource constraints) accept without
-     * blocking, or <tt>Integer.MAX_VALUE</tt> if there is no
-     * intrinsic limit.
-     * <p>Note that you <em>cannot</em> always tell if
-     * an attempt to <tt>add</tt> an element will succeed by
-     * inspecting <tt>remainingCapacity</tt> because it may be the
-     * case that a waiting consumer is ready to <tt>take</tt> an
-     * element out of an otherwise full queue.
+     * Returns the number of additional elements that this queue can ideally
+     * (in the absence of memory or resource constraints) accept without
+     * blocking, or <tt>Integer.MAX_VALUE</tt> if there is no intrinsic
+     * limit.
+     *
+     * <p>Note that you <em>cannot</em> always tell if an attempt to insert
+     * an element will succeed by inspecting <tt>remainingCapacity</tt>
+     * because it may be the case that another thread is about to
+     * insert or remove an element.
+     *
      * @return the remaining capacity
      */
     int remainingCapacity();
 
     /**
-     * Adds the specified element to this queue if it is possible to
-     * do so immediately, returning <tt>true</tt> upon success, else
-     * throwing an IllegalStateException.  
-     * @param o the element
-     * @return <tt>true</tt> (as per the general contract of
-     *         <tt>Collection.add</tt>).
+     * Removes a single instance of the specified element from this queue,
+     * if it is present.  More formally, removes an element <tt>e</tt> such
+     * that <tt>o.equals(e)</tt>, if this queue contains one or more such
+     * elements.
+     * Returns <tt>true</tt> if this queue contained the specified element
+     * (or equivalently, if this queue changed as a result of the call).
      *
-     * @throws NullPointerException if the specified element is <tt>null</tt>
-     * @throws IllegalStateException if element cannot be added
+     * @param o element to be removed from this queue, if present
+     * @return <tt>true</tt> if this queue changed as a result of the call
+     * @throws ClassCastException if the class of the specified element
+     *         is incompatible with this queue (optional)
+     * @throws NullPointerException if the specified element is null (optional)
      */
-    boolean add(E o);
+    boolean remove(Object o);
+
+    /**
+     * Returns <tt>true</tt> if this queue contains the specified element.
+     * More formally, returns <tt>true</tt> if and only if this queue contains
+     * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>.
+     *
+     * @param o object to be checked for containment in this queue
+     * @return <tt>true</tt> if this queue contains the specified element
+     * @throws ClassCastException if the class of the specified element
+     *         is incompatible with this queue (optional)
+     * @throws NullPointerException if the specified element is null (optional)
+     */
+    public boolean contains(Object o);
 
     /**
      * Removes all available elements from this queue and adds them
-     * into the given collection.  This operation may be more
+     * to the given collection.  This operation may be more
      * efficient than repeatedly polling this queue.  A failure
-     * encountered while attempting to <tt>add</tt> elements to
+     * encountered while attempting to add elements to
      * collection <tt>c</tt> may result in elements being in neither,
      * either or both collections when the associated exception is
-     * thrown. Attempts to drain a queue to itself result in
+     * thrown.  Attempts to drain a queue to itself result in
      * <tt>IllegalArgumentException</tt>. Further, the behavior of
      * this operation is undefined if the specified collection is
      * modified while the operation is in progress.
      *
      * @param c the collection to transfer elements into
-     * @return the number of elements transferred.
-     * @throws NullPointerException if c is null
-     * @throws IllegalArgumentException if c is this queue
-     * 
+     * @return the number of elements transferred
+     * @throws UnsupportedOperationException if addition of elements
+     *         is not supported by the specified collection
+     * @throws ClassCastException if the class of an element of this queue
+     *         prevents it from being added to the specified collection
+     * @throws NullPointerException if the specified collection is null
+     * @throws IllegalArgumentException if the specified collection is this
+     *         queue, or some property of an element of this queue prevents
+     *         it from being added to the specified collection
      */
     int drainTo(Collection<? super E> c);
-    
+
     /**
      * Removes at most the given number of available elements from
-     * this queue and adds them into the given collection.  A failure
-     * encountered while attempting to <tt>add</tt> elements to
+     * this queue and adds them to the given collection.  A failure
+     * encountered while attempting to add elements to
      * collection <tt>c</tt> may result in elements being in neither,
      * either or both collections when the associated exception is
-     * thrown. Attempts to drain a queue to itself result in
+     * thrown.  Attempts to drain a queue to itself result in
      * <tt>IllegalArgumentException</tt>. Further, the behavior of
      * this operation is undefined if the specified collection is
      * modified while the operation is in progress.
      *
      * @param c the collection to transfer elements into
      * @param maxElements the maximum number of elements to transfer
-     * @return the number of elements transferred.
-     * @throws NullPointerException if c is null
-     * @throws IllegalArgumentException if c is this queue
+     * @return the number of elements transferred
+     * @throws UnsupportedOperationException if addition of elements
+     *         is not supported by the specified collection
+     * @throws ClassCastException if the class of an element of this queue
+     *         prevents it from being added to the specified collection
+     * @throws NullPointerException if the specified collection is null
+     * @throws IllegalArgumentException if the specified collection is this
+     *         queue, or some property of an element of this queue prevents
+     *         it from being added to the specified collection
      */
     int drainTo(Collection<? super E> c, int maxElements);
 }
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/CompletionService.java b/libcore/concurrent/src/main/java/java/util/concurrent/CompletionService.java
index e349e5f..df9f719 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/CompletionService.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/CompletionService.java
@@ -16,52 +16,56 @@
  * submitted in one part of a program or system, and then acted upon
  * in a different part of the program when the reads complete,
  * possibly in a different order than they were requested.
-
- * <p>
  *
- * Typically, a <tt>CompletionService</tt> relies on a separate {@link
- * Executor} to actually execute the tasks, in which case the
+ * <p>Typically, a <tt>CompletionService</tt> relies on a separate
+ * {@link Executor} to actually execute the tasks, in which case the
  * <tt>CompletionService</tt> only manages an internal completion
  * queue. The {@link ExecutorCompletionService} class provides an
  * implementation of this approach.
  *
+ * <p>Memory consistency effects: Actions in a thread prior to
+ * submitting a task to a {@code CompletionService}
+ * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
+ * actions taken by that task, which in turn <i>happen-before</i>
+ * actions following a successful return from the corresponding {@code take()}.
+ *
  */
 public interface CompletionService<V> {
     /**
      * Submits a value-returning task for execution and returns a Future
-     * representing the pending results of the task. Upon completion,
+     * representing the pending results of the task.  Upon completion,
      * this task may be taken or polled.
      *
      * @param task the task to submit
      * @return a Future representing pending completion of the task
-     * @throws RejectedExecutionException if task cannot be scheduled
-     * for execution
-     * @throws NullPointerException if task null     
+     * @throws RejectedExecutionException if the task cannot be
+     *         scheduled for execution
+     * @throws NullPointerException if the task is null
      */
     Future<V> submit(Callable<V> task);
 
-
     /**
-     * Submits a Runnable task for execution and returns a Future 
-     * representing that task. Upon completion,
-     * this task may be taken or polled.
+     * Submits a Runnable task for execution and returns a Future
+     * representing that task.  Upon completion, this task may be
+     * taken or polled.
      *
      * @param task the task to submit
      * @param result the result to return upon successful completion
      * @return a Future representing pending completion of the task,
-     * and whose <tt>get()</tt> method will return the given result value 
-     * upon completion
-     * @throws RejectedExecutionException if task cannot be scheduled
-     * for execution
-     * @throws NullPointerException if task null     
+     *         and whose <tt>get()</tt> method will return the given
+     *         result value upon completion
+     * @throws RejectedExecutionException if the task cannot be
+     *         scheduled for execution
+     * @throws NullPointerException if the task is null
      */
     Future<V> submit(Runnable task, V result);
 
     /**
      * Retrieves and removes the Future representing the next
      * completed task, waiting if none are yet present.
+     *
      * @return the Future representing the next completed task
-     * @throws InterruptedException if interrupted while waiting.
+     * @throws InterruptedException if interrupted while waiting
      */
     Future<V> take() throws InterruptedException;
 
@@ -71,7 +75,7 @@
      * completed task or <tt>null</tt> if none are present.
      *
      * @return the Future representing the next completed task, or
-     * <tt>null</tt> if none are present.
+     *         <tt>null</tt> if none are present
      */
     Future<V> poll();
 
@@ -79,14 +83,15 @@
      * Retrieves and removes the Future representing the next
      * completed task, waiting if necessary up to the specified wait
      * time if none are yet present.
+     *
      * @param timeout how long to wait before giving up, in units of
-     * <tt>unit</tt>
+     *        <tt>unit</tt>
      * @param unit a <tt>TimeUnit</tt> determining how to interpret the
-     * <tt>timeout</tt> parameter
+     *        <tt>timeout</tt> parameter
      * @return the Future representing the next completed task or
-     * <tt>null</tt> if the specified waiting time elapses before one
-     * is present.
-     * @throws InterruptedException if interrupted while waiting.
+     *         <tt>null</tt> if the specified waiting time elapses
+     *         before one is present
+     * @throws InterruptedException if interrupted while waiting
      */
     Future<V> poll(long timeout, TimeUnit unit) throws InterruptedException;
 }
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/ConcurrentHashMap.java b/libcore/concurrent/src/main/java/java/util/concurrent/ConcurrentHashMap.java
index f72c6fe..cb5fb3f 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/ConcurrentHashMap.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/ConcurrentHashMap.java
@@ -14,7 +14,6 @@
 
 // BEGIN android-note
 // removed link to collections framework docs
-// removed cloneable interface from ConcurrentMap interface
 // END android-note
 
 /**
@@ -38,13 +37,12 @@
  * removal of only some entries.  Similarly, Iterators and
  * Enumerations return elements reflecting the state of the hash table
  * at some point at or since the creation of the iterator/enumeration.
- * They do <em>not</em> throw
- * {@link ConcurrentModificationException}.  However, iterators are
- * designed to be used by only one thread at a time.
+ * They do <em>not</em> throw {@link ConcurrentModificationException}.
+ * However, iterators are designed to be used by only one thread at a time.
  *
  * <p> The allowed concurrency among update operations is guided by
  * the optional <tt>concurrencyLevel</tt> constructor argument
- * (default 16), which is used as a hint for internal sizing.  The
+ * (default <tt>16</tt>), which is used as a hint for internal sizing.  The
  * table is internally partitioned to try to permit the indicated
  * number of concurrent updates without contention. Because placement
  * in hash tables is essentially random, the actual concurrency will
@@ -54,20 +52,23 @@
  * and a significantly lower value can lead to thread contention. But
  * overestimates and underestimates within an order of magnitude do
  * not usually have much noticeable impact. A value of one is
- * appropriate when it is known that only one thread will modify
- * and all others will only read.
+ * appropriate when it is known that only one thread will modify and
+ * all others will only read. Also, resizing this or any other kind of
+ * hash table is a relatively slow operation, so, when possible, it is
+ * a good idea to provide estimates of expected table sizes in
+ * constructors.
  *
- * <p>This class implements all of the <em>optional</em> methods
- * of the {@link Map} and {@link Iterator} interfaces.
+ * <p>This class and its views and iterators implement all of the
+ * <em>optional</em> methods of the {@link Map} and {@link Iterator}
+ * interfaces.
  *
- * <p> Like {@link java.util.Hashtable} but unlike {@link
- * java.util.HashMap}, this class does NOT allow <tt>null</tt> to be
- * used as a key or value.
+ * <p> Like {@link Hashtable} but unlike {@link HashMap}, this class
+ * does <em>not</em> allow <tt>null</tt> to be used as a key or value.
  *
  * @since 1.5
  * @author Doug Lea
  * @param <K> the type of keys maintained by this map
- * @param <V> the type of mapped values 
+ * @param <V> the type of mapped values
  */
 public class ConcurrentHashMap<K, V> extends AbstractMap<K, V>
         implements ConcurrentMap<K, V>, Serializable {
@@ -81,29 +82,30 @@
     /* ---------------- Constants -------------- */
 
     /**
-     * The default initial number of table slots for this table.
-     * Used when not otherwise specified in constructor.
+     * The default initial capacity for this table,
+     * used when not otherwise specified in a constructor.
      */
-    static int DEFAULT_INITIAL_CAPACITY = 16;
+    static final int DEFAULT_INITIAL_CAPACITY = 16;
 
     /**
-     * The maximum capacity, used if a higher value is implicitly
-     * specified by either of the constructors with arguments.  MUST
-     * be a power of two <= 1<<30 to ensure that entries are indexible
-     * using ints.
-     */
-    static final int MAXIMUM_CAPACITY = 1 << 30; 
-
-    /**
-     * The default load factor for this table.  Used when not
-     * otherwise specified in constructor.
+     * The default load factor for this table, used when not
+     * otherwise specified in a constructor.
      */
     static final float DEFAULT_LOAD_FACTOR = 0.75f;
 
     /**
-     * The default number of concurrency control segments.
-     **/
-    static final int DEFAULT_SEGMENTS = 16;
+     * The default concurrency level for this table, used when not
+     * otherwise specified in a constructor.
+     */
+    static final int DEFAULT_CONCURRENCY_LEVEL = 16;
+
+    /**
+     * The maximum capacity, used if a higher value is implicitly
+     * specified by either of the constructors with arguments.  MUST
+     * be a power of two <= 1<<30 to ensure that entries are indexable
+     * using ints.
+     */
+    static final int MAXIMUM_CAPACITY = 1 << 30;
 
     /**
      * The maximum number of segments to allow; used to bound
@@ -111,23 +113,31 @@
      */
     static final int MAX_SEGMENTS = 1 << 16; // slightly conservative
 
+    /**
+     * Number of unsynchronized retries in size and containsValue
+     * methods before resorting to locking. This is used to avoid
+     * unbounded retries if tables undergo continuous modification
+     * which would make it impossible to obtain an accurate result.
+     */
+    static final int RETRIES_BEFORE_LOCK = 2;
+
     /* ---------------- Fields -------------- */
 
     /**
      * Mask value for indexing into segments. The upper bits of a
      * key's hash code are used to choose the segment.
-     **/
+     */
     final int segmentMask;
 
     /**
      * Shift value for indexing within segments.
-     **/
+     */
     final int segmentShift;
 
     /**
      * The segments, each of which is a specialized hash table
      */
-    final Segment[] segments;
+    final Segment<K,V>[] segments;
 
     transient Set<K> keySet;
     transient Set<Map.Entry<K,V>> entrySet;
@@ -136,18 +146,21 @@
     /* ---------------- Small Utilities -------------- */
 
     /**
-     * Returns a hash code for non-null Object x.
-     * Uses the same hash code spreader as most other java.util hash tables.
-     * @param x the object serving as a key
-     * @return the hash code
+     * Applies a supplemental hash function to a given hashCode, which
+     * defends against poor quality hash functions.  This is critical
+     * because ConcurrentHashMap uses power-of-two length hash tables,
+     * that otherwise encounter collisions for hashCodes that do not
+     * differ in lower or upper bits.
      */
-    static int hash(Object x) {
-        int h = x.hashCode();
-        h += ~(h << 9);
-        h ^=  (h >>> 14);
-        h +=  (h << 4);
-        h ^=  (h >>> 10);
-        return h;
+    private static int hash(int h) {
+        // Spread bits to regularize both segment and index locations,
+        // using variant of single-word Wang/Jenkins hash.
+        h += (h <<  15) ^ 0xffffcd7d;
+        h ^= (h >>> 10);
+        h += (h <<   3);
+        h ^= (h >>>  6);
+        h += (h <<   2) + (h << 14);
+        return h ^ (h >>> 16);
     }
 
     /**
@@ -156,16 +169,47 @@
      * @return the segment
      */
     final Segment<K,V> segmentFor(int hash) {
-        return (Segment<K,V>) segments[(hash >>> segmentShift) & segmentMask];
+        return segments[(hash >>> segmentShift) & segmentMask];
     }
 
     /* ---------------- Inner Classes -------------- */
 
     /**
+     * ConcurrentHashMap list entry. Note that this is never exported
+     * out as a user-visible Map.Entry.
+     *
+     * Because the value field is volatile, not final, it is legal wrt
+     * the Java Memory Model for an unsynchronized reader to see null
+     * instead of initial value when read via a data race.  Although a
+     * reordering leading to this is not likely to ever actually
+     * occur, the Segment.readValueUnderLock method is used as a
+     * backup in case a null (pre-initialized) value is ever seen in
+     * an unsynchronized access method.
+     */
+    static final class HashEntry<K,V> {
+        final K key;
+        final int hash;
+        volatile V value;
+        final HashEntry<K,V> next;
+
+        HashEntry(K key, int hash, HashEntry<K,V> next, V value) {
+            this.key = key;
+            this.hash = hash;
+            this.next = next;
+            this.value = value;
+        }
+
+        @SuppressWarnings("unchecked")
+        static final <K,V> HashEntry<K,V>[] newArray(int i) {
+            return new HashEntry[i];
+        }
+    }
+
+    /**
      * Segments are specialized versions of hash tables.  This
      * subclasses from ReentrantLock opportunistically, just to
      * simplify some locking and avoid separate construction.
-     **/
+     */
     static final class Segment<K,V> extends ReentrantLock implements Serializable {
         /*
          * Segments maintain a table of entry lists that are ALWAYS
@@ -179,58 +223,59 @@
          * is less than two for the default load factor threshold.)
          *
          * Read operations can thus proceed without locking, but rely
-         * on a memory barrier to ensure that completed write
-         * operations performed by other threads are
-         * noticed. Conveniently, the "count" field, tracking the
-         * number of elements, can also serve as the volatile variable
-         * providing proper read/write barriers. This is convenient
-         * because this field needs to be read in many read operations
-         * anyway. 
+         * on selected uses of volatiles to ensure that completed
+         * write operations performed by other threads are
+         * noticed. For most purposes, the "count" field, tracking the
+         * number of elements, serves as that volatile variable
+         * ensuring visibility.  This is convenient because this field
+         * needs to be read in many read operations anyway:
          *
-         * Implementors note. The basic rules for all this are:
-         *
-         *   - All unsynchronized read operations must first read the
+         *   - All (unsynchronized) read operations must first read the
          *     "count" field, and should not look at table entries if
          *     it is 0.
          *
-         *   - All synchronized write operations should write to
-         *     the "count" field after updating. The operations must not
-         *     take any action that could even momentarily cause
-         *     a concurrent read operation to see inconsistent
-         *     data. This is made easier by the nature of the read
-         *     operations in Map. For example, no operation
+         *   - All (synchronized) write operations should write to
+         *     the "count" field after structurally changing any bin.
+         *     The operations must not take any action that could even
+         *     momentarily cause a concurrent read operation to see
+         *     inconsistent data. This is made easier by the nature of
+         *     the read operations in Map. For example, no operation
          *     can reveal that the table has grown but the threshold
          *     has not yet been updated, so there are no atomicity
          *     requirements for this with respect to reads.
          *
-         * As a guide, all critical volatile reads and writes are marked
-         * in code comments.
+         * As a guide, all critical volatile reads and writes to the
+         * count field are marked in code comments.
          */
 
         private static final long serialVersionUID = 2249069246763182397L;
 
         /**
          * The number of elements in this segment's region.
-         **/
+         */
         transient volatile int count;
 
         /**
-         * Number of updates; used for checking lack of modifications
-         * in bulk-read methods.
+         * Number of updates that alter the size of the table. This is
+         * used during bulk-read methods to make sure they see a
+         * consistent snapshot: If modCounts change during a traversal
+         * of segments computing size or checking containsValue, then
+         * we might have an inconsistent view of state so (usually)
+         * must retry.
          */
         transient int modCount;
 
         /**
          * The table is rehashed when its size exceeds this threshold.
-         * (The value of this field is always (int)(capacity *
-         * loadFactor).)
+         * (The value of this field is always <tt>(int)(capacity *
+         * loadFactor)</tt>.)
          */
         transient int threshold;
 
         /**
-         * The per-segment table
+         * The per-segment table.
          */
-        transient HashEntry[] table;
+        transient volatile HashEntry<K,V>[] table;
 
         /**
          * The load factor for the hash table.  Even though this value
@@ -242,29 +287,59 @@
 
         Segment(int initialCapacity, float lf) {
             loadFactor = lf;
-            setTable(new HashEntry[initialCapacity]);
+            setTable(HashEntry.<K,V>newArray(initialCapacity));
+        }
+
+        @SuppressWarnings("unchecked")
+        static final <K,V> Segment<K,V>[] newArray(int i) {
+            return new Segment[i];
         }
 
         /**
-         * Set table to new HashEntry array.
+         * Sets table to new HashEntry array.
          * Call only while holding lock or in constructor.
-         **/
-        void setTable(HashEntry[] newTable) {
-            table = newTable;
+         */
+        void setTable(HashEntry<K,V>[] newTable) {
             threshold = (int)(newTable.length * loadFactor);
-            count = count; // write-volatile
+            table = newTable;
+        }
+
+        /**
+         * Returns properly casted first entry of bin for given hash.
+         */
+        HashEntry<K,V> getFirst(int hash) {
+            HashEntry<K,V>[] tab = table;
+            return tab[hash & (tab.length - 1)];
+        }
+
+        /**
+         * Reads value field of an entry under lock. Called if value
+         * field ever appears to be null. This is possible only if a
+         * compiler happens to reorder a HashEntry initialization with
+         * its table assignment, which is legal under memory model
+         * but is not known to ever occur.
+         */
+        V readValueUnderLock(HashEntry<K,V> e) {
+            lock();
+            try {
+                return e.value;
+            } finally {
+                unlock();
+            }
         }
 
         /* Specialized implementations of map methods */
 
         V get(Object key, int hash) {
             if (count != 0) { // read-volatile
-                HashEntry[] tab = table;
-                int index = hash & (tab.length - 1);
-                HashEntry<K,V> e = (HashEntry<K,V>) tab[index];
+                HashEntry<K,V> e = getFirst(hash);
                 while (e != null) {
-                    if (e.hash == hash && key.equals(e.key))
-                        return e.value;
+                    if (e.hash == hash && key.equals(e.key)) {
+                        V v = e.value;
+                        if (v != null)
+                            return v;
+                        return readValueUnderLock(e); // recheck
+                    }
                     e = e.next;
                 }
             }
@@ -273,9 +348,7 @@
 
         boolean containsKey(Object key, int hash) {
             if (count != 0) { // read-volatile
-                HashEntry[] tab = table;
-                int index = hash & (tab.length - 1);
-                HashEntry<K,V> e = (HashEntry<K,V>) tab[index];
+                HashEntry<K,V> e = getFirst(hash);
                 while (e != null) {
                     if (e.hash == hash && key.equals(e.key))
                         return true;
@@ -287,12 +360,17 @@
 
         boolean containsValue(Object value) {
             if (count != 0) { // read-volatile
-                HashEntry[] tab = table;
+                HashEntry<K,V>[] tab = table;
                 int len = tab.length;
-                for (int i = 0 ; i < len; i++)
-                    for (HashEntry<K,V> e = (HashEntry<K,V>)tab[i] ; e != null ; e = e.next)
-                        if (value.equals(e.value))
+                for (int i = 0 ; i < len; i++) {
+                    for (HashEntry<K,V> e = tab[i]; e != null; e = e.next) {
+                        V v = e.value;
+                        if (v == null) // recheck
+                            v = readValueUnderLock(e);
+                        if (value.equals(v))
                             return true;
+                    }
+                }
             }
             return false;
         }
@@ -300,27 +378,16 @@
         boolean replace(K key, int hash, V oldValue, V newValue) {
             lock();
             try {
-                int c = count;
-                HashEntry[] tab = table;
-                int index = hash & (tab.length - 1);
-                HashEntry<K,V> first = (HashEntry<K,V>) tab[index];
-                HashEntry<K,V> e = first;
-                for (;;) {
-                    if (e == null)
-                        return false;
-                    if (e.hash == hash && key.equals(e.key))
-                        break;
+                HashEntry<K,V> e = getFirst(hash);
+                while (e != null && (e.hash != hash || !key.equals(e.key)))
                     e = e.next;
+
+                boolean replaced = false;
+                if (e != null && oldValue.equals(e.value)) {
+                    replaced = true;
+                    e.value = newValue;
                 }
-
-                V v = e.value;
-                if (v == null || !oldValue.equals(v))
-                    return false;
-
-                e.value = newValue;
-                count = c; // write-volatile
-                return true;
-                
+                return replaced;
             } finally {
                 unlock();
             }
@@ -329,24 +396,16 @@
         V replace(K key, int hash, V newValue) {
             lock();
             try {
-                int c = count;
-                HashEntry[] tab = table;
-                int index = hash & (tab.length - 1);
-                HashEntry<K,V> first = (HashEntry<K,V>) tab[index];
-                HashEntry<K,V> e = first;
-                for (;;) {
-                    if (e == null)
-                        return null;
-                    if (e.hash == hash && key.equals(e.key))
-                        break;
+                HashEntry<K,V> e = getFirst(hash);
+                while (e != null && (e.hash != hash || !key.equals(e.key)))
                     e = e.next;
-                }
 
-                V v = e.value;
-                e.value = newValue;
-                count = c; // write-volatile
-                return v;
-                
+                V oldValue = null;
+                if (e != null) {
+                    oldValue = e.value;
+                    e.value = newValue;
+                }
+                return oldValue;
             } finally {
                 unlock();
             }
@@ -357,37 +416,38 @@
             lock();
             try {
                 int c = count;
-                HashEntry[] tab = table;
+                if (c++ > threshold) // ensure capacity
+                    rehash();
+                HashEntry<K,V>[] tab = table;
                 int index = hash & (tab.length - 1);
-                HashEntry<K,V> first = (HashEntry<K,V>) tab[index];
+                HashEntry<K,V> first = tab[index];
+                HashEntry<K,V> e = first;
+                while (e != null && (e.hash != hash || !key.equals(e.key)))
+                    e = e.next;
 
-                for (HashEntry<K,V> e = first; e != null; e = (HashEntry<K,V>) e.next) {
-                    if (e.hash == hash && key.equals(e.key)) {
-                        V oldValue = e.value;
-                        if (!onlyIfAbsent)
-                            e.value = value;
-                        ++modCount;
-                        count = c; // write-volatile
-                        return oldValue;
-                    }
+                V oldValue;
+                if (e != null) {
+                    oldValue = e.value;
+                    if (!onlyIfAbsent)
+                        e.value = value;
                 }
-
-                tab[index] = new HashEntry<K,V>(hash, key, value, first);
-                ++modCount;
-                ++c;
-                count = c; // write-volatile
-                if (c > threshold)
-                    setTable(rehash(tab));
-                return null;
+                else {
+                    oldValue = null;
+                    ++modCount;
+                    tab[index] = new HashEntry<K,V>(key, hash, first, value);
+                    count = c; // write-volatile
+                }
+                return oldValue;
             } finally {
                 unlock();
             }
         }
 
-        HashEntry[] rehash(HashEntry[] oldTable) {
+        void rehash() {
+            HashEntry<K,V>[] oldTable = table;
             int oldCapacity = oldTable.length;
             if (oldCapacity >= MAXIMUM_CAPACITY)
-                return oldTable;
+                return;
 
             /*
              * Reclassify nodes in each list to new Map.  Because we are
@@ -403,12 +463,13 @@
              * right now.
              */
 
-            HashEntry[] newTable = new HashEntry[oldCapacity << 1];
+            HashEntry<K,V>[] newTable = HashEntry.newArray(oldCapacity<<1);
+            threshold = (int)(newTable.length * loadFactor);
             int sizeMask = newTable.length - 1;
             for (int i = 0; i < oldCapacity ; i++) {
                 // We need to guarantee that any existing reads of old Map can
                 //  proceed. So we cannot yet null out each bin.
-                HashEntry<K,V> e = (HashEntry<K,V>)oldTable[i];
+                HashEntry<K,V> e = oldTable[i];
 
                 if (e != null) {
                     HashEntry<K,V> next = e.next;
@@ -436,15 +497,14 @@
                         // Clone all remaining nodes
                         for (HashEntry<K,V> p = e; p != lastRun; p = p.next) {
                             int k = p.hash & sizeMask;
-                            newTable[k] = new HashEntry<K,V>(p.hash,
-                                                             p.key,
-                                                             p.value,
-                                                             (HashEntry<K,V>) newTable[k]);
+                            HashEntry<K,V> n = newTable[k];
+                            newTable[k] = new HashEntry<K,V>(p.key, p.hash,
+                                                             n, p.value);
                         }
                     }
                 }
             }
-            return newTable;
+            table = newTable;
         }
 
         /**
@@ -453,33 +513,31 @@
         V remove(Object key, int hash, Object value) {
             lock();
             try {
-                int c = count;
-                HashEntry[] tab = table;
+                int c = count - 1;
+                HashEntry<K,V>[] tab = table;
                 int index = hash & (tab.length - 1);
-                HashEntry<K,V> first = (HashEntry<K,V>)tab[index];
-
+                HashEntry<K,V> first = tab[index];
                 HashEntry<K,V> e = first;
-                for (;;) {
-                    if (e == null)
-                        return null;
-                    if (e.hash == hash && key.equals(e.key))
-                        break;
+                while (e != null && (e.hash != hash || !key.equals(e.key)))
                     e = e.next;
+
+                V oldValue = null;
+                if (e != null) {
+                    V v = e.value;
+                    if (value == null || value.equals(v)) {
+                        oldValue = v;
+                        // All entries following removed node can stay
+                        // in list, but all preceding ones need to be
+                        // cloned.
+                        ++modCount;
+                        HashEntry<K,V> newFirst = e.next;
+                        for (HashEntry<K,V> p = first; p != e; p = p.next)
+                            newFirst = new HashEntry<K,V>(p.key, p.hash,
+                                                          newFirst, p.value);
+                        tab[index] = newFirst;
+                        count = c; // write-volatile
+                    }
                 }
-
-                V oldValue = e.value;
-                if (value != null && !value.equals(oldValue))
-                    return null;
-
-                // All entries following removed node can stay in list, but
-                // all preceding ones need to be cloned.
-                HashEntry<K,V> newFirst = e.next;
-                for (HashEntry<K,V> p = first; p != e; p = p.next)
-                    newFirst = new HashEntry<K,V>(p.hash, p.key,
-                                                  p.value, newFirst);
-                tab[index] = newFirst;
-                ++modCount;
-                count = c-1; // write-volatile
                 return oldValue;
             } finally {
                 unlock();
@@ -487,50 +545,37 @@
         }
 
         void clear() {
-            lock();
-            try {
-                HashEntry[] tab = table;
-                for (int i = 0; i < tab.length ; i++)
-                    tab[i] = null;
-                ++modCount;
-                count = 0; // write-volatile
-            } finally {
-                unlock();
+            if (count != 0) {
+                lock();
+                try {
+                    HashEntry<K,V>[] tab = table;
+                    for (int i = 0; i < tab.length ; i++)
+                        tab[i] = null;
+                    ++modCount;
+                    count = 0; // write-volatile
+                } finally {
+                    unlock();
+                }
             }
         }
     }
 
-    /**
-     * ConcurrentHashMap list entry. Note that this is never exported
-     * out as a user-visible Map.Entry
-     */
-    static final class HashEntry<K,V> {
-        final K key;
-        V value;
-        final int hash;
-        final HashEntry<K,V> next;
-
-        HashEntry(int hash, K key, V value, HashEntry<K,V> next) {
-            this.value = value;
-            this.hash = hash;
-            this.key = key;
-            this.next = next;
-        }
-    }
 
 
     /* ---------------- Public operations -------------- */
 
     /**
      * Creates a new, empty map with the specified initial
-     * capacity and the specified load factor.
+     * capacity, load factor and concurrency level.
      *
      * @param initialCapacity the initial capacity. The implementation
      * performs internal sizing to accommodate this many elements.
      * @param loadFactor  the load factor threshold, used to control resizing.
+     * Resizing may be performed when the average number of elements per
+     * bin exceeds this threshold.
      * @param concurrencyLevel the estimated number of concurrently
      * updating threads. The implementation performs internal sizing
-     * to try to accommodate this many threads.  
+     * to try to accommodate this many threads.
      * @throws IllegalArgumentException if the initial capacity is
      * negative or the load factor or concurrencyLevel are
      * nonpositive.
@@ -552,7 +597,7 @@
         }
         segmentShift = 32 - sshift;
         segmentMask = ssize - 1;
-        this.segments = new Segment[ssize];
+        this.segments = Segment.newArray(ssize);
 
         if (initialCapacity > MAXIMUM_CAPACITY)
             initialCapacity = MAXIMUM_CAPACITY;
@@ -568,44 +613,50 @@
     }
 
     /**
-     * Creates a new, empty map with the specified initial
-     * capacity,  and with default load factor and concurrencyLevel.
+     * Creates a new, empty map with the specified initial capacity,
+     * and with default load factor (0.75) and concurrencyLevel (16).
      *
-     * @param initialCapacity The implementation performs internal
-     * sizing to accommodate this many elements.
+     * @param initialCapacity the initial capacity. The implementation
+     * performs internal sizing to accommodate this many elements.
      * @throws IllegalArgumentException if the initial capacity of
      * elements is negative.
      */
     public ConcurrentHashMap(int initialCapacity) {
-        this(initialCapacity, DEFAULT_LOAD_FACTOR, DEFAULT_SEGMENTS);
+        this(initialCapacity, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL);
     }
 
     /**
-     * Creates a new, empty map with a default initial capacity,
-     * load factor, and concurrencyLevel.
+     * Creates a new, empty map with a default initial capacity (16),
+     * load factor (0.75) and concurrencyLevel (16).
      */
     public ConcurrentHashMap() {
-        this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_SEGMENTS);
+        this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL);
     }
 
     /**
-     * Creates a new map with the same mappings as the given map.  The
-     * map is created with a capacity of twice the number of mappings in
-     * the given map or 11 (whichever is greater), and a default load factor.
-     * @param t the map
+     * Creates a new map with the same mappings as the given map.
+     * The map is created with a capacity of 1.5 times the number
+     * of mappings in the given map or 16 (whichever is greater),
+     * and a default load factor (0.75) and concurrencyLevel (16).
+     *
+     * @param m the map
      */
-    public ConcurrentHashMap(Map<? extends K, ? extends V> t) {
-        this(Math.max((int) (t.size() / DEFAULT_LOAD_FACTOR) + 1,
-                      11),
-             DEFAULT_LOAD_FACTOR, DEFAULT_SEGMENTS);
-        putAll(t);
+    public ConcurrentHashMap(Map<? extends K, ? extends V> m) {
+        this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1,
+                      DEFAULT_INITIAL_CAPACITY),
+             DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL);
+        putAll(m);
     }
 
-    // inherit Map javadoc
+    /**
+     * Returns <tt>true</tt> if this map contains no key-value mappings.
+     *
+     * @return <tt>true</tt> if this map contains no key-value mappings
+     */
     public boolean isEmpty() {
-        final Segment[] segments = this.segments;
+        final Segment<K,V>[] segments = this.segments;
         /*
-         * We need to keep track of per-segment modCounts to avoid ABA
+         * We keep track of per-segment modCounts to avoid ABA
          * problems in which an element in one segment was added and
          * in another removed during traversal, in which case the
          * table was never actually empty at any point. Note the
@@ -618,7 +669,7 @@
         for (int i = 0; i < segments.length; ++i) {
             if (segments[i].count != 0)
                 return false;
-            else 
+            else
                 mcsum += mc[i] = segments[i].modCount;
         }
         // If mcsum happens to be zero, then we know we got a snapshot
@@ -627,25 +678,35 @@
         if (mcsum != 0) {
             for (int i = 0; i < segments.length; ++i) {
                 if (segments[i].count != 0 ||
-                    mc[i] != segments[i].modCount) 
+                    mc[i] != segments[i].modCount)
                     return false;
             }
         }
         return true;
     }
 
-    // inherit Map javadoc
+    /**
+     * Returns the number of key-value mappings in this map.  If the
+     * map contains more than <tt>Integer.MAX_VALUE</tt> elements, returns
+     * <tt>Integer.MAX_VALUE</tt>.
+     *
+     * @return the number of key-value mappings in this map
+     */
     public int size() {
-        final Segment[] segments = this.segments;
+        final Segment<K,V>[] segments = this.segments;
+        long sum = 0;
+        long check = 0;
         int[] mc = new int[segments.length];
-        for (;;) {
-            long sum = 0;
+        // Try a few times to get accurate count. On failure due to
+        // continuous async changes in table, resort to locking.
+        for (int k = 0; k < RETRIES_BEFORE_LOCK; ++k) {
+            check = 0;
+            sum = 0;
             int mcsum = 0;
             for (int i = 0; i < segments.length; ++i) {
                 sum += segments[i].count;
                 mcsum += mc[i] = segments[i].modCount;
             }
-            int check = 0;
             if (mcsum != 0) {
                 for (int i = 0; i < segments.length; ++i) {
                     check += segments[i].count;
@@ -655,43 +716,51 @@
                     }
                 }
             }
-            if (check == sum) {
-                if (sum > Integer.MAX_VALUE)
-                    return Integer.MAX_VALUE;
-                else
-                    return (int)sum;
-            }
+            if (check == sum)
+                break;
         }
+        if (check != sum) { // Resort to locking all segments
+            sum = 0;
+            for (int i = 0; i < segments.length; ++i)
+                segments[i].lock();
+            for (int i = 0; i < segments.length; ++i)
+                sum += segments[i].count;
+            for (int i = 0; i < segments.length; ++i)
+                segments[i].unlock();
+        }
+        if (sum > Integer.MAX_VALUE)
+            return Integer.MAX_VALUE;
+        else
+            return (int)sum;
     }
 
-
     /**
-     * Returns the value to which the specified key is mapped in this table.
+     * Returns the value to which the specified key is mapped,
+     * or {@code null} if this map contains no mapping for the key.
      *
-     * @param   key   a key in the table.
-     * @return  the value to which the key is mapped in this table;
-     *          <tt>null</tt> if the key is not mapped to any value in
-     *          this table.
-     * @throws  NullPointerException  if the key is
-     *               <tt>null</tt>.
+     * <p>More formally, if this map contains a mapping from a key
+     * {@code k} to a value {@code v} such that {@code key.equals(k)},
+     * then this method returns {@code v}; otherwise it returns
+     * {@code null}.  (There can be at most one such mapping.)
+     *
+     * @throws NullPointerException if the specified key is null
      */
     public V get(Object key) {
-        int hash = hash(key); // throws NullPointerException if key null
+        int hash = hash(key.hashCode());
         return segmentFor(hash).get(key, hash);
     }
 
     /**
      * Tests if the specified object is a key in this table.
      *
-     * @param   key   possible key.
-     * @return  <tt>true</tt> if and only if the specified object
-     *          is a key in this table, as determined by the
-     *          <tt>equals</tt> method; <tt>false</tt> otherwise.
-     * @throws  NullPointerException  if the key is
-     *               <tt>null</tt>.
+     * @param  key   possible key
+     * @return <tt>true</tt> if and only if the specified object
+     *         is a key in this table, as determined by the
+     *         <tt>equals</tt> method; <tt>false</tt> otherwise.
+     * @throws NullPointerException if the specified key is null
      */
     public boolean containsKey(Object key) {
-        int hash = hash(key); // throws NullPointerException if key null
+        int hash = hash(key.hashCode());
         return segmentFor(hash).containsKey(key, hash);
     }
 
@@ -701,18 +770,22 @@
      * traversal of the hash table, and so is much slower than
      * method <tt>containsKey</tt>.
      *
-     * @param value value whose presence in this map is to be tested.
+     * @param value value whose presence in this map is to be tested
      * @return <tt>true</tt> if this map maps one or more keys to the
-     * specified value.
-     * @throws  NullPointerException  if the value is <tt>null</tt>.
+     *         specified value
+     * @throws NullPointerException if the specified value is null
      */
     public boolean containsValue(Object value) {
         if (value == null)
             throw new NullPointerException();
 
-        final Segment[] segments = this.segments;
+        // See explanation of modCount use above
+
+        final Segment<K,V>[] segments = this.segments;
         int[] mc = new int[segments.length];
-        for (;;) {
+
+        // Try a few times without locking
+        for (int k = 0; k < RETRIES_BEFORE_LOCK; ++k) {
             int sum = 0;
             int mcsum = 0;
             for (int i = 0; i < segments.length; ++i) {
@@ -734,287 +807,217 @@
             if (cleanSweep)
                 return false;
         }
+        // Resort to locking all segments
+        for (int i = 0; i < segments.length; ++i)
+            segments[i].lock();
+        boolean found = false;
+        try {
+            for (int i = 0; i < segments.length; ++i) {
+                if (segments[i].containsValue(value)) {
+                    found = true;
+                    break;
+                }
+            }
+        } finally {
+            for (int i = 0; i < segments.length; ++i)
+                segments[i].unlock();
+        }
+        return found;
     }
 
     /**
      * Legacy method testing if some key maps into the specified value
      * in this table.  This method is identical in functionality to
-     * {@link #containsValue}, and  exists solely to ensure
+     * {@link #containsValue}, and exists solely to ensure
      * full compatibility with class {@link java.util.Hashtable},
      * which supported this method prior to introduction of the
      * Java Collections framework.
 
-     * @param      value   a value to search for.
-     * @return     <tt>true</tt> if and only if some key maps to the
-     *             <tt>value</tt> argument in this table as
-     *             determined by the <tt>equals</tt> method;
-     *             <tt>false</tt> otherwise.
-     * @throws  NullPointerException  if the value is <tt>null</tt>.
+     * @param  value a value to search for
+     * @return <tt>true</tt> if and only if some key maps to the
+     *         <tt>value</tt> argument in this table as
+     *         determined by the <tt>equals</tt> method;
+     *         <tt>false</tt> otherwise
+     * @throws NullPointerException if the specified value is null
      */
     public boolean contains(Object value) {
         return containsValue(value);
     }
 
     /**
-     * Maps the specified <tt>key</tt> to the specified
-     * <tt>value</tt> in this table. Neither the key nor the
-     * value can be <tt>null</tt>. 
+     * Maps the specified key to the specified value in this table.
+     * Neither the key nor the value can be null.
      *
      * <p> The value can be retrieved by calling the <tt>get</tt> method
      * with a key that is equal to the original key.
      *
-     * @param      key     the table key.
-     * @param      value   the value.
-     * @return     the previous value of the specified key in this table,
-     *             or <tt>null</tt> if it did not have one.
-     * @throws  NullPointerException  if the key or value is
-     *               <tt>null</tt>.
+     * @param key key with which the specified value is to be associated
+     * @param value value to be associated with the specified key
+     * @return the previous value associated with <tt>key</tt>, or
+     *         <tt>null</tt> if there was no mapping for <tt>key</tt>
+     * @throws NullPointerException if the specified key or value is null
      */
     public V put(K key, V value) {
         if (value == null)
             throw new NullPointerException();
-        int hash = hash(key);
+        int hash = hash(key.hashCode());
         return segmentFor(hash).put(key, hash, value, false);
     }
 
     /**
-     * If the specified key is not already associated
-     * with a value, associate it with the given value.
-     * This is equivalent to
-     * <pre>
-     *   if (!map.containsKey(key)) 
-     *      return map.put(key, value);
-     *   else
-     *      return map.get(key);
-     * </pre>
-     * Except that the action is performed atomically.
-     * @param key key with which the specified value is to be associated.
-     * @param value value to be associated with the specified key.
-     * @return previous value associated with specified key, or <tt>null</tt>
-     *         if there was no mapping for key.  A <tt>null</tt> return can
-     *         also indicate that the map previously associated <tt>null</tt>
-     *         with the specified key, if the implementation supports
-     *         <tt>null</tt> values.
+     * {@inheritDoc}
      *
-     * @throws UnsupportedOperationException if the <tt>put</tt> operation is
-     *            not supported by this map.
-     * @throws ClassCastException if the class of the specified key or value
-     *            prevents it from being stored in this map.
-     * @throws NullPointerException if the specified key or value is
-     *            <tt>null</tt>.
-     *
-     **/
+     * @return the previous value associated with the specified key,
+     *         or <tt>null</tt> if there was no mapping for the key
+     * @throws NullPointerException if the specified key or value is null
+     */
     public V putIfAbsent(K key, V value) {
         if (value == null)
             throw new NullPointerException();
-        int hash = hash(key);
+        int hash = hash(key.hashCode());
         return segmentFor(hash).put(key, hash, value, true);
     }
 
-
     /**
      * Copies all of the mappings from the specified map to this one.
-     *
      * These mappings replace any mappings that this map had for any of the
-     * keys currently in the specified Map.
+     * keys currently in the specified map.
      *
-     * @param t Mappings to be stored in this map.
+     * @param m mappings to be stored in this map
      */
-    public void putAll(Map<? extends K, ? extends V> t) {
-        for (Iterator<? extends Map.Entry<? extends K, ? extends V>> it = (Iterator<? extends Map.Entry<? extends K, ? extends V>>) t.entrySet().iterator(); it.hasNext(); ) {
-            Entry<? extends K, ? extends V> e = it.next();
+    public void putAll(Map<? extends K, ? extends V> m) {
+        for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
             put(e.getKey(), e.getValue());
-        }
     }
 
     /**
-     * Removes the key (and its corresponding value) from this
-     * table. This method does nothing if the key is not in the table.
+     * Removes the key (and its corresponding value) from this map.
+     * This method does nothing if the key is not in the map.
      *
-     * @param   key   the key that needs to be removed.
-     * @return  the value to which the key had been mapped in this table,
-     *          or <tt>null</tt> if the key did not have a mapping.
-     * @throws  NullPointerException  if the key is
-     *               <tt>null</tt>.
+     * @param  key the key that needs to be removed
+     * @return the previous value associated with <tt>key</tt>, or
+     *         <tt>null</tt> if there was no mapping for <tt>key</tt>
+     * @throws NullPointerException if the specified key is null
      */
     public V remove(Object key) {
-        int hash = hash(key);
+        int hash = hash(key.hashCode());
         return segmentFor(hash).remove(key, hash, null);
     }
 
     /**
-     * Remove entry for key only if currently mapped to given value.
-     * Acts as
-     * <pre> 
-     *  if (map.get(key).equals(value)) {
-     *     map.remove(key);
-     *     return true;
-     * } else return false;
-     * </pre>
-     * except that the action is performed atomically.
-     * @param key key with which the specified value is associated.
-     * @param value value associated with the specified key.
-     * @return true if the value was removed
-     * @throws NullPointerException if the specified key is
-     *            <tt>null</tt>.
+     * {@inheritDoc}
+     *
+     * @throws NullPointerException if the specified key is null
      */
     public boolean remove(Object key, Object value) {
-        int hash = hash(key);
+        int hash = hash(key.hashCode());
+        if (value == null)
+            return false;
         return segmentFor(hash).remove(key, hash, value) != null;
     }
 
-
     /**
-     * Replace entry for key only if currently mapped to given value.
-     * Acts as
-     * <pre> 
-     *  if (map.get(key).equals(oldValue)) {
-     *     map.put(key, newValue);
-     *     return true;
-     * } else return false;
-     * </pre>
-     * except that the action is performed atomically.
-     * @param key key with which the specified value is associated.
-     * @param oldValue value expected to be associated with the specified key.
-     * @param newValue value to be associated with the specified key.
-     * @return true if the value was replaced
-     * @throws NullPointerException if the specified key or values are
-     * <tt>null</tt>.
+     * {@inheritDoc}
+     *
+     * @throws NullPointerException if any of the arguments are null
      */
     public boolean replace(K key, V oldValue, V newValue) {
         if (oldValue == null || newValue == null)
             throw new NullPointerException();
-        int hash = hash(key);
+        int hash = hash(key.hashCode());
         return segmentFor(hash).replace(key, hash, oldValue, newValue);
     }
 
     /**
-     * Replace entry for key only if currently mapped to some value.
-     * Acts as
-     * <pre> 
-     *  if ((map.containsKey(key)) {
-     *     return map.put(key, value);
-     * } else return null;
-     * </pre>
-     * except that the action is performed atomically.
-     * @param key key with which the specified value is associated.
-     * @param value value to be associated with the specified key.
-     * @return previous value associated with specified key, or <tt>null</tt>
-     *         if there was no mapping for key.  
-     * @throws NullPointerException if the specified key or value is
-     *            <tt>null</tt>.
+     * {@inheritDoc}
+     *
+     * @return the previous value associated with the specified key,
+     *         or <tt>null</tt> if there was no mapping for the key
+     * @throws NullPointerException if the specified key or value is null
      */
     public V replace(K key, V value) {
         if (value == null)
             throw new NullPointerException();
-        int hash = hash(key);
+        int hash = hash(key.hashCode());
         return segmentFor(hash).replace(key, hash, value);
     }
 
-
     /**
-     * Removes all mappings from this map.
+     * Removes all of the mappings from this map.
      */
     public void clear() {
         for (int i = 0; i < segments.length; ++i)
             segments[i].clear();
     }
 
-
-    // BEGIN android-removed
-    // /**
-    //  * Returns a shallow copy of this
-    //  * <tt>ConcurrentHashMap</tt> instance: the keys and
-    //  * values themselves are not cloned.
-    //  *
-    //  * @return a shallow copy of this map.
-    //  */
-    // public Object clone() {
-    //     // We cannot call super.clone, since it would share final
-    //     // segments array, and there's no way to reassign finals.
-    //
-    //     float lf = segments[0].loadFactor;
-    //     int segs = segments.length;
-    //     int cap = (int)(size() / lf);
-    //     if (cap < segs) cap = segs;
-    //     ConcurrentHashMap<K,V> t = new ConcurrentHashMap<K,V>(cap, lf, segs);
-    //     t.putAll(this);
-    //     return t;
-    // }
-    // END android-changed
-
     /**
-     * Returns a set view of the keys contained in this map.  The set is
-     * backed by the map, so changes to the map are reflected in the set, and
-     * vice-versa.  The set supports element removal, which removes the
-     * corresponding mapping from this map, via the <tt>Iterator.remove</tt>,
-     * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt>, and
-     * <tt>clear</tt> operations.  It does not support the <tt>add</tt> or
+     * Returns a {@link Set} view of the keys contained in this map.
+     * The set is backed by the map, so changes to the map are
+     * reflected in the set, and vice-versa.  The set supports element
+     * removal, which removes the corresponding mapping from this map,
+     * via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
+     * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt>
+     * operations.  It does not support the <tt>add</tt> or
      * <tt>addAll</tt> operations.
-     * The returned <tt>iterator</tt> is a "weakly consistent" iterator that
-     * will never throw {@link java.util.ConcurrentModificationException},
+     *
+     * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator
+     * that will never throw {@link ConcurrentModificationException},
      * and guarantees to traverse elements as they existed upon
      * construction of the iterator, and may (but is not guaranteed to)
      * reflect any modifications subsequent to construction.
-     *
-     * @return a set view of the keys contained in this map.
      */
     public Set<K> keySet() {
         Set<K> ks = keySet;
         return (ks != null) ? ks : (keySet = new KeySet());
     }
 
-
     /**
-     * Returns a collection view of the values contained in this map.  The
-     * collection is backed by the map, so changes to the map are reflected in
-     * the collection, and vice-versa.  The collection supports element
-     * removal, which removes the corresponding mapping from this map, via the
-     * <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
-     * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
-     * It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
-     * The returned <tt>iterator</tt> is a "weakly consistent" iterator that
-     * will never throw {@link java.util.ConcurrentModificationException},
+     * Returns a {@link Collection} view of the values contained in this map.
+     * The collection is backed by the map, so changes to the map are
+     * reflected in the collection, and vice-versa.  The collection
+     * supports element removal, which removes the corresponding
+     * mapping from this map, via the <tt>Iterator.remove</tt>,
+     * <tt>Collection.remove</tt>, <tt>removeAll</tt>,
+     * <tt>retainAll</tt>, and <tt>clear</tt> operations.  It does not
+     * support the <tt>add</tt> or <tt>addAll</tt> operations.
+     *
+     * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator
+     * that will never throw {@link ConcurrentModificationException},
      * and guarantees to traverse elements as they existed upon
      * construction of the iterator, and may (but is not guaranteed to)
      * reflect any modifications subsequent to construction.
-     *
-     * @return a collection view of the values contained in this map.
      */
     public Collection<V> values() {
         Collection<V> vs = values;
         return (vs != null) ? vs : (values = new Values());
     }
 
-
     /**
-     * Returns a collection view of the mappings contained in this map.  Each
-     * element in the returned collection is a <tt>Map.Entry</tt>.  The
-     * collection is backed by the map, so changes to the map are reflected in
-     * the collection, and vice-versa.  The collection supports element
-     * removal, which removes the corresponding mapping from the map, via the
-     * <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
-     * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
-     * It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
-     * The returned <tt>iterator</tt> is a "weakly consistent" iterator that
-     * will never throw {@link java.util.ConcurrentModificationException},
+     * Returns a {@link Set} view of the mappings contained in this map.
+     * The set is backed by the map, so changes to the map are
+     * reflected in the set, and vice-versa.  The set supports element
+     * removal, which removes the corresponding mapping from the map,
+     * via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
+     * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt>
+     * operations.  It does not support the <tt>add</tt> or
+     * <tt>addAll</tt> operations.
+     *
+     * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator
+     * that will never throw {@link ConcurrentModificationException},
      * and guarantees to traverse elements as they existed upon
      * construction of the iterator, and may (but is not guaranteed to)
      * reflect any modifications subsequent to construction.
-     *
-     * @return a collection view of the mappings contained in this map.
      */
     public Set<Map.Entry<K,V>> entrySet() {
         Set<Map.Entry<K,V>> es = entrySet;
-        return (es != null) ? es : (entrySet = (Set<Map.Entry<K,V>>) (Set) new EntrySet());
+        return (es != null) ? es : (entrySet = new EntrySet());
     }
 
-
     /**
      * Returns an enumeration of the keys in this table.
      *
-     * @return  an enumeration of the keys in this table.
-     * @see     #keySet
+     * @return an enumeration of the keys in this table
+     * @see #keySet()
      */
     public Enumeration<K> keys() {
         return new KeyIterator();
@@ -1023,8 +1026,8 @@
     /**
      * Returns an enumeration of the values in this table.
      *
-     * @return  an enumeration of the values in this table.
-     * @see     #values
+     * @return an enumeration of the values in this table
+     * @see #values()
      */
     public Enumeration<V> elements() {
         return new ValueIterator();
@@ -1035,7 +1038,7 @@
     abstract class HashIterator {
         int nextSegmentIndex;
         int nextTableIndex;
-        HashEntry[] currentTable;
+        HashEntry<K,V>[] currentTable;
         HashEntry<K, V> nextEntry;
         HashEntry<K, V> lastReturned;
 
@@ -1052,16 +1055,16 @@
                 return;
 
             while (nextTableIndex >= 0) {
-                if ( (nextEntry = (HashEntry<K,V>)currentTable[nextTableIndex--]) != null)
+                if ( (nextEntry = currentTable[nextTableIndex--]) != null)
                     return;
             }
 
             while (nextSegmentIndex >= 0) {
-                Segment<K,V> seg = (Segment<K,V>)segments[nextSegmentIndex--];
+                Segment<K,V> seg = segments[nextSegmentIndex--];
                 if (seg.count != 0) {
                     currentTable = seg.table;
                     for (int j = currentTable.length - 1; j >= 0; --j) {
-                        if ( (nextEntry = (HashEntry<K,V>)currentTable[j]) != null) {
+                        if ( (nextEntry = currentTable[j]) != null) {
                             nextTableIndex = j - 1;
                             return;
                         }
@@ -1088,81 +1091,58 @@
         }
     }
 
-    final class KeyIterator extends HashIterator implements Iterator<K>, Enumeration<K> {
-        public K next() { return super.nextEntry().key; }
+    final class KeyIterator
+        extends HashIterator
+        implements Iterator<K>, Enumeration<K>
+    {
+        public K next()        { return super.nextEntry().key; }
         public K nextElement() { return super.nextEntry().key; }
     }
 
-    final class ValueIterator extends HashIterator implements Iterator<V>, Enumeration<V> {
-        public V next() { return super.nextEntry().value; }
+    final class ValueIterator
+        extends HashIterator
+        implements Iterator<V>, Enumeration<V>
+    {
+        public V next()        { return super.nextEntry().value; }
         public V nextElement() { return super.nextEntry().value; }
     }
 
-    
-
     /**
-     * Entry iterator. Exported Entry objects must write-through
-     * changes in setValue, even if the nodes have been cloned. So we
-     * cannot return internal HashEntry objects. Instead, the iterator
-     * itself acts as a forwarding pseudo-entry.
+     * Custom Entry class used by EntryIterator.next(), that relays
+     * setValue changes to the underlying map.
      */
-    final class EntryIterator extends HashIterator implements Map.Entry<K,V>, Iterator<Entry<K,V>> {
-        public Map.Entry<K,V> next() {
-            nextEntry();
-            return this;
+    final class WriteThroughEntry
+        extends SimpleEntry<K,V>
+    {
+        WriteThroughEntry(K k, V v) {
+            super(k,v);
         }
 
-        public K getKey() {
-            if (lastReturned == null)
-                throw new IllegalStateException("Entry was removed");
-            return lastReturned.key;
-        }
-
-        public V getValue() {
-            if (lastReturned == null)
-                throw new IllegalStateException("Entry was removed");
-            return ConcurrentHashMap.this.get(lastReturned.key);
-        }
-
+        /**
+         * Set our entry's value and write through to the map. The
+         * value to return is somewhat arbitrary here. Since a
+         * WriteThroughEntry does not necessarily track asynchronous
+         * changes, the most recent "previous" value could be
+         * different from what we return (or could even have been
+         * removed in which case the put will re-establish). We do not
+         * and cannot guarantee more.
+         */
         public V setValue(V value) {
-            if (lastReturned == null)
-                throw new IllegalStateException("Entry was removed");
-            return ConcurrentHashMap.this.put(lastReturned.key, value);
+            if (value == null) throw new NullPointerException();
+            V v = super.setValue(value);
+            ConcurrentHashMap.this.put(getKey(), value);
+            return v;
         }
+    }
 
-        public boolean equals(Object o) {
-            // If not acting as entry, just use default.
-            if (lastReturned == null)
-                return super.equals(o);
-            if (!(o instanceof Map.Entry))
-                return false;
-            Map.Entry e = (Map.Entry)o;
-            return eq(getKey(), e.getKey()) && eq(getValue(), e.getValue());
+    final class EntryIterator
+        extends HashIterator
+        implements Iterator<Entry<K,V>>
+    {
+        public Map.Entry<K,V> next() {
+            HashEntry<K,V> e = super.nextEntry();
+            return new WriteThroughEntry(e.key, e.value);
         }
-
-        public int hashCode() {
-            // If not acting as entry, just use default.
-            if (lastReturned == null)
-                return super.hashCode();
-
-            Object k = getKey();
-            Object v = getValue();
-            return ((k == null) ? 0 : k.hashCode()) ^
-                   ((v == null) ? 0 : v.hashCode());
-        }
-
-        public String toString() {
-            // If not acting as entry, just use default.
-            if (lastReturned == null)
-                return super.toString();
-            else
-                return getKey() + "=" + getValue();
-        }
-
-        boolean eq(Object o1, Object o2) {
-            return (o1 == null ? o2 == null : o1.equals(o2));
-        }
-
     }
 
     final class KeySet extends AbstractSet<K> {
@@ -1172,6 +1152,9 @@
         public int size() {
             return ConcurrentHashMap.this.size();
         }
+        public boolean isEmpty() {
+            return ConcurrentHashMap.this.isEmpty();
+        }
         public boolean contains(Object o) {
             return ConcurrentHashMap.this.containsKey(o);
         }
@@ -1190,6 +1173,9 @@
         public int size() {
             return ConcurrentHashMap.this.size();
         }
+        public boolean isEmpty() {
+            return ConcurrentHashMap.this.isEmpty();
+        }
         public boolean contains(Object o) {
             return ConcurrentHashMap.this.containsValue(o);
         }
@@ -1205,44 +1191,32 @@
         public boolean contains(Object o) {
             if (!(o instanceof Map.Entry))
                 return false;
-            Map.Entry<K,V> e = (Map.Entry<K,V>)o;
+            Map.Entry<?,?> e = (Map.Entry<?,?>)o;
             V v = ConcurrentHashMap.this.get(e.getKey());
             return v != null && v.equals(e.getValue());
         }
         public boolean remove(Object o) {
             if (!(o instanceof Map.Entry))
                 return false;
-            Map.Entry<K,V> e = (Map.Entry<K,V>)o;
+            Map.Entry<?,?> e = (Map.Entry<?,?>)o;
             return ConcurrentHashMap.this.remove(e.getKey(), e.getValue());
         }
         public int size() {
             return ConcurrentHashMap.this.size();
         }
+        public boolean isEmpty() {
+            return ConcurrentHashMap.this.isEmpty();
+        }
         public void clear() {
             ConcurrentHashMap.this.clear();
         }
-        public Object[] toArray() {
-            // Since we don't ordinarily have distinct Entry objects, we
-            // must pack elements using exportable SimpleEntry
-            Collection<Map.Entry<K,V>> c = new ArrayList<Map.Entry<K,V>>(size());
-            for (Iterator<Map.Entry<K,V>> i = iterator(); i.hasNext(); )
-                c.add(new SimpleEntry<K,V>(i.next()));
-            return c.toArray();
-        }
-        public <T> T[] toArray(T[] a) {
-            Collection<Map.Entry<K,V>> c = new ArrayList<Map.Entry<K,V>>(size());
-            for (Iterator<Map.Entry<K,V>> i = iterator(); i.hasNext(); )
-                c.add(new SimpleEntry<K,V>(i.next()));
-            return c.toArray(a);
-        }
-
     }
 
     /**
      * This duplicates java.util.AbstractMap.SimpleEntry until this class
      * is made accessible.
      */
-    static final class SimpleEntry<K,V> implements Entry<K,V> {
+    static class SimpleEntry<K,V> implements Entry<K,V> {
         K key;
         V value;
 
@@ -1279,7 +1253,7 @@
 
         public int hashCode() {
             return ((key   == null)   ? 0 :   key.hashCode()) ^
-                   ((value == null)   ? 0 : value.hashCode());
+                    ((value == null)   ? 0 : value.hashCode());
         }
 
         public String toString() {
@@ -1291,12 +1265,11 @@
         }
     }
 
-    /* ---------------- Serialization Support -------------- */
+   /* ---------------- Serialization Support -------------- */
 
     /**
-     * Save the state of the <tt>ConcurrentHashMap</tt>
-     * instance to a stream (i.e.,
-     * serialize it).
+     * Save the state of the <tt>ConcurrentHashMap</tt> instance to a
+     * stream (i.e., serialize it).
      * @param s the stream
      * @serialData
      * the key (Object) and value (Object)
@@ -1307,12 +1280,12 @@
         s.defaultWriteObject();
 
         for (int k = 0; k < segments.length; ++k) {
-            Segment<K,V> seg = (Segment<K,V>)segments[k];
+            Segment<K,V> seg = segments[k];
             seg.lock();
             try {
-                HashEntry[] tab = seg.table;
+                HashEntry<K,V>[] tab = seg.table;
                 for (int i = 0; i < tab.length; ++i) {
-                    for (HashEntry<K,V> e = (HashEntry<K,V>)tab[i]; e != null; e = e.next) {
+                    for (HashEntry<K,V> e = tab[i]; e != null; e = e.next) {
                         s.writeObject(e.key);
                         s.writeObject(e.value);
                     }
@@ -1326,9 +1299,8 @@
     }
 
     /**
-     * Reconstitute the <tt>ConcurrentHashMap</tt>
-     * instance from a stream (i.e.,
-     * deserialize it).
+     * Reconstitute the <tt>ConcurrentHashMap</tt> instance from a
+     * stream (i.e., deserialize it).
      * @param s the stream
      */
     private void readObject(java.io.ObjectInputStream s)
@@ -1350,4 +1322,3 @@
         }
     }
 }
-
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java b/libcore/concurrent/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java
index 794142d..2253823 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java
@@ -14,7 +14,7 @@
 // END android-note
 
 /**
- * An unbounded thread-safe {@linkplain Queue queue} based on linked nodes.  
+ * An unbounded thread-safe {@linkplain Queue queue} based on linked nodes.
  * This queue orders elements FIFO (first-in-first-out).
  * The <em>head</em> of the queue is that element that has been on the
  * queue the longest time.
@@ -22,23 +22,31 @@
  * queue the shortest time. New elements
  * are inserted at the tail of the queue, and the queue retrieval
  * operations obtain elements at the head of the queue.
- * A <tt>ConcurrentLinkedQueue</tt> is an appropriate choice when 
+ * A {@code ConcurrentLinkedQueue} is an appropriate choice when
  * many threads will share access to a common collection.
- * This queue does not permit <tt>null</tt> elements.
+ * This queue does not permit {@code null} elements.
  *
- * <p>This implementation employs an efficient &quot;wait-free&quot; 
+ * <p>This implementation employs an efficient &quot;wait-free&quot;
  * algorithm based on one described in <a
  * href="http://www.cs.rochester.edu/u/michael/PODC96.html"> Simple,
  * Fast, and Practical Non-Blocking and Blocking Concurrent Queue
  * Algorithms</a> by Maged M. Michael and Michael L. Scott.
  *
- * <p>Beware that, unlike in most collections, the <tt>size</tt> method
+ * <p>Beware that, unlike in most collections, the {@code size} method
  * is <em>NOT</em> a constant-time operation. Because of the
  * asynchronous nature of these queues, determining the current number
  * of elements requires a traversal of the elements.
  *
- * <p>This class implements all of the <em>optional</em> methods
- * of the {@link Collection} and {@link Iterator} interfaces.
+ * <p>This class and its iterator implement all of the
+ * <em>optional</em> methods of the {@link Collection} and {@link
+ * Iterator} interfaces.
+ *
+ * <p>Memory consistency effects: As with other concurrent
+ * collections, actions in a thread prior to placing an object into a
+ * {@code ConcurrentLinkedQueue}
+ * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
+ * actions subsequent to the access or removal of that element from
+ * the {@code ConcurrentLinkedQueue} in another thread.
  *
  * @since 1.5
  * @author Doug Lea
@@ -50,68 +58,126 @@
     private static final long serialVersionUID = 196745693267521676L;
 
     /*
-     * This is a straight adaptation of Michael & Scott algorithm.
-     * For explanation, read the paper.  The only (minor) algorithmic
-     * difference is that this version supports lazy deletion of
-     * internal nodes (method remove(Object)) -- remove CAS'es item
-     * fields to null. The normal queue operations unlink but then
-     * pass over nodes with null item fields. Similarly, iteration
-     * methods ignore those with nulls.
+     * This is a modification of the Michael & Scott algorithm,
+     * adapted for a garbage-collected environment, with support for
+     * interior node deletion (to support remove(Object)).  For
+     * explanation, read the paper.
+     *
+     * Note that like most non-blocking algorithms in this package,
+     * this implementation relies on the fact that in garbage
+     * collected systems, there is no possibility of ABA problems due
+     * to recycled nodes, so there is no need to use "counted
+     * pointers" or related techniques seen in versions used in
+     * non-GC'ed settings.
+     *
+     * The fundamental invariants are:
+     * - There is exactly one (last) Node with a null next reference,
+     *   which is CASed when enqueueing.  This last Node can be
+     *   reached in O(1) time from tail, but tail is merely an
+     *   optimization - it can always be reached in O(N) time from
+     *   head as well.
+     * - The elements contained in the queue are the non-null items in
+     *   Nodes that are reachable from head.  CASing the item
+     *   reference of a Node to null atomically removes it from the
+     *   queue.  Reachability of all elements from head must remain
+     *   true even in the case of concurrent modifications that cause
+     *   head to advance.  A dequeued Node may remain in use
+     *   indefinitely due to creation of an Iterator or simply a
+     *   poll() that has lost its time slice.
+     *
+     * The above might appear to imply that all Nodes are GC-reachable
+     * from a predecessor dequeued Node.  That would cause two problems:
+     * - allow a rogue Iterator to cause unbounded memory retention
+     * - cause cross-generational linking of old Nodes to new Nodes if
+     *   a Node was tenured while live, which generational GCs have a
+     *   hard time dealing with, causing repeated major collections.
+     * However, only non-deleted Nodes need to be reachable from
+     * dequeued Nodes, and reachability does not necessarily have to
+     * be of the kind understood by the GC.  We use the trick of
+     * linking a Node that has just been dequeued to itself.  Such a
+     * self-link implicitly means to advance to head.
+     *
+     * Both head and tail are permitted to lag.  In fact, failing to
+     * update them every time one could is a significant optimization
+     * (fewer CASes). This is controlled by local "hops" variables
+     * that only trigger helping-CASes after experiencing multiple
+     * lags.
+     *
+     * Since head and tail are updated concurrently and independently,
+     * it is possible for tail to lag behind head (why not)?
+     *
+     * CASing a Node's item reference to null atomically removes the
+     * element from the queue.  Iterators skip over Nodes with null
+     * items.  Prior implementations of this class had a race between
+     * poll() and remove(Object) where the same element would appear
+     * to be successfully removed by two concurrent operations.  The
+     * method remove(Object) also lazily unlinks deleted Nodes, but
+     * this is merely an optimization.
+     *
+     * When constructing a Node (before enqueuing it) we avoid paying
+     * for a volatile write to item by using lazySet instead of a
+     * normal write.  This allows the cost of enqueue to be
+     * "one-and-a-half" CASes.
+     *
+     * Both head and tail may or may not point to a Node with a
+     * non-null item.  If the queue is empty, all items must of course
+     * be null.  Upon creation, both head and tail refer to a dummy
+     * Node with null item.  Both head and tail are only updated using
+     * CAS, so they never regress, although again this is merely an
+     * optimization.
      */
-
     private static class Node<E> {
         private volatile E item;
         private volatile Node<E> next;
-        
-        private static final 
-            AtomicReferenceFieldUpdater<Node, Node> 
+
+        private static final
+            AtomicReferenceFieldUpdater<Node, Node>
             nextUpdater =
             AtomicReferenceFieldUpdater.newUpdater
             (Node.class, Node.class, "next");
-        private static final 
-            AtomicReferenceFieldUpdater<Node, Object> 
+        private static final
+            AtomicReferenceFieldUpdater<Node, Object>
             itemUpdater =
             AtomicReferenceFieldUpdater.newUpdater
             (Node.class, Object.class, "item");
-        
-        Node(E x) { item = x; }
-        
-        Node(E x, Node<E> n) { item = x; next = n; }
-        
+
+
+        Node(E item) { setItem(item); }
+
         E getItem() {
             return item;
         }
-        
+
         boolean casItem(E cmp, E val) {
             return itemUpdater.compareAndSet(this, cmp, val);
         }
-        
+
         void setItem(E val) {
             itemUpdater.set(this, val);
         }
-        
+
         Node<E> getNext() {
             return next;
         }
-        
+
         boolean casNext(Node<E> cmp, Node<E> val) {
             return nextUpdater.compareAndSet(this, cmp, val);
         }
-        
+
         void setNext(Node<E> val) {
             nextUpdater.set(this, val);
-        }
-        
     }
 
-    private static final 
-        AtomicReferenceFieldUpdater<ConcurrentLinkedQueue, Node> 
-        tailUpdater = 
+    }
+
+    private static final
+        AtomicReferenceFieldUpdater<ConcurrentLinkedQueue, Node>
+        tailUpdater =
         AtomicReferenceFieldUpdater.newUpdater
         (ConcurrentLinkedQueue.class, Node.class, "tail");
-    private static final 
-        AtomicReferenceFieldUpdater<ConcurrentLinkedQueue, Node> 
-        headUpdater = 
+    private static final
+        AtomicReferenceFieldUpdater<ConcurrentLinkedQueue, Node>
+        headUpdater =
         AtomicReferenceFieldUpdater.newUpdater
         (ConcurrentLinkedQueue.class,  Node.class, "head");
 
@@ -124,118 +190,141 @@
     }
 
 
-    /**
-     * Pointer to header node, initialized to a dummy node.  The first
-     * actual node is at head.getNext().
-     */
-    private transient volatile Node<E> head = new Node<E>(null, null);
 
-    /** Pointer to last node on list **/
+    /**
+     * Pointer to first node, initialized to a dummy node.
+     */
+    private transient volatile Node<E> head = new Node<E>(null);
+
+    /** Pointer to last node on list */
     private transient volatile Node<E> tail = head;
 
 
     /**
-     * Creates a <tt>ConcurrentLinkedQueue</tt> that is initially empty.
+     * Creates a {@code ConcurrentLinkedQueue} that is initially empty.
      */
     public ConcurrentLinkedQueue() {}
 
     /**
-     * Creates a <tt>ConcurrentLinkedQueue</tt> 
+     * Creates a {@code ConcurrentLinkedQueue}
      * initially containing the elements of the given collection,
      * added in traversal order of the collection's iterator.
      * @param c the collection of elements to initially contain
-     * @throws NullPointerException if <tt>c</tt> or any element within it
-     * is <tt>null</tt>
+     * @throws NullPointerException if the specified collection or any
+     *         of its elements are null
      */
     public ConcurrentLinkedQueue(Collection<? extends E> c) {
         for (Iterator<? extends E> it = c.iterator(); it.hasNext();)
             add(it.next());
     }
 
-    // Have to override just to update the javadoc 
+    // Have to override just to update the javadoc
 
     /**
-     * Adds the specified element to the tail of this queue.
-     * @param o the element to add.
-     * @return <tt>true</tt> (as per the general contract of
-     * <tt>Collection.add</tt>).
+     * Inserts the specified element at the tail of this queue.
      *
-     * @throws NullPointerException if the specified element is <tt>null</tt>
+     * @return {@code true} (as specified by {@link Collection#add})
+     * @throws NullPointerException if the specified element is null
      */
-    public boolean add(E o) {
-        return offer(o);
+    public boolean add(E e) {
+        return offer(e);
     }
 
     /**
-     * Inserts the specified element to the tail of this queue.
-     *
-     * @param o the element to add.
-     * @return <tt>true</tt> (as per the general contract of
-     * <tt>Queue.offer</tt>).
-     * @throws NullPointerException if the specified element is <tt>null</tt>
+     * We don't bother to update head or tail pointers if less than
+     * HOPS links from "true" location.  We assume that volatile
+     * writes are significantly more expensive than volatile reads.
      */
-    public boolean offer(E o) {
-        if (o == null) throw new NullPointerException();
-        Node<E> n = new Node<E>(o, null);
-        for(;;) {
+    private static final int HOPS = 1;
+
+    /**
+     * Try to CAS head to p. If successful, repoint old head to itself
+     * as sentinel for succ(), below.
+     */
+    final void updateHead(Node<E> h, Node<E> p) {
+        if (h != p && casHead(h, p))
+            h.setNext(h);
+    }
+
+    /**
+     * Returns the successor of p, or the head node if p.next has been
+     * linked to self, which will only be true if traversing with a
+     * stale pointer that is now off the list.
+     */
+    final Node<E> succ(Node<E> p) {
+        Node<E> next = p.getNext();
+        return (p == next) ? head : next;
+    }
+
+    /**
+     * Inserts the specified element at the tail of this queue.
+     *
+     * @return {@code true} (as specified by {@link Queue#offer})
+     * @throws NullPointerException if the specified element is null
+     */
+    public boolean offer(E e) {
+        if (e == null) throw new NullPointerException();
+        Node<E> n = new Node<E>(e);
+        retry:
+        for (;;) {
             Node<E> t = tail;
-            Node<E> s = t.getNext();
-            if (t == tail) {
-                if (s == null) {
-                    if (t.casNext(s, n)) {
-                        casTail(t, n);
-                        return true;
-                    }
+            Node<E> p = t;
+            for (int hops = 0; ; hops++) {
+                Node<E> next = succ(p);
+                if (next != null) {
+                    if (hops > HOPS && t != tail)
+                        continue retry;
+                    p = next;
+                } else if (p.casNext(null, n)) {
+                    if (hops >= HOPS)
+                        casTail(t, n);  // Failure is OK.
+                    return true;
                 } else {
-                    casTail(t, s);
+                    p = succ(p);
                 }
             }
         }
     }
 
     public E poll() {
-        for (;;) {
-            Node<E> h = head;
-            Node<E> t = tail;
-            Node<E> first = h.getNext();
-            if (h == head) {
-                if (h == t) {
-                    if (first == null)
-                        return null;
-                    else
-                        casTail(t, first);
-                } else if (casHead(h, first)) {
-                    E item = first.getItem();
-                    if (item != null) {
-                        first.setItem(null);
-                        return item;
-                    }
-                    // else skip over deleted item, continue loop,
+        Node<E> h = head;
+        Node<E> p = h;
+        for (int hops = 0; ; hops++) {
+            E item = p.getItem();
+
+            if (item != null && p.casItem(item, null)) {
+                if (hops >= HOPS) {
+                    Node<E> q = p.getNext();
+                    updateHead(h, (q != null) ? q : p);
                 }
+                return item;
             }
+            Node<E> next = succ(p);
+            if (next == null) {
+                updateHead(h, p);
+                break;
+            }
+            p = next;
         }
+        return null;
     }
 
-    public E peek() { // same as poll except don't remove item
+    public E peek() {
+        Node<E> h = head;
+        Node<E> p = h;
+        E item;
         for (;;) {
-            Node<E> h = head;
-            Node<E> t = tail;
-            Node<E> first = h.getNext();
-            if (h == head) {
-                if (h == t) {
-                    if (first == null)
-                        return null;
-                    else
-                        casTail(t, first);
-                } else {
-                    E item = first.getItem();
-                    if (item != null)
-                        return item;
-                    else // remove deleted node and continue
-                        casHead(h, first);
-                }
+            item = p.getItem();
+            if (item != null)
+                break;
+            Node<E> next = succ(p);
+            if (next == null) {
+                break;
             }
+            p = next;
         }
+        updateHead(h, p);
+        return item;
     }
 
     /**
@@ -245,46 +334,50 @@
      * introducing race.)
      */
     Node<E> first() {
+        Node<E> h = head;
+        Node<E> p = h;
+        Node<E> result;
         for (;;) {
-            Node<E> h = head;
-            Node<E> t = tail;
-            Node<E> first = h.getNext();
-            if (h == head) {
-                if (h == t) {
-                    if (first == null)
-                        return null;
-                    else
-                        casTail(t, first);
-                } else {
-                    if (first.getItem() != null)
-                        return first;
-                    else // remove deleted node and continue
-                        casHead(h, first);
-                }
+            E item = p.getItem();
+            if (item != null) {
+                result = p;
+                break;
             }
+            Node<E> next = succ(p);
+            if (next == null) {
+                result = null;
+                break;
+            }
+            p = next;
         }
+        updateHead(h, p);
+        return result;
     }
 
-
+    /**
+     * Returns {@code true} if this queue contains no elements.
+     *
+     * @return {@code true} if this queue contains no elements
+     */
     public boolean isEmpty() {
         return first() == null;
     }
 
     /**
      * Returns the number of elements in this queue.  If this queue
-     * contains more than <tt>Integer.MAX_VALUE</tt> elements, returns
-     * <tt>Integer.MAX_VALUE</tt>.
+     * contains more than {@code Integer.MAX_VALUE} elements, returns
+     * {@code Integer.MAX_VALUE}.
      *
      * <p>Beware that, unlike in most collections, this method is
      * <em>NOT</em> a constant-time operation. Because of the
      * asynchronous nature of these queues, determining the current
      * number of elements requires an O(n) traversal.
      *
-     * @return  the number of elements in this queue.
+     * @return the number of elements in this queue
      */
     public int size() {
         int count = 0;
-        for (Node<E> p = first(); p != null; p = p.getNext()) {
+        for (Node<E> p = first(); p != null; p = succ(p)) {
             if (p.getItem() != null) {
                 // Collections.size() spec says to max out
                 if (++count == Integer.MAX_VALUE)
@@ -294,9 +387,17 @@
         return count;
     }
 
+    /**
+     * Returns {@code true} if this queue contains the specified element.
+     * More formally, returns {@code true} if and only if this queue contains
+     * at least one element {@code e} such that {@code o.equals(e)}.
+     *
+     * @param o object to be checked for containment in this queue
+     * @return {@code true} if this queue contains the specified element
+     */
     public boolean contains(Object o) {
         if (o == null) return false;
-        for (Node<E> p = first(); p != null; p = p.getNext()) {
+        for (Node<E> p = first(); p != null; p = succ(p)) {
             E item = p.getItem();
             if (item != null &&
                 o.equals(item))
@@ -305,22 +406,50 @@
         return false;
     }
 
+    /**
+     * Removes a single instance of the specified element from this queue,
+     * if it is present.  More formally, removes an element {@code e} such
+     * that {@code o.equals(e)}, if this queue contains one or more such
+     * elements.
+     * Returns {@code true} if this queue contained the specified element
+     * (or equivalently, if this queue changed as a result of the call).
+     *
+     * @param o element to be removed from this queue, if present
+     * @return {@code true} if this queue changed as a result of the call
+     */
     public boolean remove(Object o) {
         if (o == null) return false;
-        for (Node<E> p = first(); p != null; p = p.getNext()) {
+        Node<E> pred = null;
+        for (Node<E> p = first(); p != null; p = succ(p)) {
             E item = p.getItem();
-            if (item != null &&
-                o.equals(item) &&
-                p.casItem(item, null))
+            if (item != null && o.equals(item) && p.casItem(item, null)) {
+                Node<E> next = succ(p);
+                if (pred != null && next != null)
+                    pred.casNext(p, next);
                 return true;
+            }
+            pred = p;
         }
         return false;
     }
 
+    /**
+     * Returns an array containing all of the elements in this queue, in
+     * proper sequence.
+     *
+     * <p>The returned array will be "safe" in that no references to it are
+     * maintained by this queue.  (In other words, this method must allocate
+     * a new array).  The caller is thus free to modify the returned array.
+     *
+     * <p>This method acts as bridge between array-based and collection-based
+     * APIs.
+     *
+     * @return an array containing all of the elements in this queue
+     */
     public Object[] toArray() {
         // Use ArrayList to deal with resizing.
         ArrayList<E> al = new ArrayList<E>();
-        for (Node<E> p = first(); p != null; p = p.getNext()) {
+        for (Node<E> p = first(); p != null; p = succ(p)) {
             E item = p.getItem();
             if (item != null)
                 al.add(item);
@@ -328,11 +457,48 @@
         return al.toArray();
     }
 
+    /**
+     * Returns an array containing all of the elements in this queue, in
+     * proper sequence; the runtime type of the returned array is that of
+     * the specified array.  If the queue fits in the specified array, it
+     * is returned therein.  Otherwise, a new array is allocated with the
+     * runtime type of the specified array and the size of this queue.
+     *
+     * <p>If this queue fits in the specified array with room to spare
+     * (i.e., the array has more elements than this queue), the element in
+     * the array immediately following the end of the queue is set to
+     * {@code null}.
+     *
+     * <p>Like the {@link #toArray()} method, this method acts as bridge between
+     * array-based and collection-based APIs.  Further, this method allows
+     * precise control over the runtime type of the output array, and may,
+     * under certain circumstances, be used to save allocation costs.
+     *
+     * <p>Suppose {@code x} is a queue known to contain only strings.
+     * The following code can be used to dump the queue into a newly
+     * allocated array of {@code String}:
+     *
+     * <pre>
+     *     String[] y = x.toArray(new String[0]);</pre>
+     *
+     * Note that {@code toArray(new Object[0])} is identical in function to
+     * {@code toArray()}.
+     *
+     * @param a the array into which the elements of the queue are to
+     *          be stored, if it is big enough; otherwise, a new array of the
+     *          same runtime type is allocated for this purpose
+     * @return an array containing all of the elements in this queue
+     * @throws ArrayStoreException if the runtime type of the specified array
+     *         is not a supertype of the runtime type of every element in
+     *         this queue
+     * @throws NullPointerException if the specified array is null
+     */
+    @SuppressWarnings("unchecked")
     public <T> T[] toArray(T[] a) {
         // try to use sent-in array
         int k = 0;
         Node<E> p;
-        for (p = first(); p != null && k < a.length; p = p.getNext()) {
+        for (p = first(); p != null && k < a.length; p = succ(p)) {
             E item = p.getItem();
             if (item != null)
                 a[k++] = (T)item;
@@ -345,23 +511,23 @@
 
         // If won't fit, use ArrayList version
         ArrayList<E> al = new ArrayList<E>();
-        for (Node<E> q = first(); q != null; q = q.getNext()) {
+        for (Node<E> q = first(); q != null; q = succ(q)) {
             E item = q.getItem();
             if (item != null)
                 al.add(item);
         }
-        return (T[])al.toArray(a);
+        return al.toArray(a);
     }
 
     /**
      * Returns an iterator over the elements in this queue in proper sequence.
      * The returned iterator is a "weakly consistent" iterator that
-     * will never throw {@link java.util.ConcurrentModificationException},
+     * will never throw {@link ConcurrentModificationException},
      * and guarantees to traverse elements as they existed upon
      * construction of the iterator, and may (but is not guaranteed to)
      * reflect any modifications subsequent to construction.
      *
-     * @return an iterator over the elements in this queue in proper sequence.
+     * @return an iterator over the elements in this queue in proper sequence
      */
     public Iterator<E> iterator() {
         return new Itr();
@@ -378,7 +544,7 @@
          * that an element exists in hasNext(), we must return it in
          * the following next() call even if it was in the process of
          * being removed when hasNext() was called.
-         **/
+         */
         private E nextItem;
 
         /**
@@ -398,7 +564,15 @@
             lastRet = nextNode;
             E x = nextItem;
 
-            Node<E> p = (nextNode == null)? first() : nextNode.getNext();
+            Node<E> pred, p;
+            if (nextNode == null) {
+                p = first();
+                pred = null;
+            } else {
+                pred = nextNode;
+                p = succ(nextNode);
+            }
+
             for (;;) {
                 if (p == null) {
                     nextNode = null;
@@ -410,8 +584,13 @@
                     nextNode = p;
                     nextItem = item;
                     return x;
-                } else // skip over nulls
-                    p = p.getNext();
+                } else {
+                    // skip over nulls
+                    Node<E> next = succ(p);
+                    if (pred != null && next != null)
+                        pred.casNext(p, next);
+                    p = next;
+                }
             }
         }
 
@@ -436,7 +615,7 @@
     /**
      * Save the state to a stream (that is, serialize it).
      *
-     * @serialData All of the elements (each an <tt>E</tt>) in
+     * @serialData All of the elements (each an {@code E}) in
      * the proper order, followed by a null
      * @param s the stream
      */
@@ -447,7 +626,7 @@
         s.defaultWriteObject();
 
         // Write out all elements in the proper order.
-        for (Node<E> p = first(); p != null; p = p.getNext()) {
+        for (Node<E> p = first(); p != null; p = succ(p)) {
             Object item = p.getItem();
             if (item != null)
                 s.writeObject(item);
@@ -466,10 +645,11 @@
         throws java.io.IOException, ClassNotFoundException {
         // Read in capacity, and any hidden stuff
         s.defaultReadObject();
-        head = new Node<E>(null, null);
+        head = new Node<E>(null);
         tail = head;
         // Read in all elements and place in queue
         for (;;) {
+            @SuppressWarnings("unchecked")
             E item = (E)s.readObject();
             if (item == null)
                 break;
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/ConcurrentMap.java b/libcore/concurrent/src/main/java/java/util/concurrent/ConcurrentMap.java
index 32dc000..2daebc5 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/ConcurrentMap.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/ConcurrentMap.java
@@ -15,10 +15,17 @@
  * A {@link java.util.Map} providing additional atomic
  * <tt>putIfAbsent</tt>, <tt>remove</tt>, and <tt>replace</tt> methods.
  *
+ * <p>Memory consistency effects: As with other concurrent
+ * collections, actions in a thread prior to placing an object into a
+ * {@code ConcurrentMap} as a key or value
+ * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
+ * actions subsequent to the access or removal of that object from
+ * the {@code ConcurrentMap} in another thread.
+ *
  * @since 1.5
  * @author Doug Lea
  * @param <K> the type of keys maintained by this map
- * @param <V> the type of mapped values 
+ * @param <V> the type of mapped values
  */
 public interface ConcurrentMap<K, V> extends Map<K, V> {
     /**
@@ -26,93 +33,102 @@
      * with a value, associate it with the given value.
      * This is equivalent to
      * <pre>
-     *   if (!map.containsKey(key)) 
-     *      return map.put(key, value);
+     *   if (!map.containsKey(key))
+     *       return map.put(key, value);
      *   else
-     *      return map.get(key);
-     * </pre>
-     * Except that the action is performed atomically.
-     * @param key key with which the specified value is to be associated.
-     * @param value value to be associated with the specified key.
-     * @return previous value associated with specified key, or <tt>null</tt>
-     *         if there was no mapping for key.  A <tt>null</tt> return can
-     *         also indicate that the map previously associated <tt>null</tt>
-     *         with the specified key, if the implementation supports
-     *         <tt>null</tt> values.
+     *       return map.get(key);</pre>
+     * except that the action is performed atomically.
      *
-     * @throws UnsupportedOperationException if the <tt>put</tt> operation is
-     *            not supported by this map.
+     * @param key key with which the specified value is to be associated
+     * @param value value to be associated with the specified key
+     * @return the previous value associated with the specified key, or
+     *         <tt>null</tt> if there was no mapping for the key.
+     *         (A <tt>null</tt> return can also indicate that the map
+     *         previously associated <tt>null</tt> with the key,
+     *         if the implementation supports null values.)
+     * @throws UnsupportedOperationException if the <tt>put</tt> operation
+     *         is not supported by this map
      * @throws ClassCastException if the class of the specified key or value
-     *            prevents it from being stored in this map.
-     * @throws IllegalArgumentException if some aspect of this key or value
-     *            prevents it from being stored in this map.
-     * @throws NullPointerException if this map does not permit <tt>null</tt>
-     *            keys or values, and the specified key or value is
-     *            <tt>null</tt>.
+     *         prevents it from being stored in this map
+     * @throws NullPointerException if the specified key or value is null,
+     *         and this map does not permit null keys or values
+     * @throws IllegalArgumentException if some property of the specified key
+     *         or value prevents it from being stored in this map
      *
      */
     V putIfAbsent(K key, V value);
 
     /**
-     * Remove entry for key only if currently mapped to given value.
-     * Acts as
-     * <pre> 
-     *  if ((map.containsKey(key) && map.get(key).equals(value)) {
-     *     map.remove(key);
-     *     return true;
-     * } else return false;
-     * </pre>
+     * Removes the entry for a key only if currently mapped to a given value.
+     * This is equivalent to
+     * <pre>
+     *   if (map.containsKey(key) &amp;&amp; map.get(key).equals(value)) {
+     *       map.remove(key);
+     *       return true;
+     *   } else return false;</pre>
      * except that the action is performed atomically.
-     * @param key key with which the specified value is associated.
-     * @param value value associated with the specified key.
-     * @return true if the value was removed, false otherwise
-     * @throws NullPointerException if this map does not permit <tt>null</tt>
-     *            keys or values, and the specified key or value is
-     *            <tt>null</tt>.
+     *
+     * @param key key with which the specified value is associated
+     * @param value value expected to be associated with the specified key
+     * @return <tt>true</tt> if the value was removed
+     * @throws UnsupportedOperationException if the <tt>remove</tt> operation
+     *         is not supported by this map
+     * @throws ClassCastException if the key or value is of an inappropriate
+     *         type for this map (optional)
+     * @throws NullPointerException if the specified key or value is null,
+     *         and this map does not permit null keys or values (optional)
      */
     boolean remove(Object key, Object value);
 
-
     /**
-     * Replace entry for key only if currently mapped to given value.
-     * Acts as
-     * <pre> 
-     *  if ((map.containsKey(key) && map.get(key).equals(oldValue)) {
-     *     map.put(key, newValue);
-     *     return true;
-     * } else return false;
-     * </pre>
+     * Replaces the entry for a key only if currently mapped to a given value.
+     * This is equivalent to
+     * <pre>
+     *   if (map.containsKey(key) &amp;&amp; map.get(key).equals(oldValue)) {
+     *       map.put(key, newValue);
+     *       return true;
+     *   } else return false;</pre>
      * except that the action is performed atomically.
-     * @param key key with which the specified value is associated.
-     * @param oldValue value expected to be associated with the specified key.
-     * @param newValue value to be associated with the specified key.
-     * @return true if the value was replaced
-     * @throws NullPointerException if this map does not permit <tt>null</tt>
-     *            keys or values, and the specified key or value is
-     *            <tt>null</tt>.
+     *
+     * @param key key with which the specified value is associated
+     * @param oldValue value expected to be associated with the specified key
+     * @param newValue value to be associated with the specified key
+     * @return <tt>true</tt> if the value was replaced
+     * @throws UnsupportedOperationException if the <tt>put</tt> operation
+     *         is not supported by this map
+     * @throws ClassCastException if the class of a specified key or value
+     *         prevents it from being stored in this map
+     * @throws NullPointerException if a specified key or value is null,
+     *         and this map does not permit null keys or values
+     * @throws IllegalArgumentException if some property of a specified key
+     *         or value prevents it from being stored in this map
      */
     boolean replace(K key, V oldValue, V newValue);
 
     /**
-     * Replace entry for key only if currently mapped to some value.
-     * Acts as
-     * <pre> 
-     *  if ((map.containsKey(key)) {
-     *     return map.put(key, value);
-     * } else return null;
-     * </pre>
+     * Replaces the entry for a key only if currently mapped to some value.
+     * This is equivalent to
+     * <pre>
+     *   if (map.containsKey(key)) {
+     *       return map.put(key, value);
+     *   } else return null;</pre>
      * except that the action is performed atomically.
-     * @param key key with which the specified value is associated.
-     * @param value value to be associated with the specified key.
-     * @return previous value associated with specified key, or <tt>null</tt>
-     *         if there was no mapping for key.  A <tt>null</tt> return can
-     *         also indicate that the map previously associated <tt>null</tt>
-     *         with the specified key, if the implementation supports
-     *         <tt>null</tt> values.
-     * @throws NullPointerException if this map does not permit <tt>null</tt>
-     *            keys or values, and the specified key or value is
-     *            <tt>null</tt>.
+     *
+     * @param key key with which the specified value is associated
+     * @param value value to be associated with the specified key
+     * @return the previous value associated with the specified key, or
+     *         <tt>null</tt> if there was no mapping for the key.
+     *         (A <tt>null</tt> return can also indicate that the map
+     *         previously associated <tt>null</tt> with the key,
+     *         if the implementation supports null values.)
+     * @throws UnsupportedOperationException if the <tt>put</tt> operation
+     *         is not supported by this map
+     * @throws ClassCastException if the class of the specified key or value
+     *         prevents it from being stored in this map
+     * @throws NullPointerException if the specified key or value is null,
+     *         and this map does not permit null keys or values
+     * @throws IllegalArgumentException if some property of the specified key
+     *         or value prevents it from being stored in this map
      */
     V replace(K key, V value);
-
 }
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArrayList.java b/libcore/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArrayList.java
index 7274595..f0c8ac6 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArrayList.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArrayList.java
@@ -1,1190 +1,1317 @@
 /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with this
- * work for additional information regarding copyright ownership. The ASF
- * licenses this file to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group.  Adapted and released, under explicit permission,
+ * from JDK ArrayList.java which carries the following copyright:
+ *
+ * Copyright 1997 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
  */
 
 package java.util.concurrent;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
+import java.util.*;
+import java.util.concurrent.locks.*;
 import java.lang.reflect.Array;
-import java.util.Collection;
-import java.util.ConcurrentModificationException;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.NoSuchElementException;
-import java.util.RandomAccess;
-import java.util.concurrent.locks.ReentrantLock;
 
-// BEGIN android-added
+import sun.misc.Unsafe;
+
+// BEGIN android-note
+// removed link to collections framework docs
+// END android-note
+
 /**
- * Implements a {@link java.util.ArrayList} variant that is thread-safe. All
- * write operation result in a new copy of the underlying data being created.
- * Iterators reflect the state of the CopyOnWriteArrayList at the time they were
- * created. They are not updated to reflect subsequent changes to the list. In
- * addition, these iterators cannot be used for modifying the underlying
- * CopyOnWriteArrayList.
- * 
- * @param <E> the element type
+ * A thread-safe variant of {@link java.util.ArrayList} in which all mutative
+ * operations (<tt>add</tt>, <tt>set</tt>, and so on) are implemented by
+ * making a fresh copy of the underlying array.
+ *
+ * <p> This is ordinarily too costly, but may be <em>more</em> efficient
+ * than alternatives when traversal operations vastly outnumber
+ * mutations, and is useful when you cannot or don't want to
+ * synchronize traversals, yet need to preclude interference among
+ * concurrent threads.  The "snapshot" style iterator method uses a
+ * reference to the state of the array at the point that the iterator
+ * was created. This array never changes during the lifetime of the
+ * iterator, so interference is impossible and the iterator is
+ * guaranteed not to throw <tt>ConcurrentModificationException</tt>.
+ * The iterator will not reflect additions, removals, or changes to
+ * the list since the iterator was created.  Element-changing
+ * operations on iterators themselves (<tt>remove</tt>, <tt>set</tt>, and
+ * <tt>add</tt>) are not supported. These methods throw
+ * <tt>UnsupportedOperationException</tt>.
+ *
+ * <p>All elements are permitted, including <tt>null</tt>.
+ *
+ * <p>Memory consistency effects: As with other concurrent
+ * collections, actions in a thread prior to placing an object into a
+ * {@code CopyOnWriteArrayList}
+ * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
+ * actions subsequent to the access or removal of that element from
+ * the {@code CopyOnWriteArrayList} in another thread.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ * @param <E> the type of elements held in this collection
  */
-// END android-added
-public class CopyOnWriteArrayList<E> implements List<E>, RandomAccess, Cloneable, Serializable {
-
+public class CopyOnWriteArrayList<E>
+    implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
     private static final long serialVersionUID = 8673264195747942595L;
 
-    private transient volatile E[] arr;
+    /** The lock protecting all mutators */
+    transient final ReentrantLock lock = new ReentrantLock();
+
+    /** The array, accessed only via getArray/setArray. */
+    private volatile transient Object[] array;
 
     /**
-     * Lock for the queue write methods
+     * Gets the array.  Non-private so as to also be accessible
+     * from CopyOnWriteArraySet class.
      */
-    private final transient ReentrantLock lock = new ReentrantLock();
+    final Object[] getArray() {
+        return array;
+    }
 
-    // BEGIN android-added
     /**
-     * Creates a new, empty instance of CopyOnWriteArrayList. 
+     * Sets the array.
      */
-    // END android-added
+    final void setArray(Object[] a) {
+        array = a;
+    }
+
+    /**
+     * Creates an empty list.
+     */
     public CopyOnWriteArrayList() {
+        setArray(new Object[0]);
     }
 
-    // BEGIN android-added
     /**
-     * Creates a new instance of CopyOnWriteArrayList and fills it with the
-     * contents of a given Collection.
-     * 
-     * @param c     the collection the elements of which are to be copied into
-     *              the new instance.
+     * Creates a list containing the elements of the specified
+     * collection, in the order they are returned by the collection's
+     * iterator.
+     *
+     * @param c the collection of initially held elements
+     * @throws NullPointerException if the specified collection is null
      */
-    // END android-added
     public CopyOnWriteArrayList(Collection<? extends E> c) {
-        this((E[]) c.toArray());
+        Object[] elements = c.toArray();
+        // c.toArray might (incorrectly) not return Object[] (see 6260652)
+        if (elements.getClass() != Object[].class)
+            elements = Java6Arrays.copyOf(elements, elements.length, Object[].class);
+        setArray(elements);
     }
 
-    // BEGIN android-added
     /**
-     * Creates a new instance of CopyOnWriteArrayList and fills it with the
-     * contents of a given array.
-     * 
-     * @param array the array the elements of which are to be copied into the
-     *              new instance.
+     * Creates a list holding a copy of the given array.
+     *
+     * @param toCopyIn the array (a copy of this array is used as the
+     *        internal array)
+     * @throws NullPointerException if the specified array is null
      */
-    // END android-added
-    public CopyOnWriteArrayList(E[] array) {
-        int size = array.length;
-        E[] data = newElementArray(size);
-        for (int i = 0; i < size; i++) {
-            data[i] = array[i];
-        }
-        arr = data;
+    public CopyOnWriteArrayList(E[] toCopyIn) {
+        setArray(Java6Arrays.copyOf(toCopyIn, toCopyIn.length, Object[].class));
     }
 
-    public boolean add(E e) {
-        lock.lock();
-        try {
-            E[] data;
-            E[] old = getData();
-            int size = old.length;
-            data = newElementArray(size + 1);
-            System.arraycopy(old, 0, data, 0, size);
-            data[size] = e;
-            setData(data);
-            return true;
-        } finally {
-            lock.unlock();
-        }
-    }
-
-    public void add(int index, E e) {
-        lock.lock();
-        try {
-            E[] data;
-            E[] old = getData();
-            int size = old.length;
-            checkIndexInclusive(index, size);
-            data = newElementArray(size+1);
-            System.arraycopy(old, 0, data, 0, index);
-            data[index] = e;
-            if (size > index) {
-                System.arraycopy(old, index, data, index + 1, size - index);
-            }
-            setData(data);
-        } finally {
-            lock.unlock();
-        }
-    }
-
-    public boolean addAll(Collection<? extends E> c) {
-        Iterator it = c.iterator();
-        int ssize = c.size();
-        lock.lock();
-        try {
-            int size = size();
-            E[] data;
-            E[] old = getData();
-            int nSize = size + ssize;
-            data = newElementArray(nSize);
-            System.arraycopy(old, 0, data, 0, size);
-            while (it.hasNext()) {
-                data[size++] = (E) it.next();
-            }
-            setData(data);
-        } finally {
-            lock.unlock();
-        }
-        return true;
-    }
-
-    public boolean addAll(int index, Collection<? extends E> c) {
-        Iterator it = c.iterator();
-        int ssize = c.size();
-        lock.lock();
-        try {
-            int size = size();
-            checkIndexInclusive(index, size);
-            E[] data;
-            E[] old = getData();
-            int nSize = size + ssize;
-            data = newElementArray(nSize);
-            System.arraycopy(old, 0, data, 0, index);
-            int i = index;
-            while (it.hasNext()) {
-                data[i++] = (E) it.next();
-            }
-            if (size > index) {
-                System.arraycopy(old, index, data, index + ssize, size - index);
-            }
-            setData(data);
-        } finally {
-            lock.unlock();
-        }
-        return true;
-    }
-
-    // BEGIN android-added
     /**
-     * Adds to this CopyOnWriteArrayList all those elements from a given
-     * collection that are not yet part of the list.
-     * 
-     * @param c     the collection from which the potential new elements are
-     *              taken.
-     * 
-     * @return the number of elements actually added to this list.
+     * Returns the number of elements in this list.
+     *
+     * @return the number of elements in this list
      */
-    // END android-added
-    public int addAllAbsent(Collection<? extends E> c) {
-        if (c.size() == 0) {
-            return 0;
-        }
-        lock.lock();
-        try {
-            E[] old = getData();
-            int size = old.length;
-            E[] toAdd = newElementArray(c.size());
-            int i = 0;
-            for (Iterator it = c.iterator(); it.hasNext();) {
-                E o = (E) it.next();
-                if (indexOf(o) < 0) {
-                    toAdd[i++] = o;
-                }
-            }
-            E[] data = newElementArray(size + i);
-            System.arraycopy(old, 0, data, 0, size);
-            System.arraycopy(toAdd, 0, data, size, i);
-            setData(data);
-            return i;
-        } finally {
-            lock.unlock();
-        }
+    public int size() {
+        return getArray().length;
     }
 
-    // BEGIN android-added
     /**
-     * Adds to this CopyOnWriteArrayList another element, given that this
-     * element is not yet part of the list.
-     * 
-     * @param e     the potential new element.
-     * 
-     * @return true if the element was added, or false otherwise.
+     * Returns <tt>true</tt> if this list contains no elements.
+     *
+     * @return <tt>true</tt> if this list contains no elements
      */
-    // END android-added
-    public boolean addIfAbsent(E e) {
-        lock.lock();
-        try {
-            E[] data;
-            E[] old = getData();
-            int size = old.length;
-            if (size != 0) {
-                if (indexOf(e) >= 0) {
-                    return false;
-                }
-            }
-            data = newElementArray(size + 1);
-            System.arraycopy(old, 0, data, 0, size);
-            data[size] = e;
-            setData(data);
-            return true;
-        } finally {
-            lock.unlock();
-        }
-    }
-
-    public void clear() {
-        lock.lock();
-        try {
-            setData(newElementArray(0));
-        } finally {
-            lock.unlock();
-        }
-    }
-
-    @Override
-    public Object clone() {
-        try {
-            CopyOnWriteArrayList thisClone = (CopyOnWriteArrayList) super.clone();
-            thisClone.setData(this.getData());
-            return thisClone;
-        } catch (CloneNotSupportedException e) {
-            throw new RuntimeException("CloneNotSupportedException is not expected here");
-        }
-    }
-
-    public boolean contains(Object o) {
-        return indexOf(o) >= 0;
-    }
-
-    public boolean containsAll(Collection<?> c) {
-        E[] data = getData();
-        return containsAll(c, data, 0, data.length);
-    }
-
-    public boolean equals(Object o) {
-        if (o == this) {
-            return true;
-        }
-        if (!(o instanceof List)) {
-            return false;
-        }
-        List l = (List) o;
-        Iterator it = l.listIterator();
-        Iterator ourIt = listIterator();
-        while (it.hasNext()) {
-            if (!ourIt.hasNext()) {
-                return false;
-            }
-            Object thisListElem = it.next();
-            Object anotherListElem = ourIt.next();
-            if (!(thisListElem == null ? anotherListElem == null : thisListElem
-                    .equals(anotherListElem))) {
-                return false;
-            }
-        }
-        if (ourIt.hasNext()) {
-            return false;
-        }
-        return true;
-    }
-
-    public E get(int index) {
-        E[] data = getData();
-        return data[index];
-    }
-
-    public int hashCode() {
-        int hashCode = 1;
-        Iterator it = listIterator();
-        while (it.hasNext()) {
-            Object obj = it.next();
-            hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode());
-        }
-        return hashCode;
-    }
-
-    // BEGIN android-added
-    /**
-     * Returns the index of a given element, starting the search from a given
-     * position in the list. 
-     * 
-     * @param e     the element to search.
-     * @param index the index at which to start the search.
-     * 
-     * @return the index of the element or null, if the element has not been
-     * found at or beyond the given start index.
-     */
-    // END android-added
-    public int indexOf(E e, int index) {
-        E[] data = getData();
-        return indexOf(e, data, index, data.length - index);
-    }
-
-    public int indexOf(Object o) {
-        E[] data = getData();
-        return indexOf(o, data, 0, data.length);
-    }
-
     public boolean isEmpty() {
         return size() == 0;
     }
 
-    public Iterator<E> iterator() {
-        return new ListIteratorImpl(getData(), 0);
-    }
-
-    // BEGIN android-added
     /**
-     * Returns the last index of a given element, starting the search from
-     * a given position in the list and going backwards. 
-     * 
-     * @param e     the element to search.
-     * @param index the index at which to start the search.
-     * 
-     * @return the index of the element or null, if the element has not been
-     * found at or before the given start index.
+     * Test for equality, coping with nulls.
      */
-    // END android-added
-    public int lastIndexOf(E e, int index) {
-        E[] data = getData();
-        return lastIndexOf(e, data, 0, index);
+    private static boolean eq(Object o1, Object o2) {
+        return (o1 == null ? o2 == null : o1.equals(o2));
     }
 
+    /**
+     * static version of indexOf, to allow repeated calls without
+     * needing to re-acquire array each time.
+     * @param o element to search for
+     * @param elements the array
+     * @param index first index to search
+     * @param fence one past last index to search
+     * @return index of element, or -1 if absent
+     */
+    private static int indexOf(Object o, Object[] elements,
+                               int index, int fence) {
+        if (o == null) {
+            for (int i = index; i < fence; i++)
+                if (elements[i] == null)
+                    return i;
+        } else {
+            for (int i = index; i < fence; i++)
+                if (o.equals(elements[i]))
+                    return i;
+        }
+        return -1;
+    }
+
+    /**
+     * static version of lastIndexOf.
+     * @param o element to search for
+     * @param elements the array
+     * @param index first index to search
+     * @return index of element, or -1 if absent
+     */
+    private static int lastIndexOf(Object o, Object[] elements, int index) {
+        if (o == null) {
+            for (int i = index; i >= 0; i--)
+                if (elements[i] == null)
+                    return i;
+        } else {
+            for (int i = index; i >= 0; i--)
+                if (o.equals(elements[i]))
+                    return i;
+        }
+        return -1;
+    }
+
+    /**
+     * Returns <tt>true</tt> if this list contains the specified element.
+     * More formally, returns <tt>true</tt> if and only if this list contains
+     * at least one element <tt>e</tt> such that
+     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
+     *
+     * @param o element whose presence in this list is to be tested
+     * @return <tt>true</tt> if this list contains the specified element
+     */
+    public boolean contains(Object o) {
+        Object[] elements = getArray();
+        return indexOf(o, elements, 0, elements.length) >= 0;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public int indexOf(Object o) {
+        Object[] elements = getArray();
+        return indexOf(o, elements, 0, elements.length);
+    }
+
+    /**
+     * Returns the index of the first occurrence of the specified element in
+     * this list, searching forwards from <tt>index</tt>, or returns -1 if
+     * the element is not found.
+     * More formally, returns the lowest index <tt>i</tt> such that
+     * <tt>(i&nbsp;&gt;=&nbsp;index&nbsp;&amp;&amp;&nbsp;(e==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;e.equals(get(i))))</tt>,
+     * or -1 if there is no such index.
+     *
+     * @param e element to search for
+     * @param index index to start searching from
+     * @return the index of the first occurrence of the element in
+     *         this list at position <tt>index</tt> or later in the list;
+     *         <tt>-1</tt> if the element is not found.
+     * @throws IndexOutOfBoundsException if the specified index is negative
+     */
+    public int indexOf(E e, int index) {
+        Object[] elements = getArray();
+        return indexOf(e, elements, index, elements.length);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
     public int lastIndexOf(Object o) {
-        E[] data = getData();
-        return lastIndexOf(o, data, 0, data.length);
+        Object[] elements = getArray();
+        return lastIndexOf(o, elements, elements.length - 1);
     }
 
-    public ListIterator<E> listIterator() {
-        return new ListIteratorImpl(getData(), 0);
+    /**
+     * Returns the index of the last occurrence of the specified element in
+     * this list, searching backwards from <tt>index</tt>, or returns -1 if
+     * the element is not found.
+     * More formally, returns the highest index <tt>i</tt> such that
+     * <tt>(i&nbsp;&lt;=&nbsp;index&nbsp;&amp;&amp;&nbsp;(e==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;e.equals(get(i))))</tt>,
+     * or -1 if there is no such index.
+     *
+     * @param e element to search for
+     * @param index index to start searching backwards from
+     * @return the index of the last occurrence of the element at position
+     *         less than or equal to <tt>index</tt> in this list;
+     *         -1 if the element is not found.
+     * @throws IndexOutOfBoundsException if the specified index is greater
+     *         than or equal to the current size of this list
+     */
+    public int lastIndexOf(E e, int index) {
+        Object[] elements = getArray();
+        return lastIndexOf(e, elements, index);
     }
 
-    public ListIterator<E> listIterator(int index) {
-        E[] data = getData();
-        checkIndexInclusive(index, data.length);
-        return new ListIteratorImpl(data, index);
+    /**
+     * Returns a shallow copy of this list.  (The elements themselves
+     * are not copied.)
+     *
+     * @return a clone of this list
+     */
+    public Object clone() {
+        try {
+            CopyOnWriteArrayList c = (CopyOnWriteArrayList)(super.clone());
+            c.resetLock();
+            return c;
+        } catch (CloneNotSupportedException e) {
+            // this shouldn't happen, since we are Cloneable
+            throw new InternalError();
+        }
     }
 
-    public E remove(int index) {
-        return removeRange(index, 1);
+    /**
+     * Returns an array containing all of the elements in this list
+     * in proper sequence (from first to last element).
+     *
+     * <p>The returned array will be "safe" in that no references to it are
+     * maintained by this list.  (In other words, this method must allocate
+     * a new array).  The caller is thus free to modify the returned array.
+     *
+     * <p>This method acts as bridge between array-based and collection-based
+     * APIs.
+     *
+     * @return an array containing all the elements in this list
+     */
+    public Object[] toArray() {
+        Object[] elements = getArray();
+        return Java6Arrays.copyOf(elements, elements.length);
     }
 
-    public boolean remove(Object o) {
+    /**
+     * Returns an array containing all of the elements in this list in
+     * proper sequence (from first to last element); the runtime type of
+     * the returned array is that of the specified array.  If the list fits
+     * in the specified array, it is returned therein.  Otherwise, a new
+     * array is allocated with the runtime type of the specified array and
+     * the size of this list.
+     *
+     * <p>If this list fits in the specified array with room to spare
+     * (i.e., the array has more elements than this list), the element in
+     * the array immediately following the end of the list is set to
+     * <tt>null</tt>.  (This is useful in determining the length of this
+     * list <i>only</i> if the caller knows that this list does not contain
+     * any null elements.)
+     *
+     * <p>Like the {@link #toArray()} method, this method acts as bridge between
+     * array-based and collection-based APIs.  Further, this method allows
+     * precise control over the runtime type of the output array, and may,
+     * under certain circumstances, be used to save allocation costs.
+     *
+     * <p>Suppose <tt>x</tt> is a list known to contain only strings.
+     * The following code can be used to dump the list into a newly
+     * allocated array of <tt>String</tt>:
+     *
+     * <pre>
+     *     String[] y = x.toArray(new String[0]);</pre>
+     *
+     * Note that <tt>toArray(new Object[0])</tt> is identical in function to
+     * <tt>toArray()</tt>.
+     *
+     * @param a the array into which the elements of the list are to
+     *          be stored, if it is big enough; otherwise, a new array of the
+     *          same runtime type is allocated for this purpose.
+     * @return an array containing all the elements in this list
+     * @throws ArrayStoreException if the runtime type of the specified array
+     *         is not a supertype of the runtime type of every element in
+     *         this list
+     * @throws NullPointerException if the specified array is null
+     */
+    @SuppressWarnings("unchecked")
+    public <T> T[] toArray(T a[]) {
+        Object[] elements = getArray();
+        int len = elements.length;
+        if (a.length < len)
+            return (T[]) Java6Arrays.copyOf(elements, len, a.getClass());
+        else {
+            System.arraycopy(elements, 0, a, 0, len);
+            if (a.length > len)
+                a[len] = null;
+            return a;
+        }
+    }
+
+    // Positional Access Operations
+
+    @SuppressWarnings("unchecked")
+    private E get(Object[] a, int index) {
+        return (E) a[index];
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @throws IndexOutOfBoundsException {@inheritDoc}
+     */
+    public E get(int index) {
+        return get(getArray(), index);
+    }
+
+    /**
+     * Replaces the element at the specified position in this list with the
+     * specified element.
+     *
+     * @throws IndexOutOfBoundsException {@inheritDoc}
+     */
+    public E set(int index, E element) {
+        final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            int index = indexOf(o);
-            if (index == -1) {
-                return false;
+            Object[] elements = getArray();
+            E oldValue = get(elements, index);
+
+            if (oldValue != element) {
+                int len = elements.length;
+                Object[] newElements = Java6Arrays.copyOf(elements, len);
+                newElements[index] = element;
+                setArray(newElements);
+            } else {
+                // Not quite a no-op; ensures volatile write semantics
+                setArray(elements);
             }
-            remove(index);
+            return oldValue;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * Appends the specified element to the end of this list.
+     *
+     * @param e element to be appended to this list
+     * @return <tt>true</tt> (as specified by {@link Collection#add})
+     */
+    public boolean add(E e) {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            Object[] elements = getArray();
+            int len = elements.length;
+            Object[] newElements = Java6Arrays.copyOf(elements, len + 1);
+            newElements[len] = e;
+            setArray(newElements);
             return true;
         } finally {
             lock.unlock();
         }
     }
 
-    public boolean removeAll(Collection<?> c) {
+    /**
+     * Inserts the specified element at the specified position in this
+     * list. Shifts the element currently at that position (if any) and
+     * any subsequent elements to the right (adds one to their indices).
+     *
+     * @throws IndexOutOfBoundsException {@inheritDoc}
+     */
+    public void add(int index, E element) {
+        final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            return removeAll(c, 0, getData().length) != 0;
+            Object[] elements = getArray();
+            int len = elements.length;
+            if (index > len || index < 0)
+                throw new IndexOutOfBoundsException("Index: "+index+
+                                                    ", Size: "+len);
+            Object[] newElements;
+            int numMoved = len - index;
+            if (numMoved == 0)
+                newElements = Java6Arrays.copyOf(elements, len + 1);
+            else {
+                newElements = new Object[len + 1];
+                System.arraycopy(elements, 0, newElements, 0, index);
+                System.arraycopy(elements, index, newElements, index + 1,
+                                 numMoved);
+            }
+            newElements[index] = element;
+            setArray(newElements);
         } finally {
             lock.unlock();
         }
     }
 
-    public boolean retainAll(Collection<?> c) {
-        if (c == null) {
-            throw new NullPointerException();
-        }
+    /**
+     * Removes the element at the specified position in this list.
+     * Shifts any subsequent elements to the left (subtracts one from their
+     * indices).  Returns the element that was removed from the list.
+     *
+     * @throws IndexOutOfBoundsException {@inheritDoc}
+     */
+    public E remove(int index) {
+        final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            return retainAll(c, 0, getData().length) != 0;
+            Object[] elements = getArray();
+            int len = elements.length;
+            E oldValue = get(elements, index);
+            int numMoved = len - index - 1;
+            if (numMoved == 0)
+                setArray(Java6Arrays.copyOf(elements, len - 1));
+            else {
+                Object[] newElements = new Object[len - 1];
+                System.arraycopy(elements, 0, newElements, 0, index);
+                System.arraycopy(elements, index + 1, newElements, index,
+                                 numMoved);
+                setArray(newElements);
+            }
+            return oldValue;
         } finally {
             lock.unlock();
         }
     }
 
-    public E set(int index, E e) {
+    /**
+     * Removes the first occurrence of the specified element from this list,
+     * if it is present.  If this list does not contain the element, it is
+     * unchanged.  More formally, removes the element with the lowest index
+     * <tt>i</tt> such that
+     * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>
+     * (if such an element exists).  Returns <tt>true</tt> if this list
+     * contained the specified element (or equivalently, if this list
+     * changed as a result of the call).
+     *
+     * @param o element to be removed from this list, if present
+     * @return <tt>true</tt> if this list contained the specified element
+     */
+    public boolean remove(Object o) {
+        final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            int size = size();
-            checkIndexExlusive(index, size);
-            E[] data;
-            data = newElementArray(size);
-            E[] oldArr = getData();
-            System.arraycopy(oldArr, 0, data, 0, size);
-            E old = data[index];
-            data[index] = e;
-            setData(data);
-            return old;
-        } finally {
-            lock.unlock();
-        }
-    }
+            Object[] elements = getArray();
+            int len = elements.length;
+            if (len != 0) {
+                // Copy while searching for element to remove
+                // This wins in the normal case of element being present
+                int newlen = len - 1;
+                Object[] newElements = new Object[newlen];
 
-    public int size() {
-        return getData().length;
-    }
+                for (int i = 0; i < newlen; ++i) {
+                    if (eq(o, elements[i])) {
+                        // found one;  copy remaining and exit
+                        for (int k = i + 1; k < len; ++k)
+                            newElements[k-1] = elements[k];
+                        setArray(newElements);
+                        return true;
+                    } else
+                        newElements[i] = elements[i];
+                }
 
-    public List<E> subList(int fromIndex, int toIndex) {
-        return new SubList(this, fromIndex, toIndex);
-    }
-
-    public Object[] toArray() {
-        E[] data = getData();
-        return toArray(data, 0, data.length);
-    }
-
-    public <T> T[] toArray(T[] a) {
-        E[] data = getData();
-        return (T[]) toArray(a, data, 0, data.length);
-    }
-
-    @Override
-    public String toString() {
-        StringBuffer sb = new StringBuffer("[");
-
-        Iterator it = listIterator();
-        while (it.hasNext()) {
-            sb.append(String.valueOf(it.next()));
-            sb.append(", ");
-        }
-        if (sb.length() > 1) {
-            sb.setLength(sb.length() - 2);
-        }
-        sb.append("]");
-        return sb.toString();
-    }
-
-    // private and package private methods
-
-    @SuppressWarnings("unchecked")
-    private final E[] newElementArray(int size) {
-        return (E[])new Object[size];
-    }
-
-    /**
-     * sets the internal data array
-     *
-     * @param data array to set
-     */
-    private final void setData(E[] data) {
-        arr = data;
-    }
-
-    /**
-     * gets the internal data array
-     *
-     * @return the data array
-     */
-    final E[] getData() {
-        if (arr == null) {
-            return newElementArray(0);
-        }
-        return arr;
-    }
-
-    /**
-     * Removes from the specified range of this list
-     * all the elements that are contained in the specified collection
-     * <p/>
-     * !should be called under lock
-     *
-     * @return Returns the number of removed elements
-     */
-    final int removeAll(Collection c, int start, int size) {
-        int ssize = c.size();
-        if (ssize == 0) {
-            return 0;
-        }
-        Object[] old = getData();
-        int arrsize = old.length;
-        if (arrsize == 0) {
-            return 0;
-        }
-        Object[] data = new Object[size];
-        int j = 0;
-        for (int i = start; i < (start + size); i++) {
-            if (!c.contains(old[i])) {
-                data[j++] = old[i];
+                // special handling for last cell
+                if (eq(o, elements[newlen])) {
+                    setArray(newElements);
+                    return true;
+                }
             }
-        }
-        if (j != size) {
-            E[] result = newElementArray(arrsize - (size - j));
-            System.arraycopy(old, 0, result, 0, start);
-            System.arraycopy(data, 0, result, start, j);
-            System.arraycopy(old, start + size, result, start + j, arrsize
-                    - (start + size));
-            setData(result);
-            return (size - j);
-        }
-        return 0;
-    }
-
-    /**
-     * Retains only the elements in the specified range of this list
-     * that are contained in the specified collection
-     *
-     * @return Returns the number of removed elements
-     */
-    // should be called under lock
-    int retainAll(Collection c, int start, int size) {
-        Object[] old = getData();
-        if (size == 0) {
-            return 0;
-        }
-        if (c.size() == 0) {
-            E[] data;
-            if (size == old.length) {
-                data = newElementArray(0);
-            } else {
-                data = newElementArray(old.length - size);
-                System.arraycopy(old, 0, data, 0, start);
-                System.arraycopy(old, start + size, data, start, old.length
-                        - start - size);
-            }
-            setData(data);
-            return size;
-        }
-        Object[] temp = new Object[size];
-        int pos = 0;
-        for (int i = start; i < (start + size); i++) {
-            if (c.contains(old[i])) {
-                temp[pos++] = old[i];
-            }
-        }
-        if (pos == size) {
-            return 0;
-        }
-        E[] data = newElementArray(pos + old.length - size);
-        System.arraycopy(old, 0, data, 0, start);
-        System.arraycopy(temp, 0, data, start, pos);
-        System.arraycopy(old, start + size, data, start + pos, old.length
-                - start - size);
-        setData(data);
-        return (size - pos);
-    }
-
-    /**
-     * Removes specified range from this list
-     */
-    E removeRange(int start, int size) {
-        lock.lock();
-        try {
-            int sizeArr = size();
-            checkIndexExlusive(start, sizeArr);
-            checkIndexInclusive(start + size, sizeArr);
-            E[] data;
-            data = newElementArray(sizeArr - size);
-            E[] oldArr = getData();
-            System.arraycopy(oldArr, 0, data, 0, start);
-            E old = oldArr[start];
-            if (sizeArr > (start + size)) {
-                System.arraycopy(oldArr, start + size, data, start, sizeArr
-                        - (start + size));
-            }
-            setData(data);
-            return old;
-        } finally {
-            lock.unlock();
-        }
-    }
-
-    // some util static functions to use by iterators and methods
-    /**
-     * Returns an array containing all of the elements
-     * in the specified range of the array in proper sequence
-     */
-    static Object[] toArray(Object[] data, int start, int size) {
-        Object[] result = new Object[size];
-        System.arraycopy(data, start, result, 0, size);
-        return result;
-    }
-
-    /**
-     * Returns an array containing all of the elements
-     * in the specified range of the array in proper sequence,
-     * stores the result in the array, specified by first parameter
-     * (as for public instance method toArray(Object[] to)
-     */
-    static Object[] toArray(Object[] to, Object[] data, int start, int size) {
-        int l = data.length;
-        if (to.length < l) {
-            to = (Object[]) Array.newInstance(to.getClass().getComponentType(),
-                    l);
-        } else {
-            if (to.length > l) {
-                to[l] = null;
-            }
-        }
-        System.arraycopy(data, start, to, 0, size);
-        return to;
-    }
-
-    /**
-     * Checks if the specified range of the
-     * array contains all of the elements in the collection
-     *
-     * @param c     collection with elements
-     * @param data  array where to search the elements
-     * @param start start index
-     * @param size  size of the range
-     */
-    static final boolean containsAll(Collection c, Object[] data, int start,
-                                     int size) {
-        if (size == 0) {
             return false;
+        } finally {
+            lock.unlock();
         }
-        Iterator it = c.iterator();
-        while (it.hasNext()) {
-            Object next = it.next();
-            if (indexOf(next, data, start, size) < 0) {
-                return false;
+    }
+
+    /**
+     * Removes from this list all of the elements whose index is between
+     * <tt>fromIndex</tt>, inclusive, and <tt>toIndex</tt>, exclusive.
+     * Shifts any succeeding elements to the left (reduces their index).
+     * This call shortens the list by <tt>(toIndex - fromIndex)</tt> elements.
+     * (If <tt>toIndex==fromIndex</tt>, this operation has no effect.)
+     *
+     * @param fromIndex index of first element to be removed
+     * @param toIndex index after last element to be removed
+     * @throws IndexOutOfBoundsException if fromIndex or toIndex out of range
+     *         (@code{fromIndex < 0 || toIndex > size() || toIndex < fromIndex})
+     */
+    private void removeRange(int fromIndex, int toIndex) {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            Object[] elements = getArray();
+            int len = elements.length;
+
+            if (fromIndex < 0 || toIndex > len || toIndex < fromIndex)
+                throw new IndexOutOfBoundsException();
+            int newlen = len - (toIndex - fromIndex);
+            int numMoved = len - toIndex;
+            if (numMoved == 0)
+                setArray(Java6Arrays.copyOf(elements, newlen));
+            else {
+                Object[] newElements = new Object[newlen];
+                System.arraycopy(elements, 0, newElements, 0, fromIndex);
+                System.arraycopy(elements, toIndex, newElements,
+                                 fromIndex, numMoved);
+                setArray(newElements);
             }
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * Append the element if not present.
+     *
+     * @param e element to be added to this list, if absent
+     * @return <tt>true</tt> if the element was added
+     */
+    public boolean addIfAbsent(E e) {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            // Copy while checking if already present.
+            // This wins in the most common case where it is not present
+            Object[] elements = getArray();
+            int len = elements.length;
+            Object[] newElements = new Object[len + 1];
+            for (int i = 0; i < len; ++i) {
+                if (eq(e, elements[i]))
+                    return false; // exit, throwing away copy
+                else
+                    newElements[i] = elements[i];
+            }
+            newElements[len] = e;
+            setArray(newElements);
+            return true;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * Returns <tt>true</tt> if this list contains all of the elements of the
+     * specified collection.
+     *
+     * @param c collection to be checked for containment in this list
+     * @return <tt>true</tt> if this list contains all of the elements of the
+     *         specified collection
+     * @throws NullPointerException if the specified collection is null
+     * @see #contains(Object)
+     */
+    public boolean containsAll(Collection<?> c) {
+        Object[] elements = getArray();
+        int len = elements.length;
+        for (Object e : c) {
+            if (indexOf(e, elements, 0, len) < 0)
+                return false;
         }
         return true;
     }
 
     /**
-     * Returns the index in the specified range of the data array
-     * of the last occurrence of the specified element
+     * Removes from this list all of its elements that are contained in
+     * the specified collection. This is a particularly expensive operation
+     * in this class because of the need for an internal temporary array.
      *
-     * @param o     element to search
-     * @param data  array where to search
-     * @param start start index
-     * @param size  size of the range
-     * @return
+     * @param c collection containing elements to be removed from this list
+     * @return <tt>true</tt> if this list changed as a result of the call
+     * @throws ClassCastException if the class of an element of this list
+     *         is incompatible with the specified collection (optional)
+     * @throws NullPointerException if this list contains a null element and the
+     *         specified collection does not permit null elements (optional),
+     *         or if the specified collection is null
+     * @see #remove(Object)
      */
-    static final int lastIndexOf(Object o, Object[] data, int start, int size) {
-        if (size == 0) {
-            return -1;
-        }
-        if (o != null) {
-            for (int i = start + size - 1; i > start - 1; i--) {
-                if (o.equals(data[i])) {
-                    return i;
+    public boolean removeAll(Collection<?> c) {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            Object[] elements = getArray();
+            int len = elements.length;
+            if (len != 0) {
+                // temp array holds those elements we know we want to keep
+                int newlen = 0;
+                Object[] temp = new Object[len];
+                for (int i = 0; i < len; ++i) {
+                    Object element = elements[i];
+                    if (!c.contains(element))
+                        temp[newlen++] = element;
+                }
+                if (newlen != len) {
+                    setArray(Java6Arrays.copyOf(temp, newlen));
+                    return true;
                 }
             }
-        } else {
-            for (int i = start + size - 1; i > start - 1; i--) {
-                if (data[i] == null) {
-                    return i;
-                }
-            }
-        }
-        return -1;
-    }
-
-    /**
-     * Returns the index in the specified range of the data array
-     * of the first occurrence of the specified element
-     *
-     * @param o     element to search
-     * @param data  array where to search
-     * @param start start index
-     * @param size  end index
-     * @return
-     */
-    static final int indexOf(Object o, Object[] data, int start, int size) {
-        if (size == 0) {
-            return -1;
-        }
-        if (o == null) {
-            for (int i = start; i < start + size; i++) {
-                if (data[i] == null) {
-                    return i;
-                }
-            }
-        } else {
-            for (int i = start; i < start + size; i++) {
-                if (o.equals(data[i])) {
-                    return i;
-                }
-            }
-        }
-        return -1;
-    }
-
-    /**
-     * Throws <code>IndexOutOfBoundsException</code> if <code>index</code>
-     * is out of the list bounds.
-     *
-     * @param index element index to check.
-     */
-    static final void checkIndexInclusive(int index, int size) {
-        if (index < 0 || index > size) {
-            throw new IndexOutOfBoundsException("Index is " + index + ", size is " + size);
+            return false;
+        } finally {
+            lock.unlock();
         }
     }
 
     /**
-     * Throws <code>IndexOutOfBoundsException</code> if <code>index</code>
-     * is out of the list bounds. Excluding the last element.
+     * Retains only the elements in this list that are contained in the
+     * specified collection.  In other words, removes from this list all of
+     * its elements that are not contained in the specified collection.
      *
-     * @param index element index to check.
+     * @param c collection containing elements to be retained in this list
+     * @return <tt>true</tt> if this list changed as a result of the call
+     * @throws ClassCastException if the class of an element of this list
+     *         is incompatible with the specified collection (optional)
+     * @throws NullPointerException if this list contains a null element and the
+     *         specified collection does not permit null elements (optional),
+     *         or if the specified collection is null
+     * @see #remove(Object)
      */
-    static final void checkIndexExlusive(int index, int size) {
-        if (index < 0 || index >= size) {
-            throw new IndexOutOfBoundsException("Index is " + index + ", size is " + size);
+    public boolean retainAll(Collection<?> c) {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            Object[] elements = getArray();
+            int len = elements.length;
+            if (len != 0) {
+                // temp array holds those elements we know we want to keep
+                int newlen = 0;
+                Object[] temp = new Object[len];
+                for (int i = 0; i < len; ++i) {
+                    Object element = elements[i];
+                    if (c.contains(element))
+                        temp[newlen++] = element;
+                }
+                if (newlen != len) {
+                    setArray(Java6Arrays.copyOf(temp, newlen));
+                    return true;
+                }
+            }
+            return false;
+        } finally {
+            lock.unlock();
         }
     }
 
     /**
-     * list iterator implementation,
-     * when created gets snapshot of the list,
-     * so never throws ConcurrentModificationException
+     * Appends all of the elements in the specified collection that
+     * are not already contained in this list, to the end of
+     * this list, in the order that they are returned by the
+     * specified collection's iterator.
+     *
+     * @param c collection containing elements to be added to this list
+     * @return the number of elements added
+     * @throws NullPointerException if the specified collection is null
+     * @see #addIfAbsent(Object)
      */
-    private static class ListIteratorImpl implements ListIterator {
-        private final Object[] arr;
-
-        private int current;
-
-        private final int size;
-
-        final int size() {
-            return size;
+    public int addAllAbsent(Collection<? extends E> c) {
+        Object[] cs = c.toArray();
+        if (cs.length == 0)
+            return 0;
+        Object[] uniq = new Object[cs.length];
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            Object[] elements = getArray();
+            int len = elements.length;
+            int added = 0;
+            for (int i = 0; i < cs.length; ++i) { // scan for duplicates
+                Object e = cs[i];
+                if (indexOf(e, elements, 0, len) < 0 &&
+                    indexOf(e, uniq, 0, added) < 0)
+                    uniq[added++] = e;
+            }
+            if (added > 0) {
+                Object[] newElements = Java6Arrays.copyOf(elements, len + added);
+                System.arraycopy(uniq, 0, newElements, len, added);
+                setArray(newElements);
+            }
+            return added;
+        } finally {
+            lock.unlock();
         }
+    }
 
-        public ListIteratorImpl(Object[] data, int current) {
-            this.current = current;
-            arr = data;
-            size = data.length;
+    /**
+     * Removes all of the elements from this list.
+     * The list will be empty after this call returns.
+     */
+    public void clear() {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            setArray(new Object[0]);
+        } finally {
+            lock.unlock();
         }
+    }
 
-        public void add(Object o) {
-            throw new UnsupportedOperationException("Unsupported operation add");
+    /**
+     * Appends all of the elements in the specified collection to the end
+     * of this list, in the order that they are returned by the specified
+     * collection's iterator.
+     *
+     * @param c collection containing elements to be added to this list
+     * @return <tt>true</tt> if this list changed as a result of the call
+     * @throws NullPointerException if the specified collection is null
+     * @see #add(Object)
+     */
+    public boolean addAll(Collection<? extends E> c) {
+        Object[] cs = c.toArray();
+        if (cs.length == 0)
+            return false;
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            Object[] elements = getArray();
+            int len = elements.length;
+            Object[] newElements = Java6Arrays.copyOf(elements, len + cs.length);
+            System.arraycopy(cs, 0, newElements, len, cs.length);
+            setArray(newElements);
+            return true;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * Inserts all of the elements in the specified collection into this
+     * list, starting at the specified position.  Shifts the element
+     * currently at that position (if any) and any subsequent elements to
+     * the right (increases their indices).  The new elements will appear
+     * in this list in the order that they are returned by the
+     * specified collection's iterator.
+     *
+     * @param index index at which to insert the first element
+     *        from the specified collection
+     * @param c collection containing elements to be added to this list
+     * @return <tt>true</tt> if this list changed as a result of the call
+     * @throws IndexOutOfBoundsException {@inheritDoc}
+     * @throws NullPointerException if the specified collection is null
+     * @see #add(int,Object)
+     */
+    public boolean addAll(int index, Collection<? extends E> c) {
+        Object[] cs = c.toArray();
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            Object[] elements = getArray();
+            int len = elements.length;
+            if (index > len || index < 0)
+                throw new IndexOutOfBoundsException("Index: "+index+
+                                                    ", Size: "+len);
+            if (cs.length == 0)
+                return false;
+            int numMoved = len - index;
+            Object[] newElements;
+            if (numMoved == 0)
+                newElements = Java6Arrays.copyOf(elements, len + cs.length);
+            else {
+                newElements = new Object[len + cs.length];
+                System.arraycopy(elements, 0, newElements, 0, index);
+                System.arraycopy(elements, index,
+                                 newElements, index + cs.length,
+                                 numMoved);
+            }
+            System.arraycopy(cs, 0, newElements, index, cs.length);
+            setArray(newElements);
+            return true;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * Save the state of the list to a stream (i.e., serialize it).
+     *
+     * @serialData The length of the array backing the list is emitted
+     *               (int), followed by all of its elements (each an Object)
+     *               in the proper order.
+     * @param s the stream
+     */
+    private void writeObject(java.io.ObjectOutputStream s)
+        throws java.io.IOException{
+
+        // Write out element count, and any hidden stuff
+        s.defaultWriteObject();
+
+        Object[] elements = getArray();
+        int len = elements.length;
+        // Write out array length
+        s.writeInt(len);
+
+        // Write out all elements in the proper order.
+        for (int i = 0; i < len; i++)
+            s.writeObject(elements[i]);
+    }
+
+    /**
+     * Reconstitute the list from a stream (i.e., deserialize it).
+     * @param s the stream
+     */
+    private void readObject(java.io.ObjectInputStream s)
+        throws java.io.IOException, ClassNotFoundException {
+
+        // Read in size, and any hidden stuff
+        s.defaultReadObject();
+
+        // bind to new lock
+        resetLock();
+
+        // Read in array length and allocate array
+        int len = s.readInt();
+        Object[] elements = new Object[len];
+
+        // Read in all elements in the proper order.
+        for (int i = 0; i < len; i++)
+            elements[i] = s.readObject();
+        setArray(elements);
+    }
+
+    /**
+     * Returns a string representation of this list.  The string
+     * representation consists of the string representations of the list's
+     * elements in the order they are returned by its iterator, enclosed in
+     * square brackets (<tt>"[]"</tt>).  Adjacent elements are separated by
+     * the characters <tt>", "</tt> (comma and space).  Elements are
+     * converted to strings as by {@link String#valueOf(Object)}.
+     *
+     * @return a string representation of this list
+     */
+    public String toString() {
+        return Arrays.toString(getArray());
+    }
+
+    /**
+     * Compares the specified object with this list for equality.
+     * Returns {@code true} if the specified object is the same object
+     * as this object, or if it is also a {@link List} and the sequence
+     * of elements returned by an {@linkplain List#iterator() iterator}
+     * over the specified list is the same as the sequence returned by
+     * an iterator over this list.  The two sequences are considered to
+     * be the same if they have the same length and corresponding
+     * elements at the same position in the sequence are <em>equal</em>.
+     * Two elements {@code e1} and {@code e2} are considered
+     * <em>equal</em> if {@code (e1==null ? e2==null : e1.equals(e2))}.
+     *
+     * @param o the object to be compared for equality with this list
+     * @return {@code true} if the specified object is equal to this list
+     */
+    public boolean equals(Object o) {
+        if (o == this)
+            return true;
+        if (!(o instanceof List))
+            return false;
+
+        List<?> list = (List<?>)(o);
+        Iterator<?> it = list.iterator();
+        Object[] elements = getArray();
+        int len = elements.length;
+        for (int i = 0; i < len; ++i)
+            if (!it.hasNext() || !eq(elements[i], it.next()))
+                return false;
+        if (it.hasNext())
+            return false;
+        return true;
+    }
+
+    /**
+     * Returns the hash code value for this list.
+     *
+     * <p>This implementation uses the definition in {@link List#hashCode}.
+     *
+     * @return the hash code value for this list
+     */
+    public int hashCode() {
+        int hashCode = 1;
+        Object[] elements = getArray();
+        int len = elements.length;
+        for (int i = 0; i < len; ++i) {
+            Object obj = elements[i];
+            hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
+        }
+        return hashCode;
+    }
+
+    /**
+     * Returns an iterator over the elements in this list in proper sequence.
+     *
+     * <p>The returned iterator provides a snapshot of the state of the list
+     * when the iterator was constructed. No synchronization is needed while
+     * traversing the iterator. The iterator does <em>NOT</em> support the
+     * <tt>remove</tt> method.
+     *
+     * @return an iterator over the elements in this list in proper sequence
+     */
+    public Iterator<E> iterator() {
+        return new COWIterator<E>(getArray(), 0);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * <p>The returned iterator provides a snapshot of the state of the list
+     * when the iterator was constructed. No synchronization is needed while
+     * traversing the iterator. The iterator does <em>NOT</em> support the
+     * <tt>remove</tt>, <tt>set</tt> or <tt>add</tt> methods.
+     */
+    public ListIterator<E> listIterator() {
+        return new COWIterator<E>(getArray(), 0);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * <p>The returned iterator provides a snapshot of the state of the list
+     * when the iterator was constructed. No synchronization is needed while
+     * traversing the iterator. The iterator does <em>NOT</em> support the
+     * <tt>remove</tt>, <tt>set</tt> or <tt>add</tt> methods.
+     *
+     * @throws IndexOutOfBoundsException {@inheritDoc}
+     */
+    public ListIterator<E> listIterator(final int index) {
+        Object[] elements = getArray();
+        int len = elements.length;
+        if (index<0 || index>len)
+            throw new IndexOutOfBoundsException("Index: "+index);
+
+        return new COWIterator<E>(elements, index);
+    }
+
+    private static class COWIterator<E> implements ListIterator<E> {
+        /** Snapshot of the array **/
+        private final Object[] snapshot;
+        /** Index of element to be returned by subsequent call to next.  */
+        private int cursor;
+
+        private COWIterator(Object[] elements, int initialCursor) {
+            cursor = initialCursor;
+            snapshot = elements;
         }
 
         public boolean hasNext() {
-            if (current < size) {
-                return true;
-            }
-            return false;
+            return cursor < snapshot.length;
         }
 
         public boolean hasPrevious() {
-            return current > 0;
+            return cursor > 0;
         }
 
-        public Object next() {
-            if (hasNext()) {
-                return arr[current++];
-            }
-            throw new NoSuchElementException("pos is " + current + ", size is " + size);
+        @SuppressWarnings("unchecked")
+        public E next() {
+            if (! hasNext())
+                throw new NoSuchElementException();
+            return (E) snapshot[cursor++];
+        }
+
+        @SuppressWarnings("unchecked")
+        public E previous() {
+            if (! hasPrevious())
+                throw new NoSuchElementException();
+            return (E) snapshot[--cursor];
         }
 
         public int nextIndex() {
-            return current;
-        }
-
-        public Object previous() {
-            if (hasPrevious()) {
-                return arr[--current];
-            }
-            throw new NoSuchElementException("pos is " + (current-1) + ", size is " + size);
+            return cursor;
         }
 
         public int previousIndex() {
-            return current - 1;
+            return cursor-1;
         }
 
+        /**
+         * Not supported. Always throws UnsupportedOperationException.
+         * @throws UnsupportedOperationException always; <tt>remove</tt>
+         *         is not supported by this iterator.
+         */
         public void remove() {
-            throw new UnsupportedOperationException("Unsupported operation remove");
+            throw new UnsupportedOperationException();
         }
 
-        public void set(Object o) {
-            throw new UnsupportedOperationException("Unsupported operation set");
+        /**
+         * Not supported. Always throws UnsupportedOperationException.
+         * @throws UnsupportedOperationException always; <tt>set</tt>
+         *         is not supported by this iterator.
+         */
+        public void set(E e) {
+            throw new UnsupportedOperationException();
         }
 
-    }
-
-    /**
-     * Keeps a state of sublist implementation,
-     * size and array declared as final,
-     * so we'll never get the unconsistent state
-     */
-    static final class SubListReadData {
-        final int size;
-
-        final Object[] data;
-
-        SubListReadData(int size, Object[] data) {
-            this.size = size;
-            this.data = data;
+        /**
+         * Not supported. Always throws UnsupportedOperationException.
+         * @throws UnsupportedOperationException always; <tt>add</tt>
+         *         is not supported by this iterator.
+         */
+        public void add(E e) {
+            throw new UnsupportedOperationException();
         }
     }
 
     /**
-     * Represents a list returned by <code>sublist()</code>.
+     * Returns a view of the portion of this list between
+     * <tt>fromIndex</tt>, inclusive, and <tt>toIndex</tt>, exclusive.
+     * The returned list is backed by this list, so changes in the
+     * returned list are reflected in this list.
+     *
+     * <p>The semantics of the list returned by this method become
+     * undefined if the backing list (i.e., this list) is modified in
+     * any way other than via the returned list.
+     *
+     * @param fromIndex low endpoint (inclusive) of the subList
+     * @param toIndex high endpoint (exclusive) of the subList
+     * @return a view of the specified range within this list
+     * @throws IndexOutOfBoundsException {@inheritDoc}
      */
-    static class SubList implements List {
-        private final CopyOnWriteArrayList list;
+    public List<E> subList(int fromIndex, int toIndex) {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            Object[] elements = getArray();
+            int len = elements.length;
+            if (fromIndex < 0 || toIndex > len || fromIndex > toIndex)
+                throw new IndexOutOfBoundsException();
+            return new COWSubList<E>(this, fromIndex, toIndex);
+        } finally {
+            lock.unlock();
+        }
+    }
 
-        private volatile SubListReadData read;
+    /**
+     * Sublist for CopyOnWriteArrayList.
+     * This class extends AbstractList merely for convenience, to
+     * avoid having to define addAll, etc. This doesn't hurt, but
+     * is wasteful.  This class does not need or use modCount
+     * mechanics in AbstractList, but does need to check for
+     * concurrent modification using similar mechanics.  On each
+     * operation, the array that we expect the backing list to use
+     * is checked and updated.  Since we do this for all of the
+     * base operations invoked by those defined in AbstractList,
+     * all is well.  While inefficient, this is not worth
+     * improving.  The kinds of list operations inherited from
+     * AbstractList are already so slow on COW sublists that
+     * adding a bit more space/time doesn't seem even noticeable.
+     */
+    private static class COWSubList<E>
+        extends AbstractList<E>
+        implements RandomAccess
+    {
+        private final CopyOnWriteArrayList<E> l;
+        private final int offset;
+        private int size;
+        private Object[] expectedArray;
 
-        private final int start;
-
-        /**
-         * Sublist constructor.
-         *
-         * @param list    backing list.
-         * @param fromIdx startingIndex, inclusive
-         * @param toIdx   endIndex, exclusive
-         */
-        public SubList(CopyOnWriteArrayList list, int fromIdx, int toIdx) {
-            this.list = list;
-            Object[] data = list.getData();
-            int size = toIdx - fromIdx;
-            checkIndexExlusive(fromIdx, data.length);
-            checkIndexInclusive(toIdx, data.length);
-            read = new SubListReadData(size, list.getData());
-            start = fromIdx;
+        // only call this holding l's lock
+        COWSubList(CopyOnWriteArrayList<E> list,
+                   int fromIndex, int toIndex) {
+            l = list;
+            expectedArray = l.getArray();
+            offset = fromIndex;
+            size = toIndex - fromIndex;
         }
 
-        /**
-         * throws ConcurrentModificationException when the list
-         * is structurally modified in the other way other than via this subList
-         * <p/>
-         * Should be called under lock!
-         */
-        private void checkModifications() {
-            if (read.data != list.getData()) {
+        // only call this holding l's lock
+        private void checkForComodification() {
+            if (l.getArray() != expectedArray)
                 throw new ConcurrentModificationException();
-            }
         }
 
-        /**
-         * @see java.util.List#listIterator(int)
-         */
-        public ListIterator listIterator(int startIdx) {
-            return new SubListIterator(startIdx, read);
+        // only call this holding l's lock
+        private void rangeCheck(int index) {
+            if (index<0 || index>=size)
+                throw new IndexOutOfBoundsException("Index: "+index+
+                                                    ",Size: "+size);
         }
 
-        /**
-         * @see java.util.List#set(int, java.lang.Object)
-         */
-        public Object set(int index, Object obj) {
-            list.lock.lock();
+        public E set(int index, E element) {
+            final ReentrantLock lock = l.lock;
+            lock.lock();
             try {
-                checkIndexExlusive(index, read.size);
-                checkModifications();
-                Object result = list.set(index + start, obj);
-                read = new SubListReadData(read.size, list.getData());
-                return result;
+                rangeCheck(index);
+                checkForComodification();
+                E x = l.set(index+offset, element);
+                expectedArray = l.getArray();
+                return x;
             } finally {
-                list.lock.unlock();
+                lock.unlock();
             }
         }
 
-        /**
-         * @see java.util.List#get(int)
-         */
-        public Object get(int index) {
-            SubListReadData data = read;
-            if (data.data != list.getData()) {
-                list.lock.lock();
-                try {
-                    data = read;
-                    if (data.data != list.getData()) {
-                        throw new ConcurrentModificationException();
-                    }
-                } finally {
-                    list.lock.unlock();
-                }
+        public E get(int index) {
+            final ReentrantLock lock = l.lock;
+            lock.lock();
+            try {
+                rangeCheck(index);
+                checkForComodification();
+                return l.get(index+offset);
+            } finally {
+                lock.unlock();
             }
-            checkIndexExlusive(index, data.size);
-            return data.data[index + start];
         }
 
-        /**
-         * @see java.util.Collection#size()
-         */
         public int size() {
-            return read.size;
-        }
-
-        /**
-         * @see java.util.List#remove(int)
-         */
-        public Object remove(int index) {
-            list.lock.lock();
+            final ReentrantLock lock = l.lock;
+            lock.lock();
             try {
-                checkIndexExlusive(index, read.size);
-                checkModifications();
-                Object obj = list.remove(index + start);
-                read = new SubListReadData(read.size - 1, list.getData());
-                return obj;
+                checkForComodification();
+                return size;
             } finally {
-                list.lock.unlock();
+                lock.unlock();
             }
         }
 
-        /**
-         * @see java.util.List#add(int, java.lang.Object)
-         */
-        public void add(int index, Object object) {
-            list.lock.lock();
+        public void add(int index, E element) {
+            final ReentrantLock lock = l.lock;
+            lock.lock();
             try {
-                checkIndexInclusive(index, read.size);
-                checkModifications();
-                list.add(index + start, object);
-                read = new SubListReadData(read.size + 1, list.getData());
+                checkForComodification();
+                if (index<0 || index>size)
+                    throw new IndexOutOfBoundsException();
+                l.add(index+offset, element);
+                expectedArray = l.getArray();
+                size++;
             } finally {
-                list.lock.unlock();
-            }
-        }
-
-        public boolean add(Object o) {
-            list.lock.lock();
-            try {
-                checkModifications();
-                list.add(start + read.size, o);
-                read = new SubListReadData(read.size + 1, list.getData());
-                return true;
-            } finally {
-                list.lock.unlock();
-            }
-        }
-
-        public boolean addAll(Collection c) {
-            list.lock.lock();
-            try {
-                checkModifications();
-                int d = list.size();
-                list.addAll(start + read.size, c);
-                read = new SubListReadData(read.size + (list.size() - d), list
-                        .getData());
-                return true;
-            } finally {
-                list.lock.unlock();
+                lock.unlock();
             }
         }
 
         public void clear() {
-            list.lock.lock();
+            final ReentrantLock lock = l.lock;
+            lock.lock();
             try {
-                checkModifications();
-                list.removeRange(start, read.size);
-                read = new SubListReadData(0, list.getData());
+                checkForComodification();
+                l.removeRange(offset, offset+size);
+                expectedArray = l.getArray();
+                size = 0;
             } finally {
-                list.lock.unlock();
+                lock.unlock();
             }
         }
 
-        public boolean contains(Object o) {
-            return indexOf(o) != -1;
-        }
-
-        public boolean containsAll(Collection c) {
-            SubListReadData b = read;
-            return CopyOnWriteArrayList.containsAll(c, b.data, start, b.size);
-        }
-
-        public int indexOf(Object o) {
-            SubListReadData b = read;
-            int ind = CopyOnWriteArrayList.indexOf(o, b.data, start, b.size)
-                    - start;
-            return ind < 0 ? -1 : ind;
-        }
-
-        public boolean isEmpty() {
-            return read.size == 0;
-        }
-
-        public Iterator iterator() {
-            return new SubListIterator(0, read);
-        }
-
-        public int lastIndexOf(Object o) {
-            SubListReadData b = read;
-            int ind = CopyOnWriteArrayList
-                    .lastIndexOf(o, b.data, start, b.size)
-                    - start;
-            return ind < 0 ? -1 : ind;
-        }
-
-        public ListIterator listIterator() {
-            return new SubListIterator(0, read);
+        public E remove(int index) {
+            final ReentrantLock lock = l.lock;
+            lock.lock();
+            try {
+                rangeCheck(index);
+                checkForComodification();
+                E result = l.remove(index+offset);
+                expectedArray = l.getArray();
+                size--;
+                return result;
+            } finally {
+                lock.unlock();
+            }
         }
 
         public boolean remove(Object o) {
-            list.lock.lock();
-            try {
-                checkModifications();
-                int i = indexOf(o);
-                if (i == -1) {
-                    return false;
-                }
-                boolean result = list.remove(i + start) != null;
-                if (result) {
-                    read = new SubListReadData(read.size - 1, list.getData());
-                }
-                return result;
-            } finally {
-                list.lock.unlock();
-            }
-        }
-
-        public boolean removeAll(Collection c) {
-            list.lock.lock();
-            try {
-                checkModifications();
-                int removed = list.removeAll(c, start, read.size);
-                if (removed > 0) {
-                    read = new SubListReadData(read.size - removed, list
-                            .getData());
-                    return true;
-                }
-            } finally {
-                list.lock.unlock();
-            }
-            return false;
-        }
-
-        public boolean retainAll(Collection c) {
-            list.lock.lock();
-            try {
-                checkModifications();
-                int removed = list.retainAll(c, start, read.size);
-                if (removed > 0) {
-                    read = new SubListReadData(read.size - removed, list
-                            .getData());
-                    return true;
-                }
+            int index = indexOf(o);
+            if (index == -1)
                 return false;
-            } finally {
-                list.lock.unlock();
-            }
+            remove(index);
+            return true;
         }
 
-        public List subList(int fromIndex, int toIndex) {
-            return new SubList(list, start + fromIndex, start + toIndex);
-        }
-
-        public Object[] toArray() {
-            SubListReadData r = read;
-            return CopyOnWriteArrayList.toArray(r.data, start, r.size);
-        }
-
-        public Object[] toArray(Object[] a) {
-            SubListReadData r = read;
-            return CopyOnWriteArrayList.toArray(a, r.data, start, r.size);
-        }
-
-        /**
-         * @see java.util.List#addAll(int, java.util.Collection)
-         */
-        public boolean addAll(int index, Collection collection) {
-            list.lock.lock();
+        public Iterator<E> iterator() {
+            final ReentrantLock lock = l.lock;
+            lock.lock();
             try {
-                checkIndexInclusive(index, read.size);
-                checkModifications();
-                int d = list.size();
-                boolean rt = list.addAll(index + start, collection);
-                read = new SubListReadData(read.size + list.size() - d, list
-                        .getData());
-                return rt;
+                checkForComodification();
+                return new COWSubListIterator<E>(l, 0, offset, size);
             } finally {
-                list.lock.unlock();
+                lock.unlock();
             }
         }
 
-        /**
-         * Implementation of <code>ListIterator</code> for the
-         * <code>SubList</code>
-         * gets a snapshot of the sublist,
-         * never throws ConcurrentModificationException
-         */
-        private class SubListIterator extends ListIteratorImpl {
-            private final SubListReadData dataR;
-
-            /**
-             * Constructs an iterator starting with the given index
-             *
-             * @param index index of the first element to iterate.
-             */
-            private SubListIterator(int index, SubListReadData d) {
-                super(d.data, index + start);
-                this.dataR = d;
+        public ListIterator<E> listIterator(final int index) {
+            final ReentrantLock lock = l.lock;
+            lock.lock();
+            try {
+                checkForComodification();
+                if (index<0 || index>size)
+                    throw new IndexOutOfBoundsException("Index: "+index+
+                                                        ", Size: "+size);
+                return new COWSubListIterator<E>(l, index, offset, size);
+            } finally {
+                lock.unlock();
             }
+        }
 
-            /**
-             * @see java.util.ListIterator#nextIndex()
-             */
-            public int nextIndex() {
-                return super.nextIndex() - start;
-            }
-
-            /**
-             * @see java.util.ListIterator#previousIndex()
-             */
-            public int previousIndex() {
-                return super.previousIndex() - start;
-            }
-
-            /**
-             * @see java.util.Iterator#hasNext()
-             */
-            public boolean hasNext() {
-                return nextIndex() < dataR.size;
-            }
-
-            /**
-             * @see java.util.ListIterator#hasPrevious()
-             */
-            public boolean hasPrevious() {
-                return previousIndex() > -1;
+        public List<E> subList(int fromIndex, int toIndex) {
+            final ReentrantLock lock = l.lock;
+            lock.lock();
+            try {
+                checkForComodification();
+                if (fromIndex<0 || toIndex>size)
+                    throw new IndexOutOfBoundsException();
+                return new COWSubList<E>(l, fromIndex + offset,
+                                         toIndex + offset);
+            } finally {
+                lock.unlock();
             }
         }
 
     }
 
-    //serialization support
-    /**
-     * Writes the object state to the ObjectOutputStream.
-     *
-     * @param oos ObjectOutputStream to write object to.
-     * @throws IOException if an I/O error occur.
-     */
-    private void writeObject(ObjectOutputStream oos) throws IOException {
-        E[] back = getData();
-        int size = back.length;
-        oos.defaultWriteObject();
-        oos.writeInt(size);
-        for (int i = 0; i < size; i++) {
-            oos.writeObject(back[i]);
+
+    private static class COWSubListIterator<E> implements ListIterator<E> {
+        private final ListIterator<E> i;
+        private final int index;
+        private final int offset;
+        private final int size;
+
+        COWSubListIterator(List<E> l, int index, int offset,
+                           int size) {
+            this.index = index;
+            this.offset = offset;
+            this.size = size;
+            i = l.listIterator(index+offset);
+        }
+
+        public boolean hasNext() {
+            return nextIndex() < size;
+        }
+
+        public E next() {
+            if (hasNext())
+                return i.next();
+            else
+                throw new NoSuchElementException();
+        }
+
+        public boolean hasPrevious() {
+            return previousIndex() >= 0;
+        }
+
+        public E previous() {
+            if (hasPrevious())
+                return i.previous();
+            else
+                throw new NoSuchElementException();
+        }
+
+        public int nextIndex() {
+            return i.nextIndex() - offset;
+        }
+
+        public int previousIndex() {
+            return i.previousIndex() - offset;
+        }
+
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+
+        public void set(E e) {
+            throw new UnsupportedOperationException();
+        }
+
+        public void add(E e) {
+            throw new UnsupportedOperationException();
         }
     }
 
-    /**
-     * Reads the object state from the ObjectOutputStream.
-     *
-     * @param ois ObjectInputStream to read object from.
-     * @throws IOException if an I/O error occur.
-     */
-    private void readObject(ObjectInputStream ois) throws IOException,
-            ClassNotFoundException {
-        ois.defaultReadObject();
-        int length = ois.readInt();
-        if (length == 0) {
-            setData(newElementArray(0));
-        } else {
-            E[] back = newElementArray(length);
-            for (int i = 0; i < back.length; i++) {
-                back[i] = (E) ois.readObject();
-            }
-            setData(back);
-        }
+    // Support for resetting lock while deserializing
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+    private static final long lockOffset;
+    static {
+        try {
+            lockOffset = unsafe.objectFieldOffset
+                (CopyOnWriteArrayList.class.getDeclaredField("lock"));
+            } catch (Exception ex) { throw new Error(ex); }
+    }
+    private void resetLock() {
+        unsafe.putObjectVolatile(this, lockOffset, new ReentrantLock());
     }
 }
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArraySet.java b/libcore/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArraySet.java
index 532952b..65a05de 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArraySet.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArraySet.java
@@ -1,7 +1,7 @@
 /*
  * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain. Use, modify, and
- * redistribute this code in any way without acknowledgement.
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
  */
 
 package java.util.concurrent;
@@ -9,39 +9,37 @@
 
 // BEGIN android-note
 // removed link to collections framework docs
-// Removed clonable interface to be closer to the RI.
 // END android-note
 
 /**
- * A {@link java.util.Set} that uses {@link
- * java.util.concurrent.CopyOnWriteArrayList} for all of its
- * operations.  Thus, it shares the same basic properties:
+ * A {@link java.util.Set} that uses an internal {@link CopyOnWriteArrayList}
+ * for all of its operations.  Thus, it shares the same basic properties:
  * <ul>
  *  <li>It is best suited for applications in which set sizes generally
  *       stay small, read-only operations
  *       vastly outnumber mutative operations, and you need
  *       to prevent interference among threads during traversal.
- *  <li>Mutative operations(add, set, remove, etc) are expensive
- *      since they usually entail copying the entire underlying array.
- *  <li>Iterators do not support the mutative remove operation
- *  <li>Traversal via iterators is very fast and cannot ever encounter
+ *  <li>It is thread-safe.
+ *  <li>Mutative operations (<tt>add</tt>, <tt>set</tt>, <tt>remove</tt>, etc.)
+ *      are expensive since they usually entail copying the entire underlying
+ *      array.
+ *  <li>Iterators do not support the mutative <tt>remove</tt> operation.
+ *  <li>Traversal via iterators is fast and cannot encounter
  *      interference from other threads. Iterators rely on
  *      unchanging snapshots of the array at the time the iterators were
- *     constructed.
+ *      constructed.
  * </ul>
- * <p>
- * <b>Sample Usage.</b> Probably the main application
- * of copy-on-write sets are classes that maintain
- * sets of Handler objects
- * that must be multicasted to upon an update command. This
- * is a classic case where you do not want to be holding a
- * lock while sending a message, and where traversals normally
- * vastly overwhelm additions.
+ *
+ * <p> <b>Sample Usage.</b> The following code sketch uses a
+ * copy-on-write set to maintain a set of Handler objects that
+ * perform some action upon state updates.
+ *
  * <pre>
  * class Handler { void handle(); ... }
  *
  * class X {
- *    private final CopyOnWriteArraySet&lt;Handler&gt; handlers = new CopyOnWriteArraySet&lt;Handler&gt;();
+ *    private final CopyOnWriteArraySet&lt;Handler&gt; handlers
+ *       = new CopyOnWriteArraySet&lt;Handler&gt;();
  *    public void addHandler(Handler h) { handlers.add(h); }
  *
  *    private long internalState;
@@ -49,14 +47,13 @@
  *
  *    public void update() {
  *       changeState();
- *       Iterator it = handlers.iterator();
- *       while (it.hasNext())
- *          it.next().handle();
+ *       for (Handler handler : handlers)
+ *          handler.handle();
  *    }
  * }
  * </pre>
- * @see CopyOnWriteArrayList
  *
+ * @see CopyOnWriteArrayList
  * @since 1.5
  * @author Doug Lea
  * @param <E> the type of elements held in this collection
@@ -76,27 +73,292 @@
 
     /**
      * Creates a set containing all of the elements of the specified
-     * Collection.
-     * @param c the collection
+     * collection.
+     *
+     * @param c the collection of elements to initially contain
+     * @throws NullPointerException if the specified collection is null
      */
     public CopyOnWriteArraySet(Collection<? extends E> c) {
         al = new CopyOnWriteArrayList<E>();
         al.addAllAbsent(c);
     }
 
+    /**
+     * Returns the number of elements in this set.
+     *
+     * @return the number of elements in this set
+     */
+    public int size() {
+        return al.size();
+    }
 
-    public int      size()                    { return al.size(); }
-    public boolean  isEmpty()                 { return al.isEmpty(); }
-    public boolean  contains(Object o)        { return al.contains(o); }
-    public Object[] toArray()                 { return al.toArray(); }
-    public <T> T[]  toArray(T[] a)            { return al.toArray(a); }
-    public void     clear()                   {        al.clear(); }
-    public Iterator<E>  iterator()            { return al.iterator(); }
-    public boolean  remove(Object o)          { return al.remove(o); }
-    public boolean  add(E o)                  { return al.addIfAbsent(o); }
-    public boolean  containsAll(Collection<?> c)      { return al.containsAll(c); }
-    public boolean  addAll(Collection<? extends E> c) { return al.addAllAbsent(c) > 0; }
-    public boolean  removeAll(Collection<?> c)        { return al.removeAll(c); }
-    public boolean  retainAll(Collection<?> c)        { return al.retainAll(c); }
+    /**
+     * Returns <tt>true</tt> if this set contains no elements.
+     *
+     * @return <tt>true</tt> if this set contains no elements
+     */
+    public boolean isEmpty() {
+        return al.isEmpty();
+    }
 
+    /**
+     * Returns <tt>true</tt> if this set contains the specified element.
+     * More formally, returns <tt>true</tt> if and only if this set
+     * contains an element <tt>e</tt> such that
+     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
+     *
+     * @param o element whose presence in this set is to be tested
+     * @return <tt>true</tt> if this set contains the specified element
+     */
+    public boolean contains(Object o) {
+        return al.contains(o);
+    }
+
+    /**
+     * Returns an array containing all of the elements in this set.
+     * If this set makes any guarantees as to what order its elements
+     * are returned by its iterator, this method must return the
+     * elements in the same order.
+     *
+     * <p>The returned array will be "safe" in that no references to it
+     * are maintained by this set.  (In other words, this method must
+     * allocate a new array even if this set is backed by an array).
+     * The caller is thus free to modify the returned array.
+     *
+     * <p>This method acts as bridge between array-based and collection-based
+     * APIs.
+     *
+     * @return an array containing all the elements in this set
+     */
+    public Object[] toArray() {
+        return al.toArray();
+    }
+
+    /**
+     * Returns an array containing all of the elements in this set; the
+     * runtime type of the returned array is that of the specified array.
+     * If the set fits in the specified array, it is returned therein.
+     * Otherwise, a new array is allocated with the runtime type of the
+     * specified array and the size of this set.
+     *
+     * <p>If this set fits in the specified array with room to spare
+     * (i.e., the array has more elements than this set), the element in
+     * the array immediately following the end of the set is set to
+     * <tt>null</tt>.  (This is useful in determining the length of this
+     * set <i>only</i> if the caller knows that this set does not contain
+     * any null elements.)
+     *
+     * <p>If this set makes any guarantees as to what order its elements
+     * are returned by its iterator, this method must return the elements
+     * in the same order.
+     *
+     * <p>Like the {@link #toArray()} method, this method acts as bridge between
+     * array-based and collection-based APIs.  Further, this method allows
+     * precise control over the runtime type of the output array, and may,
+     * under certain circumstances, be used to save allocation costs.
+     *
+     * <p>Suppose <tt>x</tt> is a set known to contain only strings.
+     * The following code can be used to dump the set into a newly allocated
+     * array of <tt>String</tt>:
+     *
+     * <pre>
+     *     String[] y = x.toArray(new String[0]);</pre>
+     *
+     * Note that <tt>toArray(new Object[0])</tt> is identical in function to
+     * <tt>toArray()</tt>.
+     *
+     * @param a the array into which the elements of this set are to be
+     *        stored, if it is big enough; otherwise, a new array of the same
+     *        runtime type is allocated for this purpose.
+     * @return an array containing all the elements in this set
+     * @throws ArrayStoreException if the runtime type of the specified array
+     *         is not a supertype of the runtime type of every element in this
+     *         set
+     * @throws NullPointerException if the specified array is null
+     */
+    public <T> T[] toArray(T[] a) {
+        return al.toArray(a);
+    }
+
+    /**
+     * Removes all of the elements from this set.
+     * The set will be empty after this call returns.
+     */
+    public void clear() {
+        al.clear();
+    }
+
+    /**
+     * Removes the specified element from this set if it is present.
+     * More formally, removes an element <tt>e</tt> such that
+     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>,
+     * if this set contains such an element.  Returns <tt>true</tt> if
+     * this set contained the element (or equivalently, if this set
+     * changed as a result of the call).  (This set will not contain the
+     * element once the call returns.)
+     *
+     * @param o object to be removed from this set, if present
+     * @return <tt>true</tt> if this set contained the specified element
+     */
+    public boolean remove(Object o) {
+        return al.remove(o);
+    }
+
+    /**
+     * Adds the specified element to this set if it is not already present.
+     * More formally, adds the specified element <tt>e</tt> to this set if
+     * the set contains no element <tt>e2</tt> such that
+     * <tt>(e==null&nbsp;?&nbsp;e2==null&nbsp;:&nbsp;e.equals(e2))</tt>.
+     * If this set already contains the element, the call leaves the set
+     * unchanged and returns <tt>false</tt>.
+     *
+     * @param e element to be added to this set
+     * @return <tt>true</tt> if this set did not already contain the specified
+     *         element
+     */
+    public boolean add(E e) {
+        return al.addIfAbsent(e);
+    }
+
+    /**
+     * Returns <tt>true</tt> if this set contains all of the elements of the
+     * specified collection.  If the specified collection is also a set, this
+     * method returns <tt>true</tt> if it is a <i>subset</i> of this set.
+     *
+     * @param  c collection to be checked for containment in this set
+     * @return <tt>true</tt> if this set contains all of the elements of the
+     *         specified collection
+     * @throws NullPointerException if the specified collection is null
+     * @see #contains(Object)
+     */
+    public boolean containsAll(Collection<?> c) {
+        return al.containsAll(c);
+    }
+
+    /**
+     * Adds all of the elements in the specified collection to this set if
+     * they're not already present.  If the specified collection is also a
+     * set, the <tt>addAll</tt> operation effectively modifies this set so
+     * that its value is the <i>union</i> of the two sets.  The behavior of
+     * this operation is undefined if the specified collection is modified
+     * while the operation is in progress.
+     *
+     * @param  c collection containing elements to be added to this set
+     * @return <tt>true</tt> if this set changed as a result of the call
+     * @throws NullPointerException if the specified collection is null
+     * @see #add(Object)
+     */
+    public boolean addAll(Collection<? extends E> c) {
+        return al.addAllAbsent(c) > 0;
+    }
+
+    /**
+     * Removes from this set all of its elements that are contained in the
+     * specified collection.  If the specified collection is also a set,
+     * this operation effectively modifies this set so that its value is the
+     * <i>asymmetric set difference</i> of the two sets.
+     *
+     * @param  c collection containing elements to be removed from this set
+     * @return <tt>true</tt> if this set changed as a result of the call
+     * @throws ClassCastException if the class of an element of this set
+     *         is incompatible with the specified collection (optional)
+     * @throws NullPointerException if this set contains a null element and the
+     *         specified collection does not permit null elements (optional),
+     *         or if the specified collection is null
+     * @see #remove(Object)
+     */
+    public boolean removeAll(Collection<?> c) {
+        return al.removeAll(c);
+    }
+
+    /**
+     * Retains only the elements in this set that are contained in the
+     * specified collection.  In other words, removes from this set all of
+     * its elements that are not contained in the specified collection.  If
+     * the specified collection is also a set, this operation effectively
+     * modifies this set so that its value is the <i>intersection</i> of the
+     * two sets.
+     *
+     * @param  c collection containing elements to be retained in this set
+     * @return <tt>true</tt> if this set changed as a result of the call
+     * @throws ClassCastException if the class of an element of this set
+     *         is incompatible with the specified collection (optional)
+     * @throws NullPointerException if this set contains a null element and the
+     *         specified collection does not permit null elements (optional),
+     *         or if the specified collection is null
+     * @see #remove(Object)
+     */
+    public boolean retainAll(Collection<?> c) {
+        return al.retainAll(c);
+    }
+
+    /**
+     * Returns an iterator over the elements contained in this set
+     * in the order in which these elements were added.
+     *
+     * <p>The returned iterator provides a snapshot of the state of the set
+     * when the iterator was constructed. No synchronization is needed while
+     * traversing the iterator. The iterator does <em>NOT</em> support the
+     * <tt>remove</tt> method.
+     *
+     * @return an iterator over the elements in this set
+     */
+    public Iterator<E> iterator() {
+        return al.iterator();
+    }
+
+    /**
+     * Compares the specified object with this set for equality.
+     * Returns {@code true} if the specified object is the same object
+     * as this object, or if it is also a {@link Set} and the elements
+     * returned by an {@linkplain List#iterator() iterator} over the
+     * specified set are the same as the elements returned by an
+     * iterator over this set.  More formally, the two iterators are
+     * considered to return the same elements if they return the same
+     * number of elements and for every element {@code e1} returned by
+     * the iterator over the specified set, there is an element
+     * {@code e2} returned by the iterator over this set such that
+     * {@code (e1==null ? e2==null : e1.equals(e2))}.
+     *
+     * @param o object to be compared for equality with this set
+     * @return {@code true} if the specified object is equal to this set
+     */
+    public boolean equals(Object o) {
+        if (o == this)
+            return true;
+        if (!(o instanceof Set))
+            return false;
+        Set<?> set = (Set<?>)(o);
+        Iterator<?> it = set.iterator();
+
+        // Uses O(n^2) algorithm that is only appropriate
+        // for small sets, which CopyOnWriteArraySets should be.
+
+        //  Use a single snapshot of underlying array
+        Object[] elements = al.getArray();
+        int len = elements.length;
+        // Mark matched elements to avoid re-checking
+        boolean[] matched = new boolean[len];
+        int k = 0;
+        outer: while (it.hasNext()) {
+            if (++k > len)
+                return false;
+            Object x = it.next();
+            for (int i = 0; i < len; ++i) {
+                if (!matched[i] && eq(x, elements[i])) {
+                    matched[i] = true;
+                    continue outer;
+                }
+            }
+            return false;
+        }
+        return k == len;
+    }
+
+    /**
+     * Test for equality, coping with nulls.
+     */
+    private static boolean eq(Object o1, Object o2) {
+        return (o1 == null ? o2 == null : o1.equals(o2));
+    }
 }
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/CountDownLatch.java b/libcore/concurrent/src/main/java/java/util/concurrent/CountDownLatch.java
index 721744c..2b945dd 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/CountDownLatch.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/CountDownLatch.java
@@ -12,25 +12,25 @@
  * A synchronization aid that allows one or more threads to wait until
  * a set of operations being performed in other threads completes.
  *
- * <p>A <tt>CountDownLatch</tt> is initialized with a given
- * <em>count</em>.  The {@link #await await} methods block until the current
- * {@link #getCount count} reaches zero due to invocations of the
- * {@link #countDown} method, after which all waiting threads are
- * released and any subsequent invocations of {@link #await await} return
- * immediately. This is a one-shot phenomenon -- the count cannot be
- * reset.  If you need a version that resets the count, consider using
- * a {@link CyclicBarrier}.
+ * <p>A {@code CountDownLatch} is initialized with a given <em>count</em>.
+ * The {@link #await await} methods block until the current count reaches
+ * zero due to invocations of the {@link #countDown} method, after which
+ * all waiting threads are released and any subsequent invocations of
+ * {@link #await await} return immediately.  This is a one-shot phenomenon
+ * -- the count cannot be reset.  If you need a version that resets the
+ * count, consider using a {@link CyclicBarrier}.
  *
- * <p>A <tt>CountDownLatch</tt> is a versatile synchronization tool
+ * <p>A {@code CountDownLatch} is a versatile synchronization tool
  * and can be used for a number of purposes.  A
- * <tt>CountDownLatch</tt> initialized with a count of one serves as a
+ * {@code CountDownLatch} initialized with a count of one serves as a
  * simple on/off latch, or gate: all threads invoking {@link #await await}
  * wait at the gate until it is opened by a thread invoking {@link
- * #countDown}.  A <tt>CountDownLatch</tt> initialized to <em>N</em>
+ * #countDown}.  A {@code CountDownLatch} initialized to <em>N</em>
  * can be used to make one thread wait until <em>N</em> threads have
  * completed some action, or some action has been completed N times.
- * <p>A useful property of a <tt>CountDownLatch</tt> is that it
- * doesn't require that threads calling <tt>countDown</tt> wait for
+ *
+ * <p>A useful property of a {@code CountDownLatch} is that it
+ * doesn't require that threads calling {@code countDown} wait for
  * the count to reach zero before proceeding, it simply prevents any
  * thread from proceeding past an {@link #await await} until all
  * threads could pass.
@@ -119,6 +119,13 @@
  *
  * </pre>
  *
+ * <p>Memory consistency effects: Until the count reaches
+ * zero, actions in a thread prior to calling
+ * {@code countDown()}
+ * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
+ * actions following a successful return from a corresponding
+ * {@code await()} in another thread.
+ *
  * @since 1.5
  * @author Doug Lea
  */
@@ -128,118 +135,120 @@
      * Uses AQS state to represent count.
      */
     private static final class Sync extends AbstractQueuedSynchronizer {
+        private static final long serialVersionUID = 4982264981922014374L;
+
         Sync(int count) {
-            setState(count); 
+            setState(count);
         }
-        
+
         int getCount() {
             return getState();
         }
 
-        public int tryAcquireShared(int acquires) {
+        protected int tryAcquireShared(int acquires) {
             return getState() == 0? 1 : -1;
         }
-        
-        public boolean tryReleaseShared(int releases) {
+
+        protected boolean tryReleaseShared(int releases) {
             // Decrement count; signal when transition to zero
             for (;;) {
                 int c = getState();
                 if (c == 0)
                     return false;
                 int nextc = c-1;
-                if (compareAndSetState(c, nextc)) 
+                if (compareAndSetState(c, nextc))
                     return nextc == 0;
             }
         }
     }
 
     private final Sync sync;
+
     /**
-     * Constructs a <tt>CountDownLatch</tt> initialized with the given
-     * count.
-     * 
-     * @param count the number of times {@link #countDown} must be invoked
-     * before threads can pass through {@link #await}.
+     * Constructs a {@code CountDownLatch} initialized with the given count.
      *
-     * @throws IllegalArgumentException if <tt>count</tt> is less than zero.
+     * @param count the number of times {@link #countDown} must be invoked
+     *        before threads can pass through {@link #await}
+     * @throws IllegalArgumentException if {@code count} is negative
      */
-    public CountDownLatch(int count) { 
+    public CountDownLatch(int count) {
         if (count < 0) throw new IllegalArgumentException("count < 0");
         this.sync = new Sync(count);
     }
 
     /**
-     * Causes the current thread to wait until the latch has counted down to 
-     * zero, unless the thread is {@link Thread#interrupt interrupted}.
+     * Causes the current thread to wait until the latch has counted down to
+     * zero, unless the thread is {@linkplain Thread#interrupt interrupted}.
      *
-     * <p>If the current {@link #getCount count} is zero then this method
-     * returns immediately.
-     * <p>If the current {@link #getCount count} is greater than zero then
-     * the current thread becomes disabled for thread scheduling 
-     * purposes and lies dormant until one of two things happen:
+     * <p>If the current count is zero then this method returns immediately.
+     *
+     * <p>If the current count is greater than zero then the current
+     * thread becomes disabled for thread scheduling purposes and lies
+     * dormant until one of two things happen:
      * <ul>
      * <li>The count reaches zero due to invocations of the
      * {@link #countDown} method; or
-     * <li>Some other thread {@link Thread#interrupt interrupts} the current
-     * thread.
+     * <li>Some other thread {@linkplain Thread#interrupt interrupts}
+     * the current thread.
      * </ul>
+     *
      * <p>If the current thread:
      * <ul>
-     * <li>has its interrupted status set on entry to this method; or 
-     * <li>is {@link Thread#interrupt interrupted} while waiting, 
+     * <li>has its interrupted status set on entry to this method; or
+     * <li>is {@linkplain Thread#interrupt interrupted} while waiting,
      * </ul>
-     * then {@link InterruptedException} is thrown and the current thread's 
-     * interrupted status is cleared. 
+     * then {@link InterruptedException} is thrown and the current thread's
+     * interrupted status is cleared.
      *
      * @throws InterruptedException if the current thread is interrupted
-     * while waiting.
+     *         while waiting
      */
     public void await() throws InterruptedException {
         sync.acquireSharedInterruptibly(1);
     }
 
     /**
-     * Causes the current thread to wait until the latch has counted down to 
-     * zero, unless the thread is {@link Thread#interrupt interrupted},
+     * Causes the current thread to wait until the latch has counted down to
+     * zero, unless the thread is {@linkplain Thread#interrupt interrupted},
      * or the specified waiting time elapses.
      *
-     * <p>If the current {@link #getCount count} is zero then this method
-     * returns immediately with the value <tt>true</tt>.
+     * <p>If the current count is zero then this method returns immediately
+     * with the value {@code true}.
      *
-     * <p>If the current {@link #getCount count} is greater than zero then
-     * the current thread becomes disabled for thread scheduling 
-     * purposes and lies dormant until one of three things happen:
+     * <p>If the current count is greater than zero then the current
+     * thread becomes disabled for thread scheduling purposes and lies
+     * dormant until one of three things happen:
      * <ul>
      * <li>The count reaches zero due to invocations of the
      * {@link #countDown} method; or
-     * <li>Some other thread {@link Thread#interrupt interrupts} the current
-     * thread; or
+     * <li>Some other thread {@linkplain Thread#interrupt interrupts}
+     * the current thread; or
      * <li>The specified waiting time elapses.
      * </ul>
+     *
      * <p>If the count reaches zero then the method returns with the
-     * value <tt>true</tt>.
+     * value {@code true}.
+     *
      * <p>If the current thread:
      * <ul>
-     * <li>has its interrupted status set on entry to this method; or 
-     * <li>is {@link Thread#interrupt interrupted} while waiting, 
+     * <li>has its interrupted status set on entry to this method; or
+     * <li>is {@linkplain Thread#interrupt interrupted} while waiting,
      * </ul>
-     * then {@link InterruptedException} is thrown and the current thread's 
-     * interrupted status is cleared. 
+     * then {@link InterruptedException} is thrown and the current thread's
+     * interrupted status is cleared.
      *
-     * <p>If the specified waiting time elapses then the value <tt>false</tt>
-     * is returned.
-     * If the time is 
-     * less than or equal to zero, the method will not wait at all.
+     * <p>If the specified waiting time elapses then the value {@code false}
+     * is returned.  If the time is less than or equal to zero, the method
+     * will not wait at all.
      *
      * @param timeout the maximum time to wait
-     * @param unit the time unit of the <tt>timeout</tt> argument.
-     * @return <tt>true</tt> if the count reached zero  and <tt>false</tt>
-     * if the waiting time elapsed before the count reached zero.
-     *
+     * @param unit the time unit of the {@code timeout} argument
+     * @return {@code true} if the count reached zero and {@code false}
+     *         if the waiting time elapsed before the count reached zero
      * @throws InterruptedException if the current thread is interrupted
-     * while waiting.
+     *         while waiting
      */
-    public boolean await(long timeout, TimeUnit unit) 
+    public boolean await(long timeout, TimeUnit unit)
         throws InterruptedException {
         return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
     }
@@ -247,11 +256,12 @@
     /**
      * Decrements the count of the latch, releasing all waiting threads if
      * the count reaches zero.
-     * <p>If the current {@link #getCount count} is greater than zero then
-     * it is decremented. If the new count is zero then all waiting threads
-     * are re-enabled for thread scheduling purposes.
-     * <p>If the current {@link #getCount count} equals zero then nothing
-     * happens.
+     *
+     * <p>If the current count is greater than zero then it is decremented.
+     * If the new count is zero then all waiting threads are re-enabled for
+     * thread scheduling purposes.
+     *
+     * <p>If the current count equals zero then nothing happens.
      */
     public void countDown() {
         sync.releaseShared(1);
@@ -259,8 +269,10 @@
 
     /**
      * Returns the current count.
+     *
      * <p>This method is typically used for debugging and testing purposes.
-     * @return the current count.
+     *
+     * @return the current count
      */
     public long getCount() {
         return sync.getCount();
@@ -268,13 +280,12 @@
 
     /**
      * Returns a string identifying this latch, as well as its state.
-     * The state, in brackets, includes the String 
-     * &quot;Count =&quot; followed by the current count.
-     * @return a string identifying this latch, as well as its
-     * state
+     * The state, in brackets, includes the String {@code "Count ="}
+     * followed by the current count.
+     *
+     * @return a string identifying this latch, as well as its state
      */
     public String toString() {
         return super.toString() + "[Count = " + sync.getCount() + "]";
     }
-
 }
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/CyclicBarrier.java b/libcore/concurrent/src/main/java/java/util/concurrent/CyclicBarrier.java
index d70c4c7..d5738c5 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/CyclicBarrier.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/CyclicBarrier.java
@@ -17,10 +17,10 @@
  *
  * <p>A <tt>CyclicBarrier</tt> supports an optional {@link Runnable} command
  * that is run once per barrier point, after the last thread in the party
- * arrives, but before any threads are released. 
+ * arrives, but before any threads are released.
  * This <em>barrier action</em> is useful
  * for updating shared-state before any of the parties continue.
- * 
+ *
  * <p><b>Sample usage:</b> Here is an example of
  *  using a barrier in a parallel decomposition design:
  * <pre>
@@ -28,7 +28,7 @@
  *   final int N;
  *   final float[][] data;
  *   final CyclicBarrier barrier;
- *   
+ *
  *   class Worker implements Runnable {
  *     int myRow;
  *     Worker(int row) { myRow = row; }
@@ -37,11 +37,11 @@
  *         processRow(myRow);
  *
  *         try {
- *           barrier.await(); 
- *         } catch (InterruptedException ex) { 
- *           return; 
- *         } catch (BrokenBarrierException ex) { 
- *           return; 
+ *           barrier.await();
+ *         } catch (InterruptedException ex) {
+ *           return;
+ *         } catch (BrokenBarrierException ex) {
+ *           return;
  *         }
  *       }
  *     }
@@ -50,22 +50,22 @@
  *   public Solver(float[][] matrix) {
  *     data = matrix;
  *     N = matrix.length;
- *     barrier = new CyclicBarrier(N, 
+ *     barrier = new CyclicBarrier(N,
  *                                 new Runnable() {
- *                                   public void run() { 
- *                                     mergeRows(...); 
+ *                                   public void run() {
+ *                                     mergeRows(...);
  *                                   }
  *                                 });
- *     for (int i = 0; i < N; ++i) 
+ *     for (int i = 0; i < N; ++i)
  *       new Thread(new Worker(i)).start();
  *
  *     waitUntilDone();
  *   }
  * }
  * </pre>
- * Here, each worker thread processes a row of the matrix then waits at the 
+ * Here, each worker thread processes a row of the matrix then waits at the
  * barrier until all rows have been processed. When all rows are processed
- * the supplied {@link Runnable} barrier action is executed and merges the 
+ * the supplied {@link Runnable} barrier action is executed and merges the
  * rows. If the merger
  * determines that a solution has been found then <tt>done()</tt> will return
  * <tt>true</tt> and each worker will terminate.
@@ -74,19 +74,26 @@
  * it is executed, then any of the threads in the party could execute that
  * action when it is released. To facilitate this, each invocation of
  * {@link #await} returns the arrival index of that thread at the barrier.
- * You can then choose which thread should execute the barrier action, for 
+ * You can then choose which thread should execute the barrier action, for
  * example:
  * <pre>  if (barrier.await() == 0) {
  *     // log the completion of this iteration
  *   }</pre>
  *
- * <p>The <tt>CyclicBarrier</tt> uses a fast-fail all-or-none breakage
- * model for failed synchronization attempts: If a thread leaves a
- * barrier point prematurely because of interruption, failure, or
- * timeout, all other threads, even those that have not yet resumed
- * from a previous {@link #await}. will also leave abnormally via
- * {@link BrokenBarrierException} (or <tt>InterruptedException</tt> if
- * they too were interrupted at about the same time).
+ * <p>The <tt>CyclicBarrier</tt> uses an all-or-none breakage model
+ * for failed synchronization attempts: If a thread leaves a barrier
+ * point prematurely because of interruption, failure, or timeout, all
+ * other threads waiting at that barrier point will also leave
+ * abnormally via {@link BrokenBarrierException} (or
+ * {@link InterruptedException} if they too were interrupted at about
+ * the same time).
+ *
+ * <p>Memory consistency effects: Actions in a thread prior to calling
+ * {@code await()}
+ * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
+ * actions that are part of the barrier action, which in turn
+ * <i>happen-before</i> actions following a successful return from the
+ * corresponding {@code await()} in other threads.
  *
  * @since 1.5
  * @see CountDownLatch
@@ -94,6 +101,21 @@
  * @author Doug Lea
  */
 public class CyclicBarrier {
+    /**
+     * Each use of the barrier is represented as a generation instance.
+     * The generation changes whenever the barrier is tripped, or
+     * is reset. There can be many generations associated with threads
+     * using the barrier - due to the non-deterministic way the lock
+     * may be allocated to waiting threads - but only one of these
+     * can be active at a time (the one to which <tt>count</tt> applies)
+     * and all the rest are either broken or tripped.
+     * There need not be an active generation if there has been a break
+     * but no subsequent reset.
+     */
+    private static class Generation {
+        boolean broken = false;
+    }
+
     /** The lock for guarding barrier entry */
     private final ReentrantLock lock = new ReentrantLock();
     /** Condition to wait on until tripped */
@@ -102,53 +124,50 @@
     private final int parties;
     /* The command to run when tripped */
     private final Runnable barrierCommand;
-
-    /**
-     * The generation number. Incremented upon barrier trip.
-     * Retracted upon reset.
-     */
-    private long generation; 
-
-    /** 
-     * Breakage indicator.
-     */
-    private boolean broken; 
+    /** The current generation */
+    private Generation generation = new Generation();
 
     /**
      * Number of parties still waiting. Counts down from parties to 0
-     * on each cycle.
+     * on each generation.  It is reset to parties on each new
+     * generation or when broken.
      */
-    private int count; 
+    private int count;
 
     /**
-     * Updates state on barrier trip and wake up everyone.
-     */  
+     * Updates state on barrier trip and wakes up everyone.
+     * Called only while holding lock.
+     */
     private void nextGeneration() {
-        count = parties;
-        ++generation;
+        // signal completion of last generation
         trip.signalAll();
+        // set up next generation
+        count = parties;
+        generation = new Generation();
     }
 
     /**
-     * Sets barrier as broken and wake up everyone
+     * Sets current barrier generation as broken and wakes up everyone.
+     * Called only while holding lock.
      */
     private void breakBarrier() {
-        broken = true;
+        generation.broken = true;
+        count = parties;
         trip.signalAll();
     }
 
     /**
      * Main barrier code, covering the various policies.
      */
-    private int dowait(boolean timed, long nanos) 
-        throws InterruptedException, BrokenBarrierException, TimeoutException {
+    private int dowait(boolean timed, long nanos)
+        throws InterruptedException, BrokenBarrierException,
+               TimeoutException {
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            int index = --count;
-            long g = generation;
+            final Generation g = generation;
 
-            if (broken) 
+            if (g.broken)
                 throw new BrokenBarrierException();
 
             if (Thread.interrupted()) {
@@ -156,37 +175,45 @@
                 throw new InterruptedException();
             }
 
-            if (index == 0) {  // tripped
-                nextGeneration();
-                boolean ranAction = false;
-                try {
-                    Runnable command = barrierCommand;
-                    if (command != null) 
-                        command.run();
-                    ranAction = true;
-                    return 0;
-                } finally {
-                    if (!ranAction)
-                        breakBarrier();
-                }
-            }
+           int index = --count;
+           if (index == 0) {  // tripped
+               boolean ranAction = false;
+               try {
+                   final Runnable command = barrierCommand;
+                   if (command != null)
+                       command.run();
+                   ranAction = true;
+                   nextGeneration();
+                   return 0;
+               } finally {
+                   if (!ranAction)
+                       breakBarrier();
+               }
+           }
 
+            // loop until tripped, broken, interrupted, or timed out
             for (;;) {
                 try {
-                    if (!timed) 
+                    if (!timed)
                         trip.await();
                     else if (nanos > 0L)
                         nanos = trip.awaitNanos(nanos);
                 } catch (InterruptedException ie) {
-                    breakBarrier();
-                    throw ie;
+                    if (g == generation && ! g.broken) {
+                        breakBarrier();
+                        throw ie;
+                    } else {
+                        // We're about to finish waiting even if we had not
+                        // been interrupted, so this interrupt is deemed to
+                        // "belong" to subsequent execution.
+                        Thread.currentThread().interrupt();
+                    }
                 }
-                
-                if (broken || 
-                    g > generation) // true if a reset occurred while waiting
+
+                if (g.broken)
                     throw new BrokenBarrierException();
 
-                if (g < generation)
+                if (g != generation)
                     return index;
 
                 if (timed && nanos <= 0L) {
@@ -194,7 +221,6 @@
                     throw new TimeoutException();
                 }
             }
-
         } finally {
             lock.unlock();
         }
@@ -207,15 +233,14 @@
      * performed by the last thread entering the barrier.
      *
      * @param parties the number of threads that must invoke {@link #await}
-     * before the barrier is tripped.
+     *        before the barrier is tripped
      * @param barrierAction the command to execute when the barrier is
-     * tripped, or <tt>null</tt> if there is no action.
-     *
-     * @throws IllegalArgumentException if <tt>parties</tt> is less than 1.
+     *        tripped, or {@code null} if there is no action
+     * @throws IllegalArgumentException if {@code parties} is less than 1
      */
     public CyclicBarrier(int parties, Runnable barrierAction) {
         if (parties <= 0) throw new IllegalArgumentException();
-        this.parties = parties; 
+        this.parties = parties;
         this.count = parties;
         this.barrierCommand = barrierAction;
     }
@@ -223,12 +248,11 @@
     /**
      * Creates a new <tt>CyclicBarrier</tt> that will trip when the
      * given number of parties (threads) are waiting upon it, and
-     * does not perform a predefined action upon each barrier.
+     * does not perform a predefined action when the barrier is tripped.
      *
      * @param parties the number of threads that must invoke {@link #await}
-     * before the barrier is tripped.
-     *
-     * @throws IllegalArgumentException if <tt>parties</tt> is less than 1.
+     *        before the barrier is tripped
+     * @throws IllegalArgumentException if {@code parties} is less than 1
      */
     public CyclicBarrier(int parties) {
         this(parties, null);
@@ -236,64 +260,66 @@
 
     /**
      * Returns the number of parties required to trip this barrier.
-     * @return the number of parties required to trip this barrier.
-     **/
+     *
+     * @return the number of parties required to trip this barrier
+     */
     public int getParties() {
         return parties;
     }
 
     /**
-     * Waits until all {@link #getParties parties} have invoked <tt>await</tt>
-     * on this barrier.
+     * Waits until all {@linkplain #getParties parties} have invoked
+     * <tt>await</tt> on this barrier.
      *
      * <p>If the current thread is not the last to arrive then it is
      * disabled for thread scheduling purposes and lies dormant until
-     * one of following things happens:
+     * one of the following things happens:
      * <ul>
      * <li>The last thread arrives; or
-     * <li>Some other thread {@link Thread#interrupt interrupts} the current
-     * thread; or
-     * <li>Some other thread  {@link Thread#interrupt interrupts} one of the
-     * other waiting threads; or
+     * <li>Some other thread {@linkplain Thread#interrupt interrupts}
+     * the current thread; or
+     * <li>Some other thread {@linkplain Thread#interrupt interrupts}
+     * one of the other waiting threads; or
      * <li>Some other thread times out while waiting for barrier; or
      * <li>Some other thread invokes {@link #reset} on this barrier.
      * </ul>
+     *
      * <p>If the current thread:
      * <ul>
      * <li>has its interrupted status set on entry to this method; or
-     * <li>is {@link Thread#interrupt interrupted} while waiting
+     * <li>is {@linkplain Thread#interrupt interrupted} while waiting
      * </ul>
      * then {@link InterruptedException} is thrown and the current thread's
      * interrupted status is cleared.
      *
-     * <p>If the barrier is {@link #reset} while any thread is waiting, or if 
-     * the barrier {@link #isBroken is broken} when <tt>await</tt> is invoked,
-     * or while any thread is waiting,
-     * then {@link BrokenBarrierException} is thrown.
+     * <p>If the barrier is {@link #reset} while any thread is waiting,
+     * or if the barrier {@linkplain #isBroken is broken} when
+     * <tt>await</tt> is invoked, or while any thread is waiting, then
+     * {@link BrokenBarrierException} is thrown.
      *
-     * <p>If any thread is {@link Thread#interrupt interrupted} while waiting,
-     * then all other waiting threads will throw 
+     * <p>If any thread is {@linkplain Thread#interrupt interrupted} while waiting,
+     * then all other waiting threads will throw
      * {@link BrokenBarrierException} and the barrier is placed in the broken
      * state.
      *
      * <p>If the current thread is the last thread to arrive, and a
      * non-null barrier action was supplied in the constructor, then the
-     * current thread runs the action before allowing the other threads to 
+     * current thread runs the action before allowing the other threads to
      * continue.
      * If an exception occurs during the barrier action then that exception
      * will be propagated in the current thread and the barrier is placed in
      * the broken state.
      *
      * @return the arrival index of the current thread, where index
-     *  <tt>{@link #getParties()} - 1</tt> indicates the first to arrive and 
-     * zero indicates the last to arrive.
-     *
-     * @throws InterruptedException if the current thread was interrupted 
-     * while waiting
+     *         <tt>{@link #getParties()} - 1</tt> indicates the first
+     *         to arrive and zero indicates the last to arrive
+     * @throws InterruptedException if the current thread was interrupted
+     *         while waiting
      * @throws BrokenBarrierException if <em>another</em> thread was
-     * interrupted while the current thread was waiting, or the barrier was
-     * reset, or the barrier was broken when <tt>await</tt> was called,
-     * or the barrier action (if present) failed due an exception.
+     *         interrupted or timed out while the current thread was
+     *         waiting, or the barrier was reset, or the barrier was
+     *         broken when {@code await} was called, or the barrier
+     *         action (if present) failed due an exception.
      */
     public int await() throws InterruptedException, BrokenBarrierException {
         try {
@@ -304,8 +330,8 @@
     }
 
     /**
-     * Waits until all {@link #getParties parties} have invoked <tt>await</tt>
-     * on this barrier.
+     * Waits until all {@linkplain #getParties parties} have invoked
+     * <tt>await</tt> on this barrier, or the specified waiting time elapses.
      *
      * <p>If the current thread is not the last to arrive then it is
      * disabled for thread scheduling purposes and lies dormant until
@@ -313,34 +339,39 @@
      * <ul>
      * <li>The last thread arrives; or
      * <li>The specified timeout elapses; or
-     * <li>Some other thread {@link Thread#interrupt interrupts} the current
-     * thread; or
-     * <li>Some other thread  {@link Thread#interrupt interrupts} one of the
-     * other waiting threads; or
+     * <li>Some other thread {@linkplain Thread#interrupt interrupts}
+     * the current thread; or
+     * <li>Some other thread {@linkplain Thread#interrupt interrupts}
+     * one of the other waiting threads; or
      * <li>Some other thread times out while waiting for barrier; or
      * <li>Some other thread invokes {@link #reset} on this barrier.
      * </ul>
+     *
      * <p>If the current thread:
      * <ul>
      * <li>has its interrupted status set on entry to this method; or
-     * <li>is {@link Thread#interrupt interrupted} while waiting
+     * <li>is {@linkplain Thread#interrupt interrupted} while waiting
      * </ul>
      * then {@link InterruptedException} is thrown and the current thread's
      * interrupted status is cleared.
      *
-     * <p>If the barrier is {@link #reset} while any thread is waiting, or if 
-     * the barrier {@link #isBroken is broken} when <tt>await</tt> is invoked,
-     * or while any thread is waiting,
-     * then {@link BrokenBarrierException} is thrown.
+     * <p>If the specified waiting time elapses then {@link TimeoutException}
+     * is thrown. If the time is less than or equal to zero, the
+     * method will not wait at all.
      *
-     * <p>If any thread is {@link Thread#interrupt interrupted} while waiting,
-     * then all other waiting threads will throw 
-     * {@link BrokenBarrierException} and the barrier is placed in the broken
+     * <p>If the barrier is {@link #reset} while any thread is waiting,
+     * or if the barrier {@linkplain #isBroken is broken} when
+     * <tt>await</tt> is invoked, or while any thread is waiting, then
+     * {@link BrokenBarrierException} is thrown.
+     *
+     * <p>If any thread is {@linkplain Thread#interrupt interrupted} while
+     * waiting, then all other waiting threads will throw {@link
+     * BrokenBarrierException} and the barrier is placed in the broken
      * state.
      *
      * <p>If the current thread is the last thread to arrive, and a
      * non-null barrier action was supplied in the constructor, then the
-     * current thread runs the action before allowing the other threads to 
+     * current thread runs the action before allowing the other threads to
      * continue.
      * If an exception occurs during the barrier action then that exception
      * will be propagated in the current thread and the barrier is placed in
@@ -349,36 +380,37 @@
      * @param timeout the time to wait for the barrier
      * @param unit the time unit of the timeout parameter
      * @return the arrival index of the current thread, where index
-     *  <tt>{@link #getParties()} - 1</tt> indicates the first to arrive and 
-     * zero indicates the last to arrive.
-     *
-     * @throws InterruptedException if the current thread was interrupted 
-     * while waiting
-     * @throws TimeoutException if the specified timeout elapses.
+     *         <tt>{@link #getParties()} - 1</tt> indicates the first
+     *         to arrive and zero indicates the last to arrive
+     * @throws InterruptedException if the current thread was interrupted
+     *         while waiting
+     * @throws TimeoutException if the specified timeout elapses
      * @throws BrokenBarrierException if <em>another</em> thread was
-     * interrupted while the current thread was waiting, or the barrier was
-     * reset, or the barrier was broken when <tt>await</tt> was called,
-     * or the barrier action (if present) failed due an exception.
+     *         interrupted or timed out while the current thread was
+     *         waiting, or the barrier was reset, or the barrier was broken
+     *         when {@code await} was called, or the barrier action (if
+     *         present) failed due an exception
      */
-    public int await(long timeout, TimeUnit unit) 
-        throws InterruptedException, 
-        BrokenBarrierException, 
-        TimeoutException {
+    public int await(long timeout, TimeUnit unit)
+        throws InterruptedException,
+               BrokenBarrierException,
+               TimeoutException {
         return dowait(true, unit.toNanos(timeout));
     }
 
     /**
      * Queries if this barrier is in a broken state.
-     * @return <tt>true</tt> if one or more parties broke out of this
-     * barrier due to interruption or timeout since construction or
-     * the last reset, or a barrier action failed due to an exception; 
-     * and <tt>false</tt> otherwise.
+     *
+     * @return {@code true} if one or more parties broke out of this
+     *         barrier due to interruption or timeout since
+     *         construction or the last reset, or a barrier action
+     *         failed due to an exception; {@code false} otherwise.
      */
     public boolean isBroken() {
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            return broken;
+            return generation.broken;
         } finally {
             lock.unlock();
         }
@@ -397,15 +429,8 @@
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            /*
-             * Retract generation number enough to cover threads
-             * currently waiting on current and still resuming from
-             * previous generation, plus similarly accommodating spans
-             * after the reset.
-             */
-            generation -= 4;
-            broken = false;
-            trip.signalAll();
+            breakBarrier();   // break the current generation
+            nextGeneration(); // start a new generation
         } finally {
             lock.unlock();
         }
@@ -416,7 +441,7 @@
      * This method is primarily useful for debugging and assertions.
      *
      * @return the number of parties currently blocked in {@link #await}
-     **/
+     */
     public int getNumberWaiting() {
         final ReentrantLock lock = this.lock;
         lock.lock();
@@ -426,5 +451,4 @@
             lock.unlock();
         }
     }
-
 }
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/DelayQueue.java b/libcore/concurrent/src/main/java/java/util/concurrent/DelayQueue.java
index 156dc7e..52ac4a0 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/DelayQueue.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/DelayQueue.java
@@ -14,14 +14,22 @@
 // END android-note
 
 /**
- * An unbounded {@linkplain BlockingQueue blocking queue} of <tt>Delayed</tt>
- * elements, in which an element can only be taken when its delay has expired.
- * The <em>head</em> of the queue is that <tt>Delayed</tt> element whose delay
- * expired furthest in the past - if no delay has expired there is no head and
- * <tt>poll</tt> will return <tt>null</tt>.
- * This queue does not permit <tt>null</tt> elements.
- * <p>This class implements all of the <em>optional</em> methods
- * of the {@link Collection} and {@link Iterator} interfaces.
+ * An unbounded {@linkplain BlockingQueue blocking queue} of
+ * <tt>Delayed</tt> elements, in which an element can only be taken
+ * when its delay has expired.  The <em>head</em> of the queue is that
+ * <tt>Delayed</tt> element whose delay expired furthest in the
+ * past.  If no delay has expired there is no head and <tt>poll</tt>
+ * will return <tt>null</tt>. Expiration occurs when an element's
+ * <tt>getDelay(TimeUnit.NANOSECONDS)</tt> method returns a value less
+ * than or equal to zero.  Even though unexpired elements cannot be
+ * removed using <tt>take</tt> or <tt>poll</tt>, they are otherwise
+ * treated as normal elements. For example, the <tt>size</tt> method
+ * returns the count of both expired and unexpired elements.
+ * This queue does not permit null elements.
+ *
+ * <p>This class and its iterator implement all of the
+ * <em>optional</em> methods of the {@link Collection} and {@link
+ * Iterator} interfaces.
  *
  * @since 1.5
  * @author Doug Lea
@@ -32,10 +40,34 @@
     implements BlockingQueue<E> {
 
     private transient final ReentrantLock lock = new ReentrantLock();
-    private transient final Condition available = lock.newCondition();
     private final PriorityQueue<E> q = new PriorityQueue<E>();
 
     /**
+     * Thread designated to wait for the element at the head of
+     * the queue.  This variant of the Leader-Follower pattern
+     * (http://www.cs.wustl.edu/~schmidt/POSA/POSA2/) serves to
+     * minimize unnecessary timed waiting.  When a thread becomes
+     * the leader, it waits only for the next delay to elapse, but
+     * other threads await indefinitely.  The leader thread must
+     * signal some other thread before returning from take() or
+     * poll(...), unless some other thread becomes leader in the
+     * interim.  Whenever the head of the queue is replaced with
+     * an element with an earlier expiration time, the leader
+     * field is invalidated by being reset to null, and some
+     * waiting thread, but not necessarily the current leader, is
+     * signalled.  So waiting threads must be prepared to acquire
+     * and lose leadership while waiting.
+     */
+    private Thread leader = null;
+
+    /**
+     * Condition signalled when a newer element becomes available
+     * at the head of the queue or a new thread may need to
+     * become leader.
+     */
+    private final Condition available = lock.newCondition();
+
+    /**
      * Creates a new <tt>DelayQueue</tt> that is initially empty.
      */
     public DelayQueue() {}
@@ -44,10 +76,9 @@
      * Creates a <tt>DelayQueue</tt> initially containing the elements of the
      * given collection of {@link Delayed} instances.
      *
-     * @param c the collection
-     * @throws NullPointerException if <tt>c</tt> or any element within it
-     * is <tt>null</tt>
-     *
+     * @param c the collection of elements to initially contain
+     * @throws NullPointerException if the specified collection or any
+     *         of its elements are null
      */
     public DelayQueue(Collection<? extends E> c) {
         this.addAll(c);
@@ -56,91 +87,136 @@
     /**
      * Inserts the specified element into this delay queue.
      *
-     * @param o the element to add
-     * @return <tt>true</tt>
-     * @throws NullPointerException if the specified element is <tt>null</tt>.
+     * @param e the element to add
+     * @return <tt>true</tt> (as specified by {@link Collection#add})
+     * @throws NullPointerException if the specified element is null
      */
-    public boolean offer(E o) {
+    public boolean add(E e) {
+        return offer(e);
+    }
+
+    /**
+     * Inserts the specified element into this delay queue.
+     *
+     * @param e the element to add
+     * @return <tt>true</tt>
+     * @throws NullPointerException if the specified element is null
+     */
+    public boolean offer(E e) {
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            E first = q.peek();
-            q.offer(o);
-            if (first == null || o.compareTo(first) < 0)
-                available.signalAll();
+            q.offer(e);
+            if (q.peek() == e) {
+                leader = null;
+                available.signal();
+            }
             return true;
         } finally {
             lock.unlock();
         }
     }
 
-
     /**
-     * Adds the specified element to this delay queue. As the queue is
+     * Inserts the specified element into this delay queue. As the queue is
      * unbounded this method will never block.
-     * @param o the element to add
-     * @throws NullPointerException if the specified element is <tt>null</tt>.
+     *
+     * @param e the element to add
+     * @throws NullPointerException {@inheritDoc}
      */
-    public void put(E o) {
-        offer(o);
+    public void put(E e) {
+        offer(e);
     }
 
     /**
      * Inserts the specified element into this delay queue. As the queue is
      * unbounded this method will never block.
-     * @param o the element to add
+     *
+     * @param e the element to add
      * @param timeout This parameter is ignored as the method never blocks
      * @param unit This parameter is ignored as the method never blocks
      * @return <tt>true</tt>
-     * @throws NullPointerException if the specified element is <tt>null</tt>.
+     * @throws NullPointerException {@inheritDoc}
      */
-    public boolean offer(E o, long timeout, TimeUnit unit) {
-        return offer(o);
+    public boolean offer(E e, long timeout, TimeUnit unit) {
+        return offer(e);
     }
 
     /**
-     * Adds the specified element to this queue.
-     * @param o the element to add
-     * @return <tt>true</tt> (as per the general contract of
-     * <tt>Collection.add</tt>).
+     * Retrieves and removes the head of this queue, or returns <tt>null</tt>
+     * if this queue has no elements with an expired delay.
      *
-     * @throws NullPointerException if the specified element is <tt>null</tt>.
+     * @return the head of this queue, or <tt>null</tt> if this
+     *         queue has no elements with an expired delay
      */
-    public boolean add(E o) {
-        return offer(o);
+    public E poll() {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            E first = q.peek();
+            if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
+                return null;
+            else
+                return q.poll();
+        } finally {
+            lock.unlock();
+        }
     }
 
+    /**
+     * Retrieves and removes the head of this queue, waiting if necessary
+     * until an element with an expired delay is available on this queue.
+     *
+     * @return the head of this queue
+     * @throws InterruptedException {@inheritDoc}
+     */
     public E take() throws InterruptedException {
         final ReentrantLock lock = this.lock;
         lock.lockInterruptibly();
         try {
             for (;;) {
                 E first = q.peek();
-                if (first == null) {
+                if (first == null)
                     available.await();
-                } else {
-                    long delay =  first.getDelay(TimeUnit.NANOSECONDS);
-                    if (delay > 0) {
-                        long tl = available.awaitNanos(delay);
-                    } else {
-                        E x = q.poll();
-                        assert x != null;
-                        if (q.size() != 0)
-                            available.signalAll(); // wake up other takers
-                        return x;
-
+                else {
+                    long delay = first.getDelay(TimeUnit.NANOSECONDS);
+                    if (delay <= 0)
+                        return q.poll();
+                    else if (leader != null)
+                        available.await();
+                    else {
+                        Thread thisThread = Thread.currentThread();
+                        leader = thisThread;
+                        try {
+                            available.awaitNanos(delay);
+                        } finally {
+                            if (leader == thisThread)
+                                leader = null;
+                        }
                     }
                 }
             }
         } finally {
+            if (leader == null && q.peek() != null)
+                available.signal();
             lock.unlock();
         }
     }
 
-    public E poll(long time, TimeUnit unit) throws InterruptedException {
+    /**
+     * Retrieves and removes the head of this queue, waiting if necessary
+     * until an element with an expired delay is available on this queue,
+     * or the specified wait time expires.
+     *
+     * @return the head of this queue, or <tt>null</tt> if the
+     *         specified waiting time elapses before an element with
+     *         an expired delay becomes available
+     * @throws InterruptedException {@inheritDoc}
+     */
+    public E poll(long timeout, TimeUnit unit) throws InterruptedException {
+        long nanos = unit.toNanos(timeout);
         final ReentrantLock lock = this.lock;
         lock.lockInterruptibly();
-        long nanos = unit.toNanos(time);
         try {
             for (;;) {
                 E first = q.peek();
@@ -150,46 +226,43 @@
                     else
                         nanos = available.awaitNanos(nanos);
                 } else {
-                    long delay =  first.getDelay(TimeUnit.NANOSECONDS);
-                    if (delay > 0) {
-                        if (delay > nanos)
-                            delay = nanos;
-                        long timeLeft = available.awaitNanos(delay);
-                        nanos -= delay - timeLeft;
-                    } else {
-                        E x = q.poll();
-                        assert x != null;
-                        if (q.size() != 0)
-                            available.signalAll();
-                        return x;
+                    long delay = first.getDelay(TimeUnit.NANOSECONDS);
+                    if (delay <= 0)
+                        return q.poll();
+                    if (nanos <= 0)
+                        return null;
+                    if (nanos < delay || leader != null)
+                        nanos = available.awaitNanos(nanos);
+                    else {
+                        Thread thisThread = Thread.currentThread();
+                        leader = thisThread;
+                        try {
+                            long timeLeft = available.awaitNanos(delay);
+                            nanos -= delay - timeLeft;
+                        } finally {
+                            if (leader == thisThread)
+                                leader = null;
+                        }
                     }
                 }
             }
         } finally {
+            if (leader == null && q.peek() != null)
+                available.signal();
             lock.unlock();
         }
     }
 
-
-    public E poll() {
-        final ReentrantLock lock = this.lock;
-        lock.lock();
-        try {
-            E first = q.peek();
-            if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
-                return null;
-            else {
-                E x = q.poll();
-                assert x != null;
-                if (q.size() != 0)
-                    available.signalAll();
-                return x;
-            }
-        } finally {
-            lock.unlock();
-        }
-    }
-
+    /**
+     * Retrieves, but does not remove, the head of this queue, or
+     * returns <tt>null</tt> if this queue is empty.  Unlike
+     * <tt>poll</tt>, if no expired elements are available in the queue,
+     * this method returns the element that will expire next,
+     * if one exists.
+     *
+     * @return the head of this queue, or <tt>null</tt> if this
+     *         queue is empty.
+     */
     public E peek() {
         final ReentrantLock lock = this.lock;
         lock.lock();
@@ -210,6 +283,12 @@
         }
     }
 
+    /**
+     * @throws UnsupportedOperationException {@inheritDoc}
+     * @throws ClassCastException            {@inheritDoc}
+     * @throws NullPointerException          {@inheritDoc}
+     * @throws IllegalArgumentException      {@inheritDoc}
+     */
     public int drainTo(Collection<? super E> c) {
         if (c == null)
             throw new NullPointerException();
@@ -226,14 +305,18 @@
                 c.add(q.poll());
                 ++n;
             }
-            if (n > 0)
-                available.signalAll();
             return n;
         } finally {
             lock.unlock();
         }
     }
 
+    /**
+     * @throws UnsupportedOperationException {@inheritDoc}
+     * @throws ClassCastException            {@inheritDoc}
+     * @throws NullPointerException          {@inheritDoc}
+     * @throws IllegalArgumentException      {@inheritDoc}
+     */
     public int drainTo(Collection<? super E> c, int maxElements) {
         if (c == null)
             throw new NullPointerException();
@@ -252,8 +335,6 @@
                 c.add(q.poll());
                 ++n;
             }
-            if (n > 0)
-                available.signalAll();
             return n;
         } finally {
             lock.unlock();
@@ -263,6 +344,8 @@
     /**
      * Atomically removes all of the elements from this delay queue.
      * The queue will be empty after this call returns.
+     * Elements with an unexpired delay are not waited for; they are
+     * simply discarded from the queue.
      */
     public void clear() {
         final ReentrantLock lock = this.lock;
@@ -277,12 +360,26 @@
     /**
      * Always returns <tt>Integer.MAX_VALUE</tt> because
      * a <tt>DelayQueue</tt> is not capacity constrained.
+     *
      * @return <tt>Integer.MAX_VALUE</tt>
      */
     public int remainingCapacity() {
         return Integer.MAX_VALUE;
     }
 
+    /**
+     * Returns an array containing all of the elements in this queue.
+     * The returned array elements are in no particular order.
+     *
+     * <p>The returned array will be "safe" in that no references to it are
+     * maintained by this queue.  (In other words, this method must allocate
+     * a new array).  The caller is thus free to modify the returned array.
+     *
+     * <p>This method acts as bridge between array-based and collection-based
+     * APIs.
+     *
+     * @return an array containing all of the elements in this queue
+     */
     public Object[] toArray() {
         final ReentrantLock lock = this.lock;
         lock.lock();
@@ -293,16 +390,56 @@
         }
     }
 
-    public <T> T[] toArray(T[] array) {
+    /**
+     * Returns an array containing all of the elements in this queue; the
+     * runtime type of the returned array is that of the specified array.
+     * The returned array elements are in no particular order.
+     * If the queue fits in the specified array, it is returned therein.
+     * Otherwise, a new array is allocated with the runtime type of the
+     * specified array and the size of this queue.
+     *
+     * <p>If this queue fits in the specified array with room to spare
+     * (i.e., the array has more elements than this queue), the element in
+     * the array immediately following the end of the queue is set to
+     * <tt>null</tt>.
+     *
+     * <p>Like the {@link #toArray()} method, this method acts as bridge between
+     * array-based and collection-based APIs.  Further, this method allows
+     * precise control over the runtime type of the output array, and may,
+     * under certain circumstances, be used to save allocation costs.
+     *
+     * <p>The following code can be used to dump a delay queue into a newly
+     * allocated array of <tt>Delayed</tt>:
+     *
+     * <pre>
+     *     Delayed[] a = q.toArray(new Delayed[0]);</pre>
+     *
+     * Note that <tt>toArray(new Object[0])</tt> is identical in function to
+     * <tt>toArray()</tt>.
+     *
+     * @param a the array into which the elements of the queue are to
+     *          be stored, if it is big enough; otherwise, a new array of the
+     *          same runtime type is allocated for this purpose
+     * @return an array containing all of the elements in this queue
+     * @throws ArrayStoreException if the runtime type of the specified array
+     *         is not a supertype of the runtime type of every element in
+     *         this queue
+     * @throws NullPointerException if the specified array is null
+     */
+    public <T> T[] toArray(T[] a) {
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            return q.toArray(array);
+            return q.toArray(a);
         } finally {
             lock.unlock();
         }
     }
 
+    /**
+     * Removes a single instance of the specified element from this
+     * queue, if it is present, whether or not it has expired.
+     */
     public boolean remove(Object o) {
         final ReentrantLock lock = this.lock;
         lock.lock();
@@ -314,49 +451,61 @@
     }
 
     /**
-     * Returns an iterator over the elements in this queue. The iterator
-     * does not return the elements in any particular order. The
-     * returned iterator is a thread-safe "fast-fail" iterator that will
-     * throw {@link java.util.ConcurrentModificationException}
-     * upon detected interference.
+     * Returns an iterator over all the elements (both expired and
+     * unexpired) in this queue. The iterator does not return the
+     * elements in any particular order.  The returned
+     * <tt>Iterator</tt> is a "weakly consistent" iterator that will
+     * never throw {@link ConcurrentModificationException}, and
+     * guarantees to traverse elements as they existed upon
+     * construction of the iterator, and may (but is not guaranteed
+     * to) reflect any modifications subsequent to construction.
      *
-     * @return an iterator over the elements in this queue.
+     * @return an iterator over the elements in this queue
      */
     public Iterator<E> iterator() {
-        final ReentrantLock lock = this.lock;
-        lock.lock();
-        try {
-            return new Itr(q.iterator());
-        } finally {
-            lock.unlock();
-        }
+        return new Itr(toArray());
     }
 
-    private class Itr<E> implements Iterator<E> {
-        private final Iterator<E> iter;
-        Itr(Iterator<E> i) {
-            iter = i;
+    /**
+     * Snapshot iterator that works off copy of underlying q array.
+     */
+    private class Itr implements Iterator<E> {
+        final Object[] array; // Array of all elements
+        int cursor;           // index of next element to return;
+        int lastRet;          // index of last element, or -1 if no such
+
+        Itr(Object[] array) {
+            lastRet = -1;
+            this.array = array;
         }
 
         public boolean hasNext() {
-            return iter.hasNext();
+            return cursor < array.length;
         }
 
+        @SuppressWarnings("unchecked")
         public E next() {
-            final ReentrantLock lock = DelayQueue.this.lock;
-            lock.lock();
-            try {
-                return iter.next();
-            } finally {
-                lock.unlock();
-            }
+            if (cursor >= array.length)
+                throw new NoSuchElementException();
+            lastRet = cursor;
+            return (E)array[cursor++];
         }
 
         public void remove() {
-            final ReentrantLock lock = DelayQueue.this.lock;
+            if (lastRet < 0)
+                throw new IllegalStateException();
+            Object x = array[lastRet];
+            lastRet = -1;
+            // Traverse underlying queue to find == element,
+            // not just a .equals element.
             lock.lock();
             try {
-                iter.remove();
+                for (Iterator it = q.iterator(); it.hasNext(); ) {
+                    if (it.next() == x) {
+                        it.remove();
+                        return;
+                    }
+                }
             } finally {
                 lock.unlock();
             }
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/Delayed.java b/libcore/concurrent/src/main/java/java/util/concurrent/Delayed.java
index bd48292..af41300 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/Delayed.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/Delayed.java
@@ -4,6 +4,11 @@
  * http://creativecommons.org/licenses/publicdomain
  */
 
+/*
+ * Modified in Apache Harmony to comply with Java 5 signature
+ * specification.
+ */
+
 package java.util.concurrent;
 
 import java.util.*;
@@ -26,11 +31,12 @@
 public interface Delayed extends Comparable<Delayed> {
 
     /**
-     * Returns the delay associated with this object, in the given time unit.
+     * Returns the remaining delay associated with this object, in the
+     * given time unit.
      *
      * @param unit the time unit
-     * @return the delay; zero or negative values indicate that the
-     * delay has already elapsed
+     * @return the remaining delay; zero or negative values indicate
+     * that the delay has already elapsed
      */
     long getDelay(TimeUnit unit);
 }
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/Exchanger.java b/libcore/concurrent/src/main/java/java/util/concurrent/Exchanger.java
index da8c815..f67659c 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/Exchanger.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/Exchanger.java
@@ -1,27 +1,31 @@
 /*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
+ * Written by Doug Lea, Bill Scherer, and Michael Scott with
+ * assistance from members of JCP JSR-166 Expert Group and released to
+ * the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
  */
 
 package java.util.concurrent;
-import java.util.concurrent.locks.*;
+import java.util.concurrent.atomic.*;
+import java.util.concurrent.locks.LockSupport;
 
 /**
- * A synchronization point at which two threads can exchange objects.
- * Each thread presents some object on entry to the {@link #exchange
- * exchange} method, and receives the object presented by the other
- * thread on return.
+ * A synchronization point at which threads can pair and swap elements
+ * within pairs.  Each thread presents some object on entry to the
+ * {@link #exchange exchange} method, matches with a partner thread,
+ * and receives its partner's object on return.  An Exchanger may be
+ * viewed as a bidirectional form of a {@link SynchronousQueue}.
+ * Exchangers may be useful in applications such as genetic algorithms
+ * and pipeline designs.
  *
  * <p><b>Sample Usage:</b>
- * Here are the highlights of a class that uses an <tt>Exchanger</tt> to
- * swap buffers between threads so that the thread filling the
- * buffer gets a freshly
- * emptied one when it needs it, handing off the filled one to
- * the thread emptying the buffer.
- * <pre>
+ * Here are the highlights of a class that uses an {@code Exchanger}
+ * to swap buffers between threads so that the thread filling the
+ * buffer gets a freshly emptied one when it needs it, handing off the
+ * filled one to the thread emptying the buffer.
+ * <pre>{@code
  * class FillAndEmpty {
- *   Exchanger&lt;DataBuffer&gt; exchanger = new Exchanger();
+ *   Exchanger<DataBuffer> exchanger = new Exchanger<DataBuffer>();
  *   DataBuffer initialEmptyBuffer = ... a made-up type
  *   DataBuffer initialFullBuffer = ...
  *
@@ -31,7 +35,7 @@
  *       try {
  *         while (currentBuffer != null) {
  *           addToBuffer(currentBuffer);
- *           if (currentBuffer.full())
+ *           if (currentBuffer.isFull())
  *             currentBuffer = exchanger.exchange(currentBuffer);
  *         }
  *       } catch (InterruptedException ex) { ... handle ... }
@@ -44,7 +48,7 @@
  *       try {
  *         while (currentBuffer != null) {
  *           takeFromBuffer(currentBuffer);
- *           if (currentBuffer.empty())
+ *           if (currentBuffer.isEmpty())
  *             currentBuffer = exchanger.exchange(currentBuffer);
  *         }
  *       } catch (InterruptedException ex) { ... handle ...}
@@ -56,192 +60,597 @@
  *     new Thread(new EmptyingLoop()).start();
  *   }
  * }
- * </pre>
+ * }</pre>
+ *
+ * <p>Memory consistency effects: For each pair of threads that
+ * successfully exchange objects via an {@code Exchanger}, actions
+ * prior to the {@code exchange()} in each thread
+ * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
+ * those subsequent to a return from the corresponding {@code exchange()}
+ * in the other thread.
  *
  * @since 1.5
- * @author Doug Lea
+ * @author Doug Lea and Bill Scherer and Michael Scott
  * @param <V> The type of objects that may be exchanged
  */
 public class Exchanger<V> {
-    private final ReentrantLock lock = new ReentrantLock();
-    private final Condition taken = lock.newCondition();
-
-    /** Holder for the item being exchanged */
-    private V item;
-    
-    /**
-     * Arrival count transitions from 0 to 1 to 2 then back to 0
-     * during an exchange.
+    /*
+     * Algorithm Description:
+     *
+     * The basic idea is to maintain a "slot", which is a reference to
+     * a Node containing both an Item to offer and a "hole" waiting to
+     * get filled in.  If an incoming "occupying" thread sees that the
+     * slot is null, it CAS'es (compareAndSets) a Node there and waits
+     * for another to invoke exchange.  That second "fulfilling" thread
+     * sees that the slot is non-null, and so CASes it back to null,
+     * also exchanging items by CASing the hole, plus waking up the
+     * occupying thread if it is blocked.  In each case CAS'es may
+     * fail because a slot at first appears non-null but is null upon
+     * CAS, or vice-versa.  So threads may need to retry these
+     * actions.
+     *
+     * This simple approach works great when there are only a few
+     * threads using an Exchanger, but performance rapidly
+     * deteriorates due to CAS contention on the single slot when
+     * there are lots of threads using an exchanger.  So instead we use
+     * an "arena"; basically a kind of hash table with a dynamically
+     * varying number of slots, any one of which can be used by
+     * threads performing an exchange.  Incoming threads pick slots
+     * based on a hash of their Thread ids.  If an incoming thread
+     * fails to CAS in its chosen slot, it picks an alternative slot
+     * instead.  And similarly from there.  If a thread successfully
+     * CASes into a slot but no other thread arrives, it tries
+     * another, heading toward the zero slot, which always exists even
+     * if the table shrinks.  The particular mechanics controlling this
+     * are as follows:
+     *
+     * Waiting: Slot zero is special in that it is the only slot that
+     * exists when there is no contention.  A thread occupying slot
+     * zero will block if no thread fulfills it after a short spin.
+     * In other cases, occupying threads eventually give up and try
+     * another slot.  Waiting threads spin for a while (a period that
+     * should be a little less than a typical context-switch time)
+     * before either blocking (if slot zero) or giving up (if other
+     * slots) and restarting.  There is no reason for threads to block
+     * unless there are unlikely to be any other threads present.
+     * Occupants are mainly avoiding memory contention so sit there
+     * quietly polling for a shorter period than it would take to
+     * block and then unblock them.  Non-slot-zero waits that elapse
+     * because of lack of other threads waste around one extra
+     * context-switch time per try, which is still on average much
+     * faster than alternative approaches.
+     *
+     * Sizing: Usually, using only a few slots suffices to reduce
+     * contention.  Especially with small numbers of threads, using
+     * too many slots can lead to just as poor performance as using
+     * too few of them, and there's not much room for error.  The
+     * variable "max" maintains the number of slots actually in
+     * use.  It is increased when a thread sees too many CAS
+     * failures.  (This is analogous to resizing a regular hash table
+     * based on a target load factor, except here, growth steps are
+     * just one-by-one rather than proportional.)  Growth requires
+     * contention failures in each of three tried slots.  Requiring
+     * multiple failures for expansion copes with the fact that some
+     * failed CASes are not due to contention but instead to simple
+     * races between two threads or thread pre-emptions occurring
+     * between reading and CASing.  Also, very transient peak
+     * contention can be much higher than the average sustainable
+     * levels.  The max limit is decreased on average 50% of the times
+     * that a non-slot-zero wait elapses without being fulfilled.
+     * Threads experiencing elapsed waits move closer to zero, so
+     * eventually find existing (or future) threads even if the table
+     * has been shrunk due to inactivity.  The chosen mechanics and
+     * thresholds for growing and shrinking are intrinsically
+     * entangled with indexing and hashing inside the exchange code,
+     * and can't be nicely abstracted out.
+     *
+     * Hashing: Each thread picks its initial slot to use in accord
+     * with a simple hashcode.  The sequence is the same on each
+     * encounter by any given thread, but effectively random across
+     * threads.  Using arenas encounters the classic cost vs quality
+     * tradeoffs of all hash tables.  Here, we use a one-step FNV-1a
+     * hash code based on the current thread's Thread.getId(), along
+     * with a cheap approximation to a mod operation to select an
+     * index.  The downside of optimizing index selection in this way
+     * is that the code is hardwired to use a maximum table size of
+     * 32.  But this value more than suffices for known platforms and
+     * applications.
+     *
+     * Probing: On sensed contention of a selected slot, we probe
+     * sequentially through the table, analogously to linear probing
+     * after collision in a hash table.  (We move circularly, in
+     * reverse order, to mesh best with table growth and shrinkage
+     * rules.)  Except that to minimize the effects of false-alarms
+     * and cache thrashing, we try the first selected slot twice
+     * before moving.
+     *
+     * Padding: Even with contention management, slots are heavily
+     * contended, so use cache-padding to avoid poor memory
+     * performance.  Because of this, slots are lazily constructed
+     * only when used, to avoid wasting this space unnecessarily.
+     * While isolation of locations is not much of an issue at first
+     * in an application, as time goes on and garbage-collectors
+     * perform compaction, slots are very likely to be moved adjacent
+     * to each other, which can cause much thrashing of cache lines on
+     * MPs unless padding is employed.
+     *
+     * This is an improvement of the algorithm described in the paper
+     * "A Scalable Elimination-based Exchange Channel" by William
+     * Scherer, Doug Lea, and Michael Scott in Proceedings of SCOOL05
+     * workshop.  Available at: http://hdl.handle.net/1802/2104
      */
-    private int arrivalCount;
+
+    /** The number of CPUs, for sizing and spin control */
+    private static final int NCPU = Runtime.getRuntime().availableProcessors();
 
     /**
-     * Main exchange function, handling the different policy variants.
+     * The capacity of the arena.  Set to a value that provides more
+     * than enough space to handle contention.  On small machines
+     * most slots won't be used, but it is still not wasted because
+     * the extra space provides some machine-level address padding
+     * to minimize interference with heavily CAS'ed Slot locations.
+     * And on very large machines, performance eventually becomes
+     * bounded by memory bandwidth, not numbers of threads/CPUs.
+     * This constant cannot be changed without also modifying
+     * indexing and hashing algorithms.
      */
-    private V doExchange(V x, boolean timed, long nanos) throws InterruptedException, TimeoutException {
-        lock.lock();
-        try {
-            V other;
+    private static final int CAPACITY = 32;
 
-            // If arrival count already at two, we must wait for
-            // a previous pair to finish and reset the count;
-            while (arrivalCount == 2) {
-                if (!timed)
-                    taken.await();
-                else if (nanos > 0) 
-                    nanos = taken.awaitNanos(nanos);
-                else 
-                    throw new TimeoutException();
-            }
+    /**
+     * The value of "max" that will hold all threads without
+     * contention.  When this value is less than CAPACITY, some
+     * otherwise wasted expansion can be avoided.
+     */
+    private static final int FULL =
+        Math.max(0, Math.min(CAPACITY, NCPU / 2) - 1);
 
-            int count = ++arrivalCount;
+    /**
+     * The number of times to spin (doing nothing except polling a
+     * memory location) before blocking or giving up while waiting to
+     * be fulfilled.  Should be zero on uniprocessors.  On
+     * multiprocessors, this value should be large enough so that two
+     * threads exchanging items as fast as possible block only when
+     * one of them is stalled (due to GC or preemption), but not much
+     * longer, to avoid wasting CPU resources.  Seen differently, this
+     * value is a little over half the number of cycles of an average
+     * context switch time on most systems.  The value here is
+     * approximately the average of those across a range of tested
+     * systems.
+     */
+    private static final int SPINS = (NCPU == 1) ? 0 : 2000;
 
-            // If item is already waiting, replace it and signal other thread
-            if (count == 2) { 
-                other = item;
-                item = x;
-                taken.signal();
-                return other;
-            }
+    /**
+     * The number of times to spin before blocking in timed waits.
+     * Timed waits spin more slowly because checking the time takes
+     * time.  The best value relies mainly on the relative rate of
+     * System.nanoTime vs memory accesses.  The value is empirically
+     * derived to work well across a variety of systems.
+     */
+    private static final int TIMED_SPINS = SPINS / 20;
 
-            // Otherwise, set item and wait for another thread to
-            // replace it and signal us.
+    /**
+     * Sentinel item representing cancellation of a wait due to
+     * interruption, timeout, or elapsed spin-waits.  This value is
+     * placed in holes on cancellation, and used as a return value
+     * from waiting methods to indicate failure to set or get hole.
+     */
+    private static final Object CANCEL = new Object();
 
-            item = x;
-            InterruptedException interrupted = null;
-            try { 
-                while (arrivalCount != 2) {
-                    if (!timed)
-                        taken.await();
-                    else if (nanos > 0) 
-                        nanos = taken.awaitNanos(nanos);
-                    else 
-                        break; // timed out
-                }
-            } catch (InterruptedException ie) {
-                interrupted = ie;
-            }
+    /**
+     * Value representing null arguments/returns from public
+     * methods.  This disambiguates from internal requirement that
+     * holes start out as null to mean they are not yet set.
+     */
+    private static final Object NULL_ITEM = new Object();
 
-            // Get and reset item and count after the wait.
-            // (We need to do this even if wait was aborted.)
-            other = item;
-            item = null;
-            count = arrivalCount;
-            arrivalCount = 0; 
-            taken.signal();
-            
-            // If the other thread replaced item, then we must
-            // continue even if cancelled.
-            if (count == 2) {
-                if (interrupted != null)
-                    Thread.currentThread().interrupt();
-                return other;
-            }
+    /**
+     * Nodes hold partially exchanged data.  This class
+     * opportunistically subclasses AtomicReference to represent the
+     * hole.  So get() returns hole, and compareAndSet CAS'es value
+     * into hole.  This class cannot be parameterized as "V" because
+     * of the use of non-V CANCEL sentinels.
+     */
+    private static final class Node extends AtomicReference<Object> {
+        /** The element offered by the Thread creating this node. */
+        public final Object item;
 
-            // If no one is waiting for us, we can back out
-            if (interrupted != null) 
-                throw interrupted;
-            else  // must be timeout
-                throw new TimeoutException();
-        } finally {
-            lock.unlock();
+        /** The Thread waiting to be signalled; null until waiting. */
+        public volatile Thread waiter;
+
+        /**
+         * Creates node with given item and empty hole.
+         * @param item the item
+         */
+        public Node(Object item) {
+            this.item = item;
         }
     }
 
     /**
-     * Create a new Exchanger.
-     **/
+     * A Slot is an AtomicReference with heuristic padding to lessen
+     * cache effects of this heavily CAS'ed location.  While the
+     * padding adds noticeable space, all slots are created only on
+     * demand, and there will be more than one of them only when it
+     * would improve throughput more than enough to outweigh using
+     * extra space.
+     */
+    private static final class Slot extends AtomicReference<Object> {
+        // Improve likelihood of isolation on <= 64 byte cache lines
+        long q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, qa, qb, qc, qd, qe;
+    }
+
+    /**
+     * Slot array.  Elements are lazily initialized when needed.
+     * Declared volatile to enable double-checked lazy construction.
+     */
+    private volatile Slot[] arena = new Slot[CAPACITY];
+
+    /**
+     * The maximum slot index being used.  The value sometimes
+     * increases when a thread experiences too many CAS contentions,
+     * and sometimes decreases when a spin-wait elapses.  Changes
+     * are performed only via compareAndSet, to avoid stale values
+     * when a thread happens to stall right before setting.
+     */
+    private final AtomicInteger max = new AtomicInteger();
+
+    /**
+     * Main exchange function, handling the different policy variants.
+     * Uses Object, not "V" as argument and return value to simplify
+     * handling of sentinel values.  Callers from public methods decode
+     * and cast accordingly.
+     *
+     * @param item the (non-null) item to exchange
+     * @param timed true if the wait is timed
+     * @param nanos if timed, the maximum wait time
+     * @return the other thread's item, or CANCEL if interrupted or timed out
+     */
+    private Object doExchange(Object item, boolean timed, long nanos) {
+        Node me = new Node(item);                 // Create in case occupying
+        int index = hashIndex();                  // Index of current slot
+        int fails = 0;                            // Number of CAS failures
+
+        for (;;) {
+            Object y;                             // Contents of current slot
+            Slot slot = arena[index];
+            if (slot == null)                     // Lazily initialize slots
+                createSlot(index);                // Continue loop to reread
+            else if ((y = slot.get()) != null &&  // Try to fulfill
+                     slot.compareAndSet(y, null)) {
+                Node you = (Node)y;               // Transfer item
+                if (you.compareAndSet(null, item)) {
+                    LockSupport.unpark(you.waiter);
+                    return you.item;
+                }                                 // Else cancelled; continue
+            }
+            else if (y == null &&                 // Try to occupy
+                     slot.compareAndSet(null, me)) {
+                if (index == 0)                   // Blocking wait for slot 0
+                    return timed? awaitNanos(me, slot, nanos): await(me, slot);
+                Object v = spinWait(me, slot);    // Spin wait for non-0
+                if (v != CANCEL)
+                    return v;
+                me = new Node(item);              // Throw away cancelled node
+                int m = max.get();
+                if (m > (index >>>= 1))           // Decrease index
+                    max.compareAndSet(m, m - 1);  // Maybe shrink table
+            }
+            else if (++fails > 1) {               // Allow 2 fails on 1st slot
+                int m = max.get();
+                if (fails > 3 && m < FULL && max.compareAndSet(m, m + 1))
+                    index = m + 1;                // Grow on 3rd failed slot
+                else if (--index < 0)
+                    index = m;                    // Circularly traverse
+            }
+        }
+    }
+
+    /**
+     * Returns a hash index for the current thread.  Uses a one-step
+     * FNV-1a hash code (http://www.isthe.com/chongo/tech/comp/fnv/)
+     * based on the current thread's Thread.getId().  These hash codes
+     * have more uniform distribution properties with respect to small
+     * moduli (here 1-31) than do other simple hashing functions.
+     *
+     * <p>To return an index between 0 and max, we use a cheap
+     * approximation to a mod operation, that also corrects for bias
+     * due to non-power-of-2 remaindering (see {@link
+     * java.util.Random#nextInt}).  Bits of the hashcode are masked
+     * with "nbits", the ceiling power of two of table size (looked up
+     * in a table packed into three ints).  If too large, this is
+     * retried after rotating the hash by nbits bits, while forcing new
+     * top bit to 0, which guarantees eventual termination (although
+     * with a non-random-bias).  This requires an average of less than
+     * 2 tries for all table sizes, and has a maximum 2% difference
+     * from perfectly uniform slot probabilities when applied to all
+     * possible hash codes for sizes less than 32.
+     *
+     * @return a per-thread-random index, 0 <= index < max
+     */
+    private final int hashIndex() {
+        long id = Thread.currentThread().getId();
+        int hash = (((int)(id ^ (id >>> 32))) ^ 0x811c9dc5) * 0x01000193;
+
+        int m = max.get();
+        int nbits = (((0xfffffc00  >> m) & 4) | // Compute ceil(log2(m+1))
+                     ((0x000001f8 >>> m) & 2) | // The constants hold
+                     ((0xffff00f2 >>> m) & 1)); // a lookup table
+        int index;
+        while ((index = hash & ((1 << nbits) - 1)) > m)       // May retry on
+            hash = (hash >>> nbits) | (hash << (33 - nbits)); // non-power-2 m
+        return index;
+    }
+
+    /**
+     * Creates a new slot at given index.  Called only when the slot
+     * appears to be null.  Relies on double-check using builtin
+     * locks, since they rarely contend.  This in turn relies on the
+     * arena array being declared volatile.
+     *
+     * @param index the index to add slot at
+     */
+    private void createSlot(int index) {
+        // Create slot outside of lock to narrow sync region
+        Slot newSlot = new Slot();
+        Slot[] a = arena;
+        synchronized (a) {
+            if (a[index] == null)
+                a[index] = newSlot;
+        }
+    }
+
+    /**
+     * Tries to cancel a wait for the given node waiting in the given
+     * slot, if so, helping clear the node from its slot to avoid
+     * garbage retention.
+     *
+     * @param node the waiting node
+     * @param slot the slot it is waiting in
+     * @return true if successfully cancelled
+     */
+    private static boolean tryCancel(Node node, Slot slot) {
+        if (!node.compareAndSet(null, CANCEL))
+            return false;
+        if (slot.get() == node) // pre-check to minimize contention
+            slot.compareAndSet(node, null);
+        return true;
+    }
+
+    // Three forms of waiting. Each just different enough not to merge
+    // code with others.
+
+    /**
+     * Spin-waits for hole for a non-0 slot.  Fails if spin elapses
+     * before hole filled.  Does not check interrupt, relying on check
+     * in public exchange method to abort if interrupted on entry.
+     *
+     * @param node the waiting node
+     * @return on success, the hole; on failure, CANCEL
+     */
+    private static Object spinWait(Node node, Slot slot) {
+        int spins = SPINS;
+        for (;;) {
+            Object v = node.get();
+            if (v != null)
+                return v;
+            else if (spins > 0)
+                --spins;
+            else
+                tryCancel(node, slot);
+        }
+    }
+
+    /**
+     * Waits for (by spinning and/or blocking) and gets the hole
+     * filled in by another thread.  Fails if interrupted before
+     * hole filled.
+     *
+     * When a node/thread is about to block, it sets its waiter field
+     * and then rechecks state at least one more time before actually
+     * parking, thus covering race vs fulfiller noticing that waiter
+     * is non-null so should be woken.
+     *
+     * Thread interruption status is checked only surrounding calls to
+     * park.  The caller is assumed to have checked interrupt status
+     * on entry.
+     *
+     * @param node the waiting node
+     * @return on success, the hole; on failure, CANCEL
+     */
+    private static Object await(Node node, Slot slot) {
+        Thread w = Thread.currentThread();
+        int spins = SPINS;
+        for (;;) {
+            Object v = node.get();
+            if (v != null)
+                return v;
+            else if (spins > 0)                 // Spin-wait phase
+                --spins;
+            else if (node.waiter == null)       // Set up to block next
+                node.waiter = w;
+            else if (w.isInterrupted())         // Abort on interrupt
+                tryCancel(node, slot);
+            else                                // Block
+                LockSupport.park();
+        }
+    }
+
+    /**
+     * Waits for (at index 0) and gets the hole filled in by another
+     * thread.  Fails if timed out or interrupted before hole filled.
+     * Same basic logic as untimed version, but a bit messier.
+     *
+     * @param node the waiting node
+     * @param nanos the wait time
+     * @return on success, the hole; on failure, CANCEL
+     */
+    private Object awaitNanos(Node node, Slot slot, long nanos) {
+        int spins = TIMED_SPINS;
+        long lastTime = 0;
+        Thread w = null;
+        for (;;) {
+            Object v = node.get();
+            if (v != null)
+                return v;
+            long now = System.nanoTime();
+            if (w == null)
+                w = Thread.currentThread();
+            else
+                nanos -= now - lastTime;
+            lastTime = now;
+            if (nanos > 0) {
+                if (spins > 0)
+                    --spins;
+                else if (node.waiter == null)
+                    node.waiter = w;
+                else if (w.isInterrupted())
+                    tryCancel(node, slot);
+                else
+                    LockSupport.parkNanos(nanos);
+            }
+            else if (tryCancel(node, slot) && !w.isInterrupted())
+                return scanOnTimeout(node);
+        }
+    }
+
+    /**
+     * Sweeps through arena checking for any waiting threads.  Called
+     * only upon return from timeout while waiting in slot 0.  When a
+     * thread gives up on a timed wait, it is possible that a
+     * previously-entered thread is still waiting in some other
+     * slot.  So we scan to check for any.  This is almost always
+     * overkill, but decreases the likelihood of timeouts when there
+     * are other threads present to far less than that in lock-based
+     * exchangers in which earlier-arriving threads may still be
+     * waiting on entry locks.
+     *
+     * @param node the waiting node
+     * @return another thread's item, or CANCEL
+     */
+    private Object scanOnTimeout(Node node) {
+        Object y;
+        for (int j = arena.length - 1; j >= 0; --j) {
+            Slot slot = arena[j];
+            if (slot != null) {
+                while ((y = slot.get()) != null) {
+                    if (slot.compareAndSet(y, null)) {
+                        Node you = (Node)y;
+                        if (you.compareAndSet(null, node.item)) {
+                            LockSupport.unpark(you.waiter);
+                            return you.item;
+                        }
+                    }
+                }
+            }
+        }
+        return CANCEL;
+    }
+
+    /**
+     * Creates a new Exchanger.
+     */
     public Exchanger() {
     }
 
     /**
      * Waits for another thread to arrive at this exchange point (unless
-     * it is {@link Thread#interrupt interrupted}),
+     * the current thread is {@linkplain Thread#interrupt interrupted}),
      * and then transfers the given object to it, receiving its object
      * in return.
+     *
      * <p>If another thread is already waiting at the exchange point then
      * it is resumed for thread scheduling purposes and receives the object
-     * passed in by the current thread. The current thread returns immediately,
+     * passed in by the current thread.  The current thread returns immediately,
      * receiving the object passed to the exchange by that other thread.
-     * <p>If no other thread is already waiting at the exchange then the 
+     *
+     * <p>If no other thread is already waiting at the exchange then the
      * current thread is disabled for thread scheduling purposes and lies
      * dormant until one of two things happens:
      * <ul>
      * <li>Some other thread enters the exchange; or
-     * <li>Some other thread {@link Thread#interrupt interrupts} the current
+     * <li>Some other thread {@linkplain Thread#interrupt interrupts} the current
      * thread.
      * </ul>
      * <p>If the current thread:
      * <ul>
-     * <li>has its interrupted status set on entry to this method; or 
-     * <li>is {@link Thread#interrupt interrupted} while waiting
-     * for the exchange, 
+     * <li>has its interrupted status set on entry to this method; or
+     * <li>is {@linkplain Thread#interrupt interrupted} while waiting
+     * for the exchange,
      * </ul>
-     * then {@link InterruptedException} is thrown and the current thread's 
-     * interrupted status is cleared. 
+     * then {@link InterruptedException} is thrown and the current thread's
+     * interrupted status is cleared.
      *
      * @param x the object to exchange
-     * @return the object provided by the other thread.
-     * @throws InterruptedException if current thread was interrupted 
-     * while waiting
-     **/
+     * @return the object provided by the other thread
+     * @throws InterruptedException if the current thread was
+     *         interrupted while waiting
+     */
     public V exchange(V x) throws InterruptedException {
-        try {
-            return doExchange(x, false, 0);
-        } catch (TimeoutException cannotHappen) { 
-            throw new Error(cannotHappen);
+        if (!Thread.interrupted()) {
+            Object v = doExchange(x == null? NULL_ITEM : x, false, 0);
+            if (v == NULL_ITEM)
+                return null;
+            if (v != CANCEL)
+                return (V)v;
+            Thread.interrupted(); // Clear interrupt status on IE throw
         }
+        throw new InterruptedException();
     }
 
     /**
      * Waits for another thread to arrive at this exchange point (unless
-     * it is {@link Thread#interrupt interrupted}, or the specified waiting
-     * time elapses),
-     * and then transfers the given object to it, receiving its object
-     * in return.
+     * the current thread is {@linkplain Thread#interrupt interrupted} or
+     * the specified waiting time elapses), and then transfers the given
+     * object to it, receiving its object in return.
      *
      * <p>If another thread is already waiting at the exchange point then
      * it is resumed for thread scheduling purposes and receives the object
-     * passed in by the current thread. The current thread returns immediately,
+     * passed in by the current thread.  The current thread returns immediately,
      * receiving the object passed to the exchange by that other thread.
      *
-     * <p>If no other thread is already waiting at the exchange then the 
+     * <p>If no other thread is already waiting at the exchange then the
      * current thread is disabled for thread scheduling purposes and lies
      * dormant until one of three things happens:
      * <ul>
      * <li>Some other thread enters the exchange; or
-     * <li>Some other thread {@link Thread#interrupt interrupts} the current
-     * thread; or
+     * <li>Some other thread {@linkplain Thread#interrupt interrupts}
+     * the current thread; or
      * <li>The specified waiting time elapses.
      * </ul>
      * <p>If the current thread:
      * <ul>
-     * <li>has its interrupted status set on entry to this method; or 
-     * <li>is {@link Thread#interrupt interrupted} while waiting
-     * for the exchange, 
+     * <li>has its interrupted status set on entry to this method; or
+     * <li>is {@linkplain Thread#interrupt interrupted} while waiting
+     * for the exchange,
      * </ul>
-     * then {@link InterruptedException} is thrown and the current thread's 
-     * interrupted status is cleared. 
+     * then {@link InterruptedException} is thrown and the current thread's
+     * interrupted status is cleared.
      *
-     * <p>If the specified waiting time elapses then {@link TimeoutException}
-     * is thrown.
-     * If the time is 
-     * less than or equal to zero, the method will not wait at all.
+     * <p>If the specified waiting time elapses then {@link
+     * TimeoutException} is thrown.  If the time is less than or equal
+     * to zero, the method will not wait at all.
      *
      * @param x the object to exchange
      * @param timeout the maximum time to wait
-     * @param unit the time unit of the <tt>timeout</tt> argument.
-     * @return the object provided by the other thread.
-     * @throws InterruptedException if current thread was interrupted
-     * while waiting
-     * @throws TimeoutException if the specified waiting time elapses before
-     * another thread enters the exchange.
-     **/
-    public V exchange(V x, long timeout, TimeUnit unit) 
+     * @param unit the time unit of the <tt>timeout</tt> argument
+     * @return the object provided by the other thread
+     * @throws InterruptedException if the current thread was
+     *         interrupted while waiting
+     * @throws TimeoutException if the specified waiting time elapses
+     *         before another thread enters the exchange
+     */
+    public V exchange(V x, long timeout, TimeUnit unit)
         throws InterruptedException, TimeoutException {
-        return doExchange(x, true, unit.toNanos(timeout));
+        if (!Thread.interrupted()) {
+            Object v = doExchange(x == null? NULL_ITEM : x,
+                                  true, unit.toNanos(timeout));
+            if (v == NULL_ITEM)
+                return null;
+            if (v != CANCEL)
+                return (V)v;
+            if (!Thread.interrupted())
+                throw new TimeoutException();
+        }
+        throw new InterruptedException();
     }
-
 }
-
-
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/ExecutionException.java b/libcore/concurrent/src/main/java/java/util/concurrent/ExecutionException.java
index 8f0e448..bc561e5 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/ExecutionException.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/ExecutionException.java
@@ -19,14 +19,14 @@
     private static final long serialVersionUID = 7830266012832686185L;
 
     /**
-     * Constructs a <tt>ExecutionException</tt> with no detail message.
+     * Constructs an <tt>ExecutionException</tt> with no detail message.
      * The cause is not initialized, and may subsequently be
      * initialized by a call to {@link #initCause(Throwable) initCause}.
      */
     protected ExecutionException() { }
 
     /**
-     * Constructs a <tt>ExecutionException</tt> with the specified detail
+     * Constructs an <tt>ExecutionException</tt> with the specified detail
      * message. The cause is not initialized, and may subsequently be
      * initialized by a call to {@link #initCause(Throwable) initCause}.
      *
@@ -37,7 +37,7 @@
     }
 
     /**
-     * Constructs a <tt>ExecutionException</tt> with the specified detail
+     * Constructs an <tt>ExecutionException</tt> with the specified detail
      * message and cause.
      *
      * @param  message the detail message
@@ -49,7 +49,7 @@
     }
 
     /**
-     * Constructs a <tt>ExecutionException</tt> with the specified cause.
+     * Constructs an <tt>ExecutionException</tt> with the specified cause.
      * The detail message is set to:
      * <pre>
      *  (cause == null ? null : cause.toString())</pre>
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/Executor.java b/libcore/concurrent/src/main/java/java/util/concurrent/Executor.java
index 60fe193..a61e921 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/Executor.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/Executor.java
@@ -21,7 +21,7 @@
  * executor.execute(new RunnableTask2());
  * ...
  * </pre>
- * 
+ *
  * However, the <tt>Executor</tt> interface does not strictly
  * require that execution be asynchronous. In the simplest case, an
  * executor can run the submitted task immediately in the caller's
@@ -52,7 +52,7 @@
  *
  * <pre>
  * class SerialExecutor implements Executor {
- *     final Queue&lt;Runnable&gt; tasks = new LinkedBlockingQueue&lt;Runnable&gt;();
+ *     final Queue&lt;Runnable&gt; tasks = new ArrayDeque&lt;Runnable&gt;();
  *     final Executor executor;
  *     Runnable active;
  *
@@ -88,6 +88,11 @@
  * extensible thread pool implementation. The {@link Executors} class
  * provides convenient factory methods for these Executors.
  *
+ * <p>Memory consistency effects: Actions in a thread prior to
+ * submitting a {@code Runnable} object to an {@code Executor}
+ * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
+ * its execution begins, perhaps in another thread.
+ *
  * @since 1.5
  * @author Doug Lea
  */
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/ExecutorCompletionService.java b/libcore/concurrent/src/main/java/java/util/concurrent/ExecutorCompletionService.java
index 4f9c9d9..02606f9 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/ExecutorCompletionService.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/ExecutorCompletionService.java
@@ -6,11 +6,10 @@
 
 package java.util.concurrent;
 
-
 /**
  * A {@link CompletionService} that uses a supplied {@link Executor}
  * to execute tasks.  This class arranges that submitted tasks are,
- * upon completion, placed on a queue accessible using <tt>take</tt>.
+ * upon completion, placed on a queue accessible using {@code take}.
  * The class is lightweight enough to be suitable for transient use
  * when processing groups of tasks.
  *
@@ -19,84 +18,102 @@
  * <b>Usage Examples.</b>
  *
  * Suppose you have a set of solvers for a certain problem, each
- * returning a value of some type <tt>Result</tt>, and would like to
+ * returning a value of some type {@code Result}, and would like to
  * run them concurrently, processing the results of each of them that
- * return a non-null value, in some method <tt>use(Result r)</tt>. You
+ * return a non-null value, in some method {@code use(Result r)}. You
  * could write this as:
  *
- * <pre>
- *    void solve(Executor e, Collection&lt;Callable&lt;Result&gt;&gt; solvers)
- *      throws InterruptedException, ExecutionException {
- *        CompletionService&lt;Result&gt; ecs = new ExecutorCompletionService&lt;Result&gt;(e);
- *        for (Callable&lt;Result&gt; s : solvers)
- *            ecs.submit(s);
- *        int n = solvers.size();
- *        for (int i = 0; i &lt; n; ++i) {
- *            Result r = ecs.take().get();
- *            if (r != null) 
- *                use(r);
- *        }
- *    }
- * </pre>
+ * <pre> {@code
+ * void solve(Executor e,
+ *            Collection<Callable<Result>> solvers)
+ *     throws InterruptedException, ExecutionException {
+ *     CompletionService<Result> ecs
+ *         = new ExecutorCompletionService<Result>(e);
+ *     for (Callable<Result> s : solvers)
+ *         ecs.submit(s);
+ *     int n = solvers.size();
+ *     for (int i = 0; i < n; ++i) {
+ *         Result r = ecs.take().get();
+ *         if (r != null)
+ *             use(r);
+ *     }
+ * }}</pre>
  *
  * Suppose instead that you would like to use the first non-null result
  * of the set of tasks, ignoring any that encounter exceptions,
  * and cancelling all other tasks when the first one is ready:
  *
- * <pre>
- *    void solve(Executor e, Collection&lt;Callable&lt;Result&gt;&gt; solvers) 
- *      throws InterruptedException {
- *        CompletionService&lt;Result&gt; ecs = new ExecutorCompletionService&lt;Result&gt;(e);
- *        int n = solvers.size();
- *        List&lt;Future&lt;Result&gt;&gt; futures = new ArrayList&lt;Future&lt;Result&gt;&gt;(n);
- *        Result result = null;
- *        try {
- *            for (Callable&lt;Result&gt; s : solvers)
- *                futures.add(ecs.submit(s));
- *            for (int i = 0; i &lt; n; ++i) {
- *                try {
- *                    Result r = ecs.take().get();
- *                    if (r != null) {
- *                        result = r;
- *                        break;
- *                    }
- *                } catch(ExecutionException ignore) {}
- *            }
- *        }
- *        finally {
- *            for (Future&lt;Result&gt; f : futures)
- *                f.cancel(true);
- *        }
+ * <pre> {@code
+ * void solve(Executor e,
+ *            Collection<Callable<Result>> solvers)
+ *     throws InterruptedException {
+ *     CompletionService<Result> ecs
+ *         = new ExecutorCompletionService<Result>(e);
+ *     int n = solvers.size();
+ *     List<Future<Result>> futures
+ *         = new ArrayList<Future<Result>>(n);
+ *     Result result = null;
+ *     try {
+ *         for (Callable<Result> s : solvers)
+ *             futures.add(ecs.submit(s));
+ *         for (int i = 0; i < n; ++i) {
+ *             try {
+ *                 Result r = ecs.take().get();
+ *                 if (r != null) {
+ *                     result = r;
+ *                     break;
+ *                 }
+ *             } catch (ExecutionException ignore) {}
+ *         }
+ *     }
+ *     finally {
+ *         for (Future<Result> f : futures)
+ *             f.cancel(true);
+ *     }
  *
- *        if (result != null)
- *            use(result);
- *    }
- * </pre>
+ *     if (result != null)
+ *         use(result);
+ * }}</pre>
  */
 public class ExecutorCompletionService<V> implements CompletionService<V> {
     private final Executor executor;
+    private final AbstractExecutorService aes;
     private final BlockingQueue<Future<V>> completionQueue;
 
     /**
      * FutureTask extension to enqueue upon completion
      */
-    private class QueueingFuture extends FutureTask<V> {
-        QueueingFuture(Callable<V> c) { super(c); }
-        QueueingFuture(Runnable t, V r) { super(t, r); }
-        protected void done() { completionQueue.add(this); }
+    private class QueueingFuture extends FutureTask<Void> {
+        QueueingFuture(FutureTask<V> task) {
+            super(task, null);
+            this.task = task;
+        }
+        protected void done() { completionQueue.add(task); }
+        private final Future<V> task;
+    }
+
+    private FutureTask<V> newTaskFor(Callable<V> task) {
+        return new FutureTask<V>(task);
+    }
+
+    private FutureTask<V> newTaskFor(Runnable task, V result) {
+        return new FutureTask<V>(task, result);
     }
 
     /**
      * Creates an ExecutorCompletionService using the supplied
      * executor for base task execution and a
      * {@link LinkedBlockingQueue} as a completion queue.
+     *
      * @param executor the executor to use
-     * @throws NullPointerException if executor is <tt>null</tt>
+     * @throws NullPointerException if executor is {@code null}
      */
     public ExecutorCompletionService(Executor executor) {
-        if (executor == null) 
+        if (executor == null)
             throw new NullPointerException();
         this.executor = executor;
+        this.aes = (executor instanceof AbstractExecutorService) ?
+            (AbstractExecutorService) executor : null;
         this.completionQueue = new LinkedBlockingQueue<Future<V>>();
     }
 
@@ -104,30 +121,36 @@
      * Creates an ExecutorCompletionService using the supplied
      * executor for base task execution and the supplied queue as its
      * completion queue.
+     *
      * @param executor the executor to use
      * @param completionQueue the queue to use as the completion queue
-     * normally one dedicated for use by this service
-     * @throws NullPointerException if executor or completionQueue are <tt>null</tt>
+     *        normally one dedicated for use by this service. This
+     *        queue is treated as unbounded -- failed attempted
+     *        {@code Queue.add} operations for completed taskes cause
+     *        them not to be retrievable.
+     * @throws NullPointerException if executor or completionQueue are {@code null}
      */
     public ExecutorCompletionService(Executor executor,
                                      BlockingQueue<Future<V>> completionQueue) {
-        if (executor == null || completionQueue == null) 
+        if (executor == null || completionQueue == null)
             throw new NullPointerException();
         this.executor = executor;
+        this.aes = (executor instanceof AbstractExecutorService) ?
+            (AbstractExecutorService) executor : null;
         this.completionQueue = completionQueue;
     }
 
     public Future<V> submit(Callable<V> task) {
         if (task == null) throw new NullPointerException();
-        QueueingFuture f = new QueueingFuture(task);
-        executor.execute(f);
+        FutureTask<V> f = newTaskFor(task);
+        executor.execute(new QueueingFuture(f));
         return f;
     }
 
     public Future<V> submit(Runnable task, V result) {
         if (task == null) throw new NullPointerException();
-        QueueingFuture f = new QueueingFuture(task, result);
-        executor.execute(f);
+        FutureTask<V> f = newTaskFor(task, result);
+        executor.execute(new QueueingFuture(f));
         return f;
     }
 
@@ -144,5 +167,3 @@
     }
 
 }
-
-
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/ExecutorService.java b/libcore/concurrent/src/main/java/java/util/concurrent/ExecutorService.java
index e178eb2..757f7cb 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/ExecutorService.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/ExecutorService.java
@@ -5,7 +5,6 @@
  */
 
 package java.util.concurrent;
-
 import java.util.List;
 import java.util.Collection;
 import java.security.PrivilegedAction;
@@ -14,14 +13,18 @@
 /**
  * An {@link Executor} that provides methods to manage termination and
  * methods that can produce a {@link Future} for tracking progress of
- * one or more asynchronous tasks.  
+ * one or more asynchronous tasks.
  *
- * <p>
- * An <tt>ExecutorService</tt> can be shut down, which will cause it
- * to stop accepting new tasks.  After being shut down, the executor
- * will eventually terminate, at which point no tasks are actively
- * executing, no tasks are awaiting execution, and no new tasks can be
- * submitted.
+ * <p> An <tt>ExecutorService</tt> can be shut down, which will cause
+ * it to reject new tasks.  Two different methods are provided for
+ * shutting down an <tt>ExecutorService</tt>. The {@link #shutdown}
+ * method will allow previously submitted tasks to execute before
+ * terminating, while the {@link #shutdownNow} method prevents waiting
+ * tasks from starting and attempts to stop currently executing tasks.
+ * Upon termination, an executor has no tasks actively executing, no
+ * tasks awaiting execution, and no new tasks can be submitted.  An
+ * unused <tt>ExecutorService</tt> should be shut down to allow
+ * reclamation of its resources.
  *
  * <p> Method <tt>submit</tt> extends base method {@link
  * Executor#execute} by creating and returning a {@link Future} that
@@ -35,41 +38,74 @@
  * <p>The {@link Executors} class provides factory methods for the
  * executor services provided in this package.
  *
- * <h3>Usage Example</h3>
+ * <h3>Usage Examples</h3>
  *
  * Here is a sketch of a network service in which threads in a thread
  * pool service incoming requests. It uses the preconfigured {@link
  * Executors#newFixedThreadPool} factory method:
  *
  * <pre>
- * class NetworkService {
- *    private final ServerSocket serverSocket;
- *    private final ExecutorService pool;
+ * class NetworkService implements Runnable {
+ *   private final ServerSocket serverSocket;
+ *   private final ExecutorService pool;
  *
- *    public NetworkService(int port, int poolSize) throws IOException {
- *      serverSocket = new ServerSocket(port);
- *      pool = Executors.newFixedThreadPool(poolSize);
- *    }
- * 
- *    public void serve() {
- *      try {
- *        for (;;) {
- *          pool.execute(new Handler(serverSocket.accept()));
- *        }
- *      } catch (IOException ex) {
- *        pool.shutdown();
- *      }
- *    }
- *  }
+ *   public NetworkService(int port, int poolSize)
+ *       throws IOException {
+ *     serverSocket = new ServerSocket(port);
+ *     pool = Executors.newFixedThreadPool(poolSize);
+ *   }
  *
- *  class Handler implements Runnable {
- *    private final Socket socket;
- *    Handler(Socket socket) { this.socket = socket; }
- *    public void run() {
- *      // read and service request
- *    }
+ *   public void run() { // run the service
+ *     try {
+ *       for (;;) {
+ *         pool.execute(new Handler(serverSocket.accept()));
+ *       }
+ *     } catch (IOException ex) {
+ *       pool.shutdown();
+ *     }
+ *   }
+ * }
+ *
+ * class Handler implements Runnable {
+ *   private final Socket socket;
+ *   Handler(Socket socket) { this.socket = socket; }
+ *   public void run() {
+ *     // read and service request on socket
+ *   }
  * }
  * </pre>
+ *
+ * The following method shuts down an <tt>ExecutorService</tt> in two phases,
+ * first by calling <tt>shutdown</tt> to reject incoming tasks, and then
+ * calling <tt>shutdownNow</tt>, if necessary, to cancel any lingering tasks:
+ *
+ * <pre>
+ * void shutdownAndAwaitTermination(ExecutorService pool) {
+ *   pool.shutdown(); // Disable new tasks from being submitted
+ *   try {
+ *     // Wait a while for existing tasks to terminate
+ *     if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
+ *       pool.shutdownNow(); // Cancel currently executing tasks
+ *       // Wait a while for tasks to respond to being cancelled
+ *       if (!pool.awaitTermination(60, TimeUnit.SECONDS))
+ *           System.err.println("Pool did not terminate");
+ *     }
+ *   } catch (InterruptedException ie) {
+ *     // (Re-)Cancel if current thread also interrupted
+ *     pool.shutdownNow();
+ *     // Preserve interrupt status
+ *     Thread.currentThread().interrupt();
+ *   }
+ * }
+ * </pre>
+ *
+ * <p>Memory consistency effects: Actions in a thread prior to the
+ * submission of a {@code Runnable} or {@code Callable} task to an
+ * {@code ExecutorService}
+ * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
+ * any actions taken by that task, which in turn <i>happen-before</i> the
+ * result is retrieved via {@code Future.get()}.
+ *
  * @since 1.5
  * @author Doug Lea
  */
@@ -77,33 +113,45 @@
 
     /**
      * Initiates an orderly shutdown in which previously submitted
-     * tasks are executed, but no new tasks will be
-     * accepted. Invocation has no additional effect if already shut
-     * down.
+     * tasks are executed, but no new tasks will be accepted.
+     * Invocation has no additional effect if already shut down.
+     *
+     * <p>This method does not wait for previously submitted tasks to
+     * complete execution.  Use {@link #awaitTermination awaitTermination}
+     * to do that.
+     *
      * @throws SecurityException if a security manager exists and
-     * shutting down this ExecutorService may manipulate threads that
-     * the caller is not permitted to modify because it does not hold
-     * {@link java.lang.RuntimePermission}<tt>("modifyThread")</tt>,
-     * or the security manager's <tt>checkAccess</tt>  method denies access.
+     *         shutting down this ExecutorService may manipulate
+     *         threads that the caller is not permitted to modify
+     *         because it does not hold {@link
+     *         java.lang.RuntimePermission}<tt>("modifyThread")</tt>,
+     *         or the security manager's <tt>checkAccess</tt> method
+     *         denies access.
      */
     void shutdown();
 
     /**
      * Attempts to stop all actively executing tasks, halts the
-     * processing of waiting tasks, and returns a list of the tasks that were
-     * awaiting execution. 
-     *  
+     * processing of waiting tasks, and returns a list of the tasks
+     * that were awaiting execution.
+     *
+     * <p>This method does not wait for actively executing tasks to
+     * terminate.  Use {@link #awaitTermination awaitTermination} to
+     * do that.
+     *
      * <p>There are no guarantees beyond best-effort attempts to stop
      * processing actively executing tasks.  For example, typical
-     * implementations will cancel via {@link Thread#interrupt}, so if any
-     * tasks mask or fail to respond to interrupts, they may never terminate.
+     * implementations will cancel via {@link Thread#interrupt}, so any
+     * task that fails to respond to interrupts may never terminate.
      *
      * @return list of tasks that never commenced execution
      * @throws SecurityException if a security manager exists and
-     * shutting down this ExecutorService may manipulate threads that
-     * the caller is not permitted to modify because it does not hold
-     * {@link java.lang.RuntimePermission}<tt>("modifyThread")</tt>,
-     * or the security manager's <tt>checkAccess</tt> method denies access.
+     *         shutting down this ExecutorService may manipulate
+     *         threads that the caller is not permitted to modify
+     *         because it does not hold {@link
+     *         java.lang.RuntimePermission}<tt>("modifyThread")</tt>,
+     *         or the security manager's <tt>checkAccess</tt> method
+     *         denies access.
      */
     List<Runnable> shutdownNow();
 
@@ -130,8 +178,8 @@
      *
      * @param timeout the maximum time to wait
      * @param unit the time unit of the timeout argument
-     * @return <tt>true</tt> if this executor terminated and <tt>false</tt>
-     * if the timeout elapsed before termination
+     * @return <tt>true</tt> if this executor terminated and
+     *         <tt>false</tt> if the timeout elapsed before termination
      * @throws InterruptedException if interrupted while waiting
      */
     boolean awaitTermination(long timeout, TimeUnit unit)
@@ -139,8 +187,10 @@
 
 
     /**
-     * Submits a value-returning task for execution and returns a Future
-     * representing the pending results of the task. 
+     * Submits a value-returning task for execution and returns a
+     * Future representing the pending results of the task. The
+     * Future's <tt>get</tt> method will return the task's result upon
+     * successful completion.
      *
      * <p>
      * If you would like to immediately block waiting
@@ -154,88 +204,92 @@
      *
      * @param task the task to submit
      * @return a Future representing pending completion of the task
-     * @throws RejectedExecutionException if task cannot be scheduled
-     * for execution
-     * @throws NullPointerException if task null
+     * @throws RejectedExecutionException if the task cannot be
+     *         scheduled for execution
+     * @throws NullPointerException if the task is null
      */
     <T> Future<T> submit(Callable<T> task);
 
     /**
-     * Submits a Runnable task for execution and returns a Future 
-     * representing that task that will upon completion return 
-     * the given result
+     * Submits a Runnable task for execution and returns a Future
+     * representing that task. The Future's <tt>get</tt> method will
+     * return the given result upon successful completion.
      *
      * @param task the task to submit
      * @param result the result to return
-     * @return a Future representing pending completion of the task,
-     * and whose <tt>get()</tt> method will return the given result
-     * upon completion.
-     * @throws RejectedExecutionException if task cannot be scheduled
-     * for execution
-     * @throws NullPointerException if task null     
+     * @return a Future representing pending completion of the task
+     * @throws RejectedExecutionException if the task cannot be
+     *         scheduled for execution
+     * @throws NullPointerException if the task is null
      */
     <T> Future<T> submit(Runnable task, T result);
 
     /**
-     * Submits a Runnable task for execution and returns a Future 
-     * representing that task.
+     * Submits a Runnable task for execution and returns a Future
+     * representing that task. The Future's <tt>get</tt> method will
+     * return <tt>null</tt> upon <em>successful</em> completion.
      *
      * @param task the task to submit
-     * @return a Future representing pending completion of the task,
-     * and whose <tt>get()</tt> method will return <tt>null</tt>
-     * upon completion.
-     * @throws RejectedExecutionException if task cannot be scheduled
-     * for execution
-     * @throws NullPointerException if task null
+     * @return a Future representing pending completion of the task
+     * @throws RejectedExecutionException if the task cannot be
+     *         scheduled for execution
+     * @throws NullPointerException if the task is null
      */
     Future<?> submit(Runnable task);
 
     /**
-     * Executes the given tasks, returning their results
-     * when all complete.
+     * Executes the given tasks, returning a list of Futures holding
+     * their status and results when all complete.
+     * {@link Future#isDone} is <tt>true</tt> for each
+     * element of the returned list.
      * Note that a <em>completed</em> task could have
      * terminated either normally or by throwing an exception.
      * The results of this method are undefined if the given
      * collection is modified while this operation is in progress.
+     *
      * @param tasks the collection of tasks
      * @return A list of Futures representing the tasks, in the same
-     * sequential order as produced by the iterator for the given task
-     * list, each of which has completed.
+     *         sequential order as produced by the iterator for the
+     *         given task list, each of which has completed.
      * @throws InterruptedException if interrupted while waiting, in
-     * which case unfinished tasks are cancelled.
+     *         which case unfinished tasks are cancelled.
      * @throws NullPointerException if tasks or any of its elements are <tt>null</tt>
-     * @throws RejectedExecutionException if any task cannot be scheduled
-     * for execution
+     * @throws RejectedExecutionException if any task cannot be
+     *         scheduled for execution
      */
 
     <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks)
         throws InterruptedException;
 
     /**
-     * Executes the given tasks, returning their results
+     * Executes the given tasks, returning a list of Futures holding
+     * their status and results
      * when all complete or the timeout expires, whichever happens first.
+     * {@link Future#isDone} is <tt>true</tt> for each
+     * element of the returned list.
      * Upon return, tasks that have not completed are cancelled.
      * Note that a <em>completed</em> task could have
      * terminated either normally or by throwing an exception.
      * The results of this method are undefined if the given
      * collection is modified while this operation is in progress.
+     *
      * @param tasks the collection of tasks
      * @param timeout the maximum time to wait
      * @param unit the time unit of the timeout argument
-     * @return A list of Futures representing the tasks, in the same
-     * sequential order as produced by the iterator for the given
-     * task list. If the operation did not time out, each task will
-     * have completed. If it did time out, some of thiese tasks will
-     * not have completed.
+     * @return a list of Futures representing the tasks, in the same
+     *         sequential order as produced by the iterator for the
+     *         given task list. If the operation did not time out,
+     *         each task will have completed. If it did time out, some
+     *         of these tasks will not have completed.
      * @throws InterruptedException if interrupted while waiting, in
-     * which case unfinished tasks are cancelled.
+     *         which case unfinished tasks are cancelled
      * @throws NullPointerException if tasks, any of its elements, or
-     * unit are <tt>null</tt>
+     *         unit are <tt>null</tt>
      * @throws RejectedExecutionException if any task cannot be scheduled
-     * for execution
+     *         for execution
      */
-    <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks, 
-                                  long timeout, TimeUnit unit) 
+    <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks,
+                                  long timeout, TimeUnit unit)
         throws InterruptedException;
 
     /**
@@ -245,15 +299,16 @@
      * tasks that have not completed are cancelled.
      * The results of this method are undefined if the given
      * collection is modified while this operation is in progress.
+     *
      * @param tasks the collection of tasks
-     * @return The result returned by one of the tasks.
+     * @return the result returned by one of the tasks
      * @throws InterruptedException if interrupted while waiting
      * @throws NullPointerException if tasks or any of its elements
-     * are <tt>null</tt>
-     * @throws IllegalArgumentException if tasks empty
+     *         are <tt>null</tt>
+     * @throws IllegalArgumentException if tasks is empty
      * @throws ExecutionException if no task successfully completes
      * @throws RejectedExecutionException if tasks cannot be scheduled
-     * for execution
+     *         for execution
      */
     <T> T invokeAny(Collection<Callable<T>> tasks)
         throws InterruptedException, ExecutionException;
@@ -266,21 +321,21 @@
      * completed are cancelled.
      * The results of this method are undefined if the given
      * collection is modified while this operation is in progress.
+     *
      * @param tasks the collection of tasks
      * @param timeout the maximum time to wait
      * @param unit the time unit of the timeout argument
-     * @return The result returned by one of the tasks.
+     * @return the result returned by one of the tasks.
      * @throws InterruptedException if interrupted while waiting
      * @throws NullPointerException if tasks, any of its elements, or
-     * unit are <tt>null</tt>
+     *         unit are <tt>null</tt>
      * @throws TimeoutException if the given timeout elapses before
-     * any task successfully completes
+     *         any task successfully completes
      * @throws ExecutionException if no task successfully completes
      * @throws RejectedExecutionException if tasks cannot be scheduled
-     * for execution
+     *         for execution
      */
-    <T> T invokeAny(Collection<Callable<T>> tasks, 
-                    long timeout, TimeUnit unit) 
+    <T> T invokeAny(Collection<Callable<T>> tasks,
+                    long timeout, TimeUnit unit)
         throws InterruptedException, ExecutionException, TimeoutException;
-
 }
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/Executors.java b/libcore/concurrent/src/main/java/java/util/concurrent/Executors.java
index 23f1b75..90cf6ee 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/Executors.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/Executors.java
@@ -11,6 +11,7 @@
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.security.PrivilegedExceptionAction;
+import java.security.PrivilegedActionException;
 import java.security.AccessControlException;
 
 /**
@@ -18,18 +19,18 @@
  * ExecutorService}, {@link ScheduledExecutorService}, {@link
  * ThreadFactory}, and {@link Callable} classes defined in this
  * package. This class supports the following kinds of methods:
- * 
+ *
  * <ul>
- *   <li> Methods that create and return an {@link ExecutorService} 
- *        set up with commonly useful configuration settings. 
- *   <li> Methods that create and return a {@link ScheduledExecutorService} 
- *        set up with commonly useful configuration settings. 
+ *   <li> Methods that create and return an {@link ExecutorService}
+ *        set up with commonly useful configuration settings.
+ *   <li> Methods that create and return a {@link ScheduledExecutorService}
+ *        set up with commonly useful configuration settings.
  *   <li> Methods that create and return a "wrapped" ExecutorService, that
  *        disables reconfiguration by making implementation-specific methods
  *        inaccessible.
  *   <li> Methods that create and return a {@link ThreadFactory}
  *        that sets newly created threads to a known state.
- *   <li> Methods that create and return a {@link Callable} 
+ *   <li> Methods that create and return a {@link Callable}
  *        out of other closure-like forms, so they can be used
  *        in execution methods requiring <tt>Callable</tt>.
  * </ul>
@@ -40,14 +41,19 @@
 public class Executors {
 
     /**
-     * Creates a thread pool that reuses a fixed set of threads
-     * operating off a shared unbounded queue. If any thread
-     * terminates due to a failure during execution prior to shutdown,
-     * a new one will take its place if needed to execute subsequent
-     * tasks.
+     * Creates a thread pool that reuses a fixed number of threads
+     * operating off a shared unbounded queue.  At any point, at most
+     * <tt>nThreads</tt> threads will be active processing tasks.
+     * If additional tasks are submitted when all threads are active,
+     * they will wait in the queue until a thread is available.
+     * If any thread terminates due to a failure during execution
+     * prior to shutdown, a new one will take its place if needed to
+     * execute subsequent tasks.  The threads in the pool will exist
+     * until it is explicitly {@link ExecutorService#shutdown shutdown}.
      *
      * @param nThreads the number of threads in the pool
      * @return the newly created thread pool
+     * @throws IllegalArgumentException if <tt>nThreads &lt;= 0</tt>
      */
     public static ExecutorService newFixedThreadPool(int nThreads) {
         return new ThreadPoolExecutor(nThreads, nThreads,
@@ -56,13 +62,23 @@
     }
 
     /**
-     * Creates a thread pool that reuses a fixed set of threads
+     * Creates a thread pool that reuses a fixed number of threads
      * operating off a shared unbounded queue, using the provided
-     * ThreadFactory to create new threads when needed.
+     * ThreadFactory to create new threads when needed.  At any point,
+     * at most <tt>nThreads</tt> threads will be active processing
+     * tasks.  If additional tasks are submitted when all threads are
+     * active, they will wait in the queue until a thread is
+     * available.  If any thread terminates due to a failure during
+     * execution prior to shutdown, a new one will take its place if
+     * needed to execute subsequent tasks.  The threads in the pool will
+     * exist until it is explicitly {@link ExecutorService#shutdown
+     * shutdown}.
      *
      * @param nThreads the number of threads in the pool
      * @param threadFactory the factory to use when creating new threads
      * @return the newly created thread pool
+     * @throws NullPointerException if threadFactory is null
+     * @throws IllegalArgumentException if <tt>nThreads &lt;= 0</tt>
      */
     public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
         return new ThreadPoolExecutor(nThreads, nThreads,
@@ -85,7 +101,7 @@
      * @return the newly created single-threaded Executor
      */
     public static ExecutorService newSingleThreadExecutor() {
-        return new DelegatedExecutorService
+        return new FinalizableDelegatedExecutorService
             (new ThreadPoolExecutor(1, 1,
                                     0L, TimeUnit.MILLISECONDS,
                                     new LinkedBlockingQueue<Runnable>()));
@@ -95,17 +111,18 @@
      * Creates an Executor that uses a single worker thread operating
      * off an unbounded queue, and uses the provided ThreadFactory to
      * create a new thread when needed. Unlike the otherwise
-     * equivalent <tt>newFixedThreadPool(1, threadFactory)</tt> the returned executor
-     * is guaranteed not to be reconfigurable to use additional
-     * threads.
-     * 
+     * equivalent <tt>newFixedThreadPool(1, threadFactory)</tt> the
+     * returned executor is guaranteed not to be reconfigurable to use
+     * additional threads.
+     *
      * @param threadFactory the factory to use when creating new
      * threads
      *
      * @return the newly created single-threaded Executor
+     * @throws NullPointerException if threadFactory is null
      */
     public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
-        return new DelegatedExecutorService
+        return new FinalizableDelegatedExecutorService
             (new ThreadPoolExecutor(1, 1,
                                     0L, TimeUnit.MILLISECONDS,
                                     new LinkedBlockingQueue<Runnable>(),
@@ -141,6 +158,7 @@
      * ThreadFactory to create new threads when needed.
      * @param threadFactory the factory to use when creating new threads
      * @return the newly created thread pool
+     * @throws NullPointerException if threadFactory is null
      */
     public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
         return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
@@ -148,7 +166,7 @@
                                       new SynchronousQueue<Runnable>(),
                                       threadFactory);
     }
-   
+
     /**
      * Creates a single-threaded executor that can schedule commands
      * to run after a given delay, or to execute periodically.
@@ -181,31 +199,35 @@
      * @param threadFactory the factory to use when creating new
      * threads
      * @return a newly created scheduled executor
+     * @throws NullPointerException if threadFactory is null
      */
     public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {
         return new DelegatedScheduledExecutorService
             (new ScheduledThreadPoolExecutor(1, threadFactory));
     }
-    
+
     /**
-     * Creates a thread pool that can schedule commands to run after a 
+     * Creates a thread pool that can schedule commands to run after a
      * given delay, or to execute periodically.
      * @param corePoolSize the number of threads to keep in the pool,
      * even if they are idle.
      * @return a newly created scheduled thread pool
+     * @throws IllegalArgumentException if <tt>corePoolSize &lt; 0</tt>
      */
     public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
         return new ScheduledThreadPoolExecutor(corePoolSize);
     }
 
     /**
-     * Creates a thread pool that can schedule commands to run after a 
+     * Creates a thread pool that can schedule commands to run after a
      * given delay, or to execute periodically.
      * @param corePoolSize the number of threads to keep in the pool,
      * even if they are idle.
      * @param threadFactory the factory to use when the executor
-     * creates a new thread. 
+     * creates a new thread.
      * @return a newly created scheduled thread pool
+     * @throws IllegalArgumentException if <tt>corePoolSize &lt; 0</tt>
+     * @throws NullPointerException if threadFactory is null
      */
     public static ScheduledExecutorService newScheduledThreadPool(
             int corePoolSize, ThreadFactory threadFactory) {
@@ -244,7 +266,7 @@
             throw new NullPointerException();
         return new DelegatedScheduledExecutorService(executor);
     }
-        
+
     /**
      * Returns a default thread factory used to create new threads.
      * This factory creates all new threads used by an Executor in the
@@ -252,8 +274,9 @@
      * java.lang.SecurityManager}, it uses the group of {@link
      * System#getSecurityManager}, else the group of the thread
      * invoking this <tt>defaultThreadFactory</tt> method. Each new
-     * thread is created as a non-daemon thread with priority
-     * <tt>Thread.NORM_PRIORITY</tt>. New threads have names
+     * thread is created as a non-daemon thread with priority set to
+     * the smaller of <tt>Thread.NORM_PRIORITY</tt> and the maximum
+     * priority permitted in the thread group.  New threads have names
      * accessible via {@link Thread#getName} of
      * <em>pool-N-thread-M</em>, where <em>N</em> is the sequence
      * number of this factory, and <em>M</em> is the sequence number
@@ -307,8 +330,8 @@
      * <tt>Callable</tt> to an otherwise resultless action.
      * @param task the task to run
      * @param result the result to return
-     * @throws NullPointerException if task null
      * @return a callable object
+     * @throws NullPointerException if task null
      */
     public static <T> Callable<T> callable(Runnable task, T result) {
         if (task == null)
@@ -336,10 +359,11 @@
      * @return a callable object
      * @throws NullPointerException if action null
      */
-    public static Callable<Object> callable(PrivilegedAction action) {
+    public static Callable<Object> callable(final PrivilegedAction<?> action) {
         if (action == null)
             throw new NullPointerException();
-        return new PrivilegedActionAdapter(action);
+        return new Callable<Object>() {
+            public Object call() { return action.run(); }};
     }
 
     /**
@@ -350,10 +374,11 @@
      * @return a callable object
      * @throws NullPointerException if action null
      */
-    public static Callable<Object> callable(PrivilegedExceptionAction action) {
+    public static Callable<Object> callable(final PrivilegedExceptionAction<?> action) {
         if (action == null)
             throw new NullPointerException();
-        return new PrivilegedExceptionActionAdapter(action);
+        return new Callable<Object>() {
+            public Object call() throws Exception { return action.run(); }};
     }
 
     /**
@@ -373,9 +398,9 @@
     public static <T> Callable<T> privilegedCallable(Callable<T> callable) {
         if (callable == null)
             throw new NullPointerException();
-        return new PrivilegedCallable(callable);
+        return new PrivilegedCallable<T>(callable);
     }
-    
+
     /**
      * Returns a {@link Callable} object that will, when
      * called, execute the given <tt>callable</tt> under the current
@@ -397,7 +422,7 @@
     public static <T> Callable<T> privilegedCallableUsingCurrentClassLoader(Callable<T> callable) {
         if (callable == null)
             throw new NullPointerException();
-        return new PrivilegedCallableUsingCurrentClassLoader(callable);
+        return new PrivilegedCallableUsingCurrentClassLoader<T>(callable);
     }
 
     // Non-public classes supporting the public methods
@@ -408,71 +433,39 @@
     static final class RunnableAdapter<T> implements Callable<T> {
         final Runnable task;
         final T result;
-        RunnableAdapter(Runnable  task, T result) {
-            this.task = task; 
+        RunnableAdapter(Runnable task, T result) {
+            this.task = task;
             this.result = result;
         }
-        public T call() { 
-            task.run(); 
-            return result; 
+        public T call() {
+            task.run();
+            return result;
         }
     }
 
     /**
-     * A callable that runs given privileged action and returns its result
-     */
-    static final class PrivilegedActionAdapter implements Callable<Object> {
-        PrivilegedActionAdapter(PrivilegedAction action) {
-            this.action = action;
-        }
-        public Object call () {
-            return action.run();
-        }
-        private final PrivilegedAction action;
-    }
-
-    /**
-     * A callable that runs given privileged exception action and returns its result
-     */
-    static final class PrivilegedExceptionActionAdapter implements Callable<Object> {
-        PrivilegedExceptionActionAdapter(PrivilegedExceptionAction action) {
-            this.action = action;
-        }
-        public Object call () throws Exception {
-            return action.run();
-        }
-        private final PrivilegedExceptionAction action;
-    }
-
-
-    /**
      * A callable that runs under established access control settings
      */
     static final class PrivilegedCallable<T> implements Callable<T> {
-        private final AccessControlContext acc;
         private final Callable<T> task;
-        private T result;
-        private Exception exception;
+        private final AccessControlContext acc;
+
         PrivilegedCallable(Callable<T> task) {
             this.task = task;
             this.acc = AccessController.getContext();
         }
 
         public T call() throws Exception {
-            AccessController.doPrivileged(new PrivilegedAction() {
-                    public Object run() {
-                        try {
-                            result = task.call();
-                        } catch(Exception ex) {
-                            exception = ex;
+            try {
+                return AccessController.doPrivileged(
+                    new PrivilegedExceptionAction<T>() {
+                        public T run() throws Exception {
+                            return task.call();
                         }
-                        return null;
-                    }
-                }, acc);
-            if (exception != null)
-                throw exception;
-            else 
-                return result;
+                    }, acc);
+            } catch (PrivilegedActionException e) {
+                throw e.getException();
+            }
         }
     }
 
@@ -481,44 +474,50 @@
      * current ClassLoader
      */
     static final class PrivilegedCallableUsingCurrentClassLoader<T> implements Callable<T> {
-        private final ClassLoader ccl;
-        private final AccessControlContext acc;
         private final Callable<T> task;
-        private T result;
-        private Exception exception;
+        private final AccessControlContext acc;
+        private final ClassLoader ccl;
+
         PrivilegedCallableUsingCurrentClassLoader(Callable<T> task) {
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null) {
+                // Calls to getContextClassLoader from this class
+                // never trigger a security check, but we check
+                // whether our callers have this permission anyways.
+                sm.checkPermission(new RuntimePermission("getContextClassLoader"));
+
+                // Whether setContextClassLoader turns out to be necessary
+                // or not, we fail fast if permission is not available.
+                sm.checkPermission(new RuntimePermission("setContextClassLoader"));
+            }
             this.task = task;
-            this.ccl = Thread.currentThread().getContextClassLoader();
             this.acc = AccessController.getContext();
-            acc.checkPermission(new RuntimePermission("getContextClassLoader"));
-            acc.checkPermission(new RuntimePermission("setContextClassLoader"));
+            this.ccl = Thread.currentThread().getContextClassLoader();
         }
 
         public T call() throws Exception {
-            AccessController.doPrivileged(new PrivilegedAction() {
-                    public Object run() {
-                        ClassLoader savedcl = null;
-                        Thread t = Thread.currentThread();
-                        try {
-                            ClassLoader cl = t.getContextClassLoader();
-                            if (ccl != cl) {
-                                t.setContextClassLoader(ccl);
-                                savedcl = cl;
+            try {
+                return AccessController.doPrivileged(
+                    new PrivilegedExceptionAction<T>() {
+                        public T run() throws Exception {
+                            ClassLoader savedcl = null;
+                            Thread t = Thread.currentThread();
+                            try {
+                                ClassLoader cl = t.getContextClassLoader();
+                                if (ccl != cl) {
+                                    t.setContextClassLoader(ccl);
+                                    savedcl = cl;
+                                }
+                                return task.call();
+                            } finally {
+                                if (savedcl != null)
+                                    t.setContextClassLoader(savedcl);
                             }
-                            result = task.call();
-                        } catch(Exception ex) {
-                            exception = ex;
-                        } finally {
-                            if (savedcl != null)
-                                t.setContextClassLoader(savedcl);
                         }
-                        return null;
-                    }
-                }, acc);
-            if (exception != null)
-                throw exception;
-            else 
-                return result;
+                    }, acc);
+            } catch (PrivilegedActionException e) {
+                throw e.getException();
+            }
         }
     }
 
@@ -526,22 +525,22 @@
      * The default thread factory
      */
     static class DefaultThreadFactory implements ThreadFactory {
-        static final AtomicInteger poolNumber = new AtomicInteger(1);
-        final ThreadGroup group;
-        final AtomicInteger threadNumber = new AtomicInteger(1);
-        final String namePrefix;
+        private static final AtomicInteger poolNumber = new AtomicInteger(1);
+        private final ThreadGroup group;
+        private final AtomicInteger threadNumber = new AtomicInteger(1);
+        private final String namePrefix;
 
         DefaultThreadFactory() {
             SecurityManager s = System.getSecurityManager();
             group = (s != null)? s.getThreadGroup() :
                                  Thread.currentThread().getThreadGroup();
-            namePrefix = "pool-" + 
-                          poolNumber.getAndIncrement() + 
+            namePrefix = "pool-" +
+                          poolNumber.getAndIncrement() +
                          "-thread-";
         }
 
         public Thread newThread(Runnable r) {
-            Thread t = new Thread(group, r, 
+            Thread t = new Thread(group, r,
                                   namePrefix + threadNumber.getAndIncrement(),
                                   0);
             if (t.isDaemon())
@@ -553,38 +552,46 @@
     }
 
     /**
-     *  Thread factory capturing access control and class loader
+     * Thread factory capturing access control context and class loader
      */
     static class PrivilegedThreadFactory extends DefaultThreadFactory {
-        private final ClassLoader ccl;
         private final AccessControlContext acc;
+        private final ClassLoader ccl;
 
         PrivilegedThreadFactory() {
             super();
-            this.ccl = Thread.currentThread().getContextClassLoader();
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null) {
+                // Calls to getContextClassLoader from this class
+                // never trigger a security check, but we check
+                // whether our callers have this permission anyways.
+                sm.checkPermission(new RuntimePermission("getContextClassLoader"));
+
+                // Fail fast
+                sm.checkPermission(new RuntimePermission("setContextClassLoader"));
+            }
             this.acc = AccessController.getContext();
-            acc.checkPermission(new RuntimePermission("setContextClassLoader"));
+            this.ccl = Thread.currentThread().getContextClassLoader();
         }
-        
+
         public Thread newThread(final Runnable r) {
             return super.newThread(new Runnable() {
                 public void run() {
-                    AccessController.doPrivileged(new PrivilegedAction() {
-                        public Object run() { 
+                    AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                        public Void run() {
                             Thread.currentThread().setContextClassLoader(ccl);
                             r.run();
-                            return null; 
+                            return null;
                         }
                     }, acc);
                 }
             });
         }
-        
     }
 
-   /**
+    /**
      * A wrapper class that exposes only the ExecutorService methods
-     * of an implementation.
+     * of an ExecutorService implementation.
      */
     static class DelegatedExecutorService extends AbstractExecutorService {
         private final ExecutorService e;
@@ -611,8 +618,8 @@
             throws InterruptedException {
             return e.invokeAll(tasks);
         }
-        public <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks, 
-                                             long timeout, TimeUnit unit) 
+        public <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks,
+                                             long timeout, TimeUnit unit)
             throws InterruptedException {
             return e.invokeAll(tasks, timeout, unit);
         }
@@ -620,19 +627,29 @@
             throws InterruptedException, ExecutionException {
             return e.invokeAny(tasks);
         }
-        public <T> T invokeAny(Collection<Callable<T>> tasks, 
-                               long timeout, TimeUnit unit) 
+        public <T> T invokeAny(Collection<Callable<T>> tasks,
+                               long timeout, TimeUnit unit)
             throws InterruptedException, ExecutionException, TimeoutException {
             return e.invokeAny(tasks, timeout, unit);
         }
     }
-    
+
+    static class FinalizableDelegatedExecutorService
+        extends DelegatedExecutorService {
+        FinalizableDelegatedExecutorService(ExecutorService executor) {
+            super(executor);
+        }
+        protected void finalize()  {
+            super.shutdown();
+        }
+    }
+
     /**
-     * A wrapper class that exposes only the ExecutorService and 
-     * ScheduleExecutor methods of a ScheduledExecutorService implementation.
+     * A wrapper class that exposes only the ScheduledExecutorService
+     * methods of a ScheduledExecutorService implementation.
      */
     static class DelegatedScheduledExecutorService
-            extends DelegatedExecutorService 
+            extends DelegatedExecutorService
             implements ScheduledExecutorService {
         private final ScheduledExecutorService e;
         DelegatedScheduledExecutorService(ScheduledExecutorService executor) {
@@ -653,7 +670,7 @@
         }
     }
 
-        
+
     /** Cannot instantiate. */
     private Executors() {}
 }
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/Future.java b/libcore/concurrent/src/main/java/java/util/concurrent/Future.java
index 38fa8c6..0459ee4 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/Future.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/Future.java
@@ -29,10 +29,13 @@
  * class App {
  *   ExecutorService executor = ...
  *   ArchiveSearcher searcher = ...
- *   void showSearch(final String target) throws InterruptedException {
- *     Future&lt;String&gt; future = executor.submit(new Callable&lt;String&gt;() {
- *         public String call() { return searcher.search(target); }
- *     });
+ *   void showSearch(final String target)
+ *       throws InterruptedException {
+ *     Future&lt;String&gt; future
+ *       = executor.submit(new Callable&lt;String&gt;() {
+ *         public String call() {
+ *             return searcher.search(target);
+ *         }});
  *     displayOtherThings(); // do other things while searching
  *     try {
  *       displayText(future.get()); // use future
@@ -41,8 +44,8 @@
  * }
  * </pre>
  *
- * The {@link FutureTask} class is an implementation of <tt>Future</tt> that 
- * implements <tt>Runnable</tt>, and so may be executed by an <tt>Executor</tt>. 
+ * The {@link FutureTask} class is an implementation of <tt>Future</tt> that
+ * implements <tt>Runnable</tt>, and so may be executed by an <tt>Executor</tt>.
  * For example, the above construction with <tt>submit</tt> could be replaced by:
  * <pre>
  *     FutureTask&lt;String&gt; future =
@@ -52,6 +55,11 @@
  *       }});
  *     executor.execute(future);
  * </pre>
+ *
+ * <p>Memory consistency effects: Actions taken by the asynchronous computation
+ * <a href="package-summary.html#MemoryVisibility"> <i>happen-before</i></a>
+ * actions following the corresponding {@code Future.get()} in another thread.
+ *
  * @see FutureTask
  * @see Executor
  * @since 1.5
@@ -62,7 +70,7 @@
 
     /**
      * Attempts to cancel execution of this task.  This attempt will
-     * fail if the task has already completed, already been cancelled,
+     * fail if the task has already completed, has already been cancelled,
      * or could not be cancelled for some other reason. If successful,
      * and this task has not started when <tt>cancel</tt> is called,
      * this task should never run.  If the task has already started,
@@ -70,6 +78,10 @@
      * whether the thread executing this task should be interrupted in
      * an attempt to stop the task.
      *
+     * <p>After this method returns, subsequent calls to {@link #isDone} will
+     * always return <tt>true</tt>.  Subsequent calls to {@link #isCancelled}
+     * will always return <tt>true</tt> if this method returned <tt>true</tt>.
+     *
      * @param mayInterruptIfRunning <tt>true</tt> if the thread executing this
      * task should be interrupted; otherwise, in-progress tasks are allowed
      * to complete
@@ -83,18 +95,18 @@
      * Returns <tt>true</tt> if this task was cancelled before it completed
      * normally.
      *
-     * @return <tt>true</tt> if task was cancelled before it completed
+     * @return <tt>true</tt> if this task was cancelled before it completed
      */
     boolean isCancelled();
 
     /**
-     * Returns <tt>true</tt> if this task completed.  
+     * Returns <tt>true</tt> if this task completed.
      *
      * Completion may be due to normal termination, an exception, or
      * cancellation -- in all of these cases, this method will return
      * <tt>true</tt>.
-     * 
-     * @return <tt>true</tt> if this task completed.
+     *
+     * @return <tt>true</tt> if this task completed
      */
     boolean isDone();
 
@@ -128,6 +140,3 @@
     V get(long timeout, TimeUnit unit)
         throws InterruptedException, ExecutionException, TimeoutException;
 }
-
-
-
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/FutureTask.java b/libcore/concurrent/src/main/java/java/util/concurrent/FutureTask.java
index 87db1cd..8aa9dd1 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/FutureTask.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/FutureTask.java
@@ -35,7 +35,7 @@
     private final Sync sync;
 
     /**
-     * Creates a <tt>FutureTask</tt> that will upon running, execute the
+     * Creates a <tt>FutureTask</tt> that will, upon running, execute the
      * given <tt>Callable</tt>.
      *
      * @param  callable the callable task
@@ -48,11 +48,11 @@
     }
 
     /**
-     * Creates a <tt>FutureTask</tt> that will upon running, execute the
+     * Creates a <tt>FutureTask</tt> that will, upon running, execute the
      * given <tt>Runnable</tt>, and arrange that <tt>get</tt> will return the
      * given result on successful completion.
      *
-     * @param  runnable the runnable task
+     * @param runnable the runnable task
      * @param result the result to return on successful completion. If
      * you don't need a particular result, consider using
      * constructions of the form:
@@ -66,7 +66,7 @@
     public boolean isCancelled() {
         return sync.innerIsCancelled();
     }
-    
+
     public boolean isDone() {
         return sync.innerIsDone();
     }
@@ -74,11 +74,17 @@
     public boolean cancel(boolean mayInterruptIfRunning) {
         return sync.innerCancel(mayInterruptIfRunning);
     }
-    
+
+    /**
+     * @throws CancellationException {@inheritDoc}
+     */
     public V get() throws InterruptedException, ExecutionException {
         return sync.innerGet();
     }
 
+    /**
+     * @throws CancellationException {@inheritDoc}
+     */
     public V get(long timeout, TimeUnit unit)
         throws InterruptedException, ExecutionException, TimeoutException {
         return sync.innerGet(unit.toNanos(timeout));
@@ -98,8 +104,10 @@
     /**
      * Sets the result of this Future to the given value unless
      * this future has already been set or has been cancelled.
+     * This method is invoked internally by the <tt>run</tt> method
+     * upon successful completion of the computation.
      * @param v the value
-     */ 
+     */
     protected void set(V v) {
         sync.innerSet(v);
     }
@@ -108,15 +116,22 @@
      * Causes this future to report an <tt>ExecutionException</tt>
      * with the given throwable as its cause, unless this Future has
      * already been set or has been cancelled.
-     * @param t the cause of failure.
-     */ 
+     * This method is invoked internally by the <tt>run</tt> method
+     * upon failure of the computation.
+     * @param t the cause of failure
+     */
     protected void setException(Throwable t) {
         sync.innerSetException(t);
     }
-    
+
+    // The following (duplicated) doc comment can be removed once
+    //
+    // 6270645: Javadoc comments should be inherited from most derived
+    //          superinterface or superclass
+    // is fixed.
     /**
-     * Sets this Future to the result of computation unless
-     * it has been cancelled.
+     * Sets this Future to the result of its computation
+     * unless it has been cancelled.
      */
     public void run() {
         sync.innerRun();
@@ -143,6 +158,10 @@
      * Uses AQS sync state to represent run status
      */
     private final class Sync extends AbstractQueuedSynchronizer {
+        private static final long serialVersionUID = -7828117401763700385L;
+
+        /** State value representing that task is ready to run */
+        private static final int READY     = 0;
         /** State value representing that task is running */
         private static final int RUNNING   = 1;
         /** State value representing that task ran */
@@ -157,10 +176,10 @@
         /** The exception to throw from get() */
         private Throwable exception;
 
-        /** 
+        /**
          * The thread running task. When nulled after set/cancel, this
          * indicates that the results are accessible.  Must be
-         * volatile, to serve as write barrier on completion.
+         * volatile, to ensure visibility upon completion.
          */
         private volatile Thread runner;
 
@@ -176,7 +195,7 @@
          * Implements AQS base acquire to succeed if ran or cancelled
          */
         protected int tryAcquireShared(int ignore) {
-            return innerIsDone()? 1 : -1;
+            return innerIsDone() ? 1 : -1;
         }
 
         /**
@@ -185,13 +204,13 @@
          */
         protected boolean tryReleaseShared(int ignore) {
             runner = null;
-            return true; 
+            return true;
         }
 
         boolean innerIsCancelled() {
             return getState() == CANCELLED;
         }
-        
+
         boolean innerIsDone() {
             return ranOrCancelled(getState()) && runner == null;
         }
@@ -207,7 +226,7 @@
 
         V innerGet(long nanosTimeout) throws InterruptedException, ExecutionException, TimeoutException {
             if (!tryAcquireSharedNanos(0, nanosTimeout))
-                throw new TimeoutException();                
+                throw new TimeoutException();
             if (getState() == CANCELLED)
                 throw new CancellationException();
             if (exception != null)
@@ -216,28 +235,55 @@
         }
 
         void innerSet(V v) {
-            int s = getState();
-            if (ranOrCancelled(s) || !compareAndSetState(s, RAN))
-                return;
-            result = v;
-            releaseShared(0);
-            done();
+            for (;;) {
+                int s = getState();
+                if (s == RAN)
+                    return;
+                if (s == CANCELLED) {
+                    // aggressively release to set runner to null,
+                    // in case we are racing with a cancel request
+                    // that will try to interrupt runner
+                    releaseShared(0);
+                    return;
+                }
+                if (compareAndSetState(s, RAN)) {
+                    result = v;
+                    releaseShared(0);
+                    done();
+                    return;
+                }
+            }
         }
 
         void innerSetException(Throwable t) {
-            int s = getState();
-            if (ranOrCancelled(s) || !compareAndSetState(s, RAN)) 
-                return;
-            exception = t;
-            result = null;
-            releaseShared(0);
-            done();
+            for (;;) {
+                int s = getState();
+                if (s == RAN)
+                    return;
+                if (s == CANCELLED) {
+                    // aggressively release to set runner to null,
+                    // in case we are racing with a cancel request
+                    // that will try to interrupt runner
+                    releaseShared(0);
+                    return;
+                }
+                if (compareAndSetState(s, RAN)) {
+                    exception = t;
+                    releaseShared(0);
+                    done();
+                    return;
+                }
+            }
         }
 
         boolean innerCancel(boolean mayInterruptIfRunning) {
-            int s = getState();
-            if (ranOrCancelled(s) || !compareAndSetState(s, CANCELLED)) 
-                return false;
+            for (;;) {
+                int s = getState();
+                if (ranOrCancelled(s))
+                    return false;
+                if (compareAndSetState(s, CANCELLED))
+                    break;
+            }
             if (mayInterruptIfRunning) {
                 Thread r = runner;
                 if (r != null)
@@ -249,28 +295,37 @@
         }
 
         void innerRun() {
-            if (!compareAndSetState(0, RUNNING)) 
+            if (!compareAndSetState(READY, RUNNING))
                 return;
-            try {
-                runner = Thread.currentThread();
-                innerSet(callable.call());
-            } catch(Throwable ex) {
-                innerSetException(ex);
-            } 
+
+            runner = Thread.currentThread();
+            if (getState() == RUNNING) { // recheck after setting thread
+                V result;
+                try {
+                    result = callable.call();
+                } catch (Throwable ex) {
+                    setException(ex);
+                    return;
+                }
+                set(result);
+            } else {
+                releaseShared(0); // cancel
+            }
         }
 
         boolean innerRunAndReset() {
-            if (!compareAndSetState(0, RUNNING)) 
+            if (!compareAndSetState(READY, RUNNING))
                 return false;
             try {
                 runner = Thread.currentThread();
-                callable.call(); // don't set result
+                if (getState() == RUNNING)
+                    callable.call(); // don't set result
                 runner = null;
-                return compareAndSetState(RUNNING, 0);
-            } catch(Throwable ex) {
-                innerSetException(ex);
+                return compareAndSetState(RUNNING, READY);
+            } catch (Throwable ex) {
+                setException(ex);
                 return false;
-            } 
+            }
         }
     }
 }
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/Java6Arrays.java b/libcore/concurrent/src/main/java/java/util/concurrent/Java6Arrays.java
new file mode 100644
index 0000000..6b728be
--- /dev/null
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/Java6Arrays.java
@@ -0,0 +1,77 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.util.concurrent;
+
+import java.lang.reflect.Array;
+
+/**
+ * Arrays.copyOf and Arrays.copyOfRange backported from Java 6.
+ */
+class Java6Arrays {
+
+    static <T> T[] copyOf(T[] original, int newLength) {
+        if (null == original) {
+            throw new NullPointerException();
+        }
+        if (0 <= newLength) {
+            return copyOfRange(original, 0, newLength);
+        }
+        throw new NegativeArraySizeException();
+    }
+
+    static <T, U> T[] copyOf(U[] original, int newLength,
+            Class<? extends T[]> newType) {
+        if (0 <= newLength) {
+            return copyOfRange(original, 0, newLength, newType);
+        }
+        throw new NegativeArraySizeException();
+    }
+
+    @SuppressWarnings("unchecked")
+    static <T> T[] copyOfRange(T[] original, int start, int end) {
+        if (original.length >= start && 0 <= start) {
+            if (start <= end) {
+                int length = end - start;
+                int copyLength = Math.min(length, original.length - start);
+                T[] copy = (T[]) Array.newInstance(original.getClass().getComponentType(), length);
+                System.arraycopy(original, start, copy, 0, copyLength);
+                return copy;
+            }
+            throw new IllegalArgumentException();
+        }
+        throw new ArrayIndexOutOfBoundsException();
+    }
+
+    @SuppressWarnings("unchecked")
+    static <T, U> T[] copyOfRange(U[] original, int start, int end,
+            Class<? extends T[]> newType) {
+        if (start <= end) {
+            if (original.length >= start && 0 <= start) {
+                int length = end - start;
+                int copyLength = Math.min(length, original.length - start);
+                T[] copy = (T[]) Array.newInstance(newType.getComponentType(),
+                        length);
+                System.arraycopy(original, start, copy, 0, copyLength);
+                return copy;
+            }
+            throw new ArrayIndexOutOfBoundsException();
+        }
+        throw new IllegalArgumentException();
+    }
+
+}
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/LinkedBlockingQueue.java b/libcore/concurrent/src/main/java/java/util/concurrent/LinkedBlockingQueue.java
index 662f63e..e06f7bd 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/LinkedBlockingQueue.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/LinkedBlockingQueue.java
@@ -32,14 +32,15 @@
  * dynamically created upon each insertion unless this would bring the
  * queue above capacity.
  *
- * <p>This class implements all of the <em>optional</em> methods
- * of the {@link Collection} and {@link Iterator} interfaces.
+ * <p>This class and its iterator implement all of the
+ * <em>optional</em> methods of the {@link Collection} and {@link
+ * Iterator} interfaces.
  *
  * @since 1.5
  * @author Doug Lea
  * @param <E> the type of elements held in this collection
  *
- **/
+ */
 public class LinkedBlockingQueue<E> extends AbstractQueue<E>
         implements BlockingQueue<E>, java.io.Serializable {
     private static final long serialVersionUID = -6903933977591709194L;
@@ -56,7 +57,7 @@
      * items have been entered since the signal. And symmetrically for
      * takes signalling puts. Operations such as remove(Object) and
      * iterators acquire both locks.
-    */
+     */
 
     /**
      * Linked list node class
@@ -93,7 +94,7 @@
     private final Condition notFull = putLock.newCondition();
 
     /**
-     * Signal a waiting take. Called only from put/offer (which do not
+     * Signals a waiting take. Called only from put/offer (which do not
      * otherwise ordinarily lock takeLock.)
      */
     private void signalNotEmpty() {
@@ -107,7 +108,7 @@
     }
 
     /**
-     * Signal a waiting put. Called only from take/poll.
+     * Signals a waiting put. Called only from take/poll.
      */
     private void signalNotFull() {
         final ReentrantLock putLock = this.putLock;
@@ -120,7 +121,7 @@
     }
 
     /**
-     * Create a node and link it at end of queue
+     * Creates a node and links it at end of queue.
      * @param x the item
      */
     private void insert(E x) {
@@ -128,11 +129,13 @@
     }
 
     /**
-     * Remove a node from head of queue,
+     * Removes a node from head of queue,
      * @return the node
      */
     private E extract() {
-        Node<E> first = head.next;
+        Node<E> h = head;
+        Node<E> first = h.next;
+        h.next = null; // help GC
         head = first;
         E x = first.item;
         first.item = null;
@@ -167,9 +170,9 @@
     /**
      * Creates a <tt>LinkedBlockingQueue</tt> with the given (fixed) capacity.
      *
-     * @param capacity the capacity of this queue.
+     * @param capacity the capacity of this queue
      * @throws IllegalArgumentException if <tt>capacity</tt> is not greater
-     *         than zero.
+     *         than zero
      */
     public LinkedBlockingQueue(int capacity) {
         if (capacity <= 0) throw new IllegalArgumentException();
@@ -182,14 +185,15 @@
      * {@link Integer#MAX_VALUE}, initially containing the elements of the
      * given collection,
      * added in traversal order of the collection's iterator.
+     *
      * @param c the collection of elements to initially contain
-     * @throws NullPointerException if <tt>c</tt> or any element within it
-     * is <tt>null</tt>
+     * @throws NullPointerException if the specified collection or any
+     *         of its elements are null
      */
     public LinkedBlockingQueue(Collection<? extends E> c) {
         this(Integer.MAX_VALUE);
-        for (Iterator<? extends E> it = c.iterator(); it.hasNext();)
-            add(it.next());
+        for (E e : c)
+            add(e);
     }
 
 
@@ -198,7 +202,7 @@
     /**
      * Returns the number of elements in this queue.
      *
-     * @return  the number of elements in this queue.
+     * @return the number of elements in this queue
      */
     public int size() {
         return count.get();
@@ -207,31 +211,29 @@
     // this doc comment is a modified copy of the inherited doc comment,
     // without the reference to unlimited queues.
     /**
-     * Returns the number of elements that this queue can ideally (in
-     * the absence of memory or resource constraints) accept without
+     * Returns the number of additional elements that this queue can ideally
+     * (in the absence of memory or resource constraints) accept without
      * blocking. This is always equal to the initial capacity of this queue
      * less the current <tt>size</tt> of this queue.
-     * <p>Note that you <em>cannot</em> always tell if
-     * an attempt to <tt>add</tt> an element will succeed by
-     * inspecting <tt>remainingCapacity</tt> because it may be the
-     * case that a waiting consumer is ready to <tt>take</tt> an
-     * element out of an otherwise full queue.
-     * 
-     * @return the remaining capacity
+     *
+     * <p>Note that you <em>cannot</em> always tell if an attempt to insert
+     * an element will succeed by inspecting <tt>remainingCapacity</tt>
+     * because it may be the case that another thread is about to
+     * insert or remove an element.
      */
     public int remainingCapacity() {
         return capacity - count.get();
     }
 
     /**
-     * Adds the specified element to the tail of this queue, waiting if
+     * Inserts the specified element at the tail of this queue, waiting if
      * necessary for space to become available.
-     * @param o the element to add
-     * @throws InterruptedException if interrupted while waiting.
-     * @throws NullPointerException if the specified element is <tt>null</tt>.
+     *
+     * @throws InterruptedException {@inheritDoc}
+     * @throws NullPointerException {@inheritDoc}
      */
-    public void put(E o) throws InterruptedException {
-        if (o == null) throw new NullPointerException();
+    public void put(E e) throws InterruptedException {
+        if (e == null) throw new NullPointerException();
         // Note: convention in all put/take/etc is to preset
         // local var holding count  negative to indicate failure unless set.
         int c = -1;
@@ -255,7 +257,7 @@
                 notFull.signal(); // propagate to a non-interrupted thread
                 throw ie;
             }
-            insert(o);
+            insert(e);
             c = count.getAndIncrement();
             if (c + 1 < capacity)
                 notFull.signal();
@@ -269,20 +271,16 @@
     /**
      * Inserts the specified element at the tail of this queue, waiting if
      * necessary up to the specified wait time for space to become available.
-     * @param o the element to add
-     * @param timeout how long to wait before giving up, in units of
-     * <tt>unit</tt>
-     * @param unit a <tt>TimeUnit</tt> determining how to interpret the
-     * <tt>timeout</tt> parameter
+     *
      * @return <tt>true</tt> if successful, or <tt>false</tt> if
-     * the specified waiting time elapses before space is available.
-     * @throws InterruptedException if interrupted while waiting.
-     * @throws NullPointerException if the specified element is <tt>null</tt>.
+     *         the specified waiting time elapses before space is available.
+     * @throws InterruptedException {@inheritDoc}
+     * @throws NullPointerException {@inheritDoc}
      */
-    public boolean offer(E o, long timeout, TimeUnit unit)
+    public boolean offer(E e, long timeout, TimeUnit unit)
         throws InterruptedException {
 
-        if (o == null) throw new NullPointerException();
+        if (e == null) throw new NullPointerException();
         long nanos = unit.toNanos(timeout);
         int c = -1;
         final ReentrantLock putLock = this.putLock;
@@ -291,7 +289,7 @@
         try {
             for (;;) {
                 if (count.get() < capacity) {
-                    insert(o);
+                    insert(e);
                     c = count.getAndIncrement();
                     if (c + 1 < capacity)
                         notFull.signal();
@@ -315,16 +313,18 @@
     }
 
     /**
-     * Inserts the specified element at the tail of this queue if possible,
-     * returning immediately if this queue is full.
+     * Inserts the specified element at the tail of this queue if it is
+     * possible to do so immediately without exceeding the queue's capacity,
+     * returning <tt>true</tt> upon success and <tt>false</tt> if this queue
+     * is full.
+     * When using a capacity-restricted queue, this method is generally
+     * preferable to method {@link BlockingQueue#add add}, which can fail to
+     * insert an element only by throwing an exception.
      *
-     * @param o the element to add.
-     * @return <tt>true</tt> if it was possible to add the element to
-     *         this queue, else <tt>false</tt>
-     * @throws NullPointerException if the specified element is <tt>null</tt>
+     * @throws NullPointerException if the specified element is null
      */
-    public boolean offer(E o) {
-        if (o == null) throw new NullPointerException();
+    public boolean offer(E e) {
+        if (e == null) throw new NullPointerException();
         final AtomicInteger count = this.count;
         if (count.get() == capacity)
             return false;
@@ -333,7 +333,7 @@
         putLock.lock();
         try {
             if (count.get() < capacity) {
-                insert(o);
+                insert(e);
                 c = count.getAndIncrement();
                 if (c + 1 < capacity)
                     notFull.signal();
@@ -447,6 +447,17 @@
         }
     }
 
+    /**
+     * Removes a single instance of the specified element from this queue,
+     * if it is present.  More formally, removes an element <tt>e</tt> such
+     * that <tt>o.equals(e)</tt>, if this queue contains one or more such
+     * elements.
+     * Returns <tt>true</tt> if this queue contained the specified element
+     * (or equivalently, if this queue changed as a result of the call).
+     *
+     * @param o element to be removed from this queue, if present
+     * @return <tt>true</tt> if this queue changed as a result of the call
+     */
     public boolean remove(Object o) {
         if (o == null) return false;
         boolean removed = false;
@@ -465,6 +476,8 @@
             if (removed) {
                 p.item = null;
                 trail.next = p.next;
+                if (last == p)
+                    last = trail;
                 if (count.getAndDecrement() == capacity)
                     notFull.signalAll();
             }
@@ -474,6 +487,19 @@
         return removed;
     }
 
+    /**
+     * Returns an array containing all of the elements in this queue, in
+     * proper sequence.
+     *
+     * <p>The returned array will be "safe" in that no references to it are
+     * maintained by this queue.  (In other words, this method must allocate
+     * a new array).  The caller is thus free to modify the returned array.
+     *
+     * <p>This method acts as bridge between array-based and collection-based
+     * APIs.
+     *
+     * @return an array containing all of the elements in this queue
+     */
     public Object[] toArray() {
         fullyLock();
         try {
@@ -488,6 +514,42 @@
         }
     }
 
+    /**
+     * Returns an array containing all of the elements in this queue, in
+     * proper sequence; the runtime type of the returned array is that of
+     * the specified array.  If the queue fits in the specified array, it
+     * is returned therein.  Otherwise, a new array is allocated with the
+     * runtime type of the specified array and the size of this queue.
+     *
+     * <p>If this queue fits in the specified array with room to spare
+     * (i.e., the array has more elements than this queue), the element in
+     * the array immediately following the end of the queue is set to
+     * <tt>null</tt>.
+     *
+     * <p>Like the {@link #toArray()} method, this method acts as bridge between
+     * array-based and collection-based APIs.  Further, this method allows
+     * precise control over the runtime type of the output array, and may,
+     * under certain circumstances, be used to save allocation costs.
+     *
+     * <p>Suppose <tt>x</tt> is a queue known to contain only strings.
+     * The following code can be used to dump the queue into a newly
+     * allocated array of <tt>String</tt>:
+     *
+     * <pre>
+     *     String[] y = x.toArray(new String[0]);</pre>
+     *
+     * Note that <tt>toArray(new Object[0])</tt> is identical in function to
+     * <tt>toArray()</tt>.
+     *
+     * @param a the array into which the elements of the queue are to
+     *          be stored, if it is big enough; otherwise, a new array of the
+     *          same runtime type is allocated for this purpose
+     * @return an array containing all of the elements in this queue
+     * @throws ArrayStoreException if the runtime type of the specified array
+     *         is not a supertype of the runtime type of every element in
+     *         this queue
+     * @throws NullPointerException if the specified array is null
+     */
     public <T> T[] toArray(T[] a) {
         fullyLock();
         try {
@@ -499,6 +561,8 @@
             int k = 0;
             for (Node p = head.next; p != null; p = p.next)
                 a[k++] = (T)p.item;
+            if (a.length > k)
+                a[k] = null;
             return a;
         } finally {
             fullyUnlock();
@@ -514,10 +578,16 @@
         }
     }
 
+    /**
+     * Atomically removes all of the elements from this queue.
+     * The queue will be empty after this call returns.
+     */
     public void clear() {
         fullyLock();
         try {
             head.next = null;
+            assert head.item == null;
+            last = head;
             if (count.getAndSet(0) == capacity)
                 notFull.signalAll();
         } finally {
@@ -525,16 +595,24 @@
         }
     }
 
+    /**
+     * @throws UnsupportedOperationException {@inheritDoc}
+     * @throws ClassCastException            {@inheritDoc}
+     * @throws NullPointerException          {@inheritDoc}
+     * @throws IllegalArgumentException      {@inheritDoc}
+     */
     public int drainTo(Collection<? super E> c) {
         if (c == null)
             throw new NullPointerException();
         if (c == this)
             throw new IllegalArgumentException();
-        Node first;
+        Node<E> first;
         fullyLock();
         try {
             first = head.next;
             head.next = null;
+            assert head.item == null;
+            last = head;
             if (count.getAndSet(0) == capacity)
                 notFull.signalAll();
         } finally {
@@ -549,14 +627,18 @@
         }
         return n;
     }
-        
+
+    /**
+     * @throws UnsupportedOperationException {@inheritDoc}
+     * @throws ClassCastException            {@inheritDoc}
+     * @throws NullPointerException          {@inheritDoc}
+     * @throws IllegalArgumentException      {@inheritDoc}
+     */
     public int drainTo(Collection<? super E> c, int maxElements) {
         if (c == null)
             throw new NullPointerException();
         if (c == this)
             throw new IllegalArgumentException();
-        if (maxElements <= 0)
-            return 0;
         fullyLock();
         try {
             int n = 0;
@@ -569,6 +651,9 @@
             }
             if (n != 0) {
                 head.next = p;
+                assert head.item == null;
+                if (p == null)
+                    last = head;
                 if (count.getAndAdd(-n) == capacity)
                     notFull.signalAll();
             }
@@ -581,12 +666,12 @@
     /**
      * Returns an iterator over the elements in this queue in proper sequence.
      * The returned <tt>Iterator</tt> is a "weakly consistent" iterator that
-     * will never throw {@link java.util.ConcurrentModificationException},
+     * will never throw {@link ConcurrentModificationException},
      * and guarantees to traverse elements as they existed upon
      * construction of the iterator, and may (but is not guaranteed to)
      * reflect any modifications subsequent to construction.
      *
-     * @return an iterator over the elements in this queue in proper sequence.
+     * @return an iterator over the elements in this queue in proper sequence
      */
     public Iterator<E> iterator() {
       return new Itr();
@@ -660,6 +745,8 @@
                 if (p == node) {
                     p.item = null;
                     trail.next = p.next;
+                    if (last == p)
+                        last = trail;
                     int c = count.getAndDecrement();
                     if (c == capacity)
                         notFull.signalAll();
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/PriorityBlockingQueue.java b/libcore/concurrent/src/main/java/java/util/concurrent/PriorityBlockingQueue.java
index 83f1040..7a33dc7 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/PriorityBlockingQueue.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/PriorityBlockingQueue.java
@@ -19,16 +19,47 @@
  * blocking retrieval operations.  While this queue is logically
  * unbounded, attempted additions may fail due to resource exhaustion
  * (causing <tt>OutOfMemoryError</tt>). This class does not permit
- * <tt>null</tt> elements.  A priority queue relying on natural
- * ordering also does not permit insertion of non-comparable objects
- * (doing so results in <tt>ClassCastException</tt>).
+ * <tt>null</tt> elements.  A priority queue relying on {@linkplain
+ * Comparable natural ordering} also does not permit insertion of
+ * non-comparable objects (doing so results in
+ * <tt>ClassCastException</tt>).
  *
- * <p>This class implements all of the <em>optional</em> methods
- * of the {@link Collection} and {@link Iterator} interfaces.
- * <p>The Iterator provided in method {@link #iterator()} is
- * <em>not</em> guaranteed to traverse the elements of the
- * PriorityBlockingQueue in any particular order. If you need ordered
- * traversal, consider using <tt>Arrays.sort(pq.toArray())</tt>.
+ * <p>This class and its iterator implement all of the
+ * <em>optional</em> methods of the {@link Collection} and {@link
+ * Iterator} interfaces.  The Iterator provided in method {@link
+ * #iterator()} is <em>not</em> guaranteed to traverse the elements of
+ * the PriorityBlockingQueue in any particular order. If you need
+ * ordered traversal, consider using
+ * <tt>Arrays.sort(pq.toArray())</tt>.  Also, method <tt>drainTo</tt>
+ * can be used to <em>remove</em> some or all elements in priority
+ * order and place them in another collection.
+ *
+ * <p>Operations on this class make no guarantees about the ordering
+ * of elements with equal priority. If you need to enforce an
+ * ordering, you can define custom classes or comparators that use a
+ * secondary key to break ties in primary priority values.  For
+ * example, here is a class that applies first-in-first-out
+ * tie-breaking to comparable elements. To use it, you would insert a
+ * <tt>new FIFOEntry(anEntry)</tt> instead of a plain entry object.
+ *
+ * <pre>
+ * class FIFOEntry&lt;E extends Comparable&lt;? super E&gt;&gt;
+ *     implements Comparable&lt;FIFOEntry&lt;E&gt;&gt; {
+ *   final static AtomicLong seq = new AtomicLong();
+ *   final long seqNum;
+ *   final E entry;
+ *   public FIFOEntry(E entry) {
+ *     seqNum = seq.getAndIncrement();
+ *     this.entry = entry;
+ *   }
+ *   public E getEntry() { return entry; }
+ *   public int compareTo(FIFOEntry&lt;E&gt; other) {
+ *     int res = entry.compareTo(other.entry);
+ *     if (res == 0 &amp;&amp; other.entry != this.entry)
+ *       res = (seqNum &lt; other.seqNum ? -1 : 1);
+ *     return res;
+ *   }
+ * }</pre>
  *
  * @since 1.5
  * @author Doug Lea
@@ -43,24 +74,22 @@
     private final Condition notEmpty = lock.newCondition();
 
     /**
-     * Creates a <tt>PriorityBlockingQueue</tt> with the default initial 
-     * capacity
-     * (11) that orders its elements according to their natural
-     * ordering (using <tt>Comparable</tt>).
+     * Creates a <tt>PriorityBlockingQueue</tt> with the default
+     * initial capacity (11) that orders its elements according to
+     * their {@linkplain Comparable natural ordering}.
      */
     public PriorityBlockingQueue() {
         q = new PriorityQueue<E>();
     }
 
     /**
-     * Creates a <tt>PriorityBlockingQueue</tt> with the specified initial
-     * capacity
-     * that orders its elements according to their natural ordering
-     * (using <tt>Comparable</tt>).
+     * Creates a <tt>PriorityBlockingQueue</tt> with the specified
+     * initial capacity that orders its elements according to their
+     * {@linkplain Comparable natural ordering}.
      *
-     * @param initialCapacity the initial capacity for this priority queue.
+     * @param initialCapacity the initial capacity for this priority queue
      * @throws IllegalArgumentException if <tt>initialCapacity</tt> is less
-     * than 1
+     *         than 1
      */
     public PriorityBlockingQueue(int initialCapacity) {
         q = new PriorityQueue<E>(initialCapacity, null);
@@ -68,15 +97,15 @@
 
     /**
      * Creates a <tt>PriorityBlockingQueue</tt> with the specified initial
-     * capacity
-     * that orders its elements according to the specified comparator.
+     * capacity that orders its elements according to the specified
+     * comparator.
      *
-     * @param initialCapacity the initial capacity for this priority queue.
-     * @param comparator the comparator used to order this priority queue.
-     * If <tt>null</tt> then the order depends on the elements' natural
-     * ordering.
+     * @param initialCapacity the initial capacity for this priority queue
+     * @param  comparator the comparator that will be used to order this
+     *         priority queue.  If {@code null}, the {@linkplain Comparable
+     *         natural ordering} of the elements will be used.
      * @throws IllegalArgumentException if <tt>initialCapacity</tt> is less
-     * than 1
+     *         than 1
      */
     public PriorityBlockingQueue(int initialCapacity,
                                  Comparator<? super E> comparator) {
@@ -85,75 +114,54 @@
 
     /**
      * Creates a <tt>PriorityBlockingQueue</tt> containing the elements
-     * in the specified collection.  The priority queue has an initial
-     * capacity of 110% of the size of the specified collection. If
-     * the specified collection is a {@link SortedSet} or a {@link
-     * PriorityQueue}, this priority queue will be sorted according to
-     * the same comparator, or according to its elements' natural
-     * order if the collection is sorted according to its elements'
-     * natural order.  Otherwise, this priority queue is ordered
-     * according to its elements' natural order.
+     * in the specified collection.  If the specified collection is a
+     * {@link SortedSet} or a {@link PriorityQueue},  this
+     * priority queue will be ordered according to the same ordering.
+     * Otherwise, this priority queue will be ordered according to the
+     * {@linkplain Comparable natural ordering} of its elements.
      *
-     * @param c the collection whose elements are to be placed
-     *        into this priority queue.
+     * @param  c the collection whose elements are to be placed
+     *         into this priority queue
      * @throws ClassCastException if elements of the specified collection
      *         cannot be compared to one another according to the priority
-     *         queue's ordering.
-     * @throws NullPointerException if <tt>c</tt> or any element within it
-     * is <tt>null</tt>
+     *         queue's ordering
+     * @throws NullPointerException if the specified collection or any
+     *         of its elements are null
      */
     public PriorityBlockingQueue(Collection<? extends E> c) {
         q = new PriorityQueue<E>(c);
     }
 
-
-    // these first few override just to update doc comments
-
     /**
-     * Adds the specified element to this queue.
-     * @param o the element to add
-     * @return <tt>true</tt> (as per the general contract of
-     * <tt>Collection.add</tt>).
+     * Inserts the specified element into this priority queue.
      *
-     * @throws NullPointerException if the specified element is <tt>null</tt>.
+     * @param e the element to add
+     * @return <tt>true</tt> (as specified by {@link Collection#add})
      * @throws ClassCastException if the specified element cannot be compared
-     * with elements currently in the priority queue according
-     * to the priority queue's ordering.
+     *         with elements currently in the priority queue according to the
+     *         priority queue's ordering
+     * @throws NullPointerException if the specified element is null
      */
-    public boolean add(E o) {
-        return super.add(o);
+    public boolean add(E e) {
+        return offer(e);
     }
 
     // BEGIN android-changed
     /**
-     * Returns the comparator used to order this collection, or <tt>null</tt>
-     * if this collection is sorted according to its elements natural ordering
-     * (using <tt>Comparable</tt>).
-     *
-     * @return the comparator used to order this collection, or <tt>null</tt>
-     * if this collection is sorted according to its elements natural ordering.
-     */
-    public Comparator<? super E> comparator() {
-        return q.comparator();
-    }
-    // END android-changed
-
-    /**
      * Inserts the specified element into this priority queue.
      *
-     * @param o the element to add
-     * @return <tt>true</tt>
+     * @param e the element to add
+     * @return <tt>true</tt> (as specified by {@link Queue#offer})
      * @throws ClassCastException if the specified element cannot be compared
-     * with elements currently in the priority queue according
-     * to the priority queue's ordering.
-     * @throws NullPointerException if the specified element is <tt>null</tt>.
+     *         with elements currently in the priority queue according to the
+     *         priority queue's ordering
+     * @throws NullPointerException if the specified element is null
      */
-    public boolean offer(E o) {
-        if (o == null) throw new NullPointerException();
+    public boolean offer(E e) {
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            boolean ok = q.offer(o);
+            boolean ok = q.offer(e);
             assert ok;
             notEmpty.signal();
             return true;
@@ -163,32 +171,44 @@
     }
 
     /**
-     * Adds the specified element to this priority queue. As the queue is
+     * Inserts the specified element into this priority queue. As the queue is
      * unbounded this method will never block.
-     * @param o the element to add
-     * @throws ClassCastException if the element cannot be compared
-     * with elements currently in the priority queue according
-     * to the priority queue's ordering.
-     * @throws NullPointerException if the specified element is <tt>null</tt>.
+     *
+     * @param e the element to add
+     * @throws ClassCastException if the specified element cannot be compared
+     *         with elements currently in the priority queue according to the
+     *         priority queue's ordering
+     * @throws NullPointerException if the specified element is null
      */
-    public void put(E o) {
-        offer(o); // never need to block
+    public void put(E e) {
+        offer(e); // never need to block
     }
 
     /**
      * Inserts the specified element into this priority queue. As the queue is
      * unbounded this method will never block.
-     * @param o the element to add
+     *
+     * @param e the element to add
      * @param timeout This parameter is ignored as the method never blocks
      * @param unit This parameter is ignored as the method never blocks
      * @return <tt>true</tt>
-     * @throws ClassCastException if the element cannot be compared
-     * with elements currently in the priority queue according
-     * to the priority queue's ordering.
-     * @throws NullPointerException if the specified element is <tt>null</tt>.
+     * @throws ClassCastException if the specified element cannot be compared
+     *         with elements currently in the priority queue according to the
+     *         priority queue's ordering
+     * @throws NullPointerException if the specified element is null
      */
-    public boolean offer(E o, long timeout, TimeUnit unit) {
-        return offer(o); // never need to block
+    public boolean offer(E e, long timeout, TimeUnit unit) {
+        return offer(e); // never need to block
+    }
+
+    public E poll() {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            return q.poll();
+        } finally {
+            lock.unlock();
+        }
     }
 
     public E take() throws InterruptedException {
@@ -210,17 +230,6 @@
         }
     }
 
-
-    public E poll() {
-        final ReentrantLock lock = this.lock;
-        lock.lock();
-        try {
-            return q.poll();
-        } finally {
-            lock.unlock();
-        }
-    }
-
     public E poll(long timeout, TimeUnit unit) throws InterruptedException {
         long nanos = unit.toNanos(timeout);
         final ReentrantLock lock = this.lock;
@@ -254,6 +263,19 @@
         }
     }
 
+    /**
+     * Returns the comparator used to order the elements in this queue,
+     * or <tt>null</tt> if this queue uses the {@linkplain Comparable
+     * natural ordering} of its elements.
+     *
+     * @return the comparator used to order the elements in this queue,
+     *         or <tt>null</tt> if this queue uses the natural
+     *         ordering of its elements
+     */
+    public Comparator<? super E> comparator() {
+        return q.comparator();
+    }
+
     public int size() {
         final ReentrantLock lock = this.lock;
         lock.lock();
@@ -273,6 +295,17 @@
         return Integer.MAX_VALUE;
     }
 
+    /**
+     * Removes a single instance of the specified element from this queue,
+     * if it is present.  More formally, removes an element {@code e} such
+     * that {@code o.equals(e)}, if this queue contains one or more such
+     * elements.  Returns {@code true} if and only if this queue contained
+     * the specified element (or equivalently, if this queue changed as a
+     * result of the call).
+     *
+     * @param o element to be removed from this queue, if present
+     * @return <tt>true</tt> if this queue changed as a result of the call
+     */
     public boolean remove(Object o) {
         final ReentrantLock lock = this.lock;
         lock.lock();
@@ -283,6 +316,14 @@
         }
     }
 
+    /**
+     * Returns {@code true} if this queue contains the specified element.
+     * More formally, returns {@code true} if and only if this queue contains
+     * at least one element {@code e} such that {@code o.equals(e)}.
+     *
+     * @param o object to be checked for containment in this queue
+     * @return <tt>true</tt> if this queue contains the specified element
+     */
     public boolean contains(Object o) {
         final ReentrantLock lock = this.lock;
         lock.lock();
@@ -293,6 +334,19 @@
         }
     }
 
+    /**
+     * Returns an array containing all of the elements in this queue.
+     * The returned array elements are in no particular order.
+     *
+     * <p>The returned array will be "safe" in that no references to it are
+     * maintained by this queue.  (In other words, this method must allocate
+     * a new array).  The caller is thus free to modify the returned array.
+     *
+     * <p>This method acts as bridge between array-based and collection-based
+     * APIs.
+     *
+     * @return an array containing all of the elements in this queue
+     */
     public Object[] toArray() {
         final ReentrantLock lock = this.lock;
         lock.lock();
@@ -314,6 +368,12 @@
         }
     }
 
+    /**
+     * @throws UnsupportedOperationException {@inheritDoc}
+     * @throws ClassCastException            {@inheritDoc}
+     * @throws NullPointerException          {@inheritDoc}
+     * @throws IllegalArgumentException      {@inheritDoc}
+     */
     public int drainTo(Collection<? super E> c) {
         if (c == null)
             throw new NullPointerException();
@@ -334,6 +394,12 @@
         }
     }
 
+    /**
+     * @throws UnsupportedOperationException {@inheritDoc}
+     * @throws ClassCastException            {@inheritDoc}
+     * @throws NullPointerException          {@inheritDoc}
+     * @throws IllegalArgumentException      {@inheritDoc}
+     */
     public int drainTo(Collection<? super E> c, int maxElements) {
         if (c == null)
             throw new NullPointerException();
@@ -357,7 +423,7 @@
     }
 
     /**
-     * Atomically removes all of the elements from this delay queue.
+     * Atomically removes all of the elements from this queue.
      * The queue will be empty after this call returns.
      */
     public void clear() {
@@ -370,6 +436,43 @@
         }
     }
 
+    /**
+     * Returns an array containing all of the elements in this queue; the
+     * runtime type of the returned array is that of the specified array.
+     * The returned array elements are in no particular order.
+     * If the queue fits in the specified array, it is returned therein.
+     * Otherwise, a new array is allocated with the runtime type of the
+     * specified array and the size of this queue.
+     *
+     * <p>If this queue fits in the specified array with room to spare
+     * (i.e., the array has more elements than this queue), the element in
+     * the array immediately following the end of the queue is set to
+     * <tt>null</tt>.
+     *
+     * <p>Like the {@link #toArray()} method, this method acts as bridge between
+     * array-based and collection-based APIs.  Further, this method allows
+     * precise control over the runtime type of the output array, and may,
+     * under certain circumstances, be used to save allocation costs.
+     *
+     * <p>Suppose <tt>x</tt> is a queue known to contain only strings.
+     * The following code can be used to dump the queue into a newly
+     * allocated array of <tt>String</tt>:
+     *
+     * <pre>
+     *     String[] y = x.toArray(new String[0]);</pre>
+     *
+     * Note that <tt>toArray(new Object[0])</tt> is identical in function to
+     * <tt>toArray()</tt>.
+     *
+     * @param a the array into which the elements of the queue are to
+     *          be stored, if it is big enough; otherwise, a new array of the
+     *          same runtime type is allocated for this purpose
+     * @return an array containing all of the elements in this queue
+     * @throws ArrayStoreException if the runtime type of the specified array
+     *         is not a supertype of the runtime type of every element in
+     *         this queue
+     * @throws NullPointerException if the specified array is null
+     */
     public <T> T[] toArray(T[] a) {
         final ReentrantLock lock = this.lock;
         lock.lock();
@@ -383,54 +486,58 @@
     /**
      * Returns an iterator over the elements in this queue. The
      * iterator does not return the elements in any particular order.
-     * The returned iterator is a thread-safe "fast-fail" iterator
-     * that will throw {@link
-     * java.util.ConcurrentModificationException} upon detected
-     * interference.
+     * The returned <tt>Iterator</tt> is a "weakly consistent"
+     * iterator that will never throw {@link
+     * ConcurrentModificationException}, and guarantees to traverse
+     * elements as they existed upon construction of the iterator, and
+     * may (but is not guaranteed to) reflect any modifications
+     * subsequent to construction.
      *
-     * @return an iterator over the elements in this queue.
+     * @return an iterator over the elements in this queue
      */
     public Iterator<E> iterator() {
-        final ReentrantLock lock = this.lock;
-        lock.lock();
-        try {
-            return new Itr(q.iterator());
-        } finally {
-            lock.unlock();
-        }
+        return new Itr(toArray());
     }
 
-    private class Itr<E> implements Iterator<E> {
-        private final Iterator<E> iter;
-        Itr(Iterator<E> i) {
-            iter = i;
+    /**
+     * Snapshot iterator that works off copy of underlying q array.
+     */
+    private class Itr implements Iterator<E> {
+        final Object[] array; // Array of all elements
+        int cursor;           // index of next element to return;
+        int lastRet;          // index of last element, or -1 if no such
+
+        Itr(Object[] array) {
+            lastRet = -1;
+            this.array = array;
         }
 
         public boolean hasNext() {
-            /*
-             * No sync -- we rely on underlying hasNext to be
-             * stateless, in which case we can return true by mistake
-             * only when next() will subsequently throw
-             * ConcurrentModificationException.
-             */
-            return iter.hasNext();
+            return cursor < array.length;
         }
 
         public E next() {
-            ReentrantLock lock = PriorityBlockingQueue.this.lock;
-            lock.lock();
-            try {
-                return iter.next();
-            } finally {
-                lock.unlock();
-            }
+            if (cursor >= array.length)
+                throw new NoSuchElementException();
+            lastRet = cursor;
+            return (E)array[cursor++];
         }
 
         public void remove() {
-            ReentrantLock lock = PriorityBlockingQueue.this.lock;
+            if (lastRet < 0)
+                throw new IllegalStateException();
+            Object x = array[lastRet];
+            lastRet = -1;
+            // Traverse underlying queue to find == element,
+            // not just a .equals element.
             lock.lock();
             try {
-                iter.remove();
+                for (Iterator it = q.iterator(); it.hasNext(); ) {
+                    if (it.next() == x) {
+                        it.remove();
+                        return;
+                    }
+                }
             } finally {
                 lock.unlock();
             }
@@ -438,7 +545,7 @@
     }
 
     /**
-     * Save the state to a stream (that is, serialize it).  This
+     * Saves the state to a stream (that is, serializes it).  This
      * merely wraps default serialization within lock.  The
      * serialization strategy for items is left to underlying
      * Queue. Note that locking is not needed on deserialization, so
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/RejectedExecutionException.java b/libcore/concurrent/src/main/java/java/util/concurrent/RejectedExecutionException.java
index 199b9de..30b043d 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/RejectedExecutionException.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/RejectedExecutionException.java
@@ -9,7 +9,7 @@
 /**
  * Exception thrown by an {@link Executor} when a task cannot be
  * accepted for execution.
- * 
+ *
  * @since 1.5
  * @author Doug Lea
  */
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/RejectedExecutionHandler.java b/libcore/concurrent/src/main/java/java/util/concurrent/RejectedExecutionHandler.java
index 4b4bbea..417a27c 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/RejectedExecutionHandler.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/RejectedExecutionHandler.java
@@ -7,8 +7,7 @@
 package java.util.concurrent;
 
 /**
- * A handler for tasks that cannot be executed by a {@link
- * ThreadPoolExecutor}.
+ * A handler for tasks that cannot be executed by a {@link ThreadPoolExecutor}.
  *
  * @since 1.5
  * @author Doug Lea
@@ -17,13 +16,14 @@
 
     /**
      * Method that may be invoked by a {@link ThreadPoolExecutor} when
-     * <tt>execute</tt> cannot accept a task. This may occur when no
-     * more threads or queue slots are available because their bounds
-     * would be exceeded, or upon shutdown of the Executor.
+     * {@link ThreadPoolExecutor#execute execute} cannot accept a
+     * task.  This may occur when no more threads or queue slots are
+     * available because their bounds would be exceeded, or upon
+     * shutdown of the Executor.
      *
-     * In the absence other alternatives, the method may throw an
-     * unchecked {@link RejectedExecutionException}, which will be
-     * propagated to the caller of <tt>execute</tt>.
+     * <p>In the absence of other alternatives, the method may throw
+     * an unchecked {@link RejectedExecutionException}, which will be
+     * propagated to the caller of {@code execute}.
      *
      * @param r the runnable task requested to be executed
      * @param executor the executor attempting to execute this task
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/ScheduledExecutorService.java b/libcore/concurrent/src/main/java/java/util/concurrent/ScheduledExecutorService.java
index 9579fef..c170c4a 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/ScheduledExecutorService.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/ScheduledExecutorService.java
@@ -10,13 +10,13 @@
 
 /**
  * An {@link ExecutorService} that can schedule commands to run after a given
- * delay, or to execute periodically. 
+ * delay, or to execute periodically.
  *
  * <p> The <tt>schedule</tt> methods create tasks with various delays
  * and return a task object that can be used to cancel or check
  * execution. The <tt>scheduleAtFixedRate</tt> and
  * <tt>scheduleWithFixedDelay</tt> methods create and execute tasks
- * that run periodically until cancelled.  
+ * that run periodically until cancelled.
  *
  * <p> Commands submitted using the {@link Executor#execute} and
  * {@link ExecutorService} <tt>submit</tt> methods are scheduled with
@@ -33,27 +33,27 @@
  * TimeUnit.MILLISECONDS)</tt>. Beware however that expiration of a
  * relative delay need not coincide with the current <tt>Date</tt> at
  * which the task is enabled due to network time synchronization
- * protocols, clock drift, or other factors. 
+ * protocols, clock drift, or other factors.
  *
  * The {@link Executors} class provides convenient factory methods for
  * the ScheduledExecutorService implementations provided in this package.
  *
  * <h3>Usage Example</h3>
- * 
+ *
  * Here is a class with a method that sets up a ScheduledExecutorService
  * to beep every ten seconds for an hour:
  *
  * <pre>
- * import static java.util.concurrent.TimeUnit;
+ * import static java.util.concurrent.TimeUnit.*;
  * class BeeperControl {
- *    private final ScheduledExecutorService scheduler = 
+ *    private final ScheduledExecutorService scheduler =
  *       Executors.newScheduledThreadPool(1);
  *
  *    public void beepForAnHour() {
  *        final Runnable beeper = new Runnable() {
  *                public void run() { System.out.println("beep"); }
  *            };
- *        final ScheduledFuture&lt;?&gt; beeperHandle = 
+ *        final ScheduledFuture&lt;?&gt; beeperHandle =
  *            scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
  *        scheduler.schedule(new Runnable() {
  *                public void run() { beeperHandle.cancel(true); }
@@ -70,76 +70,90 @@
     /**
      * Creates and executes a one-shot action that becomes enabled
      * after the given delay.
-     * @param command the task to execute.
-     * @param delay the time from now to delay execution.
-     * @param unit the time unit of the delay parameter.
-     * @return a Future representing pending completion of the task,
-     * and whose <tt>get()</tt> method will return <tt>null</tt>
-     * upon completion.
-     * @throws RejectedExecutionException if task cannot be scheduled
-     * for execution.
+     *
+     * @param command the task to execute
+     * @param delay the time from now to delay execution
+     * @param unit the time unit of the delay parameter
+     * @return a ScheduledFuture representing pending completion of
+     *         the task and whose <tt>get()</tt> method will return
+     *         <tt>null</tt> upon completion
+     * @throws RejectedExecutionException if the task cannot be
+     *         scheduled for execution
      * @throws NullPointerException if command is null
      */
-    public ScheduledFuture<?> schedule(Runnable command, long delay,  TimeUnit unit);
+    public ScheduledFuture<?> schedule(Runnable command,
+                                       long delay, TimeUnit unit);
 
     /**
      * Creates and executes a ScheduledFuture that becomes enabled after the
      * given delay.
-     * @param callable the function to execute.
-     * @param delay the time from now to delay execution.
-     * @param unit the time unit of the delay parameter.
-     * @return a ScheduledFuture that can be used to extract result or cancel.
-     * @throws RejectedExecutionException if task cannot be scheduled
-     * for execution.
+     *
+     * @param callable the function to execute
+     * @param delay the time from now to delay execution
+     * @param unit the time unit of the delay parameter
+     * @return a ScheduledFuture that can be used to extract result or cancel
+     * @throws RejectedExecutionException if the task cannot be
+     *         scheduled for execution
      * @throws NullPointerException if callable is null
      */
-    public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit);
+    public <V> ScheduledFuture<V> schedule(Callable<V> callable,
+                                           long delay, TimeUnit unit);
 
     /**
      * Creates and executes a periodic action that becomes enabled first
      * after the given initial delay, and subsequently with the given
      * period; that is executions will commence after
      * <tt>initialDelay</tt> then <tt>initialDelay+period</tt>, then
-     * <tt>initialDelay + 2 * period</tt>, and so on.  
+     * <tt>initialDelay + 2 * period</tt>, and so on.
      * If any execution of the task
      * encounters an exception, subsequent executions are suppressed.
      * Otherwise, the task will only terminate via cancellation or
-     * termination of the executor.
-     * @param command the task to execute.
-     * @param initialDelay the time to delay first execution.
-     * @param period the period between successive executions.
+     * termination of the executor.  If any execution of this task
+     * takes longer than its period, then subsequent executions
+     * may start late, but will not concurrently execute.
+     *
+     * @param command the task to execute
+     * @param initialDelay the time to delay first execution
+     * @param period the period between successive executions
      * @param unit the time unit of the initialDelay and period parameters
-     * @return a Future representing pending completion of the task,
-     * and whose <tt>get()</tt> method will throw an exception upon
-     * cancellation.
-     * @throws RejectedExecutionException if task cannot be scheduled
-     * for execution.
+     * @return a ScheduledFuture representing pending completion of
+     *         the task, and whose <tt>get()</tt> method will throw an
+     *         exception upon cancellation
+     * @throws RejectedExecutionException if the task cannot be
+     *         scheduled for execution
      * @throws NullPointerException if command is null
-     * @throws IllegalArgumentException if period less than or equal to zero.
+     * @throws IllegalArgumentException if period less than or equal to zero
      */
-    public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay,  long period, TimeUnit unit);
-    
+    public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
+                                                  long initialDelay,
+                                                  long period,
+                                                  TimeUnit unit);
+
     /**
      * Creates and executes a periodic action that becomes enabled first
      * after the given initial delay, and subsequently with the
      * given delay between the termination of one execution and the
-     * commencement of the next. If any execution of the task
+     * commencement of the next.  If any execution of the task
      * encounters an exception, subsequent executions are suppressed.
      * Otherwise, the task will only terminate via cancellation or
      * termination of the executor.
-     * @param command the task to execute.
-     * @param initialDelay the time to delay first execution.
+     *
+     * @param command the task to execute
+     * @param initialDelay the time to delay first execution
      * @param delay the delay between the termination of one
-     * execution and the commencement of the next.
+     * execution and the commencement of the next
      * @param unit the time unit of the initialDelay and delay parameters
-     * @return a Future representing pending completion of the task,
-     * and whose <tt>get()</tt> method will throw an exception upon
-     * cancellation.
-     * @throws RejectedExecutionException if task cannot be scheduled
-     * for execution.
+     * @return a ScheduledFuture representing pending completion of
+     *         the task, and whose <tt>get()</tt> method will throw an
+     *         exception upon cancellation
+     * @throws RejectedExecutionException if the task cannot be
+     *         scheduled for execution
      * @throws NullPointerException if command is null
-     * @throws IllegalArgumentException if delay less than or equal to zero.
+     * @throws IllegalArgumentException if delay less than or equal to zero
      */
-    public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay,  long delay, TimeUnit unit);
+    public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
+                                                     long initialDelay,
+                                                     long delay,
+                                                     TimeUnit unit);
 
 }
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/ScheduledThreadPoolExecutor.java b/libcore/concurrent/src/main/java/java/util/concurrent/ScheduledThreadPoolExecutor.java
index 09ec681..83ffb99 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/ScheduledThreadPoolExecutor.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/ScheduledThreadPoolExecutor.java
@@ -4,8 +4,13 @@
  * http://creativecommons.org/licenses/publicdomain
  */
 
+/*
+ * Modified in Apache Harmony.
+ */
+
 package java.util.concurrent;
 import java.util.concurrent.atomic.*;
+import java.util.concurrent.locks.*;
 import java.util.*;
 
 /**
@@ -16,25 +21,60 @@
  * flexibility or capabilities of {@link ThreadPoolExecutor} (which
  * this class extends) are required.
  *
- * <p> Delayed tasks execute no sooner than they are enabled, but
+ * <p>Delayed tasks execute no sooner than they are enabled, but
  * without any real-time guarantees about when, after they are
  * enabled, they will commence. Tasks scheduled for exactly the same
  * execution time are enabled in first-in-first-out (FIFO) order of
  * submission.
  *
+ * <p>Successive executions of a task scheduled via
+ * <code>scheduleAtFixedRate</code> or
+ * <code>scheduleWithFixedDelay</code> do not overlap. While different
+ * executions may be performed by different threads, the effects of
+ * prior executions <a
+ * href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
+ * those of subsequent ones.
+ *
  * <p>While this class inherits from {@link ThreadPoolExecutor}, a few
  * of the inherited tuning methods are not useful for it. In
- * particular, because it acts as a fixed-sized pool using
- * <tt>corePoolSize</tt> threads and an unbounded queue, adjustments
- * to <tt>maximumPoolSize</tt> have no useful effect.
+ * particular, because it acts as a fixed-sized pool using {@code
+ * corePoolSize} threads and an unbounded queue, adjustments to {@code
+ * maximumPoolSize} have no useful effect.
  *
  * @since 1.5
  * @author Doug Lea
  */
-public class ScheduledThreadPoolExecutor 
-        extends ThreadPoolExecutor 
+public class ScheduledThreadPoolExecutor
+        extends ThreadPoolExecutor
         implements ScheduledExecutorService {
 
+    /*
+     * This class specializes ThreadPoolExecutor implementation by
+     *
+     * 1. Using a custom task type, ScheduledFutureTask for
+     *    tasks, even those that don't require scheduling (i.e.,
+     *    those submitted using ExecutorService execute, not
+     *    ScheduledExecutorService methods) which are treated as
+     *    delayed tasks with a delay of zero.
+     *
+     * 2. Using a custom queue (DelayedWorkQueue), a variant of
+     *    unbounded DelayQueue. The lack of capacity constraint and
+     *    the fact that corePoolSize and maximumPoolSize are
+     *    effectively identical simplifies some execution mechanics
+     *    (see delayedExecute) compared to ThreadPoolExecutor.
+     *
+     * 3. Supporting optional run-after-shutdown parameters, which
+     *    leads to overrides of shutdown methods to remove and cancel
+     *    tasks that should NOT be run after shutdown, as well as
+     *    different recheck logic when task (re)submission overlaps
+     *    with a shutdown.
+     *
+     * 4. Task decoration methods to allow interception and
+     *    instrumentation, which are needed because subclasses cannot
+     *    otherwise override submit methods to get this effect. These
+     *    don't have any impact on pool control logic though.
+     */
+
     /**
      * False if should cancel/suppress periodic tasks on shutdown.
      */
@@ -46,28 +86,40 @@
     private volatile boolean executeExistingDelayedTasksAfterShutdown = true;
 
     /**
+     * True if ScheduledFutureTask.cancel should remove from queue
+     */
+    private volatile boolean removeOnCancel = false;
+
+    /**
      * Sequence number to break scheduling ties, and in turn to
      * guarantee FIFO order among tied entries.
      */
     private static final AtomicLong sequencer = new AtomicLong(0);
 
-    /** Base of nanosecond timings, to avoid wrapping */
-    private static final long NANO_ORIGIN = System.nanoTime();
 
     /**
-     * Returns nanosecond time offset by origin
+     * Value of System.nanoTime upon static initialization.  This is
+     * used as an offset by now() to avoid wraparound of time values
+     * that would make them appear negative.
      */
-    final long now() {
-        return System.nanoTime() - NANO_ORIGIN;
+    static final long initialNanoTime = System.nanoTime();
+
+    /**
+     * Returns current nanosecond time.
+     */
+    static long now() {
+        return System.nanoTime() - initialNanoTime;
     }
 
-    private class ScheduledFutureTask<V> 
+    private class ScheduledFutureTask<V>
             extends FutureTask<V> implements ScheduledFuture<V> {
-        
+
         /** Sequence number to break ties FIFO */
         private final long sequenceNumber;
+
         /** The time the task is enabled to execute in nanoTime units */
         private long time;
+
         /**
          * Period in nanoseconds for repeating tasks.  A positive
          * value indicates fixed-rate execution.  A negative value
@@ -76,8 +128,16 @@
          */
         private final long period;
 
+        /** The actual task to be re-enqueued by reExecutePeriodic */
+        ScheduledFutureTask<V> outerTask = this;
+
         /**
-         * Creates a one-shot action with given nanoTime-based trigger time
+         * Index into delay queue, to support faster cancellation.
+         */
+        int heapIndex;
+
+        /**
+         * Creates a one-shot action with given nanoTime-based trigger time.
          */
         ScheduledFutureTask(Runnable r, V result, long ns) {
             super(r, result);
@@ -87,9 +147,9 @@
         }
 
         /**
-         * Creates a periodic action with given nano time and period
+         * Creates a periodic action with given nano time and period.
          */
-        ScheduledFutureTask(Runnable r, V result, long ns,  long period) {
+        ScheduledFutureTask(Runnable r, V result, long ns, long period) {
             super(r, result);
             this.time = ns;
             this.period = period;
@@ -97,7 +157,7 @@
         }
 
         /**
-         * Creates a one-shot action with given nanoTime-based trigger
+         * Creates a one-shot action with given nanoTime-based trigger.
          */
         ScheduledFutureTask(Callable<V> callable, long ns) {
             super(callable);
@@ -107,122 +167,162 @@
         }
 
         public long getDelay(TimeUnit unit) {
-            long d = unit.convert(time - now(), TimeUnit.NANOSECONDS);
-            return d;
+            long d = time - now();
+            return d<=0? 0 : unit.convert(d, TimeUnit.NANOSECONDS);
         }
 
         public int compareTo(Delayed other) {
             if (other == this) // compare zero ONLY if same object
                 return 0;
-            ScheduledFutureTask<?> x = (ScheduledFutureTask<?>)other;
-            long diff = time - x.time;
-            if (diff < 0)
-                return -1;
-            else if (diff > 0)
-                return 1;
-            else if (sequenceNumber < x.sequenceNumber)
-                return -1;
-            else
-                return 1;
+            if (other instanceof ScheduledFutureTask) {
+                ScheduledFutureTask<?> x = (ScheduledFutureTask<?>)other;
+                long diff = time - x.time;
+                if (diff < 0)
+                    return -1;
+                else if (diff > 0)
+                    return 1;
+                else if (sequenceNumber < x.sequenceNumber)
+                    return -1;
+                else
+                    return 1;
+            }
+            long d = (getDelay(TimeUnit.NANOSECONDS) -
+                      other.getDelay(TimeUnit.NANOSECONDS));
+            return (d == 0) ? 0 : ((d < 0) ? -1 : 1);
         }
 
         /**
          * Returns true if this is a periodic (not a one-shot) action.
+         *
          * @return true if periodic
          */
-        boolean isPeriodic() {
+        public boolean isPeriodic() {
             return period != 0;
         }
 
         /**
-         * Run a periodic task
+         * Sets the next time to run for a periodic task.
          */
-        private void runPeriodic() {
-            boolean ok = ScheduledFutureTask.super.runAndReset();
-            boolean down = isShutdown();
-            // Reschedule if not cancelled and not shutdown or policy allows
-            if (ok && (!down ||
-                       (getContinueExistingPeriodicTasksAfterShutdownPolicy() && 
-                        !isTerminating()))) {
-                long p = period;
-                if (p > 0)
-                    time += p;
-                else
-                    time = now() - p;
-                ScheduledThreadPoolExecutor.super.getQueue().add(this);
-            }
-            // This might have been the final executed delayed
-            // task.  Wake up threads to check.
-            else if (down) 
-                interruptIdleWorkers();
+        private void setNextRunTime() {
+            long p = period;
+            if (p > 0)
+                time += p;
+            else
+                time = now() - p;
+        }
+
+        public boolean cancel(boolean mayInterruptIfRunning) {
+            boolean cancelled = super.cancel(mayInterruptIfRunning);
+            if (cancelled && removeOnCancel && heapIndex >= 0)
+                remove(this);
+            return cancelled;
         }
 
         /**
          * Overrides FutureTask version so as to reset/requeue if periodic.
-         */ 
+         */
         public void run() {
-            if (isPeriodic())
-                runPeriodic();
-            else 
+            boolean periodic = isPeriodic();
+            if (!canRunInCurrentRunState(periodic))
+                cancel(false);
+            else if (!periodic)
                 ScheduledFutureTask.super.run();
+            else if (ScheduledFutureTask.super.runAndReset()) {
+                setNextRunTime();
+                reExecutePeriodic(outerTask);
+            }
         }
     }
 
     /**
-     * Specialized variant of ThreadPoolExecutor.execute for delayed tasks.
+     * Returns true if can run a task given current run state
+     * and run-after-shutdown parameters.
+     *
+     * @param periodic true if this task periodic, false if delayed
      */
-    private void delayedExecute(Runnable command) {
-        if (isShutdown()) {
-            reject(command);
-            return;
-        }
-        // Prestart a thread if necessary. We cannot prestart it
-        // running the task because the task (probably) shouldn't be
-        // run yet, so thread will just idle until delay elapses.
-        if (getPoolSize() < getCorePoolSize())
-            prestartCoreThread();
-            
-        super.getQueue().add(command);
+    boolean canRunInCurrentRunState(boolean periodic) {
+        return isRunningOrShutdown(periodic ?
+                                   continueExistingPeriodicTasksAfterShutdown :
+                                   executeExistingDelayedTasksAfterShutdown);
     }
 
     /**
-     * Cancel and clear the queue of all tasks that should not be run
-     * due to shutdown policy.
+     * Main execution method for delayed or periodic tasks.  If pool
+     * is shut down, rejects the task. Otherwise adds task to queue
+     * and starts a thread, if necessary, to run it.  (We cannot
+     * prestart the thread to run the task because the task (probably)
+     * shouldn't be run yet,) If the pool is shut down while the task
+     * is being added, cancel and remove it if required by state and
+     * run-after-shutdown parameters.
+     *
+     * @param task the task
      */
-    private void cancelUnwantedTasks() {
-        boolean keepDelayed = getExecuteExistingDelayedTasksAfterShutdownPolicy();
-        boolean keepPeriodic = getContinueExistingPeriodicTasksAfterShutdownPolicy();
-        if (!keepDelayed && !keepPeriodic) 
-            super.getQueue().clear();
-        else if (keepDelayed || keepPeriodic) {
-            Object[] entries = super.getQueue().toArray();
-            for (int i = 0; i < entries.length; ++i) {
-                Object e = entries[i];
+    private void delayedExecute(ScheduledFutureTask<?> task) {
+        if (isShutdown())
+            reject(task);
+        else {
+            super.getQueue().add(task);
+            if (isShutdown() &&
+                !canRunInCurrentRunState(task.isPeriodic()) &&
+                remove(task))
+                task.cancel(false);
+            else
+                prestartCoreThread();
+        }
+    }
+
+    /**
+     * Requeues a periodic task unless current run state precludes it.
+     * Same idea as delayedExecute except drops task rather than rejecting.
+     *
+     * @param task the task
+     */
+    void reExecutePeriodic(ScheduledFutureTask<?> task) {
+        if (canRunInCurrentRunState(true)) {
+            super.getQueue().add(task);
+            if (!canRunInCurrentRunState(true) && remove(task))
+                task.cancel(false);
+            else
+                prestartCoreThread();
+        }
+    }
+
+    /**
+     * Cancels and clears the queue of all tasks that should not be run
+     * due to shutdown policy.  Invoked within super.shutdown.
+     */
+    @Override void onShutdown() {
+        BlockingQueue<Runnable> q = super.getQueue();
+        boolean keepDelayed =
+            getExecuteExistingDelayedTasksAfterShutdownPolicy();
+        boolean keepPeriodic =
+            getContinueExistingPeriodicTasksAfterShutdownPolicy();
+        if (!keepDelayed && !keepPeriodic)
+            q.clear();
+        else {
+            // Traverse snapshot to avoid iterator exceptions
+            for (Object e : q.toArray()) {
                 if (e instanceof ScheduledFutureTask) {
-                    ScheduledFutureTask<?> t = (ScheduledFutureTask<?>)e;
-                    if (t.isPeriodic()? !keepPeriodic : !keepDelayed)
-                        t.cancel(false);
+                    ScheduledFutureTask<?> t =
+                        (ScheduledFutureTask<?>)e;
+                    if ((t.isPeriodic() ? !keepPeriodic : !keepDelayed) ||
+                        t.isCancelled()) { // also remove if already cancelled
+                        if (q.remove(t))
+                            t.cancel(false);
+                    }
                 }
             }
-            entries = null;
-            purge();
         }
-    }
-
-    public boolean remove(Runnable task) {
-        if (!(task instanceof ScheduledFutureTask))
-            return false;
-        return getQueue().remove(task);
+        tryTerminate();
     }
 
     /**
-     * Creates a new ScheduledThreadPoolExecutor with the given core
-     * pool size.
-     * 
-     * @param corePoolSize the number of threads to keep in the pool,
-     * even if they are idle.
-     * @throws IllegalArgumentException if corePoolSize less than or
-     * equal to zero
+     * Creates a new {@code ScheduledThreadPoolExecutor} with the
+     * given core pool size.
+     *
+     * @param corePoolSize the number of threads to keep in the pool, even
+     *        if they are idle
+     * @throws IllegalArgumentException if {@code corePoolSize < 0}
      */
     public ScheduledThreadPoolExecutor(int corePoolSize) {
         super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
@@ -230,14 +330,15 @@
     }
 
     /**
-     * Creates a new ScheduledThreadPoolExecutor with the given
-     * initial parameters.
-     * 
-     * @param corePoolSize the number of threads to keep in the pool,
-     * even if they are idle.
+     * Creates a new {@code ScheduledThreadPoolExecutor} with the
+     * given initial parameters.
+     *
+     * @param corePoolSize the number of threads to keep in the pool, even
+     *        if they are idle
      * @param threadFactory the factory to use when the executor
-     * creates a new thread. 
-     * @throws NullPointerException if threadFactory is null
+     *        creates a new thread
+     * @throws IllegalArgumentException if {@code corePoolSize < 0}
+     * @throws NullPointerException if {@code threadFactory} is null
      */
     public ScheduledThreadPoolExecutor(int corePoolSize,
                              ThreadFactory threadFactory) {
@@ -248,12 +349,13 @@
     /**
      * Creates a new ScheduledThreadPoolExecutor with the given
      * initial parameters.
-     * 
-     * @param corePoolSize the number of threads to keep in the pool,
-     * even if they are idle.
+     *
+     * @param corePoolSize the number of threads to keep in the pool, even
+     *        if they are idle
      * @param handler the handler to use when execution is blocked
-     * because the thread bounds and queue capacities are reached.
-     * @throws NullPointerException if handler is null
+     *        because the thread bounds and queue capacities are reached
+     * @throws IllegalArgumentException if {@code corePoolSize < 0}
+     * @throws NullPointerException if {@code handler} is null
      */
     public ScheduledThreadPoolExecutor(int corePoolSize,
                               RejectedExecutionHandler handler) {
@@ -264,14 +366,16 @@
     /**
      * Creates a new ScheduledThreadPoolExecutor with the given
      * initial parameters.
-     * 
-     * @param corePoolSize the number of threads to keep in the pool,
-     * even if they are idle.
+     *
+     * @param corePoolSize the number of threads to keep in the pool, even
+     *        if they are idle
      * @param threadFactory the factory to use when the executor
-     * creates a new thread. 
+     *        creates a new thread
      * @param handler the handler to use when execution is blocked
-     * because the thread bounds and queue capacities are reached.
-     * @throws NullPointerException if threadFactory or handler is null
+     *        because the thread bounds and queue capacities are reached
+     * @throws IllegalArgumentException if {@code corePoolSize < 0}
+     * @throws NullPointerException if {@code threadFactory} or
+     *         {@code handler} is null
      */
     public ScheduledThreadPoolExecutor(int corePoolSize,
                               ThreadFactory threadFactory,
@@ -280,128 +384,178 @@
               new DelayedWorkQueue(), threadFactory, handler);
     }
 
-    public ScheduledFuture<?> schedule(Runnable command, 
-                                       long delay, 
+    /**
+     * Returns the trigger time of a delayed action
+     */
+    private static long nextTriggerTime(long delay, TimeUnit unit) {
+        long triggerTime;
+        long now = now();
+        if (delay <= 0)
+            return now;            // avoid negative trigger times
+        else if ((triggerTime = now + unit.toNanos(delay)) < 0)
+            return Long.MAX_VALUE; // avoid numerical overflow
+        else
+            return triggerTime;
+    }
+
+    /**
+     * @throws RejectedExecutionException {@inheritDoc}
+     * @throws NullPointerException       {@inheritDoc}
+     */
+    public ScheduledFuture<?> schedule(Runnable command,
+                                       long delay,
                                        TimeUnit unit) {
         if (command == null || unit == null)
             throw new NullPointerException();
-        long triggerTime = now() + unit.toNanos(delay);
-        ScheduledFutureTask<?> t = 
-            new ScheduledFutureTask<Boolean>(command, null, triggerTime);
+        long triggerTime = nextTriggerTime(delay, unit);
+        ScheduledFutureTask<?> t
+                = new ScheduledFutureTask<Void>(command, null, triggerTime);
         delayedExecute(t);
         return t;
     }
 
-    public <V> ScheduledFuture<V> schedule(Callable<V> callable, 
-                                           long delay, 
+    /**
+     * @throws RejectedExecutionException {@inheritDoc}
+     * @throws NullPointerException       {@inheritDoc}
+     */
+    public <V> ScheduledFuture<V> schedule(Callable<V> callable,
+                                           long delay,
                                            TimeUnit unit) {
         if (callable == null || unit == null)
             throw new NullPointerException();
-        if (delay < 0) delay = 0;
-        long triggerTime = now() + unit.toNanos(delay);
-        ScheduledFutureTask<V> t = 
-            new ScheduledFutureTask<V>(callable, triggerTime);
+        long triggerTime = nextTriggerTime(delay, unit);
+        ScheduledFutureTask<V> t
+                = new ScheduledFutureTask<V>(callable, triggerTime);
         delayedExecute(t);
         return t;
     }
 
-    public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, 
-                                                  long initialDelay,  
-                                                  long period, 
+    /**
+     * @throws RejectedExecutionException {@inheritDoc}
+     * @throws NullPointerException       {@inheritDoc}
+     * @throws IllegalArgumentException   {@inheritDoc}
+     */
+    public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
+                                                  long initialDelay,
+                                                  long period,
                                                   TimeUnit unit) {
         if (command == null || unit == null)
             throw new NullPointerException();
         if (period <= 0)
             throw new IllegalArgumentException();
         if (initialDelay < 0) initialDelay = 0;
-        long triggerTime = now() + unit.toNanos(initialDelay);
-        ScheduledFutureTask<?> t = 
-            new ScheduledFutureTask<Object>(command, 
-                                            null,
-                                            triggerTime,
-                                            unit.toNanos(period));
-        delayedExecute(t);
-        return t;
+        long triggerTime = nextTriggerTime(initialDelay, unit);
+        ScheduledFutureTask<Void> sft =
+            new ScheduledFutureTask<Void>(command,
+                                          null,
+                                          triggerTime,
+                                          unit.toNanos(period));
+        sft.outerTask = sft;
+        delayedExecute(sft);
+        return sft;
     }
-    
-    public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, 
-                                                     long initialDelay,  
-                                                     long delay, 
+
+    /**
+     * @throws RejectedExecutionException {@inheritDoc}
+     * @throws NullPointerException       {@inheritDoc}
+     * @throws IllegalArgumentException   {@inheritDoc}
+     */
+    public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
+                                                     long initialDelay,
+                                                     long delay,
                                                      TimeUnit unit) {
         if (command == null || unit == null)
             throw new NullPointerException();
         if (delay <= 0)
             throw new IllegalArgumentException();
-        if (initialDelay < 0) initialDelay = 0;
-        long triggerTime = now() + unit.toNanos(initialDelay);
-        ScheduledFutureTask<?> t = 
-            new ScheduledFutureTask<Boolean>(command, 
-                                             null,
-                                             triggerTime,
-                                             unit.toNanos(-delay));
-        delayedExecute(t);
-        return t;
+        long triggerTime = nextTriggerTime(initialDelay, unit);
+        ScheduledFutureTask<Void> sft =
+            new ScheduledFutureTask<Void>(command,
+                                          null,
+                                          triggerTime,
+                                          unit.toNanos(-delay));
+        sft.outerTask = sft;
+        delayedExecute(sft);
+        return sft;
     }
-    
 
     /**
-     * Execute command with zero required delay. This has effect
-     * equivalent to <tt>schedule(command, 0, anyUnit)</tt>.  Note
-     * that inspections of the queue and of the list returned by
-     * <tt>shutdownNow</tt> will access the zero-delayed
-     * {@link ScheduledFuture}, not the <tt>command</tt> itself.
+     * Executes {@code command} with zero required delay.
+     * This has effect equivalent to
+     * {@link #schedule(Runnable,long,TimeUnit) schedule(command, 0, anyUnit)}.
+     * Note that inspections of the queue and of the list returned by
+     * {@code shutdownNow} will access the zero-delayed
+     * {@link ScheduledFuture}, not the {@code command} itself.
      *
-     * @param command the task to execute
+     * <p>A consequence of the use of {@code ScheduledFuture} objects is
+     * that {@link ThreadPoolExecutor#afterExecute afterExecute} is always
+     * called with a null second {@code Throwable} argument, even if the
+     * {@code command} terminated abruptly.  Instead, the {@code Throwable}
+     * thrown by such a task can be obtained via {@link Future#get}.
+     *
      * @throws RejectedExecutionException at discretion of
-     * <tt>RejectedExecutionHandler</tt>, if task cannot be accepted
-     * for execution because the executor has been shut down.
-     * @throws NullPointerException if command is null
+     *         {@code RejectedExecutionHandler}, if the task
+     *         cannot be accepted for execution because the
+     *         executor has been shut down
+     * @throws NullPointerException {@inheritDoc}
      */
     public void execute(Runnable command) {
-        if (command == null)
-            throw new NullPointerException();
         schedule(command, 0, TimeUnit.NANOSECONDS);
     }
 
     // Override AbstractExecutorService methods
 
+    /**
+     * @throws RejectedExecutionException {@inheritDoc}
+     * @throws NullPointerException       {@inheritDoc}
+     */
     public Future<?> submit(Runnable task) {
         return schedule(task, 0, TimeUnit.NANOSECONDS);
     }
 
+    /**
+     * @throws RejectedExecutionException {@inheritDoc}
+     * @throws NullPointerException       {@inheritDoc}
+     */
     public <T> Future<T> submit(Runnable task, T result) {
-        return schedule(Executors.callable(task, result), 
+        return schedule(Executors.callable(task, result),
                         0, TimeUnit.NANOSECONDS);
     }
 
+    /**
+     * @throws RejectedExecutionException {@inheritDoc}
+     * @throws NullPointerException       {@inheritDoc}
+     */
     public <T> Future<T> submit(Callable<T> task) {
         return schedule(task, 0, TimeUnit.NANOSECONDS);
     }
 
     /**
-     * Set policy on whether to continue executing existing periodic
-     * tasks even when this executor has been <tt>shutdown</tt>. In
-     * this case, these tasks will only terminate upon
-     * <tt>shutdownNow</tt>, or after setting the policy to
-     * <tt>false</tt> when already shutdown. This value is by default
-     * false.
-     * @param value if true, continue after shutdown, else don't.
-     * @see #getExecuteExistingDelayedTasksAfterShutdownPolicy
+     * Sets the policy on whether to continue executing existing
+     * periodic tasks even when this executor has been {@code shutdown}.
+     * In this case, these tasks will only terminate upon
+     * {@code shutdownNow} or after setting the policy to
+     * {@code false} when already shutdown.
+     * This value is by default {@code false}.
+     *
+     * @param value if {@code true}, continue after shutdown, else don't.
+     * @see #getContinueExistingPeriodicTasksAfterShutdownPolicy
      */
     public void setContinueExistingPeriodicTasksAfterShutdownPolicy(boolean value) {
         continueExistingPeriodicTasksAfterShutdown = value;
         if (!value && isShutdown())
-            cancelUnwantedTasks();
+            onShutdown();
     }
 
     /**
-     * Get the policy on whether to continue executing existing
-     * periodic tasks even when this executor has been
-     * <tt>shutdown</tt>. In this case, these tasks will only
-     * terminate upon <tt>shutdownNow</tt> or after setting the policy
-     * to <tt>false</tt> when already shutdown. This value is by
-     * default false.
-     * @return true if will continue after shutdown.
+     * Gets the policy on whether to continue executing existing
+     * periodic tasks even when this executor has been {@code shutdown}.
+     * In this case, these tasks will only terminate upon
+     * {@code shutdownNow} or after setting the policy to
+     * {@code false} when already shutdown.
+     * This value is by default {@code false}.
+     *
+     * @return {@code true} if will continue after shutdown
      * @see #setContinueExistingPeriodicTasksAfterShutdownPolicy
      */
     public boolean getContinueExistingPeriodicTasksAfterShutdownPolicy() {
@@ -409,66 +563,79 @@
     }
 
     /**
-     * Set policy on whether to execute existing delayed
-     * tasks even when this executor has been <tt>shutdown</tt>. In
-     * this case, these tasks will only terminate upon
-     * <tt>shutdownNow</tt>, or after setting the policy to
-     * <tt>false</tt> when already shutdown. This value is by default
-     * true.
-     * @param value if true, execute after shutdown, else don't.
+     * Sets the policy on whether to execute existing delayed
+     * tasks even when this executor has been {@code shutdown}.
+     * In this case, these tasks will only terminate upon
+     * {@code shutdownNow}, or after setting the policy to
+     * {@code false} when already shutdown.
+     * This value is by default {@code true}.
+     *
+     * @param value if {@code true}, execute after shutdown, else don't.
      * @see #getExecuteExistingDelayedTasksAfterShutdownPolicy
      */
     public void setExecuteExistingDelayedTasksAfterShutdownPolicy(boolean value) {
         executeExistingDelayedTasksAfterShutdown = value;
         if (!value && isShutdown())
-            cancelUnwantedTasks();
+            onShutdown();
     }
 
     /**
-     * Get policy on whether to execute existing delayed
-     * tasks even when this executor has been <tt>shutdown</tt>. In
-     * this case, these tasks will only terminate upon
-     * <tt>shutdownNow</tt>, or after setting the policy to
-     * <tt>false</tt> when already shutdown. This value is by default
-     * true.
-     * @return true if will execute after shutdown.
+     * Gets the policy on whether to execute existing delayed
+     * tasks even when this executor has been {@code shutdown}.
+     * In this case, these tasks will only terminate upon
+     * {@code shutdownNow}, or after setting the policy to
+     * {@code false} when already shutdown.
+     * This value is by default {@code true}.
+     *
+     * @return {@code true} if will execute after shutdown
      * @see #setExecuteExistingDelayedTasksAfterShutdownPolicy
      */
     public boolean getExecuteExistingDelayedTasksAfterShutdownPolicy() {
         return executeExistingDelayedTasksAfterShutdown;
     }
 
-
     /**
      * Initiates an orderly shutdown in which previously submitted
-     * tasks are executed, but no new tasks will be accepted. If the
-     * <tt>ExecuteExistingDelayedTasksAfterShutdownPolicy</tt> has
-     * been set <tt>false</tt>, existing delayed tasks whose delays
-     * have not yet elapsed are cancelled. And unless the
-     * <tt>ContinueExistingPeriodicTasksAfterShutdownPolicy</tt> has
-     * been set <tt>true</tt>, future executions of existing periodic
-     * tasks will be cancelled.
+     * tasks are executed, but no new tasks will be accepted.
+     * Invocation has no additional effect if already shut down.
+     *
+     * <p>This method does not wait for previously submitted tasks to
+     * complete execution.  Use {@link #awaitTermination awaitTermination}
+     * to do that.
+     *
+     * <p>If the {@code ExecuteExistingDelayedTasksAfterShutdownPolicy}
+     * has been set {@code false}, existing delayed tasks whose delays
+     * have not yet elapsed are cancelled.  And unless the {@code
+     * ContinueExistingPeriodicTasksAfterShutdownPolicy} has been set
+     * {@code true}, future executions of existing periodic tasks will
+     * be cancelled.
+     *
+     * @throws SecurityException {@inheritDoc}
      */
     public void shutdown() {
-        cancelUnwantedTasks();
         super.shutdown();
     }
 
     /**
      * Attempts to stop all actively executing tasks, halts the
-     * processing of waiting tasks, and returns a list of the tasks that were
-     * awaiting execution. 
-     *  
+     * processing of waiting tasks, and returns a list of the tasks
+     * that were awaiting execution.
+     *
+     * <p>This method does not wait for actively executing tasks to
+     * terminate.  Use {@link #awaitTermination awaitTermination} to
+     * do that.
+     *
      * <p>There are no guarantees beyond best-effort attempts to stop
      * processing actively executing tasks.  This implementation
-     * cancels tasks via {@link Thread#interrupt}, so if any tasks mask or
-     * fail to respond to interrupts, they may never terminate.
+     * cancels tasks via {@link Thread#interrupt}, so any task that
+     * fails to respond to interrupts may never terminate.
      *
-     * @return list of tasks that never commenced execution.  Each
-     * element of this list is a {@link ScheduledFuture},
-     * including those tasks submitted using <tt>execute</tt>, which
-     * are for scheduling purposes used as the basis of a zero-delay
-     * <tt>ScheduledFuture</tt>.
+     * @return list of tasks that never commenced execution.
+     *         Each element of this list is a {@link ScheduledFuture},
+     *         including those tasks submitted using {@code execute},
+     *         which are for scheduling purposes used as the basis of a
+     *         zero-delay {@code ScheduledFuture}.
+     * @throws SecurityException {@inheritDoc}
      */
     public List<Runnable> shutdownNow() {
         return super.shutdownNow();
@@ -477,9 +644,9 @@
     /**
      * Returns the task queue used by this executor.  Each element of
      * this queue is a {@link ScheduledFuture}, including those
-     * tasks submitted using <tt>execute</tt> which are for scheduling
+     * tasks submitted using {@code execute} which are for scheduling
      * purposes used as the basis of a zero-delay
-     * <tt>ScheduledFuture</tt>. Iteration over this queue is
+     * {@code ScheduledFuture}.  Iteration over this queue is
      * <em>not</em> guaranteed to traverse tasks in the order in
      * which they will execute.
      *
@@ -490,52 +657,478 @@
     }
 
     /**
-     * An annoying wrapper class to convince generics compiler to
-     * use a DelayQueue<ScheduledFutureTask> as a BlockingQueue<Runnable>
-     */ 
-    private static class DelayedWorkQueue 
-        extends AbstractCollection<Runnable> 
+     * Specialized delay queue. To mesh with TPE declarations, this
+     * class must be declared as a BlockingQueue<Runnable> even though
+     * it can only hold RunnableScheduledFutures.
+     */
+    static class DelayedWorkQueue extends AbstractQueue<Runnable>
         implements BlockingQueue<Runnable> {
-        
-        private final DelayQueue<ScheduledFutureTask> dq = new DelayQueue<ScheduledFutureTask>();
-        public Runnable poll() { return dq.poll(); }
-        public Runnable peek() { return dq.peek(); }
-        public Runnable take() throws InterruptedException { return dq.take(); }
-        public Runnable poll(long timeout, TimeUnit unit) throws InterruptedException {
-            return dq.poll(timeout, unit);
+
+        /*
+         * A DelayedWorkQueue is based on a heap-based data structure
+         * like those in DelayQueue and PriorityQueue, except that
+         * every ScheduledFutureTask also records its index into the
+         * heap array. This eliminates the need to find a task upon
+         * cancellation, greatly speeding up removal (down from O(n)
+         * to O(log n)), and reducing garbage retention that would
+         * otherwise occur by waiting for the element to rise to top
+         * before clearing. But because the queue may also hold
+         * RunnableScheduledFutures that are not ScheduledFutureTasks,
+         * we are not guaranteed to have such indices available, in
+         * which case we fall back to linear search. (We expect that
+         * most tasks will not be decorated, and that the faster cases
+         * will be much more common.)
+         *
+         * All heap operations must record index changes -- mainly
+         * within siftUp and siftDown. Upon removal, a task's
+         * heapIndex is set to -1. Note that ScheduledFutureTasks can
+         * appear at most once in the queue (this need not be true for
+         * other kinds of tasks or work queues), so are uniquely
+         * identified by heapIndex.
+         */
+
+        private static final int INITIAL_CAPACITY = 16;
+        private ScheduledFutureTask[] queue =
+            new ScheduledFutureTask[INITIAL_CAPACITY];
+        private final ReentrantLock lock = new ReentrantLock();
+        private int size = 0;
+
+        /**
+         * Thread designated to wait for the task at the head of the
+         * queue.  This variant of the Leader-Follower pattern
+         * (http://www.cs.wustl.edu/~schmidt/POSA/POSA2/) serves to
+         * minimize unnecessary timed waiting.  When a thread becomes
+         * the leader, it waits only for the next delay to elapse, but
+         * other threads await indefinitely.  The leader thread must
+         * signal some other thread before returning from take() or
+         * poll(...), unless some other thread becomes leader in the
+         * interim.  Whenever the head of the queue is replaced with a
+         * task with an earlier expiration time, the leader field is
+         * invalidated by being reset to null, and some waiting
+         * thread, but not necessarily the current leader, is
+         * signalled.  So waiting threads must be prepared to acquire
+         * and lose leadership while waiting.
+         */
+        private Thread leader = null;
+
+        /**
+         * Condition signalled when a newer task becomes available at the
+         * head of the queue or a new thread may need to become leader.
+         */
+        private final Condition available = lock.newCondition();
+
+        /**
+         * Set f's heapIndex if it is a ScheduledFutureTask.
+         */
+        private void setIndex(ScheduledFutureTask f, int idx) {
+            if (f instanceof ScheduledFutureTask)
+                ((ScheduledFutureTask)f).heapIndex = idx;
         }
 
-        public boolean add(Runnable x) { return dq.add((ScheduledFutureTask)x); }
-        public boolean offer(Runnable x) { return dq.offer((ScheduledFutureTask)x); }
-        public void put(Runnable x)  {
-            dq.put((ScheduledFutureTask)x); 
-        }
-        public boolean offer(Runnable x, long timeout, TimeUnit unit) {
-            return dq.offer((ScheduledFutureTask)x, timeout, unit);
+        /**
+         * Sift element added at bottom up to its heap-ordered spot.
+         * Call only when holding lock.
+         */
+        private void siftUp(int k, ScheduledFutureTask key) {
+            while (k > 0) {
+                int parent = (k - 1) >>> 1;
+                ScheduledFutureTask e = queue[parent];
+                if (key.compareTo(e) >= 0)
+                    break;
+                queue[k] = e;
+                setIndex(e, k);
+                k = parent;
+            }
+            queue[k] = key;
+            setIndex(key, k);
         }
 
-        public Runnable remove() { return dq.remove(); }
-        public Runnable element() { return dq.element(); }
-        public void clear() { dq.clear(); }
-        public int drainTo(Collection<? super Runnable> c) { return dq.drainTo(c); }
-        public int drainTo(Collection<? super Runnable> c, int maxElements) { 
-            return dq.drainTo(c, maxElements); 
+        /**
+         * Sift element added at top down to its heap-ordered spot.
+         * Call only when holding lock.
+         */
+        private void siftDown(int k, ScheduledFutureTask key) {
+            int half = size >>> 1;
+            while (k < half) {
+                int child = (k << 1) + 1;
+                ScheduledFutureTask c = queue[child];
+                int right = child + 1;
+                if (right < size && c.compareTo(queue[right]) > 0)
+                    c = queue[child = right];
+                if (key.compareTo(c) <= 0)
+                    break;
+                queue[k] = c;
+                setIndex(c, k);
+                k = child;
+            }
+            queue[k] = key;
+            setIndex(key, k);
         }
 
-        public int remainingCapacity() { return dq.remainingCapacity(); }
-        public boolean remove(Object x) { return dq.remove(x); }
-        public boolean contains(Object x) { return dq.contains(x); }
-        public int size() { return dq.size(); }
-        public boolean isEmpty() { return dq.isEmpty(); }
-        public Object[] toArray() { return dq.toArray(); }
-        public <T> T[] toArray(T[] array) { return dq.toArray(array); }
-        public Iterator<Runnable> iterator() { 
-            return new Iterator<Runnable>() {
-                private Iterator<ScheduledFutureTask> it = dq.iterator();
-                public boolean hasNext() { return it.hasNext(); }
-                public Runnable next() { return it.next(); }
-                public void remove() {  it.remove(); }
-            };
+        /**
+         * Resize the heap array.  Call only when holding lock.
+         */
+        private void grow() {
+            int oldCapacity = queue.length;
+            int newCapacity = oldCapacity + (oldCapacity >> 1); // grow 50%
+            if (newCapacity < 0) // overflow
+                newCapacity = Integer.MAX_VALUE;
+            queue = Java6Arrays.copyOf(queue, newCapacity);
+        }
+
+        /**
+         * Find index of given object, or -1 if absent
+         */
+        private int indexOf(Object x) {
+            if (x != null) {
+                if (x instanceof ScheduledFutureTask) {
+                    int i = ((ScheduledFutureTask) x).heapIndex;
+                    // Sanity check; x could conceivably be a
+                    // ScheduledFutureTask from some other pool.
+                    if (i >= 0 && i < size && queue[i] == x)
+                        return i;
+                } else {
+                    for (int i = 0; i < size; i++)
+                        if (x.equals(queue[i]))
+                            return i;
+                }
+            }
+            return -1;
+        }
+
+        public boolean contains(Object x) {
+            final ReentrantLock lock = this.lock;
+            lock.lock();
+            try {
+                return indexOf(x) != -1;
+            } finally {
+                lock.unlock();
+            }
+        }
+
+        public boolean remove(Object x) {
+            final ReentrantLock lock = this.lock;
+            lock.lock();
+            try {
+                int i = indexOf(x);
+                if (i < 0)
+                    return false;
+
+                setIndex(queue[i], -1);
+                int s = --size;
+                ScheduledFutureTask replacement = queue[s];
+                queue[s] = null;
+                if (s != i) {
+                    siftDown(i, replacement);
+                    if (queue[i] == replacement)
+                        siftUp(i, replacement);
+                }
+                return true;
+            } finally {
+                lock.unlock();
+            }
+        }
+
+        public int size() {
+            final ReentrantLock lock = this.lock;
+            lock.lock();
+            try {
+                return size;
+            } finally {
+                lock.unlock();
+            }
+        }
+
+        public boolean isEmpty() {
+            return size() == 0;
+        }
+
+        public int remainingCapacity() {
+            return Integer.MAX_VALUE;
+        }
+
+        public ScheduledFutureTask peek() {
+            final ReentrantLock lock = this.lock;
+            lock.lock();
+            try {
+                return queue[0];
+            } finally {
+                lock.unlock();
+            }
+        }
+
+        public boolean offer(Runnable x) {
+            if (x == null)
+                throw new NullPointerException();
+            ScheduledFutureTask e = (ScheduledFutureTask)x;
+            final ReentrantLock lock = this.lock;
+            lock.lock();
+            try {
+                int i = size;
+                if (i >= queue.length)
+                    grow();
+                size = i + 1;
+                if (i == 0) {
+                    queue[0] = e;
+                    setIndex(e, 0);
+                } else {
+                    siftUp(i, e);
+                }
+                if (queue[0] == e) {
+                    leader = null;
+                    available.signal();
+                }
+            } finally {
+                lock.unlock();
+            }
+            return true;
+        }
+
+        public void put(Runnable e) {
+            offer(e);
+        }
+
+        public boolean add(Runnable e) {
+            return offer(e);
+        }
+
+        public boolean offer(Runnable e, long timeout, TimeUnit unit) {
+            return offer(e);
+        }
+
+        /**
+         * Performs common bookkeeping for poll and take: Replaces
+         * first element with last and sifts it down.  Call only when
+         * holding lock.
+         * @param f the task to remove and return
+         */
+        private ScheduledFutureTask finishPoll(ScheduledFutureTask f) {
+            int s = --size;
+            ScheduledFutureTask x = queue[s];
+            queue[s] = null;
+            if (s != 0)
+                siftDown(0, x);
+            setIndex(f, -1);
+            return f;
+        }
+
+        public ScheduledFutureTask poll() {
+            final ReentrantLock lock = this.lock;
+            lock.lock();
+            try {
+                ScheduledFutureTask first = queue[0];
+                if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
+                    return null;
+                else
+                    return finishPoll(first);
+            } finally {
+                lock.unlock();
+            }
+        }
+
+        public ScheduledFutureTask take() throws InterruptedException {
+            final ReentrantLock lock = this.lock;
+            lock.lockInterruptibly();
+            try {
+                for (;;) {
+                    ScheduledFutureTask first = queue[0];
+                    if (first == null)
+                        available.await();
+                    else {
+                        long delay = first.getDelay(TimeUnit.NANOSECONDS);
+                        if (delay <= 0)
+                            return finishPoll(first);
+                        else if (leader != null)
+                            available.await();
+                        else {
+                            Thread thisThread = Thread.currentThread();
+                            leader = thisThread;
+                            try {
+                                available.awaitNanos(delay);
+                            } finally {
+                                if (leader == thisThread)
+                                    leader = null;
+                            }
+                        }
+                    }
+                }
+            } finally {
+                if (leader == null && queue[0] != null)
+                    available.signal();
+                lock.unlock();
+            }
+        }
+
+        public ScheduledFutureTask poll(long timeout, TimeUnit unit)
+            throws InterruptedException {
+            long nanos = unit.toNanos(timeout);
+            final ReentrantLock lock = this.lock;
+            lock.lockInterruptibly();
+            try {
+                for (;;) {
+                    ScheduledFutureTask first = queue[0];
+                    if (first == null) {
+                        if (nanos <= 0)
+                            return null;
+                        else
+                            nanos = available.awaitNanos(nanos);
+                    } else {
+                        long delay = first.getDelay(TimeUnit.NANOSECONDS);
+                        if (delay <= 0)
+                            return finishPoll(first);
+                        if (nanos <= 0)
+                            return null;
+                        if (nanos < delay || leader != null)
+                            nanos = available.awaitNanos(nanos);
+                        else {
+                            Thread thisThread = Thread.currentThread();
+                            leader = thisThread;
+                            try {
+                                long timeLeft = available.awaitNanos(delay);
+                                nanos -= delay - timeLeft;
+                            } finally {
+                                if (leader == thisThread)
+                                    leader = null;
+                            }
+                        }
+                    }
+                }
+            } finally {
+                if (leader == null && queue[0] != null)
+                    available.signal();
+                lock.unlock();
+            }
+        }
+
+        public void clear() {
+            final ReentrantLock lock = this.lock;
+            lock.lock();
+            try {
+                for (int i = 0; i < size; i++) {
+                    ScheduledFutureTask t = queue[i];
+                    if (t != null) {
+                        queue[i] = null;
+                        setIndex(t, -1);
+                    }
+                }
+                size = 0;
+            } finally {
+                lock.unlock();
+            }
+        }
+
+        /**
+         * Return and remove first element only if it is expired.
+         * Used only by drainTo.  Call only when holding lock.
+         */
+        private ScheduledFutureTask pollExpired() {
+            ScheduledFutureTask first = queue[0];
+            if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
+                return null;
+            return finishPoll(first);
+        }
+
+        public int drainTo(Collection<? super Runnable> c) {
+            if (c == null)
+                throw new NullPointerException();
+            if (c == this)
+                throw new IllegalArgumentException();
+            final ReentrantLock lock = this.lock;
+            lock.lock();
+            try {
+                ScheduledFutureTask first;
+                int n = 0;
+                while ((first = pollExpired()) != null) {
+                    c.add(first);
+                    ++n;
+                }
+                return n;
+            } finally {
+                lock.unlock();
+            }
+        }
+
+        public int drainTo(Collection<? super Runnable> c, int maxElements) {
+            if (c == null)
+                throw new NullPointerException();
+            if (c == this)
+                throw new IllegalArgumentException();
+            if (maxElements <= 0)
+                return 0;
+            final ReentrantLock lock = this.lock;
+            lock.lock();
+            try {
+                ScheduledFutureTask first;
+                int n = 0;
+                while (n < maxElements && (first = pollExpired()) != null) {
+                    c.add(first);
+                    ++n;
+                }
+                return n;
+            } finally {
+                lock.unlock();
+            }
+        }
+
+        public Object[] toArray() {
+            final ReentrantLock lock = this.lock;
+            lock.lock();
+            try {
+                return Java6Arrays.copyOf(queue, size, Object[].class);
+            } finally {
+                lock.unlock();
+            }
+        }
+
+        @SuppressWarnings("unchecked")
+        public <T> T[] toArray(T[] a) {
+            final ReentrantLock lock = this.lock;
+            lock.lock();
+            try {
+                if (a.length < size)
+                    return (T[]) Java6Arrays.copyOf(queue, size, a.getClass());
+                System.arraycopy(queue, 0, a, 0, size);
+                if (a.length > size)
+                    a[size] = null;
+                return a;
+            } finally {
+                lock.unlock();
+            }
+        }
+
+        public Iterator<Runnable> iterator() {
+            return new Itr(Java6Arrays.copyOf(queue, size));
+        }
+
+        /**
+         * Snapshot iterator that works off copy of underlying q array.
+         */
+        private class Itr implements Iterator<Runnable> {
+            final ScheduledFutureTask[] array;
+            int cursor = 0;     // index of next element to return
+            int lastRet = -1;   // index of last element, or -1 if no such
+
+            Itr(ScheduledFutureTask[] array) {
+                this.array = array;
+            }
+
+            public boolean hasNext() {
+                return cursor < array.length;
+            }
+
+            public Runnable next() {
+                if (cursor >= array.length)
+                    throw new NoSuchElementException();
+                lastRet = cursor;
+                return array[cursor++];
+            }
+
+            public void remove() {
+                if (lastRet < 0)
+                    throw new IllegalStateException();
+                DelayedWorkQueue.this.remove(array[lastRet]);
+                lastRet = -1;
+            }
         }
     }
 }
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/Semaphore.java b/libcore/concurrent/src/main/java/java/util/concurrent/Semaphore.java
index 6eb80bc..1052364 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/Semaphore.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/Semaphore.java
@@ -14,7 +14,7 @@
  * permits.  Each {@link #acquire} blocks if necessary until a permit is
  * available, and then takes it.  Each {@link #release} adds a permit,
  * potentially releasing a blocking acquirer.
- * However, no actual permit objects are used; the <tt>Semaphore</tt> just
+ * However, no actual permit objects are used; the {@code Semaphore} just
  * keeps a count of the number available and acts accordingly.
  *
  * <p>Semaphores are often used to restrict the number of threads than can
@@ -22,7 +22,7 @@
  * a class that uses a semaphore to control access to a pool of items:
  * <pre>
  * class Pool {
- *   private static final MAX_AVAILABLE = 100;
+ *   private static final int MAX_AVAILABLE = 100;
  *   private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);
  *
  *   public Object getItem() throws InterruptedException {
@@ -93,15 +93,19 @@
  * guarantees about the order in which threads acquire permits. In
  * particular, <em>barging</em> is permitted, that is, a thread
  * invoking {@link #acquire} can be allocated a permit ahead of a
- * thread that has been waiting.  When fairness is set true, the
+ * thread that has been waiting - logically the new thread places itself at
+ * the head of the queue of waiting threads. When fairness is set true, the
  * semaphore guarantees that threads invoking any of the {@link
- * #acquire() acquire} methods are allocated permits in the order in
+ * #acquire() acquire} methods are selected to obtain permits in the order in
  * which their invocation of those methods was processed
  * (first-in-first-out; FIFO). Note that FIFO ordering necessarily
  * applies to specific internal points of execution within these
  * methods.  So, it is possible for one thread to invoke
- * <tt>acquire</tt> before another, but reach the ordering point after
+ * {@code acquire} before another, but reach the ordering point after
  * the other, and similarly upon return from the method.
+ * Also note that the untimed {@link #tryAcquire() tryAcquire} methods do not
+ * honor the fairness setting, but will take any permits that are
+ * available.
  *
  * <p>Generally, semaphores used to control resource access should be
  * initialized as fair, to ensure that no thread is starved out from
@@ -114,6 +118,12 @@
  * permits at a time.  Beware of the increased risk of indefinite
  * postponement when these methods are used without fairness set true.
  *
+ * <p>Memory consistency effects: Actions in a thread prior to calling
+ * a "release" method such as {@code release()}
+ * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
+ * actions following a successful "acquire" method such as {@code acquire()}
+ * in another thread.
+ *
  * @since 1.5
  * @author Doug Lea
  *
@@ -130,10 +140,12 @@
      * versions.
      */
     abstract static class Sync extends AbstractQueuedSynchronizer {
+        private static final long serialVersionUID = 1192457210091910933L;
+
         Sync(int permits) {
             setState(permits);
         }
-        
+
         final int getPermits() {
             return getState();
         }
@@ -147,11 +159,11 @@
                     return remaining;
             }
         }
-        
+
         protected final boolean tryReleaseShared(int releases) {
             for (;;) {
                 int p = getState();
-                if (compareAndSetState(p, p + releases)) 
+                if (compareAndSetState(p, p + releases))
                     return true;
             }
         }
@@ -178,10 +190,12 @@
      * NonFair version
      */
     final static class NonfairSync extends Sync {
+        private static final long serialVersionUID = -2694183684443567898L;
+
         NonfairSync(int permits) {
             super(permits);
         }
-       
+
         protected int tryAcquireShared(int acquires) {
             return nonfairTryAcquireShared(acquires);
         }
@@ -191,10 +205,12 @@
      * Fair version
      */
     final static class FairSync extends Sync {
+        private static final long serialVersionUID = 2014338818796000944L;
+
         FairSync(int permits) {
             super(permits);
         }
-        
+
         protected int tryAcquireShared(int acquires) {
             Thread current = Thread.currentThread();
             for (;;) {
@@ -211,57 +227,59 @@
     }
 
     /**
-     * Creates a <tt>Semaphore</tt> with the given number of
+     * Creates a {@code Semaphore} with the given number of
      * permits and nonfair fairness setting.
-     * @param permits the initial number of permits available. This
-     * value may be negative, in which case releases must
-     * occur before any acquires will be granted.
+     *
+     * @param permits the initial number of permits available.
+     *        This value may be negative, in which case releases
+     *        must occur before any acquires will be granted.
      */
-    public Semaphore(int permits) { 
+    public Semaphore(int permits) {
         sync = new NonfairSync(permits);
     }
 
     /**
-     * Creates a <tt>Semaphore</tt> with the given number of
+     * Creates a {@code Semaphore} with the given number of
      * permits and the given fairness setting.
-     * @param permits the initial number of permits available. This
-     * value may be negative, in which case releases must
-     * occur before any acquires will be granted.
-     * @param fair true if this semaphore will guarantee first-in
-     * first-out granting of permits under contention, else false.
+     *
+     * @param permits the initial number of permits available.
+     *        This value may be negative, in which case releases
+     *        must occur before any acquires will be granted.
+     * @param fair {@code true} if this semaphore will guarantee
+     *        first-in first-out granting of permits under contention,
+     *        else {@code false}
      */
-    public Semaphore(int permits, boolean fair) { 
+    public Semaphore(int permits, boolean fair) {
         sync = (fair)? new FairSync(permits) : new NonfairSync(permits);
     }
 
     /**
      * Acquires a permit from this semaphore, blocking until one is
-     * available, or the thread is {@link Thread#interrupt interrupted}.
+     * available, or the thread is {@linkplain Thread#interrupt interrupted}.
      *
      * <p>Acquires a permit, if one is available and returns immediately,
      * reducing the number of available permits by one.
+     *
      * <p>If no permit is available then the current thread becomes
      * disabled for thread scheduling purposes and lies dormant until
      * one of two things happens:
      * <ul>
      * <li>Some other thread invokes the {@link #release} method for this
      * semaphore and the current thread is next to be assigned a permit; or
-     * <li>Some other thread {@link Thread#interrupt interrupts} the current
-     * thread.
+     * <li>Some other thread {@linkplain Thread#interrupt interrupts}
+     * the current thread.
      * </ul>
      *
      * <p>If the current thread:
      * <ul>
      * <li>has its interrupted status set on entry to this method; or
-     * <li>is {@link Thread#interrupt interrupted} while waiting
+     * <li>is {@linkplain Thread#interrupt interrupted} while waiting
      * for a permit,
      * </ul>
      * then {@link InterruptedException} is thrown and the current thread's
      * interrupted status is cleared.
      *
      * @throws InterruptedException if the current thread is interrupted
-     *
-     * @see Thread#interrupt
      */
     public void acquire() throws InterruptedException {
         sync.acquireSharedInterruptibly(1);
@@ -273,103 +291,105 @@
      *
      * <p>Acquires a permit, if one is available and returns immediately,
      * reducing the number of available permits by one.
+     *
      * <p>If no permit is available then the current thread becomes
      * disabled for thread scheduling purposes and lies dormant until
      * some other thread invokes the {@link #release} method for this
      * semaphore and the current thread is next to be assigned a permit.
      *
-     * <p>If the current thread
-     * is {@link Thread#interrupt interrupted} while waiting
-     * for a permit then it will continue to wait, but the time at which
-     * the thread is assigned a permit may change compared to the time it
-     * would have received the permit had no interruption occurred. When the
-     * thread does return from this method its interrupt status will be set.
-     *
+     * <p>If the current thread is {@linkplain Thread#interrupt interrupted}
+     * while waiting for a permit then it will continue to wait, but the
+     * time at which the thread is assigned a permit may change compared to
+     * the time it would have received the permit had no interruption
+     * occurred.  When the thread does return from this method its interrupt
+     * status will be set.
      */
     public void acquireUninterruptibly() {
         sync.acquireShared(1);
     }
 
     /**
-     * Acquires a permit from this semaphore, only if one is available at the 
+     * Acquires a permit from this semaphore, only if one is available at the
      * time of invocation.
+     *
      * <p>Acquires a permit, if one is available and returns immediately,
-     * with the value <tt>true</tt>,
+     * with the value {@code true},
      * reducing the number of available permits by one.
      *
      * <p>If no permit is available then this method will return
-     * immediately with the value <tt>false</tt>.
+     * immediately with the value {@code false}.
      *
      * <p>Even when this semaphore has been set to use a
-     * fair ordering policy, a call to <tt>tryAcquire()</tt> <em>will</em>
+     * fair ordering policy, a call to {@code tryAcquire()} <em>will</em>
      * immediately acquire a permit if one is available, whether or not
-     * other threads are currently waiting. 
-     * This &quot;barging&quot; behavior can be useful in certain 
+     * other threads are currently waiting.
+     * This &quot;barging&quot; behavior can be useful in certain
      * circumstances, even though it breaks fairness. If you want to honor
-     * the fairness setting, then use 
+     * the fairness setting, then use
      * {@link #tryAcquire(long, TimeUnit) tryAcquire(0, TimeUnit.SECONDS) }
      * which is almost equivalent (it also detects interruption).
      *
-     * @return <tt>true</tt> if a permit was acquired and <tt>false</tt>
-     * otherwise.
+     * @return {@code true} if a permit was acquired and {@code false}
+     *         otherwise
      */
     public boolean tryAcquire() {
         return sync.nonfairTryAcquireShared(1) >= 0;
     }
 
     /**
-     * Acquires a permit from this semaphore, if one becomes available 
-     * within the given waiting time and the
-     * current thread has not been {@link Thread#interrupt interrupted}.
+     * Acquires a permit from this semaphore, if one becomes available
+     * within the given waiting time and the current thread has not
+     * been {@linkplain Thread#interrupt interrupted}.
+     *
      * <p>Acquires a permit, if one is available and returns immediately,
-     * with the value <tt>true</tt>,
+     * with the value {@code true},
      * reducing the number of available permits by one.
-     * <p>If no permit is available then
-     * the current thread becomes disabled for thread scheduling
-     * purposes and lies dormant until one of three things happens:
+     *
+     * <p>If no permit is available then the current thread becomes
+     * disabled for thread scheduling purposes and lies dormant until
+     * one of three things happens:
      * <ul>
      * <li>Some other thread invokes the {@link #release} method for this
      * semaphore and the current thread is next to be assigned a permit; or
-     * <li>Some other thread {@link Thread#interrupt interrupts} the current
-     * thread; or
+     * <li>Some other thread {@linkplain Thread#interrupt interrupts}
+     * the current thread; or
      * <li>The specified waiting time elapses.
      * </ul>
-     * <p>If a permit is acquired then the value <tt>true</tt> is returned.
+     *
+     * <p>If a permit is acquired then the value {@code true} is returned.
+     *
      * <p>If the current thread:
      * <ul>
      * <li>has its interrupted status set on entry to this method; or
-     * <li>is {@link Thread#interrupt interrupted} while waiting to acquire
-     * a permit,
+     * <li>is {@linkplain Thread#interrupt interrupted} while waiting
+     * to acquire a permit,
      * </ul>
      * then {@link InterruptedException} is thrown and the current thread's
      * interrupted status is cleared.
-     * <p>If the specified waiting time elapses then the value <tt>false</tt>
-     * is returned.
-     * If the time is less than or equal to zero, the method will not wait 
-     * at all.
+     *
+     * <p>If the specified waiting time elapses then the value {@code false}
+     * is returned.  If the time is less than or equal to zero, the method
+     * will not wait at all.
      *
      * @param timeout the maximum time to wait for a permit
-     * @param unit the time unit of the <tt>timeout</tt> argument.
-     * @return <tt>true</tt> if a permit was acquired and <tt>false</tt>
-     * if the waiting time elapsed before a permit was acquired.
-     *
+     * @param unit the time unit of the {@code timeout} argument
+     * @return {@code true} if a permit was acquired and {@code false}
+     *         if the waiting time elapsed before a permit was acquired
      * @throws InterruptedException if the current thread is interrupted
-     *
-     * @see Thread#interrupt
-     *
      */
-    public boolean tryAcquire(long timeout, TimeUnit unit) 
+    public boolean tryAcquire(long timeout, TimeUnit unit)
         throws InterruptedException {
         return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
     }
 
     /**
      * Releases a permit, returning it to the semaphore.
-     * <p>Releases a permit, increasing the number of available permits
-     * by one.
-     * If any threads are blocking trying to acquire a permit, then one
-     * is selected and given the permit that was just released.
-     * That thread is re-enabled for thread scheduling purposes.
+     *
+     * <p>Releases a permit, increasing the number of available permits by
+     * one.  If any threads are trying to acquire a permit, then one is
+     * selected and given the permit that was just released.  That thread
+     * is (re)enabled for thread scheduling purposes.
+     *
      * <p>There is no requirement that a thread that releases a permit must
      * have acquired that permit by calling {@link #acquire}.
      * Correct usage of a semaphore is established by programming convention
@@ -378,45 +398,42 @@
     public void release() {
         sync.releaseShared(1);
     }
-       
+
     /**
-     * Acquires the given number of permits from this semaphore, 
-     * blocking until all are available, 
-     * or the thread is {@link Thread#interrupt interrupted}.
+     * Acquires the given number of permits from this semaphore,
+     * blocking until all are available,
+     * or the thread is {@linkplain Thread#interrupt interrupted}.
      *
      * <p>Acquires the given number of permits, if they are available,
-     * and returns immediately,
-     * reducing the number of available permits by the given amount.
+     * and returns immediately, reducing the number of available permits
+     * by the given amount.
      *
      * <p>If insufficient permits are available then the current thread becomes
      * disabled for thread scheduling purposes and lies dormant until
      * one of two things happens:
      * <ul>
-     * <li>Some other thread invokes one of the {@link #release() release} 
+     * <li>Some other thread invokes one of the {@link #release() release}
      * methods for this semaphore, the current thread is next to be assigned
      * permits and the number of available permits satisfies this request; or
-     * <li>Some other thread {@link Thread#interrupt interrupts} the current
-     * thread.
+     * <li>Some other thread {@linkplain Thread#interrupt interrupts}
+     * the current thread.
      * </ul>
      *
      * <p>If the current thread:
      * <ul>
      * <li>has its interrupted status set on entry to this method; or
-     * <li>is {@link Thread#interrupt interrupted} while waiting
+     * <li>is {@linkplain Thread#interrupt interrupted} while waiting
      * for a permit,
      * </ul>
      * then {@link InterruptedException} is thrown and the current thread's
-     * interrupted status is cleared. 
-     * Any permits that were to be assigned to this thread are instead 
-     * assigned to the next waiting thread(s), as if
-     * they had been made available by a call to {@link #release()}.
+     * interrupted status is cleared.
+     * Any permits that were to be assigned to this thread are instead
+     * assigned to other threads trying to acquire permits, as if
+     * permits had been made available by a call to {@link #release()}.
      *
      * @param permits the number of permits to acquire
-     *
      * @throws InterruptedException if the current thread is interrupted
-     * @throws IllegalArgumentException if permits less than zero.
-     *
-     * @see Thread#interrupt
+     * @throws IllegalArgumentException if {@code permits} is negative
      */
     public void acquire(int permits) throws InterruptedException {
         if (permits < 0) throw new IllegalArgumentException();
@@ -424,27 +441,26 @@
     }
 
     /**
-     * Acquires the given number of permits from this semaphore, 
+     * Acquires the given number of permits from this semaphore,
      * blocking until all are available.
      *
      * <p>Acquires the given number of permits, if they are available,
-     * and returns immediately,
-     * reducing the number of available permits by the given amount.
+     * and returns immediately, reducing the number of available permits
+     * by the given amount.
      *
      * <p>If insufficient permits are available then the current thread becomes
      * disabled for thread scheduling purposes and lies dormant until
-     * some other thread invokes one of the {@link #release() release} 
+     * some other thread invokes one of the {@link #release() release}
      * methods for this semaphore, the current thread is next to be assigned
      * permits and the number of available permits satisfies this request.
      *
-     * <p>If the current thread
-     * is {@link Thread#interrupt interrupted} while waiting
-     * for permits then it will continue to wait and its position in the
-     * queue is not affected. When the
-     * thread does return from this method its interrupt status will be set.
+     * <p>If the current thread is {@linkplain Thread#interrupt interrupted}
+     * while waiting for permits then it will continue to wait and its
+     * position in the queue is not affected.  When the thread does return
+     * from this method its interrupt status will be set.
      *
      * @param permits the number of permits to acquire
-     * @throws IllegalArgumentException if permits less than zero.
+     * @throws IllegalArgumentException if {@code permits} is negative
      *
      */
     public void acquireUninterruptibly(int permits) {
@@ -456,16 +472,16 @@
      * Acquires the given number of permits from this semaphore, only
      * if all are available at the time of invocation.
      *
-     * <p>Acquires the given number of permits, if they are available, and 
-     * returns immediately, with the value <tt>true</tt>,
+     * <p>Acquires the given number of permits, if they are available, and
+     * returns immediately, with the value {@code true},
      * reducing the number of available permits by the given amount.
      *
      * <p>If insufficient permits are available then this method will return
-     * immediately with the value <tt>false</tt> and the number of available
+     * immediately with the value {@code false} and the number of available
      * permits is unchanged.
      *
      * <p>Even when this semaphore has been set to use a fair ordering
-     * policy, a call to <tt>tryAcquire</tt> <em>will</em>
+     * policy, a call to {@code tryAcquire} <em>will</em>
      * immediately acquire a permit if one is available, whether or
      * not other threads are currently waiting.  This
      * &quot;barging&quot; behavior can be useful in certain
@@ -475,10 +491,9 @@
      * which is almost equivalent (it also detects interruption).
      *
      * @param permits the number of permits to acquire
-     *
-     * @return <tt>true</tt> if the permits were acquired and <tt>false</tt>
-     * otherwise.
-     * @throws IllegalArgumentException if permits less than zero.
+     * @return {@code true} if the permits were acquired and
+     *         {@code false} otherwise
+     * @throws IllegalArgumentException if {@code permits} is negative
      */
     public boolean tryAcquire(int permits) {
         if (permits < 0) throw new IllegalArgumentException();
@@ -486,55 +501,54 @@
     }
 
     /**
-     * Acquires the given number of permits from this semaphore, if all 
-     * become available within the given waiting time and the
-     * current thread has not been {@link Thread#interrupt interrupted}.
-     * <p>Acquires the given number of permits, if they are available and 
-     * returns immediately, with the value <tt>true</tt>,
+     * Acquires the given number of permits from this semaphore, if all
+     * become available within the given waiting time and the current
+     * thread has not been {@linkplain Thread#interrupt interrupted}.
+     *
+     * <p>Acquires the given number of permits, if they are available and
+     * returns immediately, with the value {@code true},
      * reducing the number of available permits by the given amount.
+     *
      * <p>If insufficient permits are available then
      * the current thread becomes disabled for thread scheduling
      * purposes and lies dormant until one of three things happens:
      * <ul>
-     * <li>Some other thread invokes one of the {@link #release() release} 
+     * <li>Some other thread invokes one of the {@link #release() release}
      * methods for this semaphore, the current thread is next to be assigned
      * permits and the number of available permits satisfies this request; or
-     * <li>Some other thread {@link Thread#interrupt interrupts} the current
-     * thread; or
+     * <li>Some other thread {@linkplain Thread#interrupt interrupts}
+     * the current thread; or
      * <li>The specified waiting time elapses.
      * </ul>
-     * <p>If the permits are acquired then the value <tt>true</tt> is returned.
+     *
+     * <p>If the permits are acquired then the value {@code true} is returned.
+     *
      * <p>If the current thread:
      * <ul>
      * <li>has its interrupted status set on entry to this method; or
-     * <li>is {@link Thread#interrupt interrupted} while waiting to acquire
-     * the permits,
+     * <li>is {@linkplain Thread#interrupt interrupted} while waiting
+     * to acquire the permits,
      * </ul>
      * then {@link InterruptedException} is thrown and the current thread's
      * interrupted status is cleared.
-     * Any permits that were to be assigned to this thread, are instead 
-     * assigned to the next waiting thread(s), as if
-     * they had been made available by a call to {@link #release()}.
+     * Any permits that were to be assigned to this thread, are instead
+     * assigned to other threads trying to acquire permits, as if
+     * the permits had been made available by a call to {@link #release()}.
      *
-     * <p>If the specified waiting time elapses then the value <tt>false</tt>
-     * is returned.
-     * If the time is
-     * less than or equal to zero, the method will not wait at all.
-     * Any permits that were to be assigned to this thread, are instead 
-     * assigned to the next waiting thread(s), as if
-     * they had been made available by a call to {@link #release()}.
+     * <p>If the specified waiting time elapses then the value {@code false}
+     * is returned.  If the time is less than or equal to zero, the method
+     * will not wait at all.  Any permits that were to be assigned to this
+     * thread, are instead assigned to other threads trying to acquire
+     * permits, as if the permits had been made available by a call to
+     * {@link #release()}.
      *
      * @param permits the number of permits to acquire
      * @param timeout the maximum time to wait for the permits
-     * @param unit the time unit of the <tt>timeout</tt> argument.
-     * @return <tt>true</tt> if all permits were acquired and <tt>false</tt>
-     * if the waiting time elapsed before all permits were acquired.
-     *
+     * @param unit the time unit of the {@code timeout} argument
+     * @return {@code true} if all permits were acquired and {@code false}
+     *         if the waiting time elapsed before all permits were acquired
      * @throws InterruptedException if the current thread is interrupted
-     * @throws IllegalArgumentException if permits less than zero.
-     *
-     * @see Thread#interrupt
-     *
+     * @throws IllegalArgumentException if {@code permits} is negative
      */
     public boolean tryAcquire(int permits, long timeout, TimeUnit unit)
         throws InterruptedException {
@@ -544,19 +558,17 @@
 
     /**
      * Releases the given number of permits, returning them to the semaphore.
-     * <p>Releases the given number of permits, increasing the number of 
+     *
+     * <p>Releases the given number of permits, increasing the number of
      * available permits by that amount.
-     * If any threads are blocking trying to acquire permits, then the
-     * one that has been waiting the longest
+     * If any threads are trying to acquire permits, then one
      * is selected and given the permits that were just released.
      * If the number of available permits satisfies that thread's request
-     * then that thread is re-enabled for thread scheduling purposes; otherwise
-     * the thread continues to wait. If there are still permits available
-     * after the first thread's request has been satisfied, then those permits
-     * are assigned to the next waiting thread. If it is satisfied then it is
-     * re-enabled for thread scheduling purposes. This continues until there
-     * are insufficient permits to satisfy the next waiting thread, or there
-     * are no more waiting threads.
+     * then that thread is (re)enabled for thread scheduling purposes;
+     * otherwise the thread will wait until sufficient permits are available.
+     * If there are still permits available
+     * after this thread's request has been satisfied, then those permits
+     * are assigned in turn to other threads trying to acquire permits.
      *
      * <p>There is no requirement that a thread that releases a permit must
      * have acquired that permit by calling {@link Semaphore#acquire acquire}.
@@ -564,7 +576,7 @@
      * in the application.
      *
      * @param permits the number of permits to release
-     * @throws IllegalArgumentException if permits less than zero.
+     * @throws IllegalArgumentException if {@code permits} is negative
      */
     public void release(int permits) {
         if (permits < 0) throw new IllegalArgumentException();
@@ -573,16 +585,19 @@
 
     /**
      * Returns the current number of permits available in this semaphore.
+     *
      * <p>This method is typically used for debugging and testing purposes.
-     * @return the number of permits available in this semaphore.
+     *
+     * @return the number of permits available in this semaphore
      */
     public int availablePermits() {
         return sync.getPermits();
     }
 
     /**
-     * Acquire and return all permits that are immediately available.
-     * @return the number of permits 
+     * Acquires and returns all permits that are immediately available.
+     *
+     * @return the number of permits acquired
      */
     public int drainPermits() {
         return sync.drainPermits();
@@ -592,19 +607,21 @@
      * Shrinks the number of available permits by the indicated
      * reduction. This method can be useful in subclasses that use
      * semaphores to track resources that become unavailable. This
-     * method differs from <tt>acquire</tt> in that it does not block
+     * method differs from {@code acquire} in that it does not block
      * waiting for permits to become available.
+     *
      * @param reduction the number of permits to remove
-     * @throws IllegalArgumentException if reduction is negative
+     * @throws IllegalArgumentException if {@code reduction} is negative
      */
     protected void reducePermits(int reduction) {
-    if (reduction < 0) throw new IllegalArgumentException();
+        if (reduction < 0) throw new IllegalArgumentException();
         sync.reducePermits(reduction);
     }
 
     /**
-     * Returns true if this semaphore has fairness set true.
-     * @return true if this semaphore has fairness set true.
+     * Returns {@code true} if this semaphore has fairness set true.
+     *
+     * @return {@code true} if this semaphore has fairness set true
      */
     public boolean isFair() {
         return sync instanceof FairSync;
@@ -612,25 +629,25 @@
 
     /**
      * Queries whether any threads are waiting to acquire. Note that
-     * because cancellations may occur at any time, a <tt>true</tt>
+     * because cancellations may occur at any time, a {@code true}
      * return does not guarantee that any other thread will ever
      * acquire.  This method is designed primarily for use in
      * monitoring of the system state.
      *
-     * @return true if there may be other threads waiting to acquire
-     * the lock.
+     * @return {@code true} if there may be other threads waiting to
+     *         acquire the lock
      */
-    public final boolean hasQueuedThreads() { 
+    public final boolean hasQueuedThreads() {
         return sync.hasQueuedThreads();
     }
 
     /**
-     * Returns an estimate of the number of threads waiting to
-     * acquire.  The value is only an estimate because the number of
-     * threads may change dynamically while this method traverses
-     * internal data structures.  This method is designed for use in
-     * monitoring of the system state, not for synchronization
-     * control.
+     * Returns an estimate of the number of threads waiting to acquire.
+     * The value is only an estimate because the number of threads may
+     * change dynamically while this method traverses internal data
+     * structures.  This method is designed for use in monitoring of the
+     * system state, not for synchronization control.
+     *
      * @return the estimated number of threads waiting for this lock
      */
     public final int getQueueLength() {
@@ -638,13 +655,13 @@
     }
 
     /**
-     * Returns a collection containing threads that may be waiting to
-     * acquire.  Because the actual set of threads may change
-     * dynamically while constructing this result, the returned
-     * collection is only a best-effort estimate.  The elements of the
-     * returned collection are in no particular order.  This method is
-     * designed to facilitate construction of subclasses that provide
-     * more extensive monitoring facilities.
+     * Returns a collection containing threads that may be waiting to acquire.
+     * Because the actual set of threads may change dynamically while
+     * constructing this result, the returned collection is only a best-effort
+     * estimate.  The elements of the returned collection are in no particular
+     * order.  This method is designed to facilitate construction of
+     * subclasses that provide more extensive monitoring facilities.
+     *
      * @return the collection of threads
      */
     protected Collection<Thread> getQueuedThreads() {
@@ -653,13 +670,12 @@
 
     /**
      * Returns a string identifying this semaphore, as well as its state.
-     * The state, in brackets, includes the String 
-     * &quot;Permits =&quot; followed by the number of permits.
-     * @return a string identifying this semaphore, as well as its
-     * state
+     * The state, in brackets, includes the String {@code "Permits ="}
+     * followed by the number of permits.
+     *
+     * @return a string identifying this semaphore, as well as its state
      */
     public String toString() {
         return super.toString() + "[Permits = " + sync.getPermits() + "]";
     }
-
 }
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/SynchronousQueue.java b/libcore/concurrent/src/main/java/java/util/concurrent/SynchronousQueue.java
index b8d3536..0d297ff 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/SynchronousQueue.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/SynchronousQueue.java
@@ -1,11 +1,13 @@
 /*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
+ * Written by Doug Lea, Bill Scherer, and Michael Scott with
+ * assistance from members of JCP JSR-166 Expert Group and released to
+ * the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
  */
 
 package java.util.concurrent;
 import java.util.concurrent.locks.*;
+import java.util.concurrent.atomic.*;
 import java.util.*;
 
 // BEGIN android-note
@@ -13,20 +15,21 @@
 // END android-note
 
 /**
- * A {@linkplain BlockingQueue blocking queue} in which each
- * <tt>put</tt> must wait for a <tt>take</tt>, and vice versa.  A
- * synchronous queue does not have any internal capacity, not even a
- * capacity of one. You cannot <tt>peek</tt> at a synchronous queue
- * because an element is only present when you try to take it; you
- * cannot add an element (using any method) unless another thread is
- * trying to remove it; you cannot iterate as there is nothing to
- * iterate.  The <em>head</em> of the queue is the element that the
- * first queued thread is trying to add to the queue; if there are no
- * queued threads then no element is being added and the head is
- * <tt>null</tt>.  For purposes of other <tt>Collection</tt> methods
- * (for example <tt>contains</tt>), a <tt>SynchronousQueue</tt> acts
- * as an empty collection.  This queue does not permit <tt>null</tt>
- * elements.
+ * A {@linkplain BlockingQueue blocking queue} in which each insert
+ * operation must wait for a corresponding remove operation by another
+ * thread, and vice versa.  A synchronous queue does not have any
+ * internal capacity, not even a capacity of one.  You cannot
+ * <tt>peek</tt> at a synchronous queue because an element is only
+ * present when you try to remove it; you cannot insert an element
+ * (using any method) unless another thread is trying to remove it;
+ * you cannot iterate as there is nothing to iterate.  The
+ * <em>head</em> of the queue is the element that the first queued
+ * inserting thread is trying to add to the queue; if there is no such
+ * queued thread then no element is available for removal and
+ * <tt>poll()</tt> will return <tt>null</tt>.  For purposes of other
+ * <tt>Collection</tt> methods (for example <tt>contains</tt>), a
+ * <tt>SynchronousQueue</tt> acts as an empty collection.  This queue
+ * does not permit <tt>null</tt> elements.
  *
  * <p>Synchronous queues are similar to rendezvous channels used in
  * CSP and Ada. They are well suited for handoff designs, in which an
@@ -37,52 +40,746 @@
  * <p> This class supports an optional fairness policy for ordering
  * waiting producer and consumer threads.  By default, this ordering
  * is not guaranteed. However, a queue constructed with fairness set
- * to <tt>true</tt> grants threads access in FIFO order. Fairness
- * generally decreases throughput but reduces variability and avoids
- * starvation.
+ * to <tt>true</tt> grants threads access in FIFO order.
  *
- * <p>This class implements all of the <em>optional</em> methods
- * of the {@link Collection} and {@link Iterator} interfaces.
+ * <p>This class and its iterator implement all of the
+ * <em>optional</em> methods of the {@link Collection} and {@link
+ * Iterator} interfaces.
  *
  * @since 1.5
- * @author Doug Lea
+ * @author Doug Lea and Bill Scherer and Michael Scott
  * @param <E> the type of elements held in this collection
  */
 public class SynchronousQueue<E> extends AbstractQueue<E>
-        implements BlockingQueue<E>, java.io.Serializable {
+    implements BlockingQueue<E>, java.io.Serializable {
     private static final long serialVersionUID = -3223113410248163686L;
 
     /*
-      This implementation divides actions into two cases for puts:
+     * This class implements extensions of the dual stack and dual
+     * queue algorithms described in "Nonblocking Concurrent Objects
+     * with Condition Synchronization", by W. N. Scherer III and
+     * M. L. Scott.  18th Annual Conf. on Distributed Computing,
+     * Oct. 2004 (see also
+     * http://www.cs.rochester.edu/u/scott/synchronization/pseudocode/duals.html).
+     * The (Lifo) stack is used for non-fair mode, and the (Fifo)
+     * queue for fair mode. The performance of the two is generally
+     * similar. Fifo usually supports higher throughput under
+     * contention but Lifo maintains higher thread locality in common
+     * applications.
+     *
+     * A dual queue (and similarly stack) is one that at any given
+     * time either holds "data" -- items provided by put operations,
+     * or "requests" -- slots representing take operations, or is
+     * empty. A call to "fulfill" (i.e., a call requesting an item
+     * from a queue holding data or vice versa) dequeues a
+     * complementary node.  The most interesting feature of these
+     * queues is that any operation can figure out which mode the
+     * queue is in, and act accordingly without needing locks.
+     *
+     * Both the queue and stack extend abstract class Transferer
+     * defining the single method transfer that does a put or a
+     * take. These are unified into a single method because in dual
+     * data structures, the put and take operations are symmetrical,
+     * so nearly all code can be combined. The resulting transfer
+     * methods are on the long side, but are easier to follow than
+     * they would be if broken up into nearly-duplicated parts.
+     *
+     * The queue and stack data structures share many conceptual
+     * similarities but very few concrete details. For simplicity,
+     * they are kept distinct so that they can later evolve
+     * separately.
+     *
+     * The algorithms here differ from the versions in the above paper
+     * in extending them for use in synchronous queues, as well as
+     * dealing with cancellation. The main differences include:
+     *
+     *  1. The original algorithms used bit-marked pointers, but
+     *     the ones here use mode bits in nodes, leading to a number
+     *     of further adaptations.
+     *  2. SynchronousQueues must block threads waiting to become
+     *     fulfilled.
+     *  3. Support for cancellation via timeout and interrupts,
+     *     including cleaning out cancelled nodes/threads
+     *     from lists to avoid garbage retention and memory depletion.
+     *
+     * Blocking is mainly accomplished using LockSupport park/unpark,
+     * except that nodes that appear to be the next ones to become
+     * fulfilled first spin a bit (on multiprocessors only). On very
+     * busy synchronous queues, spinning can dramatically improve
+     * throughput. And on less busy ones, the amount of spinning is
+     * small enough not to be noticeable.
+     *
+     * Cleaning is done in different ways in queues vs stacks.  For
+     * queues, we can almost always remove a node immediately in O(1)
+     * time (modulo retries for consistency checks) when it is
+     * cancelled. But if it may be pinned as the current tail, it must
+     * wait until some subsequent cancellation. For stacks, we need a
+     * potentially O(n) traversal to be sure that we can remove the
+     * node, but this can run concurrently with other threads
+     * accessing the stack.
+     *
+     * While garbage collection takes care of most node reclamation
+     * issues that otherwise complicate nonblocking algorithms, care
+     * is taken to "forget" references to data, other nodes, and
+     * threads that might be held on to long-term by blocked
+     * threads. In cases where setting to null would otherwise
+     * conflict with main algorithms, this is done by changing a
+     * node's link to now point to the node itself. This doesn't arise
+     * much for Stack nodes (because blocked threads do not hang on to
+     * old head pointers), but references in Queue nodes must be
+     * aggressively forgotten to avoid reachability of everything any
+     * node has ever referred to since arrival.
+     */
 
-      * An arriving producer that does not already have a waiting consumer
-      creates a node holding item, and then waits for a consumer to take it.
-      * An arriving producer that does already have a waiting consumer fills
-      the slot node created by the consumer, and notifies it to continue.
+    /**
+     * Shared internal API for dual stacks and queues.
+     */
+    static abstract class Transferer {
+        /**
+         * Performs a put or take.
+         *
+         * @param e if non-null, the item to be handed to a consumer;
+         *          if null, requests that transfer return an item
+         *          offered by producer.
+         * @param timed if this operation should timeout
+         * @param nanos the timeout, in nanoseconds
+         * @return if non-null, the item provided or received; if null,
+         *         the operation failed due to timeout or interrupt --
+         *         the caller can distinguish which of these occurred
+         *         by checking Thread.interrupted.
+         */
+        abstract Object transfer(Object e, boolean timed, long nanos);
+    }
 
-      And symmetrically, two for takes:
+    /** The number of CPUs, for spin control */
+    static final int NCPUS = Runtime.getRuntime().availableProcessors();
 
-      * An arriving consumer that does not already have a waiting producer
-      creates an empty slot node, and then waits for a producer to fill it.
-      * An arriving consumer that does already have a waiting producer takes
-      item from the node created by the producer, and notifies it to continue.
+    /**
+     * The number of times to spin before blocking in timed waits.
+     * The value is empirically derived -- it works well across a
+     * variety of processors and OSes. Empirically, the best value
+     * seems not to vary with number of CPUs (beyond 2) so is just
+     * a constant.
+     */
+    static final int maxTimedSpins = (NCPUS < 2)? 0 : 32;
 
-      When a put or take waiting for the actions of its counterpart
-      aborts due to interruption or timeout, it marks the node
-      it created as "CANCELLED", which causes its counterpart to retry
-      the entire put or take sequence.
+    /**
+     * The number of times to spin before blocking in untimed waits.
+     * This is greater than timed value because untimed waits spin
+     * faster since they don't need to check times on each spin.
+     */
+    static final int maxUntimedSpins = maxTimedSpins * 16;
 
-      This requires keeping two simple queues, waitingProducers and
-      waitingConsumers. Each of these can be FIFO (preserves fairness)
-      or LIFO (improves throughput).
-    */
+    /**
+     * The number of nanoseconds for which it is faster to spin
+     * rather than to use timed park. A rough estimate suffices.
+     */
+    static final long spinForTimeoutThreshold = 1000L;
 
-    /** Lock protecting both wait queues */
-    private final ReentrantLock qlock;
-    /** Queue holding waiting puts */
-    private final WaitQueue waitingProducers;
-    /** Queue holding waiting takes */
-    private final WaitQueue waitingConsumers;
+    /** Dual stack */
+    static final class TransferStack extends Transferer {
+        /*
+         * This extends Scherer-Scott dual stack algorithm, differing,
+         * among other ways, by using "covering" nodes rather than
+         * bit-marked pointers: Fulfilling operations push on marker
+         * nodes (with FULFILLING bit set in mode) to reserve a spot
+         * to match a waiting node.
+         */
+
+        /* Modes for SNodes, ORed together in node fields */
+        /** Node represents an unfulfilled consumer */
+        static final int REQUEST    = 0;
+        /** Node represents an unfulfilled producer */
+        static final int DATA       = 1;
+        /** Node is fulfilling another unfulfilled DATA or REQUEST */
+        static final int FULFILLING = 2;
+
+        /** Return true if m has fulfilling bit set */
+        static boolean isFulfilling(int m) { return (m & FULFILLING) != 0; }
+
+        /** Node class for TransferStacks. */
+        static final class SNode {
+            volatile SNode next;        // next node in stack
+            volatile SNode match;       // the node matched to this
+            volatile Thread waiter;     // to control park/unpark
+            Object item;                // data; or null for REQUESTs
+            int mode;
+            // Note: item and mode fields don't need to be volatile
+            // since they are always written before, and read after,
+            // other volatile/atomic operations.
+
+            SNode(Object item) {
+                this.item = item;
+            }
+
+            static final AtomicReferenceFieldUpdater<SNode, SNode>
+                nextUpdater = AtomicReferenceFieldUpdater.newUpdater
+                (SNode.class, SNode.class, "next");
+
+            boolean casNext(SNode cmp, SNode val) {
+                return (cmp == next &&
+                        nextUpdater.compareAndSet(this, cmp, val));
+            }
+
+            static final AtomicReferenceFieldUpdater<SNode, SNode>
+                matchUpdater = AtomicReferenceFieldUpdater.newUpdater
+                (SNode.class, SNode.class, "match");
+
+            /**
+             * Tries to match node s to this node, if so, waking up thread.
+             * Fulfillers call tryMatch to identify their waiters.
+             * Waiters block until they have been matched.
+             *
+             * @param s the node to match
+             * @return true if successfully matched to s
+             */
+            boolean tryMatch(SNode s) {
+                if (match == null &&
+                    matchUpdater.compareAndSet(this, null, s)) {
+                    Thread w = waiter;
+                    if (w != null) {    // waiters need at most one unpark
+                        waiter = null;
+                        LockSupport.unpark(w);
+                    }
+                    return true;
+                }
+                return match == s;
+            }
+
+            /**
+             * Tries to cancel a wait by matching node to itself.
+             */
+            void tryCancel() {
+                matchUpdater.compareAndSet(this, null, this);
+            }
+
+            boolean isCancelled() {
+                return match == this;
+            }
+        }
+
+        /** The head (top) of the stack */
+        volatile SNode head;
+
+        static final AtomicReferenceFieldUpdater<TransferStack, SNode>
+            headUpdater = AtomicReferenceFieldUpdater.newUpdater
+            (TransferStack.class,  SNode.class, "head");
+
+        boolean casHead(SNode h, SNode nh) {
+            return h == head && headUpdater.compareAndSet(this, h, nh);
+        }
+
+        /**
+         * Creates or resets fields of a node. Called only from transfer
+         * where the node to push on stack is lazily created and
+         * reused when possible to help reduce intervals between reads
+         * and CASes of head and to avoid surges of garbage when CASes
+         * to push nodes fail due to contention.
+         */
+        static SNode snode(SNode s, Object e, SNode next, int mode) {
+            if (s == null) s = new SNode(e);
+            s.mode = mode;
+            s.next = next;
+            return s;
+        }
+
+        /**
+         * Puts or takes an item.
+         */
+        Object transfer(Object e, boolean timed, long nanos) {
+            /*
+             * Basic algorithm is to loop trying one of three actions:
+             *
+             * 1. If apparently empty or already containing nodes of same
+             *    mode, try to push node on stack and wait for a match,
+             *    returning it, or null if cancelled.
+             *
+             * 2. If apparently containing node of complementary mode,
+             *    try to push a fulfilling node on to stack, match
+             *    with corresponding waiting node, pop both from
+             *    stack, and return matched item. The matching or
+             *    unlinking might not actually be necessary because of
+             *    other threads performing action 3:
+             *
+             * 3. If top of stack already holds another fulfilling node,
+             *    help it out by doing its match and/or pop
+             *    operations, and then continue. The code for helping
+             *    is essentially the same as for fulfilling, except
+             *    that it doesn't return the item.
+             */
+
+            SNode s = null; // constructed/reused as needed
+            int mode = (e == null)? REQUEST : DATA;
+
+            for (;;) {
+                SNode h = head;
+                if (h == null || h.mode == mode) {  // empty or same-mode
+                    if (timed && nanos <= 0) {      // can't wait
+                        if (h != null && h.isCancelled())
+                            casHead(h, h.next);     // pop cancelled node
+                        else
+                            return null;
+                    } else if (casHead(h, s = snode(s, e, h, mode))) {
+                        SNode m = awaitFulfill(s, timed, nanos);
+                        if (m == s) {               // wait was cancelled
+                            clean(s);
+                            return null;
+                        }
+                        if ((h = head) != null && h.next == s)
+                            casHead(h, s.next);     // help s's fulfiller
+                        return mode == REQUEST? m.item : s.item;
+                    }
+                } else if (!isFulfilling(h.mode)) { // try to fulfill
+                    if (h.isCancelled())            // already cancelled
+                        casHead(h, h.next);         // pop and retry
+                    else if (casHead(h, s=snode(s, e, h, FULFILLING|mode))) {
+                        for (;;) { // loop until matched or waiters disappear
+                            SNode m = s.next;       // m is s's match
+                            if (m == null) {        // all waiters are gone
+                                casHead(s, null);   // pop fulfill node
+                                s = null;           // use new node next time
+                                break;              // restart main loop
+                            }
+                            SNode mn = m.next;
+                            if (m.tryMatch(s)) {
+                                casHead(s, mn);     // pop both s and m
+                                return (mode == REQUEST)? m.item : s.item;
+                            } else                  // lost match
+                                s.casNext(m, mn);   // help unlink
+                        }
+                    }
+                } else {                            // help a fulfiller
+                    SNode m = h.next;               // m is h's match
+                    if (m == null)                  // waiter is gone
+                        casHead(h, null);           // pop fulfilling node
+                    else {
+                        SNode mn = m.next;
+                        if (m.tryMatch(h))          // help match
+                            casHead(h, mn);         // pop both h and m
+                        else                        // lost match
+                            h.casNext(m, mn);       // help unlink
+                    }
+                }
+            }
+        }
+
+        /**
+         * Spins/blocks until node s is matched by a fulfill operation.
+         *
+         * @param s the waiting node
+         * @param timed true if timed wait
+         * @param nanos timeout value
+         * @return matched node, or s if cancelled
+         */
+        SNode awaitFulfill(SNode s, boolean timed, long nanos) {
+            /*
+             * When a node/thread is about to block, it sets its waiter
+             * field and then rechecks state at least one more time
+             * before actually parking, thus covering race vs
+             * fulfiller noticing that waiter is non-null so should be
+             * woken.
+             *
+             * When invoked by nodes that appear at the point of call
+             * to be at the head of the stack, calls to park are
+             * preceded by spins to avoid blocking when producers and
+             * consumers are arriving very close in time.  This can
+             * happen enough to bother only on multiprocessors.
+             *
+             * The order of checks for returning out of main loop
+             * reflects fact that interrupts have precedence over
+             * normal returns, which have precedence over
+             * timeouts. (So, on timeout, one last check for match is
+             * done before giving up.) Except that calls from untimed
+             * SynchronousQueue.{poll/offer} don't check interrupts
+             * and don't wait at all, so are trapped in transfer
+             * method rather than calling awaitFulfill.
+             */
+            long lastTime = (timed)? System.nanoTime() : 0;
+            Thread w = Thread.currentThread();
+            SNode h = head;
+            int spins = (shouldSpin(s)?
+                         (timed? maxTimedSpins : maxUntimedSpins) : 0);
+            for (;;) {
+                if (w.isInterrupted())
+                    s.tryCancel();
+                SNode m = s.match;
+                if (m != null)
+                    return m;
+                if (timed) {
+                    long now = System.nanoTime();
+                    nanos -= now - lastTime;
+                    lastTime = now;
+                    if (nanos <= 0) {
+                        s.tryCancel();
+                        continue;
+                    }
+                }
+                if (spins > 0)
+                    spins = shouldSpin(s)? (spins-1) : 0;
+                else if (s.waiter == null)
+                    s.waiter = w; // establish waiter so can park next iter
+                else if (!timed)
+                    LockSupport.park();
+                else if (nanos > spinForTimeoutThreshold)
+                    LockSupport.parkNanos(nanos);
+            }
+        }
+
+        /**
+         * Returns true if node s is at head or there is an active
+         * fulfiller.
+         */
+        boolean shouldSpin(SNode s) {
+            SNode h = head;
+            return (h == s || h == null || isFulfilling(h.mode));
+        }
+
+        /**
+         * Unlinks s from the stack.
+         */
+        void clean(SNode s) {
+            s.item = null;   // forget item
+            s.waiter = null; // forget thread
+
+            /*
+             * At worst we may need to traverse entire stack to unlink
+             * s. If there are multiple concurrent calls to clean, we
+             * might not see s if another thread has already removed
+             * it. But we can stop when we see any node known to
+             * follow s. We use s.next unless it too is cancelled, in
+             * which case we try the node one past. We don't check any
+             * further because we don't want to doubly traverse just to
+             * find sentinel.
+             */
+
+            SNode past = s.next;
+            if (past != null && past.isCancelled())
+                past = past.next;
+
+            // Absorb cancelled nodes at head
+            SNode p;
+            while ((p = head) != null && p != past && p.isCancelled())
+                casHead(p, p.next);
+
+            // Unsplice embedded nodes
+            while (p != null && p != past) {
+                SNode n = p.next;
+                if (n != null && n.isCancelled())
+                    p.casNext(n, n.next);
+                else
+                    p = n;
+            }
+        }
+    }
+
+    /** Dual Queue */
+    static final class TransferQueue extends Transferer {
+        /*
+         * This extends Scherer-Scott dual queue algorithm, differing,
+         * among other ways, by using modes within nodes rather than
+         * marked pointers. The algorithm is a little simpler than
+         * that for stacks because fulfillers do not need explicit
+         * nodes, and matching is done by CAS'ing QNode.item field
+         * from non-null to null (for put) or vice versa (for take).
+         */
+
+        /** Node class for TransferQueue. */
+        static final class QNode {
+            volatile QNode next;          // next node in queue
+            volatile Object item;         // CAS'ed to or from null
+            volatile Thread waiter;       // to control park/unpark
+            final boolean isData;
+
+            QNode(Object item, boolean isData) {
+                this.item = item;
+                this.isData = isData;
+            }
+
+            static final AtomicReferenceFieldUpdater<QNode, QNode>
+                nextUpdater = AtomicReferenceFieldUpdater.newUpdater
+                (QNode.class, QNode.class, "next");
+
+            boolean casNext(QNode cmp, QNode val) {
+                return (next == cmp &&
+                        nextUpdater.compareAndSet(this, cmp, val));
+            }
+
+            static final AtomicReferenceFieldUpdater<QNode, Object>
+                itemUpdater = AtomicReferenceFieldUpdater.newUpdater
+                (QNode.class, Object.class, "item");
+
+            boolean casItem(Object cmp, Object val) {
+                return (item == cmp &&
+                        itemUpdater.compareAndSet(this, cmp, val));
+            }
+
+            /**
+             * Tries to cancel by CAS'ing ref to this as item.
+             */
+            void tryCancel(Object cmp) {
+                itemUpdater.compareAndSet(this, cmp, this);
+            }
+
+            boolean isCancelled() {
+                return item == this;
+            }
+
+            /**
+             * Returns true if this node is known to be off the queue
+             * because its next pointer has been forgotten due to
+             * an advanceHead operation.
+             */
+            boolean isOffList() {
+                return next == this;
+            }
+        }
+
+        /** Head of queue */
+        transient volatile QNode head;
+        /** Tail of queue */
+        transient volatile QNode tail;
+        /**
+         * Reference to a cancelled node that might not yet have been
+         * unlinked from queue because it was the last inserted node
+         * when it cancelled.
+         */
+        transient volatile QNode cleanMe;
+
+        TransferQueue() {
+            QNode h = new QNode(null, false); // initialize to dummy node.
+            head = h;
+            tail = h;
+        }
+
+        static final AtomicReferenceFieldUpdater<TransferQueue, QNode>
+            headUpdater = AtomicReferenceFieldUpdater.newUpdater
+            (TransferQueue.class,  QNode.class, "head");
+
+        /**
+         * Tries to cas nh as new head; if successful, unlink
+         * old head's next node to avoid garbage retention.
+         */
+        void advanceHead(QNode h, QNode nh) {
+            if (h == head && headUpdater.compareAndSet(this, h, nh))
+                h.next = h; // forget old next
+        }
+
+        static final AtomicReferenceFieldUpdater<TransferQueue, QNode>
+            tailUpdater = AtomicReferenceFieldUpdater.newUpdater
+            (TransferQueue.class, QNode.class, "tail");
+
+        /**
+         * Tries to cas nt as new tail.
+         */
+        void advanceTail(QNode t, QNode nt) {
+            if (tail == t)
+                tailUpdater.compareAndSet(this, t, nt);
+        }
+
+        static final AtomicReferenceFieldUpdater<TransferQueue, QNode>
+            cleanMeUpdater = AtomicReferenceFieldUpdater.newUpdater
+            (TransferQueue.class, QNode.class, "cleanMe");
+
+        /**
+         * Tries to CAS cleanMe slot.
+         */
+        boolean casCleanMe(QNode cmp, QNode val) {
+            return (cleanMe == cmp &&
+                    cleanMeUpdater.compareAndSet(this, cmp, val));
+        }
+
+        /**
+         * Puts or takes an item.
+         */
+        Object transfer(Object e, boolean timed, long nanos) {
+            /* Basic algorithm is to loop trying to take either of
+             * two actions:
+             *
+             * 1. If queue apparently empty or holding same-mode nodes,
+             *    try to add node to queue of waiters, wait to be
+             *    fulfilled (or cancelled) and return matching item.
+             *
+             * 2. If queue apparently contains waiting items, and this
+             *    call is of complementary mode, try to fulfill by CAS'ing
+             *    item field of waiting node and dequeuing it, and then
+             *    returning matching item.
+             *
+             * In each case, along the way, check for and try to help
+             * advance head and tail on behalf of other stalled/slow
+             * threads.
+             *
+             * The loop starts off with a null check guarding against
+             * seeing uninitialized head or tail values. This never
+             * happens in current SynchronousQueue, but could if
+             * callers held non-volatile/final ref to the
+             * transferer. The check is here anyway because it places
+             * null checks at top of loop, which is usually faster
+             * than having them implicitly interspersed.
+             */
+
+            QNode s = null; // constructed/reused as needed
+            boolean isData = (e != null);
+
+            for (;;) {
+                QNode t = tail;
+                QNode h = head;
+                if (t == null || h == null)         // saw uninitialized value
+                    continue;                       // spin
+
+                if (h == t || t.isData == isData) { // empty or same-mode
+                    QNode tn = t.next;
+                    if (t != tail)                  // inconsistent read
+                        continue;
+                    if (tn != null) {               // lagging tail
+                        advanceTail(t, tn);
+                        continue;
+                    }
+                    if (timed && nanos <= 0)        // can't wait
+                        return null;
+                    if (s == null)
+                        s = new QNode(e, isData);
+                    if (!t.casNext(null, s))        // failed to link in
+                        continue;
+
+                    advanceTail(t, s);              // swing tail and wait
+                    Object x = awaitFulfill(s, e, timed, nanos);
+                    if (x == s) {                   // wait was cancelled
+                        clean(t, s);
+                        return null;
+                    }
+
+                    if (!s.isOffList()) {           // not already unlinked
+                        advanceHead(t, s);          // unlink if head
+                        if (x != null)              // and forget fields
+                            s.item = s;
+                        s.waiter = null;
+                    }
+                    return (x != null)? x : e;
+
+                } else {                            // complementary-mode
+                    QNode m = h.next;               // node to fulfill
+                    if (t != tail || m == null || h != head)
+                        continue;                   // inconsistent read
+
+                    Object x = m.item;
+                    if (isData == (x != null) ||    // m already fulfilled
+                        x == m ||                   // m cancelled
+                        !m.casItem(x, e)) {         // lost CAS
+                        advanceHead(h, m);          // dequeue and retry
+                        continue;
+                    }
+
+                    advanceHead(h, m);              // successfully fulfilled
+                    LockSupport.unpark(m.waiter);
+                    return (x != null)? x : e;
+                }
+            }
+        }
+
+        /**
+         * Spins/blocks until node s is fulfilled.
+         *
+         * @param s the waiting node
+         * @param e the comparison value for checking match
+         * @param timed true if timed wait
+         * @param nanos timeout value
+         * @return matched item, or s if cancelled
+         */
+        Object awaitFulfill(QNode s, Object e, boolean timed, long nanos) {
+            /* Same idea as TransferStack.awaitFulfill */
+            long lastTime = (timed)? System.nanoTime() : 0;
+            Thread w = Thread.currentThread();
+            int spins = ((head.next == s) ?
+                         (timed? maxTimedSpins : maxUntimedSpins) : 0);
+            for (;;) {
+                if (w.isInterrupted())
+                    s.tryCancel(e);
+                Object x = s.item;
+                if (x != e)
+                    return x;
+                if (timed) {
+                    long now = System.nanoTime();
+                    nanos -= now - lastTime;
+                    lastTime = now;
+                    if (nanos <= 0) {
+                        s.tryCancel(e);
+                        continue;
+                    }
+                }
+                if (spins > 0)
+                    --spins;
+                else if (s.waiter == null)
+                    s.waiter = w;
+                else if (!timed)
+                    LockSupport.park();
+                else if (nanos > spinForTimeoutThreshold)
+                    LockSupport.parkNanos(nanos);
+            }
+        }
+
+        /**
+         * Gets rid of cancelled node s with original predecessor pred.
+         */
+        void clean(QNode pred, QNode s) {
+            s.waiter = null; // forget thread
+            /*
+             * At any given time, exactly one node on list cannot be
+             * deleted -- the last inserted node. To accommodate this,
+             * if we cannot delete s, we save its predecessor as
+             * "cleanMe", deleting the previously saved version
+             * first. At least one of node s or the node previously
+             * saved can always be deleted, so this always terminates.
+             */
+            while (pred.next == s) { // Return early if already unlinked
+                QNode h = head;
+                QNode hn = h.next;   // Absorb cancelled first node as head
+                if (hn != null && hn.isCancelled()) {
+                    advanceHead(h, hn);
+                    continue;
+                }
+                QNode t = tail;      // Ensure consistent read for tail
+                if (t == h)
+                    return;
+                QNode tn = t.next;
+                if (t != tail)
+                    continue;
+                if (tn != null) {
+                    advanceTail(t, tn);
+                    continue;
+                }
+                if (s != t) {        // If not tail, try to unsplice
+                    QNode sn = s.next;
+                    if (sn == s || pred.casNext(s, sn))
+                        return;
+                }
+                QNode dp = cleanMe;
+                if (dp != null) {    // Try unlinking previous cancelled node
+                    QNode d = dp.next;
+                    QNode dn;
+                    if (d == null ||               // d is gone or
+                        d == dp ||                 // d is off list or
+                        !d.isCancelled() ||        // d not cancelled or
+                        (d != t &&                 // d not tail and
+                         (dn = d.next) != null &&  //   has successor
+                         dn != d &&                //   that is on list
+                         dp.casNext(d, dn)))       // d unspliced
+                        casCleanMe(dp, null);
+                    if (dp == pred)
+                        return;      // s is already saved node
+                } else if (casCleanMe(null, pred))
+                    return;          // Postpone cleaning s
+            }
+        }
+    }
+
+    /**
+     * The transferer. Set only in constructor, but cannot be declared
+     * as final without further complicating serialization.  Since
+     * this is accessed only at most once per public method, there
+     * isn't a noticeable performance penalty for using volatile
+     * instead of final here.
+     */
+    private transient volatile Transferer transferer;
 
     /**
      * Creates a <tt>SynchronousQueue</tt> with nonfair access policy.
@@ -92,394 +789,92 @@
     }
 
     /**
-     * Creates a <tt>SynchronousQueue</tt> with specified fairness policy.
-     * @param fair if true, threads contend in FIFO order for access;
-     * otherwise the order is unspecified.
+     * Creates a <tt>SynchronousQueue</tt> with the specified fairness policy.
+     *
+     * @param fair if true, waiting threads contend in FIFO order for
+     *        access; otherwise the order is unspecified.
      */
     public SynchronousQueue(boolean fair) {
-        if (fair) {
-            qlock = new ReentrantLock(true);
-            waitingProducers = new FifoWaitQueue();
-            waitingConsumers = new FifoWaitQueue();
-        }
-        else {
-            qlock = new ReentrantLock();
-            waitingProducers = new LifoWaitQueue();
-            waitingConsumers = new LifoWaitQueue();
-        }
-    }
-
-    /**
-     * Queue to hold waiting puts/takes; specialized to Fifo/Lifo below.
-     * These queues have all transient fields, but are serializable
-     * in order to recover fairness settings when deserialized.
-     */
-    static abstract class WaitQueue implements java.io.Serializable {
-        /** Create, add, and return node for x */
-        abstract Node enq(Object x);
-        /** Remove and return node, or null if empty */
-        abstract Node deq();
-    }
-
-    /**
-     * FIFO queue to hold waiting puts/takes.
-     */
-    static final class FifoWaitQueue extends WaitQueue implements java.io.Serializable {
-        private static final long serialVersionUID = -3623113410248163686L;
-        private transient Node head;
-        private transient Node last;
-
-        Node enq(Object x) {
-            Node p = new Node(x);
-            if (last == null)
-                last = head = p;
-            else
-                last = last.next = p;
-            return p;
-        }
-
-        Node deq() {
-            Node p = head;
-            if (p != null) {
-                if ((head = p.next) == null)
-                    last = null;
-                p.next = null;
-            }
-            return p;
-        }
-    }
-
-    /**
-     * LIFO queue to hold waiting puts/takes.
-     */
-    static final class LifoWaitQueue extends WaitQueue implements java.io.Serializable {
-        private static final long serialVersionUID = -3633113410248163686L;
-        private transient Node head;
-
-        Node enq(Object x) {
-            return head = new Node(x, head);
-        }
-
-        Node deq() {
-            Node p = head;
-            if (p != null) {
-                head = p.next;
-                p.next = null;
-            }
-            return p;
-        }
-    }
-
-    /**
-     * Nodes each maintain an item and handle waits and signals for
-     * getting and setting it. The class extends
-     * AbstractQueuedSynchronizer to manage blocking, using AQS state
-     *  0 for waiting, 1 for ack, -1 for cancelled.
-     */
-    static final class Node extends AbstractQueuedSynchronizer {
-        /** Synchronization state value representing that node acked */
-        private static final int ACK    =  1;
-        /** Synchronization state value representing that node cancelled */
-        private static final int CANCEL = -1;
-
-        /** The item being transferred */
-        Object item;
-        /** Next node in wait queue */
-        Node next;
-
-        /** Creates a node with initial item */
-        Node(Object x) { item = x; }
-
-        /** Creates a node with initial item and next */
-        Node(Object x, Node n) { item = x; next = n; }
-
-        /**
-         * Implements AQS base acquire to succeed if not in WAITING state
-         */
-        protected boolean tryAcquire(int ignore) {
-            return getState() != 0;
-        }
-
-        /**
-         * Implements AQS base release to signal if state changed
-         */
-        protected boolean tryRelease(int newState) {
-            return compareAndSetState(0, newState);
-        }
-
-        /**
-         * Takes item and nulls out field (for sake of GC)
-         */
-        private Object extract() {
-            Object x = item;
-            item = null;
-            return x;
-        }
-
-        /**
-         * Tries to cancel on interrupt; if so rethrowing,
-         * else setting interrupt state
-         */
-        private void checkCancellationOnInterrupt(InterruptedException ie) 
-            throws InterruptedException {
-            if (release(CANCEL)) 
-                throw ie;
-            Thread.currentThread().interrupt();
-        }
-
-        /**
-         * Fills in the slot created by the consumer and signal consumer to
-         * continue.
-         */
-        boolean setItem(Object x) {
-            item = x; // can place in slot even if cancelled
-            return release(ACK);
-        }
-
-        /**
-         * Removes item from slot created by producer and signal producer
-         * to continue.
-         */
-        Object getItem() {
-            return (release(ACK))? extract() : null;
-        }
-
-        /**
-         * Waits for a consumer to take item placed by producer.
-         */
-        void waitForTake() throws InterruptedException {
-            try {
-                acquireInterruptibly(0);
-            } catch (InterruptedException ie) {
-                checkCancellationOnInterrupt(ie);
-            }
-        }
-
-        /**
-         * Waits for a producer to put item placed by consumer.
-         */
-        Object waitForPut() throws InterruptedException {
-            try {
-                acquireInterruptibly(0);
-            } catch (InterruptedException ie) {
-                checkCancellationOnInterrupt(ie);
-            }
-            return extract();
-        }
-
-        /**
-         * Waits for a consumer to take item placed by producer or time out.
-         */
-        boolean waitForTake(long nanos) throws InterruptedException {
-            try {
-                if (!tryAcquireNanos(0, nanos) &&
-                    release(CANCEL))
-                    return false;
-            } catch (InterruptedException ie) {
-                checkCancellationOnInterrupt(ie);
-            }
-            return true;
-        }
-
-        /**
-         * Waits for a producer to put item placed by consumer, or time out.
-         */
-        Object waitForPut(long nanos) throws InterruptedException {
-            try {
-                if (!tryAcquireNanos(0, nanos) &&
-                    release(CANCEL))
-                    return null;
-            } catch (InterruptedException ie) {
-                checkCancellationOnInterrupt(ie);
-            }
-            return extract();
-        }
+        transferer = (fair)? new TransferQueue() : new TransferStack();
     }
 
     /**
      * Adds the specified element to this queue, waiting if necessary for
      * another thread to receive it.
-     * @param o the element to add
-     * @throws InterruptedException if interrupted while waiting.
-     * @throws NullPointerException if the specified element is <tt>null</tt>.
+     *
+     * @throws InterruptedException {@inheritDoc}
+     * @throws NullPointerException {@inheritDoc}
      */
     public void put(E o) throws InterruptedException {
         if (o == null) throw new NullPointerException();
-        final ReentrantLock qlock = this.qlock;
-
-        for (;;) {
-            Node node;
-            boolean mustWait;
-            if (Thread.interrupted()) throw new InterruptedException();
-            qlock.lock();
-            try {
-                node = waitingConsumers.deq();
-                if ( (mustWait = (node == null)) )
-                    node = waitingProducers.enq(o);
-            } finally {
-                qlock.unlock();
-            }
-
-            if (mustWait) {
-                node.waitForTake();
-                return;
-            }
-
-            else if (node.setItem(o))
-                return;
-
-            // else consumer cancelled, so retry
+        if (transferer.transfer(o, false, 0) == null) {
+            Thread.interrupted();
+            throw new InterruptedException();
         }
     }
 
     /**
      * Inserts the specified element into this queue, waiting if necessary
      * up to the specified wait time for another thread to receive it.
-     * @param o the element to add
-     * @param timeout how long to wait before giving up, in units of
-     * <tt>unit</tt>
-     * @param unit a <tt>TimeUnit</tt> determining how to interpret the
-     * <tt>timeout</tt> parameter
-     * @return <tt>true</tt> if successful, or <tt>false</tt> if
-     * the specified waiting time elapses before a consumer appears.
-     * @throws InterruptedException if interrupted while waiting.
-     * @throws NullPointerException if the specified element is <tt>null</tt>.
+     *
+     * @return <tt>true</tt> if successful, or <tt>false</tt> if the
+     *         specified waiting time elapses before a consumer appears.
+     * @throws InterruptedException {@inheritDoc}
+     * @throws NullPointerException {@inheritDoc}
      */
-    public boolean offer(E o, long timeout, TimeUnit unit) throws InterruptedException {
+    public boolean offer(E o, long timeout, TimeUnit unit)
+        throws InterruptedException {
         if (o == null) throw new NullPointerException();
-        long nanos = unit.toNanos(timeout);
-        final ReentrantLock qlock = this.qlock;
-        for (;;) {
-            Node node;
-            boolean mustWait;
-            if (Thread.interrupted()) throw new InterruptedException();
-            qlock.lock();
-            try {
-                node = waitingConsumers.deq();
-                if ( (mustWait = (node == null)) )
-                    node = waitingProducers.enq(o);
-            } finally {
-                qlock.unlock();
-            }
+        if (transferer.transfer(o, true, unit.toNanos(timeout)) != null)
+            return true;
+        if (!Thread.interrupted())
+            return false;
+        throw new InterruptedException();
+    }
 
-            if (mustWait) 
-                return node.waitForTake(nanos);
-
-            else if (node.setItem(o))
-                return true;
-
-            // else consumer cancelled, so retry
-        }
+    /**
+     * Inserts the specified element into this queue, if another thread is
+     * waiting to receive it.
+     *
+     * @param e the element to add
+     * @return <tt>true</tt> if the element was added to this queue, else
+     *         <tt>false</tt>
+     * @throws NullPointerException if the specified element is null
+     */
+    public boolean offer(E e) {
+        if (e == null) throw new NullPointerException();
+        return transferer.transfer(e, true, 0) != null;
     }
 
     /**
      * Retrieves and removes the head of this queue, waiting if necessary
      * for another thread to insert it.
-     * @throws InterruptedException if interrupted while waiting.
+     *
      * @return the head of this queue
+     * @throws InterruptedException {@inheritDoc}
      */
     public E take() throws InterruptedException {
-        final ReentrantLock qlock = this.qlock;
-        for (;;) {
-            Node node;
-            boolean mustWait;
-
-            if (Thread.interrupted()) throw new InterruptedException();
-            qlock.lock();
-            try {
-                node = waitingProducers.deq();
-                if ( (mustWait = (node == null)) )
-                    node = waitingConsumers.enq(null);
-            } finally {
-                qlock.unlock();
-            }
-
-            if (mustWait) {
-                Object x = node.waitForPut();
-                return (E)x;
-            }
-            else {
-                Object x = node.getItem();
-                if (x != null)
-                    return (E)x;
-                // else cancelled, so retry
-            }
-        }
+        Object e = transferer.transfer(null, false, 0);
+        if (e != null)
+            return (E)e;
+        Thread.interrupted();
+        throw new InterruptedException();
     }
 
     /**
      * Retrieves and removes the head of this queue, waiting
      * if necessary up to the specified wait time, for another thread
      * to insert it.
-     * @param timeout how long to wait before giving up, in units of
-     * <tt>unit</tt>
-     * @param unit a <tt>TimeUnit</tt> determining how to interpret the
-     * <tt>timeout</tt> parameter
+     *
      * @return the head of this queue, or <tt>null</tt> if the
-     * specified waiting time elapses before an element is present.
-     * @throws InterruptedException if interrupted while waiting.
+     *         specified waiting time elapses before an element is present.
+     * @throws InterruptedException {@inheritDoc}
      */
     public E poll(long timeout, TimeUnit unit) throws InterruptedException {
-        long nanos = unit.toNanos(timeout);
-        final ReentrantLock qlock = this.qlock;
-
-        for (;;) {
-            Node node;
-            boolean mustWait;
-
-            if (Thread.interrupted()) throw new InterruptedException();
-            qlock.lock();
-            try {
-                node = waitingProducers.deq();
-                if ( (mustWait = (node == null)) )
-                    node = waitingConsumers.enq(null);
-            } finally {
-                qlock.unlock();
-            }
-
-            if (mustWait) {
-                Object x = node.waitForPut(nanos);
-                return (E)x;
-            }
-            else {
-                Object x = node.getItem();
-                if (x != null)
-                    return (E)x;
-                // else cancelled, so retry
-            }
-        }
-    }
-
-    // Untimed nonblocking versions
-
-   /**
-    * Inserts the specified element into this queue, if another thread is
-    * waiting to receive it.
-    *
-    * @param o the element to add.
-    * @return <tt>true</tt> if it was possible to add the element to
-    *         this queue, else <tt>false</tt>
-    * @throws NullPointerException if the specified element is <tt>null</tt>
-    */
-    public boolean offer(E o) {
-        if (o == null) throw new NullPointerException();
-        final ReentrantLock qlock = this.qlock;
-
-        for (;;) {
-            Node node;
-            qlock.lock();
-            try {
-                node = waitingConsumers.deq();
-            } finally {
-                qlock.unlock();
-            }
-            if (node == null)
-                return false;
-
-            else if (node.setItem(o))
-                return true;
-            // else retry
-        }
+        Object e = transferer.transfer(null, true, unit.toNanos(timeout));
+        if (e != null || !Thread.interrupted())
+            return (E)e;
+        throw new InterruptedException();
     }
 
     /**
@@ -490,30 +885,13 @@
      *         element is available.
      */
     public E poll() {
-        final ReentrantLock qlock = this.qlock;
-        for (;;) {
-            Node node;
-            qlock.lock();
-            try {
-                node = waitingProducers.deq();
-            } finally {
-                qlock.unlock();
-            }
-            if (node == null)
-                return null;
-
-            else {
-                Object x = node.getItem();
-                if (x != null)
-                    return (E)x;
-                // else retry
-            }
-        }
+        return (E)transferer.transfer(null, true, 0);
     }
 
     /**
-     * Always returns <tt>true</tt>. 
+     * Always returns <tt>true</tt>.
      * A <tt>SynchronousQueue</tt> has no internal capacity.
+     *
      * @return <tt>true</tt>
      */
     public boolean isEmpty() {
@@ -523,6 +901,7 @@
     /**
      * Always returns zero.
      * A <tt>SynchronousQueue</tt> has no internal capacity.
+     *
      * @return zero.
      */
     public int size() {
@@ -532,6 +911,7 @@
     /**
      * Always returns zero.
      * A <tt>SynchronousQueue</tt> has no internal capacity.
+     *
      * @return zero.
      */
     public int remainingCapacity() {
@@ -542,11 +922,13 @@
      * Does nothing.
      * A <tt>SynchronousQueue</tt> has no internal capacity.
      */
-    public void clear() {}
+    public void clear() {
+    }
 
     /**
      * Always returns <tt>false</tt>.
      * A <tt>SynchronousQueue</tt> has no internal capacity.
+     *
      * @param o the element
      * @return <tt>false</tt>
      */
@@ -566,8 +948,9 @@
     }
 
     /**
-     * Returns <tt>false</tt> unless given collection is empty.
+     * Returns <tt>false</tt> unless the given collection is empty.
      * A <tt>SynchronousQueue</tt> has no internal capacity.
+     *
      * @param c the collection
      * @return <tt>false</tt> unless given collection is empty
      */
@@ -578,6 +961,7 @@
     /**
      * Always returns <tt>false</tt>.
      * A <tt>SynchronousQueue</tt> has no internal capacity.
+     *
      * @param c the collection
      * @return <tt>false</tt>
      */
@@ -588,6 +972,7 @@
     /**
      * Always returns <tt>false</tt>.
      * A <tt>SynchronousQueue</tt> has no internal capacity.
+     *
      * @param c the collection
      * @return <tt>false</tt>
      */
@@ -596,9 +981,10 @@
     }
 
     /**
-     * Always returns <tt>null</tt>. 
+     * Always returns <tt>null</tt>.
      * A <tt>SynchronousQueue</tt> does not return elements
      * unless actively waited on.
+     *
      * @return <tt>null</tt>
      */
     public E peek() {
@@ -628,7 +1014,6 @@
         return new EmptyIterator<E>();
     }
 
-
     /**
      * Returns a zero-length array.
      * @return a zero-length array
@@ -640,8 +1025,10 @@
     /**
      * Sets the zeroeth element of the specified array to <tt>null</tt>
      * (if the array has non-zero length) and returns it.
+     *
      * @param a the array
      * @return the specified array
+     * @throws NullPointerException if the specified array is null
      */
     public <T> T[] toArray(T[] a) {
         if (a.length > 0)
@@ -649,7 +1036,12 @@
         return a;
     }
 
-
+    /**
+     * @throws UnsupportedOperationException {@inheritDoc}
+     * @throws ClassCastException            {@inheritDoc}
+     * @throws NullPointerException          {@inheritDoc}
+     * @throws IllegalArgumentException      {@inheritDoc}
+     */
     public int drainTo(Collection<? super E> c) {
         if (c == null)
             throw new NullPointerException();
@@ -664,6 +1056,12 @@
         return n;
     }
 
+    /**
+     * @throws UnsupportedOperationException {@inheritDoc}
+     * @throws ClassCastException            {@inheritDoc}
+     * @throws NullPointerException          {@inheritDoc}
+     * @throws IllegalArgumentException      {@inheritDoc}
+     */
     public int drainTo(Collection<? super E> c, int maxElements) {
         if (c == null)
             throw new NullPointerException();
@@ -677,9 +1075,54 @@
         }
         return n;
     }
+
+    /*
+     * To cope with serialization strategy in the 1.5 version of
+     * SynchronousQueue, we declare some unused classes and fields
+     * that exist solely to enable serializability across versions.
+     * These fields are never used, so are initialized only if this
+     * object is ever serialized or deserialized.
+     */
+
+    static class WaitQueue implements java.io.Serializable { }
+    static class LifoWaitQueue extends WaitQueue {
+        private static final long serialVersionUID = -3633113410248163686L;
+    }
+    static class FifoWaitQueue extends WaitQueue {
+        private static final long serialVersionUID = -3623113410248163686L;
+    }
+    private ReentrantLock qlock;
+    private WaitQueue waitingProducers;
+    private WaitQueue waitingConsumers;
+
+    /**
+     * Save the state to a stream (that is, serialize it).
+     *
+     * @param s the stream
+     */
+    private void writeObject(java.io.ObjectOutputStream s)
+        throws java.io.IOException {
+        boolean fair = transferer instanceof TransferQueue;
+        if (fair) {
+            qlock = new ReentrantLock(true);
+            waitingProducers = new FifoWaitQueue();
+            waitingConsumers = new FifoWaitQueue();
+        }
+        else {
+            qlock = new ReentrantLock();
+            waitingProducers = new LifoWaitQueue();
+            waitingConsumers = new LifoWaitQueue();
+        }
+        s.defaultWriteObject();
+    }
+
+    private void readObject(final java.io.ObjectInputStream s)
+        throws java.io.IOException, ClassNotFoundException {
+        s.defaultReadObject();
+        if (waitingProducers instanceof FifoWaitQueue)
+            transferer = new TransferQueue();
+        else
+            transferer = new TransferStack();
+    }
+
 }
-
-
-
-
-
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/ThreadFactory.java b/libcore/concurrent/src/main/java/java/util/concurrent/ThreadFactory.java
index 04c63e1..2f0fb1a 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/ThreadFactory.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/ThreadFactory.java
@@ -11,7 +11,7 @@
  * removes hardwiring of calls to {@link Thread#Thread(Runnable) new Thread},
  * enabling applications to use special thread subclasses, priorities, etc.
  *
- * <p> 
+ * <p>
  * The simplest implementation of this interface is just:
  * <pre>
  * class SimpleThreadFactory implements ThreadFactory {
@@ -23,18 +23,19 @@
  *
  * The {@link Executors#defaultThreadFactory} method provides a more
  * useful simple implementation, that sets the created thread context
- * to known values before returning it. 
+ * to known values before returning it.
  * @since 1.5
  * @author Doug Lea
  */
-public interface ThreadFactory { 
+public interface ThreadFactory {
 
     /**
-     * Constructs a new <tt>Thread</tt>.  Implementations may also initialize
-     * priority, name, daemon status, <tt>ThreadGroup</tt>, etc.
+     * Constructs a new {@code Thread}.  Implementations may also initialize
+     * priority, name, daemon status, {@code ThreadGroup}, etc.
      *
      * @param r a runnable to be executed by new thread instance
-     * @return constructed thread
+     * @return constructed thread, or {@code null} if the request to
+     *         create a thread is rejected
      */
     Thread newThread(Runnable r);
 }
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/ThreadPoolExecutor.java b/libcore/concurrent/src/main/java/java/util/concurrent/ThreadPoolExecutor.java
index 1aa8e55..d0c934d 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/ThreadPoolExecutor.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/ThreadPoolExecutor.java
@@ -6,13 +6,9 @@
 
 package java.util.concurrent;
 import java.util.concurrent.locks.*;
+import java.util.concurrent.atomic.*;
 import java.util.*;
 
-// BEGIN android-note
-// Altered {@link TimeUnit#NANOSECONDS} because our javadoc tool doesn't
-// like it.
-// END android-note
-
 /**
  * An {@link ExecutorService} that executes each submitted task using
  * one of possibly several pooled threads, normally configured
@@ -23,7 +19,7 @@
  * asynchronous tasks, due to reduced per-task invocation overhead,
  * and they provide a means of bounding and managing the resources,
  * including threads, consumed when executing a collection of tasks.
- * Each <tt>ThreadPoolExecutor</tt> also maintains some basic
+ * Each {@code ThreadPoolExecutor} also maintains some basic
  * statistics, such as the number of completed tasks.
  *
  * <p>To be useful across a wide range of contexts, this class
@@ -42,61 +38,63 @@
  *
  * <dt>Core and maximum pool sizes</dt>
  *
- * <dd>A <tt>ThreadPoolExecutor</tt> will automatically adjust the
- * pool size 
- * (see {@link ThreadPoolExecutor#getPoolSize})
- * according to the bounds set by corePoolSize 
- * (see {@link ThreadPoolExecutor#getCorePoolSize})
- * and
- * maximumPoolSize
- * (see {@link ThreadPoolExecutor#getMaximumPoolSize}).
- * When a new task is submitted in method {@link
- * ThreadPoolExecutor#execute}, and fewer than corePoolSize threads
- * are running, a new thread is created to handle the request, even if
- * other worker threads are idle.  If there are more than
- * corePoolSize but less than maximumPoolSize threads running, a new
- * thread will be created only if the queue is full.  By setting
- * corePoolSize and maximumPoolSize the same, you create a fixed-size
- * thread pool. By setting maximumPoolSize to an essentially unbounded
- * value such as <tt>Integer.MAX_VALUE</tt>, you allow the pool to
- * accommodate an arbitrary number of concurrent tasks. Most typically,
- * core and maximum pool sizes are set only upon construction, but they
- * may also be changed dynamically using {@link
- * ThreadPoolExecutor#setCorePoolSize} and {@link
- * ThreadPoolExecutor#setMaximumPoolSize}. <dd>
+ * <dd>A {@code ThreadPoolExecutor} will automatically adjust the
+ * pool size (see {@link #getPoolSize})
+ * according to the bounds set by
+ * corePoolSize (see {@link #getCorePoolSize}) and
+ * maximumPoolSize (see {@link #getMaximumPoolSize}).
  *
- * <dt> On-demand construction
+ * When a new task is submitted in method {@link #execute}, and fewer
+ * than corePoolSize threads are running, a new thread is created to
+ * handle the request, even if other worker threads are idle.  If
+ * there are more than corePoolSize but less than maximumPoolSize
+ * threads running, a new thread will be created only if the queue is
+ * full.  By setting corePoolSize and maximumPoolSize the same, you
+ * create a fixed-size thread pool. By setting maximumPoolSize to an
+ * essentially unbounded value such as {@code Integer.MAX_VALUE}, you
+ * allow the pool to accommodate an arbitrary number of concurrent
+ * tasks. Most typically, core and maximum pool sizes are set only
+ * upon construction, but they may also be changed dynamically using
+ * {@link #setCorePoolSize} and {@link #setMaximumPoolSize}. </dd>
+ *
+ * <dt>On-demand construction</dt>
  *
  * <dd> By default, even core threads are initially created and
- * started only when needed by new tasks, but this can be overridden
- * dynamically using method {@link
- * ThreadPoolExecutor#prestartCoreThread} or
- * {@link ThreadPoolExecutor#prestartAllCoreThreads}.  </dd>
+ * started only when new tasks arrive, but this can be overridden
+ * dynamically using method {@link #prestartCoreThread} or {@link
+ * #prestartAllCoreThreads}.  You probably want to prestart threads if
+ * you construct the pool with a non-empty queue. </dd>
  *
  * <dt>Creating new threads</dt>
  *
- * <dd>New threads are created using a {@link
- * java.util.concurrent.ThreadFactory}.  If not otherwise specified, a
- * {@link Executors#defaultThreadFactory} is used, that creates threads to all
- * be in the same {@link ThreadGroup} and with the same
- * <tt>NORM_PRIORITY</tt> priority and non-daemon status. By supplying
- * a different ThreadFactory, you can alter the thread's name, thread
- * group, priority, daemon status, etc.  </dd>
+ * <dd>New threads are created using a {@link ThreadFactory}.  If not
+ * otherwise specified, a {@link Executors#defaultThreadFactory} is
+ * used, that creates threads to all be in the same {@link
+ * ThreadGroup} and with the same {@code NORM_PRIORITY} priority and
+ * non-daemon status. By supplying a different ThreadFactory, you can
+ * alter the thread's name, thread group, priority, daemon status,
+ * etc. If a {@code ThreadFactory} fails to create a thread when asked
+ * by returning null from {@code newThread}, the executor will
+ * continue, but might not be able to execute any tasks. Threads
+ * should possess the "modifyThread" {@code RuntimePermission}. If
+ * worker threads or other threads using the pool do not possess this
+ * permission, service may be degraded: configuration changes may not
+ * take effect in a timely manner, and a shutdown pool may remain in a
+ * state in which termination is possible but not completed.</dd>
  *
  * <dt>Keep-alive times</dt>
  *
  * <dd>If the pool currently has more than corePoolSize threads,
  * excess threads will be terminated if they have been idle for more
- * than the keepAliveTime (see {@link
- * ThreadPoolExecutor#getKeepAliveTime}). This provides a means of
- * reducing resource consumption when the pool is not being actively
- * used. If the pool becomes more active later, new threads will be
- * constructed. This parameter can also be changed dynamically
- * using method {@link ThreadPoolExecutor#setKeepAliveTime}. Using
- * a value of <tt>Long.MAX_VALUE</tt> <code>TimeUnit.NANOSECONDS</code>
- * effectively disables idle threads from ever terminating prior
- * to shut down.
- * </dd>
+ * than the keepAliveTime (see {@link #getKeepAliveTime}). This
+ * provides a means of reducing resource consumption when the pool is
+ * not being actively used. If the pool becomes more active later, new
+ * threads will be constructed. This parameter can also be changed
+ * dynamically using method {@link #setKeepAliveTime}. Using a value
+ * of {@code Long.MAX_VALUE} {@link TimeUnit#NANOSECONDS} effectively
+ * disables idle threads from ever terminating prior to shut down. The
+ * keep-alive policy applies only when there are more than
+ * corePoolSizeThreads.</dd>
  *
  * <dt>Queuing</dt>
  *
@@ -112,7 +110,7 @@
  * <li> If corePoolSize or more threads are running, the Executor
  * always prefers queuing a request rather than adding a new
  * thread.</li>
- * 
+ *
  * <li> If a request cannot be queued, a new thread is created unless
  * this would exceed maximumPoolSize, in which case, the task will be
  * rejected.</li>
@@ -135,7 +133,7 @@
  *
  * <li><em> Unbounded queues.</em> Using an unbounded queue (for
  * example a {@link LinkedBlockingQueue} without a predefined
- * capacity) will cause new tasks to be queued in cases where all
+ * capacity) will cause new tasks to wait in the queue when all
  * corePoolSize threads are busy. Thus, no more than corePoolSize
  * threads will ever be created. (And the value of the maximumPoolSize
  * therefore doesn't have any effect.)  This may be appropriate when
@@ -165,35 +163,33 @@
  *
  * <dt>Rejected tasks</dt>
  *
- * <dd> New tasks submitted in method {@link
- * ThreadPoolExecutor#execute} will be <em>rejected</em> when the
- * Executor has been shut down, and also when the Executor uses finite
- * bounds for both maximum threads and work queue capacity, and is
- * saturated.  In either case, the <tt>execute</tt> method invokes the
- * {@link RejectedExecutionHandler#rejectedExecution} method of its
- * {@link RejectedExecutionHandler}.  Four predefined handler policies
- * are provided:
+ * <dd> New tasks submitted in method {@link #execute} will be
+ * <em>rejected</em> when the Executor has been shut down, and also
+ * when the Executor uses finite bounds for both maximum threads and
+ * work queue capacity, and is saturated.  In either case, the {@code
+ * execute} method invokes the {@link
+ * RejectedExecutionHandler#rejectedExecution} method of its {@link
+ * RejectedExecutionHandler}.  Four predefined handler policies are
+ * provided:
  *
  * <ol>
  *
- * <li> In the
- * default {@link ThreadPoolExecutor.AbortPolicy}, the handler throws a
- * runtime {@link RejectedExecutionException} upon rejection. </li>
- * 
- * <li> In {@link
- * ThreadPoolExecutor.CallerRunsPolicy}, the thread that invokes
- * <tt>execute</tt> itself runs the task. This provides a simple
- * feedback control mechanism that will slow down the rate that new
- * tasks are submitted. </li>
+ * <li> In the default {@link ThreadPoolExecutor.AbortPolicy}, the
+ * handler throws a runtime {@link RejectedExecutionException} upon
+ * rejection. </li>
  *
- * <li> In {@link ThreadPoolExecutor.DiscardPolicy},
- * a task that cannot be executed is simply dropped.  </li>
+ * <li> In {@link ThreadPoolExecutor.CallerRunsPolicy}, the thread
+ * that invokes {@code execute} itself runs the task. This provides a
+ * simple feedback control mechanism that will slow down the rate that
+ * new tasks are submitted. </li>
  *
- * <li>In {@link
- * ThreadPoolExecutor.DiscardOldestPolicy}, if the executor is not
- * shut down, the task at the head of the work queue is dropped, and
- * then execution is retried (which can fail again, causing this to be
- * repeated.) </li>
+ * <li> In {@link ThreadPoolExecutor.DiscardPolicy}, a task that
+ * cannot be executed is simply dropped.  </li>
+ *
+ * <li>In {@link ThreadPoolExecutor.DiscardOldestPolicy}, if the
+ * executor is not shut down, the task at the head of the work queue
+ * is dropped, and then execution is retried (which can fail again,
+ * causing this to be repeated.) </li>
  *
  * </ol>
  *
@@ -204,50 +200,62 @@
  *
  * <dt>Hook methods</dt>
  *
- * <dd>This class provides <tt>protected</tt> overridable {@link
- * ThreadPoolExecutor#beforeExecute} and {@link
- * ThreadPoolExecutor#afterExecute} methods that are called before and
- * after execution of each task.  These can be used to manipulate the
- * execution environment, for example, reinitializing ThreadLocals,
- * gathering statistics, or adding log entries. Additionally, method
- * {@link ThreadPoolExecutor#terminated} can be overridden to perform
- * any special processing that needs to be done once the Executor has
- * fully terminated.</dd>
+ * <dd>This class provides {@code protected} overridable {@link
+ * #beforeExecute} and {@link #afterExecute} methods that are called
+ * before and after execution of each task.  These can be used to
+ * manipulate the execution environment; for example, reinitializing
+ * ThreadLocals, gathering statistics, or adding log
+ * entries. Additionally, method {@link #terminated} can be overridden
+ * to perform any special processing that needs to be done once the
+ * Executor has fully terminated.
+ *
+ * <p>If hook or callback methods throw exceptions, internal worker
+ * threads may in turn fail and abruptly terminate.</dd>
  *
  * <dt>Queue maintenance</dt>
  *
- * <dd> Method {@link ThreadPoolExecutor#getQueue} allows access to
- * the work queue for purposes of monitoring and debugging.  Use of
- * this method for any other purpose is strongly discouraged.  Two
- * supplied methods, {@link ThreadPoolExecutor#remove} and {@link
- * ThreadPoolExecutor#purge} are available to assist in storage
- * reclamation when large numbers of queued tasks become
- * cancelled.</dd> </dl>
+ * <dd> Method {@link #getQueue} allows access to the work queue for
+ * purposes of monitoring and debugging.  Use of this method for any
+ * other purpose is strongly discouraged.  Two supplied methods,
+ * {@link #remove} and {@link #purge} are available to assist in
+ * storage reclamation when large numbers of queued tasks become
+ * cancelled.</dd>
+ *
+ * <dt>Finalization</dt>
+ *
+ * <dd> A pool that is no longer referenced in a program <em>AND</em>
+ * has no remaining threads will be {@code shutdown} automatically. If
+ * you would like to ensure that unreferenced pools are reclaimed even
+ * if users forget to call {@link #shutdown}, then you must arrange
+ * that unused threads eventually die, by setting appropriate
+ * keep-alive times using a lower bound of zero core threads.  </dd>
+ *
+ * </dl>
  *
  * <p> <b>Extension example</b>. Most extensions of this class
  * override one or more of the protected hook methods. For example,
  * here is a subclass that adds a simple pause/resume feature:
  *
- * <pre>
+ *  <pre> {@code
  * class PausableThreadPoolExecutor extends ThreadPoolExecutor {
  *   private boolean isPaused;
  *   private ReentrantLock pauseLock = new ReentrantLock();
  *   private Condition unpaused = pauseLock.newCondition();
  *
  *   public PausableThreadPoolExecutor(...) { super(...); }
- * 
+ *
  *   protected void beforeExecute(Thread t, Runnable r) {
  *     super.beforeExecute(t, r);
  *     pauseLock.lock();
  *     try {
  *       while (isPaused) unpaused.await();
- *     } catch(InterruptedException ie) {
+ *     } catch (InterruptedException ie) {
  *       t.interrupt();
  *     } finally {
  *       pauseLock.unlock();
  *     }
  *   }
- * 
+ *
  *   public void pause() {
  *     pauseLock.lock();
  *     try {
@@ -256,7 +264,7 @@
  *       pauseLock.unlock();
  *     }
  *   }
- * 
+ *
  *   public void resume() {
  *     pauseLock.lock();
  *     try {
@@ -266,86 +274,196 @@
  *       pauseLock.unlock();
  *     }
  *   }
- * }
- * </pre>
+ * }}</pre>
+ *
  * @since 1.5
  * @author Doug Lea
  */
 public class ThreadPoolExecutor extends AbstractExecutorService {
     /**
-     * Only used to force toArray() to produce a Runnable[].
+     * The main pool control state, ctl, is an atomic integer packing
+     * two conceptual fields
+     *   workerCount, indicating the effective number of threads
+     *   runState,    indicating whether running, shutting down etc
+     *
+     * In order to pack them into one int, we limit workerCount to
+     * (2^29)-1 (about 500 million) threads rather than (2^31)-1 (2
+     * billion) otherwise representable. If this is ever an issue in
+     * the future, the variable can be changed to be an AtomicLong,
+     * and the shift/mask constants below adjusted. But until the need
+     * arises, this code is a bit faster and simpler using an int.
+     *
+     * The workerCount is the number of workers that have been
+     * permitted to start and not permitted to stop.  The value may be
+     * transiently different from the actual number of live threads,
+     * for example when a ThreadFactory fails to create a thread when
+     * asked, and when exiting threads are still performing
+     * bookkeeping before terminating. The user-visible pool size is
+     * reported as the current size of the workers set.
+     *
+     * The runState provides the main lifecyle control, taking on values:
+     *
+     *   RUNNING:  Accept new tasks and process queued tasks
+     *   SHUTDOWN: Don't accept new tasks, but process queued tasks
+     *   STOP:     Don't accept new tasks, don't process queued tasks,
+     *             and interrupt in-progress tasks
+     *   TIDYING:  All tasks have terminated, workerCount is zero,
+     *             the thread transitioning to state TIDYING
+     *             will run the terminated() hook method
+     *   TERMINATED: terminated() has completed
+     *
+     * The numerical order among these values matters, to allow
+     * ordered comparisons. The runState monotonically increases over
+     * time, but need not hit each state. The transitions are:
+     *
+     * RUNNING -> SHUTDOWN
+     *    On invocation of shutdown(), perhaps implicitly in finalize()
+     * (RUNNING or SHUTDOWN) -> STOP
+     *    On invocation of shutdownNow()
+     * SHUTDOWN -> TIDYING
+     *    When both queue and pool are empty
+     * STOP -> TIDYING
+     *    When pool is empty
+     * TIDYING -> TERMINATED
+     *    When the terminated() hook method has completed
+     *
+     * Threads waiting in awaitTermination() will return when the
+     * state reaches TERMINATED.
+     *
+     * Detecting the transition from SHUTDOWN to TIDYING is less
+     * straightforward than you'd like because the queue may become
+     * empty after non-empty and vice versa during SHUTDOWN state, but
+     * we can only terminate if, after seeing that it is empty, we see
+     * that workerCount is 0 (which sometimes entails a recheck -- see
+     * below).
      */
-    private static final Runnable[] EMPTY_RUNNABLE_ARRAY = new Runnable[0];
+    private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
+    private static final int COUNT_BITS = Integer.SIZE - 3;
+    private static final int CAPACITY   = (1 << COUNT_BITS) - 1;
+
+    // runState is stored in the high-order bits
+    private static final int RUNNING    = -1 << COUNT_BITS;
+    private static final int SHUTDOWN   =  0 << COUNT_BITS;
+    private static final int STOP       =  1 << COUNT_BITS;
+    private static final int TIDYING    =  2 << COUNT_BITS;
+    private static final int TERMINATED =  3 << COUNT_BITS;
+
+    // Packing and unpacking ctl
+    private static int runStateOf(int c)     { return c & ~CAPACITY; }
+    private static int workerCountOf(int c)  { return c & CAPACITY; }
+    private static int ctlOf(int rs, int wc) { return rs | wc; }
+
+    /*
+     * Bit field accessors that don't require unpacking ctl.
+     * These depend on the bit layout and on workerCount being never negative.
+     */
+
+    private static boolean runStateLessThan(int c, int s) {
+        return c < s;
+    }
+
+    private static boolean runStateAtLeast(int c, int s) {
+        return c >= s;
+    }
+
+    private static boolean isRunning(int c) {
+        return c < SHUTDOWN;
+    }
 
     /**
-     * Permission for checking shutdown
+     * Attempt to CAS-increment the workerCount field of ctl.
      */
-    private static final RuntimePermission shutdownPerm =
-        new RuntimePermission("modifyThread");
+    private boolean compareAndIncrementWorkerCount(int expect) {
+        return ctl.compareAndSet(expect, expect + 1);
+    }
 
     /**
-     * Queue used for holding tasks and handing off to worker threads.
+     * Attempt to CAS-decrement the workerCount field of ctl.
+     */
+    private boolean compareAndDecrementWorkerCount(int expect) {
+        return ctl.compareAndSet(expect, expect - 1);
+    }
+
+    /**
+     * Decrements the workerCount field of ctl. This is called only on
+     * abrupt termination of a thread (see processWorkerExit). Other
+     * decrements are performed within getTask.
+     */
+    private void decrementWorkerCount() {
+        do {} while (! compareAndDecrementWorkerCount(ctl.get()));
+    }
+
+    /**
+     * The queue used for holding tasks and handing off to worker
+     * threads.  We do not require that workQueue.poll() returning
+     * null necessarily means that workQueue.isEmpty(), so rely
+     * solely on isEmpty to see if the queue is empty (which we must
+     * do for example when deciding whether to transition from
+     * SHUTDOWN to TIDYING).  This accommodates special-purpose
+     * queues such as DelayQueues for which poll() is allowed to
+     * return null even if it may later return non-null when delays
+     * expire.
      */
     private final BlockingQueue<Runnable> workQueue;
 
     /**
-     * Lock held on updates to poolSize, corePoolSize, maximumPoolSize, and
-     * workers set.
+     * Lock held on access to workers set and related bookkeeping.
+     * While we could use a concurrent set of some sort, it turns out
+     * to be generally preferable to use a lock. Among the reasons is
+     * that this serializes interruptIdleWorkers, which avoids
+     * unnecessary interrupt storms, especially during shutdown.
+     * Otherwise exiting threads would concurrently interrupt those
+     * that have not yet interrupted. It also simplifies some of the
+     * associated statistics bookkeeping of largestPoolSize etc. We
+     * also hold mainLock on shutdown and shutdownNow, for the sake of
+     * ensuring workers set is stable while separately checking
+     * permission to interrupt and actually interrupting.
      */
     private final ReentrantLock mainLock = new ReentrantLock();
 
     /**
+     * Set containing all worker threads in pool. Accessed only when
+     * holding mainLock.
+     */
+    private final HashSet<Worker> workers = new HashSet<Worker>();
+
+    /**
      * Wait condition to support awaitTermination
      */
     private final Condition termination = mainLock.newCondition();
 
     /**
-     * Set containing all worker threads in pool.
+     * Tracks largest attained pool size. Accessed only under
+     * mainLock.
      */
-    private final HashSet<Worker> workers = new HashSet<Worker>();
+    private int largestPoolSize;
 
     /**
-     * Timeout in nanoseconds for idle threads waiting for work.
-     * Threads use this timeout only when there are more than
-     * corePoolSize present. Otherwise they wait forever for new work.
+     * Counter for completed tasks. Updated only on termination of
+     * worker threads. Accessed only under mainLock.
      */
-    private volatile long  keepAliveTime;
+    private long completedTaskCount;
+
+    /*
+     * All user control parameters are declared as volatiles so that
+     * ongoing actions are based on freshest values, but without need
+     * for locking, since no internal invariants depend on them
+     * changing synchronously with respect to other actions.
+     */
 
     /**
-     * Core pool size, updated only while holding mainLock,
-     * but volatile to allow concurrent readability even
-     * during updates.
+     * Factory for new threads. All threads are created using this
+     * factory (via method addWorker).  All callers must be prepared
+     * for addWorker to fail, which may reflect a system or user's
+     * policy limiting the number of threads.  Even though it is not
+     * treated as an error, failure to create threads may result in
+     * new tasks being rejected or existing ones remaining stuck in
+     * the queue. On the other hand, no special precautions exist to
+     * handle OutOfMemoryErrors that might be thrown while trying to
+     * create threads, since there is generally no recourse from
+     * within this class.
      */
-    private volatile int   corePoolSize;
-
-    /**
-     * Maximum pool size, updated only while holding mainLock
-     * but volatile to allow concurrent readability even
-     * during updates.
-     */
-    private volatile int   maximumPoolSize;
-
-    /**
-     * Current pool size, updated only while holding mainLock
-     * but volatile to allow concurrent readability even
-     * during updates.
-     */
-    private volatile int   poolSize;
-
-    /**
-     * Lifecycle state
-     */
-    volatile int runState;
-
-    // Special values for runState
-    /** Normal, not-shutdown mode */
-    static final int RUNNING    = 0;
-    /** Controlled shutdown mode */
-    static final int SHUTDOWN   = 1;
-    /** Immediate shutdown mode */
-    static final int STOP       = 2;
-    /** Final state */
-    static final int TERMINATED = 3;
+    private volatile ThreadFactory threadFactory;
 
     /**
      * Handler called when saturated or shutdown in execute.
@@ -353,21 +471,24 @@
     private volatile RejectedExecutionHandler handler;
 
     /**
-     * Factory for new threads.
+     * Timeout in nanoseconds for idle threads waiting for work.
+     * Threads use this timeout when there are more than corePoolSize
+     * present. Otherwise they wait forever for new work.
      */
-    private volatile ThreadFactory threadFactory;
+    private volatile long keepAliveTime;
 
     /**
-     * Tracks largest attained pool size.
+     * Core pool size is the minimum number of workers to keep alive
+     * (and not allow to time out etc).
      */
-    private int largestPoolSize;
+    private volatile int corePoolSize;
 
     /**
-     * Counter for completed tasks. Updated only on termination of
-     * worker threads.
+     * Maximum pool size. Note that the actual maximum is internally
+     * bounded by CAPACITY.
      */
-    private long completedTaskCount;
-    
+    private volatile int maximumPoolSize;
+
     /**
      * The default rejected execution handler
      */
@@ -375,336 +496,622 @@
         new AbortPolicy();
 
     /**
-     * Invoke the rejected execution handler for the given command.
+     * Permission required for callers of shutdown and shutdownNow.
+     * We additionally require (see checkShutdownAccess) that callers
+     * have permission to actually interrupt threads in the worker set
+     * (as governed by Thread.interrupt, which relies on
+     * ThreadGroup.checkAccess, which in turn relies on
+     * SecurityManager.checkAccess). Shutdowns are attempted only if
+     * these checks pass.
+     *
+     * All actual invocations of Thread.interrupt (see
+     * interruptIdleWorkers and interruptWorkers) ignore
+     * SecurityExceptions, meaning that the attempted interrupts
+     * silently fail. In the case of shutdown, they should not fail
+     * unless the SecurityManager has inconsistent policies, sometimes
+     * allowing access to a thread and sometimes not. In such cases,
+     * failure to actually interrupt threads may disable or delay full
+     * termination. Other uses of interruptIdleWorkers are advisory,
+     * and failure to actually interrupt will merely delay response to
+     * configuration changes so is not handled exceptionally.
      */
-    void reject(Runnable command) {
+    private static final RuntimePermission shutdownPerm =
+        new RuntimePermission("modifyThread");
+
+    /**
+     * Class Worker mainly maintains interrupt control state for
+     * threads running tasks, along with other minor bookkeeping.
+     * This class opportunistically extends AbstractQueuedSynchronizer
+     * to simplify acquiring and releasing a lock surrounding each
+     * task execution.  This protects against interrupts that are
+     * intended to wake up a worker thread waiting for a task from
+     * instead interrupting a task being run.  We implement a simple
+     * non-reentrant mutual exclusion lock rather than use ReentrantLock
+     * because we do not want worker tasks to be able to reacquire the
+     * lock when they invoke pool control methods like setCorePoolSize.
+     */
+    private final class Worker
+        extends AbstractQueuedSynchronizer
+        implements Runnable
+    {
+        /**
+         * This class will never be serialized, but we provide a
+         * serialVersionUID to suppress a javac warning.
+         */
+        private static final long serialVersionUID = 6138294804551838833L;
+
+        /** Thread this worker is running in.  Null if factory fails. */
+        final Thread thread;
+        /** Initial task to run.  Possibly null. */
+        Runnable firstTask;
+        /** Per-thread task counter */
+        volatile long completedTasks;
+
+        /**
+         * Creates with given first task and thread from ThreadFactory.
+         * @param firstTask the first task (null if none)
+         */
+        Worker(Runnable firstTask) {
+            this.firstTask = firstTask;
+            this.thread = getThreadFactory().newThread(this);
+        }
+
+        /** Delegates main run loop to outer runWorker  */
+        public void run() {
+            runWorker(this);
+        }
+
+        // Lock methods
+        //
+        // The value 0 represents the unlocked state.
+        // The value 1 represents the locked state.
+
+        protected boolean isHeldExclusively() {
+            return getState() == 1;
+        }
+
+        protected boolean tryAcquire(int unused) {
+            if (compareAndSetState(0, 1)) {
+                setExclusiveOwnerThread(Thread.currentThread());
+                return true;
+            }
+            return false;
+        }
+
+        protected boolean tryRelease(int unused) {
+            setExclusiveOwnerThread(null);
+            setState(0);
+            return true;
+        }
+
+        public void lock()        { acquire(1); }
+        public boolean tryLock()  { return tryAcquire(1); }
+        public void unlock()      { release(1); }
+        public boolean isLocked() { return isHeldExclusively(); }
+    }
+
+    /*
+     * Methods for setting control state
+     */
+
+    /**
+     * Transitions runState to given target, or leaves it alone if
+     * already at least the given target.
+     *
+     * @param targetState the desired state, either SHUTDOWN or STOP
+     *        (but not TIDYING or TERMINATED -- use tryTerminate for that)
+     */
+    private void advanceRunState(int targetState) {
+        for (;;) {
+            int c = ctl.get();
+            if (runStateAtLeast(c, targetState) ||
+                ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
+                break;
+        }
+    }
+
+    /**
+     * Transitions to TERMINATED state if either (SHUTDOWN and pool
+     * and queue empty) or (STOP and pool empty).  If otherwise
+     * eligible to terminate but workerCount is nonzero, interrupts an
+     * idle worker to ensure that shutdown signals propagate. This
+     * method must be called following any action that might make
+     * termination possible -- reducing worker count or removing tasks
+     * from the queue during shutdown. The method is non-private to
+     * allow access from ScheduledThreadPoolExecutor.
+     */
+    final void tryTerminate() {
+        for (;;) {
+            int c = ctl.get();
+            if (isRunning(c) ||
+                runStateAtLeast(c, TIDYING) ||
+                (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
+                return;
+            if (workerCountOf(c) != 0) { // Eligible to terminate
+                interruptIdleWorkers(ONLY_ONE);
+                return;
+            }
+
+            final ReentrantLock mainLock = this.mainLock;
+            mainLock.lock();
+            try {
+                if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
+                    try {
+                        terminated();
+                    } finally {
+                        ctl.set(ctlOf(TERMINATED, 0));
+                        termination.signalAll();
+                    }
+                    return;
+                }
+            } finally {
+                mainLock.unlock();
+            }
+            // else retry on failed CAS
+        }
+    }
+
+    /*
+     * Methods for controlling interrupts to worker threads.
+     */
+
+    /**
+     * If there is a security manager, makes sure caller has
+     * permission to shut down threads in general (see shutdownPerm).
+     * If this passes, additionally makes sure the caller is allowed
+     * to interrupt each worker thread. This might not be true even if
+     * first check passed, if the SecurityManager treats some threads
+     * specially.
+     */
+    private void checkShutdownAccess() {
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkPermission(shutdownPerm);
+            final ReentrantLock mainLock = this.mainLock;
+            mainLock.lock();
+            try {
+                for (Worker w : workers)
+                    security.checkAccess(w.thread);
+            } finally {
+                mainLock.unlock();
+            }
+        }
+    }
+
+    /**
+     * Interrupts all threads, even if active. Ignores SecurityExceptions
+     * (in which case some threads may remain uninterrupted).
+     */
+    private void interruptWorkers() {
+        final ReentrantLock mainLock = this.mainLock;
+        mainLock.lock();
+        try {
+            for (Worker w : workers) {
+                try {
+                    w.thread.interrupt();
+                } catch (SecurityException ignore) {
+                }
+            }
+        } finally {
+            mainLock.unlock();
+        }
+    }
+
+    /**
+     * Interrupts threads that might be waiting for tasks (as
+     * indicated by not being locked) so they can check for
+     * termination or configuration changes. Ignores
+     * SecurityExceptions (in which case some threads may remain
+     * uninterrupted).
+     *
+     * @param onlyOne If true, interrupt at most one worker. This is
+     * called only from tryTerminate when termination is otherwise
+     * enabled but there are still other workers.  In this case, at
+     * most one waiting worker is interrupted to propagate shutdown
+     * signals in case all threads are currently waiting.
+     * Interrupting any arbitrary thread ensures that newly arriving
+     * workers since shutdown began will also eventually exit.
+     * To guarantee eventual termination, it suffices to always
+     * interrupt only one idle worker, but shutdown() interrupts all
+     * idle workers so that redundant workers exit promptly, not
+     * waiting for a straggler task to finish.
+     */
+    private void interruptIdleWorkers(boolean onlyOne) {
+        final ReentrantLock mainLock = this.mainLock;
+        mainLock.lock();
+        try {
+            for (Worker w : workers) {
+                Thread t = w.thread;
+                if (!t.isInterrupted() && w.tryLock()) {
+                    try {
+                        t.interrupt();
+                    } catch (SecurityException ignore) {
+                    } finally {
+                        w.unlock();
+                    }
+                }
+                if (onlyOne)
+                    break;
+            }
+        } finally {
+            mainLock.unlock();
+        }
+    }
+
+    /**
+     * Common form of interruptIdleWorkers, to avoid having to
+     * remember what the boolean argument means.
+     */
+    private void interruptIdleWorkers() {
+        interruptIdleWorkers(false);
+    }
+
+    private static final boolean ONLY_ONE = true;
+
+    /**
+     * Ensures that unless the pool is stopping, the current thread
+     * does not have its interrupt set. This requires a double-check
+     * of state in case the interrupt was cleared concurrently with a
+     * shutdownNow -- if so, the interrupt is re-enabled.
+     */
+    private void clearInterruptsForTaskRun() {
+        if (runStateLessThan(ctl.get(), STOP) &&
+            Thread.interrupted() &&
+            runStateAtLeast(ctl.get(), STOP))
+            Thread.currentThread().interrupt();
+    }
+
+    /*
+     * Misc utilities, most of which are also exported to
+     * ScheduledThreadPoolExecutor
+     */
+
+    /**
+     * Invokes the rejected execution handler for the given command.
+     * Package-protected for use by ScheduledThreadPoolExecutor.
+     */
+    final void reject(Runnable command) {
         handler.rejectedExecution(command, this);
     }
 
     /**
-     * Create and return a new thread running firstTask as its first
-     * task. Call only while holding mainLock
-     * @param firstTask the task the new thread should run first (or
-     * null if none)
-     * @return the new thread
+     * Performs any further cleanup following run state transition on
+     * invocation of shutdown.  A no-op here, but used by
+     * ScheduledThreadPoolExecutor to cancel delayed tasks.
      */
-    private Thread addThread(Runnable firstTask) {
-        Worker w = new Worker(firstTask);
-        Thread t = threadFactory.newThread(w);
-        w.thread = t;
-        workers.add(w);
-        int nt = ++poolSize;
-        if (nt > largestPoolSize)
-            largestPoolSize = nt;
-        return t;
+    void onShutdown() {
     }
 
     /**
-     * Create and start a new thread running firstTask as its first
-     * task, only if fewer than corePoolSize threads are running.
-     * @param firstTask the task the new thread should run first (or
-     * null if none)
-     * @return true if successful.
+     * State check needed by ScheduledThreadPoolExecutor to
+     * enable running tasks during shutdown.
+     *
+     * @param shutdownOK true if should return true if SHUTDOWN
      */
-    private boolean addIfUnderCorePoolSize(Runnable firstTask) {
-        Thread t = null;
+    final boolean isRunningOrShutdown(boolean shutdownOK) {
+        int rs = runStateOf(ctl.get());
+        return rs == RUNNING || (rs == SHUTDOWN && shutdownOK);
+    }
+
+    /**
+     * Drains the task queue into a new list, normally using
+     * drainTo. But if the queue is a DelayQueue or any other kind of
+     * queue for which poll or drainTo may fail to remove some
+     * elements, it deletes them one by one.
+     */
+    private List<Runnable> drainQueue() {
+        BlockingQueue<Runnable> q = workQueue;
+        List<Runnable> taskList = new ArrayList<Runnable>();
+        q.drainTo(taskList);
+        if (!q.isEmpty()) {
+            for (Runnable r : q.toArray(new Runnable[0])) {
+                if (q.remove(r))
+                    taskList.add(r);
+            }
+        }
+        return taskList;
+    }
+
+    /*
+     * Methods for creating, running and cleaning up after workers
+     */
+
+    /**
+     * Checks if a new worker can be added with respect to current
+     * pool state and the given bound (either core or maximum). If so,
+     * the worker count is adjusted accordingly, and, if possible, a
+     * new worker is created and started running firstTask as its
+     * first task. This method returns false if the pool is stopped or
+     * eligible to shut down. It also returns false if the thread
+     * factory fails to create a thread when asked, which requires a
+     * backout of workerCount, and a recheck for termination, in case
+     * the existence of this worker was holding up termination.
+     *
+     * @param firstTask the task the new thread should run first (or
+     * null if none). Workers are created with an initial first task
+     * (in method execute()) to bypass queuing when there are fewer
+     * than corePoolSize threads (in which case we always start one),
+     * or when the queue is full (in which case we must bypass queue).
+     * Initially idle threads are usually created via
+     * prestartCoreThread or to replace other dying workers.
+     *
+     * @param core if true use corePoolSize as bound, else
+     * maximumPoolSize. (A boolean indicator is used here rather than a
+     * value to ensure reads of fresh values after checking other pool
+     * state).
+     * @return true if successful
+     */
+    private boolean addWorker(Runnable firstTask, boolean core) {
+        retry:
+        for (;;) {
+            int c = ctl.get();
+            int rs = runStateOf(c);
+
+            // Check if queue empty only if necessary.
+            if (rs >= SHUTDOWN &&
+                ! (rs == SHUTDOWN &&
+                   firstTask == null &&
+                   ! workQueue.isEmpty()))
+                return false;
+
+            for (;;) {
+                int wc = workerCountOf(c);
+                if (wc >= CAPACITY ||
+                    wc >= (core ? corePoolSize : maximumPoolSize))
+                    return false;
+                if (compareAndIncrementWorkerCount(c))
+                    break retry;
+                c = ctl.get();  // Re-read ctl
+                if (runStateOf(c) != rs)
+                    continue retry;
+                // else CAS failed due to workerCount change; retry inner loop
+            }
+        }
+
+        Worker w = new Worker(firstTask);
+        Thread t = w.thread;
+
         final ReentrantLock mainLock = this.mainLock;
         mainLock.lock();
         try {
-            if (poolSize < corePoolSize)
-                t = addThread(firstTask);
+            // Recheck while holding lock.
+            // Back out on ThreadFactory failure or if
+            // shut down before lock acquired.
+            int c = ctl.get();
+            int rs = runStateOf(c);
+
+            if (t == null ||
+                (rs >= SHUTDOWN &&
+                 ! (rs == SHUTDOWN &&
+                    firstTask == null))) {
+                decrementWorkerCount();
+                tryTerminate();
+                return false;
+            }
+
+            workers.add(w);
+
+            int s = workers.size();
+            if (s > largestPoolSize)
+                largestPoolSize = s;
         } finally {
             mainLock.unlock();
         }
-        if (t == null)
-            return false;
+
         t.start();
+        // It is possible (but unlikely) for a thread to have been
+        // added to workers, but not yet started, during transition to
+        // STOP, which could result in a rare missed interrupt,
+        // because Thread.interrupt is not guaranteed to have any effect
+        // on a non-yet-started Thread (see Thread#interrupt).
+        if (runStateOf(ctl.get()) == STOP && ! t.isInterrupted())
+            t.interrupt();
+
         return true;
     }
 
     /**
-     * Create and start a new thread only if fewer than maximumPoolSize
-     * threads are running.  The new thread runs as its first task the
-     * next task in queue, or if there is none, the given task.
-     * @param firstTask the task the new thread should run first (or
-     * null if none)
-     * @return null on failure, else the first task to be run by new thread.
-     */
-    private Runnable addIfUnderMaximumPoolSize(Runnable firstTask) {
-        Thread t = null;
-        Runnable next = null;
-        final ReentrantLock mainLock = this.mainLock;
-        mainLock.lock();
-        try {
-            if (poolSize < maximumPoolSize) {
-                next = workQueue.poll();
-                if (next == null)
-                    next = firstTask;
-                t = addThread(next);
-            }
-        } finally {
-            mainLock.unlock();
-        }
-        if (t == null)
-            return null;
-        t.start();
-        return next;
-    }
-
-
-    /**
-     * Get the next task for a worker thread to run.
-     * @return the task
-     * @throws InterruptedException if interrupted while waiting for task
-     */
-    Runnable getTask() throws InterruptedException {
-        for (;;) {
-            switch(runState) {
-            case RUNNING: {
-                if (poolSize <= corePoolSize)   // untimed wait if core
-                    return workQueue.take();
-                
-                long timeout = keepAliveTime;
-                if (timeout <= 0) // die immediately for 0 timeout
-                    return null;
-                Runnable r =  workQueue.poll(timeout, TimeUnit.NANOSECONDS);
-                if (r != null)
-                    return r;
-                if (poolSize > corePoolSize) // timed out
-                    return null;
-                // else, after timeout, pool shrank so shouldn't die, so retry
-                break;
-            }
-
-            case SHUTDOWN: {
-                // Help drain queue 
-                Runnable r = workQueue.poll();
-                if (r != null)
-                    return r;
-                    
-                // Check if can terminate
-                if (workQueue.isEmpty()) {
-                    interruptIdleWorkers();
-                    return null;
-                }
-
-                // There could still be delayed tasks in queue.
-                // Wait for one, re-checking state upon interruption
-                try {
-                    return workQueue.take();
-                } catch(InterruptedException ignore) {}
-                break;
-            }
-
-            case STOP:
-                return null;
-            default:
-                assert false; 
-            }
-        }
-    }
-
-    /**
-     * Wake up all threads that might be waiting for tasks.
-     */
-    void interruptIdleWorkers() {
-        final ReentrantLock mainLock = this.mainLock;
-        mainLock.lock();
-        try {
-            for (Worker w : workers)
-                w.interruptIfIdle();
-        } finally {
-            mainLock.unlock();
-        }
-    }
-
-    /**
-     * Perform bookkeeping for a terminated worker thread.
+     * Performs cleanup and bookkeeping for a dying worker. Called
+     * only from worker threads. Unless completedAbruptly is set,
+     * assumes that workerCount has already been adjusted to account
+     * for exit.  This method removes thread from worker set, and
+     * possibly terminates the pool or replaces the worker if either
+     * it exited due to user task exception or if fewer than
+     * corePoolSize workers are running or queue is non-empty but
+     * there are no workers.
+     *
      * @param w the worker
+     * @param completedAbruptly if the worker died due to user exception
      */
-    void workerDone(Worker w) {
+    private void processWorkerExit(Worker w, boolean completedAbruptly) {
+        if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
+            decrementWorkerCount();
+
         final ReentrantLock mainLock = this.mainLock;
         mainLock.lock();
         try {
             completedTaskCount += w.completedTasks;
             workers.remove(w);
-            if (--poolSize > 0)
-                return;
-
-            // Else, this is the last thread. Deal with potential shutdown.
-
-            int state = runState;
-            assert state != TERMINATED;
-
-            if (state != STOP) {
-                // If there are queued tasks but no threads, create
-                // replacement.
-                Runnable r = workQueue.poll();
-                if (r != null) {
-                    addThread(r).start();
-                    return;
-                }
-
-                // If there are some (presumably delayed) tasks but
-                // none pollable, create an idle replacement to wait.
-                if (!workQueue.isEmpty()) { 
-                    addThread(null).start();
-                    return;
-                }
-
-                // Otherwise, we can exit without replacement
-                if (state == RUNNING)
-                    return;
-            }
-
-            // Either state is STOP, or state is SHUTDOWN and there is
-            // no work to do. So we can terminate.
-            termination.signalAll();
-            runState = TERMINATED;
-            // fall through to call terminate() outside of lock.
         } finally {
             mainLock.unlock();
         }
 
-        assert runState == TERMINATED;
-        terminated(); 
+        tryTerminate();
+
+        int c = ctl.get();
+        if (runStateLessThan(c, STOP)) {
+            if (!completedAbruptly) {
+                int min = corePoolSize;
+                if (min == 0 && ! workQueue.isEmpty())
+                    min = 1;
+                if (workerCountOf(c) >= min)
+                    return; // replacement not needed
+            }
+            addWorker(null, false);
+        }
     }
 
     /**
-     *  Worker threads
-     */
-    private class Worker implements Runnable {
-
-        /**
-         * The runLock is acquired and released surrounding each task
-         * execution. It mainly protects against interrupts that are
-         * intended to cancel the worker thread from instead
-         * interrupting the task being run.
-         */
-        private final ReentrantLock runLock = new ReentrantLock();
-
-        /**
-         * Initial task to run before entering run loop
-         */
-        private Runnable firstTask;
-
-        /**
-         * Per thread completed task counter; accumulated
-         * into completedTaskCount upon termination.
-         */
-        volatile long completedTasks;
-
-        /**
-         * Thread this worker is running in.  Acts as a final field,
-         * but cannot be set until thread is created.
-         */
-        Thread thread;
-
-        Worker(Runnable firstTask) {
-            this.firstTask = firstTask;
-        }
-
-        boolean isActive() {
-            return runLock.isLocked();
-        }
-
-        /**
-         * Interrupt thread if not running a task
-         */
-        void interruptIfIdle() {
-            final ReentrantLock runLock = this.runLock;
-            if (runLock.tryLock()) {
-                try {
-                    thread.interrupt();
-                } finally {
-                    runLock.unlock();
-                }
-            }
-        }
-
-        /**
-         * Cause thread to die even if running a task.
-         */
-        void interruptNow() {
-            thread.interrupt();
-        }
-
-        /**
-         * Run a single task between before/after methods.
-         */
-        private void runTask(Runnable task) {
-            final ReentrantLock runLock = this.runLock;
-            runLock.lock();
-            try {
-                // Abort now if immediate cancel.  Otherwise, we have
-                // committed to run this task.
-                if (runState == STOP)
-                    return;
-
-                Thread.interrupted(); // clear interrupt status on entry
-                boolean ran = false;
-                beforeExecute(thread, task);
-                try {
-                    task.run();
-                    ran = true;
-                    afterExecute(task, null);
-                    ++completedTasks;
-                } catch(RuntimeException ex) {
-                    if (!ran)
-                        afterExecute(task, ex);
-                    // Else the exception occurred within
-                    // afterExecute itself in which case we don't
-                    // want to call it again.
-                    throw ex;
-                }
-            } finally {
-                runLock.unlock();
-            }
-        }
-
-        /**
-         * Main run loop
-         */
-        public void run() {
-            try {
-                Runnable task = firstTask;
-                firstTask = null;
-                while (task != null || (task = getTask()) != null) {
-                    runTask(task);
-                    task = null; // unnecessary but can help GC
-                }
-            } catch(InterruptedException ie) {
-                // fall through
-            } finally {
-                workerDone(this);
-            }
-        }
-    }
-
-    // Public methods
-
-    /**
-     * Creates a new <tt>ThreadPoolExecutor</tt> with the given
-     * initial parameters and default thread factory and handler.  It
-     * may be more convenient to use one of the {@link Executors}
-     * factory methods instead of this general purpose constructor.
+     * Performs blocking or timed wait for a task, depending on
+     * current configuration settings, or returns null if this worker
+     * must exit because of any of:
+     * 1. There are more than maximumPoolSize workers (due to
+     *    a call to setMaximumPoolSize).
+     * 2. The pool is stopped.
+     * 3. The pool is shutdown and the queue is empty.
+     * 4. This worker timed out waiting for a task, and timed-out
+     *    workers are subject to termination (that is,
+     *    {@code workerCount > corePoolSize})
+     *    both before and after the timed wait.
      *
-     * @param corePoolSize the number of threads to keep in the
-     * pool, even if they are idle.
+     * @return task, or null if the worker must exit, in which case
+     *         workerCount is decremented
+     */
+    private Runnable getTask() {
+        boolean timedOut = false; // Did the last poll() time out?
+
+        retry:
+        for (;;) {
+            int c = ctl.get();
+            int rs = runStateOf(c);
+
+            // Check if queue empty only if necessary.
+            if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
+                decrementWorkerCount();
+                return null;
+            }
+
+            boolean timed;      // Are workers subject to culling?
+
+            for (;;) {
+                int wc = workerCountOf(c);
+                timed = wc > corePoolSize;
+
+                if (wc <= maximumPoolSize && ! (timedOut && timed))
+                    break;
+                if (compareAndDecrementWorkerCount(c))
+                    return null;
+                c = ctl.get();  // Re-read ctl
+                if (runStateOf(c) != rs)
+                    continue retry;
+                // else CAS failed due to workerCount change; retry inner loop
+            }
+
+            try {
+                Runnable r = timed ?
+                    workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
+                    workQueue.take();
+                if (r != null)
+                    return r;
+                timedOut = true;
+            } catch (InterruptedException retry) {
+                timedOut = false;
+            }
+        }
+    }
+
+    /**
+     * Main worker run loop.  Repeatedly gets tasks from queue and
+     * executes them, while coping with a number of issues:
+     *
+     * 1. We may start out with an initial task, in which case we
+     * don't need to get the first one. Otherwise, as long as pool is
+     * running, we get tasks from getTask. If it returns null then the
+     * worker exits due to changed pool state or configuration
+     * parameters.  Other exits result from exception throws in
+     * external code, in which case completedAbruptly holds, which
+     * usually leads processWorkerExit to replace this thread.
+     *
+     * 2. Before running any task, the lock is acquired to prevent
+     * other pool interrupts while the task is executing, and
+     * clearInterruptsForTaskRun called to ensure that unless pool is
+     * stopping, this thread does not have its interrupt set.
+     *
+     * 3. Each task run is preceded by a call to beforeExecute, which
+     * might throw an exception, in which case we cause thread to die
+     * (breaking loop with completedAbruptly true) without processing
+     * the task.
+     *
+     * 4. Assuming beforeExecute completes normally, we run the task,
+     * gathering any of its thrown exceptions to send to
+     * afterExecute. We separately handle RuntimeException, Error
+     * (both of which the specs guarantee that we trap) and arbitrary
+     * Throwables.  Because we cannot rethrow Throwables within
+     * Runnable.run, we wrap them within Errors on the way out (to the
+     * thread's UncaughtExceptionHandler).  Any thrown exception also
+     * conservatively causes thread to die.
+     *
+     * 5. After task.run completes, we call afterExecute, which may
+     * also throw an exception, which will also cause thread to
+     * die. According to JLS Sec 14.20, this exception is the one that
+     * will be in effect even if task.run throws.
+     *
+     * The net effect of the exception mechanics is that afterExecute
+     * and the thread's UncaughtExceptionHandler have as accurate
+     * information as we can provide about any problems encountered by
+     * user code.
+     *
+     * @param w the worker
+     */
+    final void runWorker(Worker w) {
+        Runnable task = w.firstTask;
+        w.firstTask = null;
+        boolean completedAbruptly = true;
+        try {
+            while (task != null || (task = getTask()) != null) {
+                w.lock();
+                clearInterruptsForTaskRun();
+                try {
+                    beforeExecute(w.thread, task);
+                    Throwable thrown = null;
+                    try {
+                        task.run();
+                    } catch (RuntimeException x) {
+                        thrown = x; throw x;
+                    } catch (Error x) {
+                        thrown = x; throw x;
+                    } catch (Throwable x) {
+                        thrown = x; throw new Error(x);
+                    } finally {
+                        afterExecute(task, thrown);
+                    }
+                } finally {
+                    task = null;
+                    w.completedTasks++;
+                    w.unlock();
+                }
+            }
+            completedAbruptly = false;
+        } finally {
+            processWorkerExit(w, completedAbruptly);
+        }
+    }
+
+    // Public constructors and methods
+
+    /**
+     * Creates a new {@code ThreadPoolExecutor} with the given initial
+     * parameters and default thread factory and rejected execution handler.
+     * It may be more convenient to use one of the {@link Executors} factory
+     * methods instead of this general purpose constructor.
+     *
+     * @param corePoolSize the number of threads to keep in the pool, even
+     *        if they are idle
      * @param maximumPoolSize the maximum number of threads to allow in the
-     * pool.
+     *        pool
      * @param keepAliveTime when the number of threads is greater than
-     * the core, this is the maximum time that excess idle threads
-     * will wait for new tasks before terminating.
-     * @param unit the time unit for the keepAliveTime
-     * argument.
-     * @param workQueue the queue to use for holding tasks before they
-     * are executed. This queue will hold only the <tt>Runnable</tt>
-     * tasks submitted by the <tt>execute</tt> method.
-     * @throws IllegalArgumentException if corePoolSize, or
-     * keepAliveTime less than zero, or if maximumPoolSize less than or
-     * equal to zero, or if corePoolSize greater than maximumPoolSize.
-     * @throws NullPointerException if <tt>workQueue</tt> is null
+     *        the core, this is the maximum time that excess idle threads
+     *        will wait for new tasks before terminating.
+     * @param unit the time unit for the {@code keepAliveTime} argument
+     * @param workQueue the queue to use for holding tasks before they are
+     *        executed.  This queue will hold only the {@code Runnable}
+     *        tasks submitted by the {@code execute} method.
+     * @throws IllegalArgumentException if one of the following holds:<br>
+     *         {@code corePoolSize < 0}<br>
+     *         {@code keepAliveTime < 0}<br>
+     *         {@code maximumPoolSize <= 0}<br>
+     *         {@code maximumPoolSize < corePoolSize}
+     * @throws NullPointerException if {@code workQueue} is null
      */
     public ThreadPoolExecutor(int corePoolSize,
                               int maximumPoolSize,
@@ -716,28 +1123,29 @@
     }
 
     /**
-     * Creates a new <tt>ThreadPoolExecutor</tt> with the given initial
-     * parameters.
+     * Creates a new {@code ThreadPoolExecutor} with the given initial
+     * parameters and default rejected execution handler.
      *
-     * @param corePoolSize the number of threads to keep in the
-     * pool, even if they are idle.
+     * @param corePoolSize the number of threads to keep in the pool, even
+     *        if they are idle
      * @param maximumPoolSize the maximum number of threads to allow in the
-     * pool.
+     *        pool
      * @param keepAliveTime when the number of threads is greater than
-     * the core, this is the maximum time that excess idle threads
-     * will wait for new tasks before terminating.
-     * @param unit the time unit for the keepAliveTime
-     * argument.
-     * @param workQueue the queue to use for holding tasks before they
-     * are executed. This queue will hold only the <tt>Runnable</tt>
-     * tasks submitted by the <tt>execute</tt> method.
+     *        the core, this is the maximum time that excess idle threads
+     *        will wait for new tasks before terminating.
+     * @param unit the time unit for the {@code keepAliveTime} argument
+     * @param workQueue the queue to use for holding tasks before they are
+     *        executed.  This queue will hold only the {@code Runnable}
+     *        tasks submitted by the {@code execute} method.
      * @param threadFactory the factory to use when the executor
-     * creates a new thread.
-     * @throws IllegalArgumentException if corePoolSize, or
-     * keepAliveTime less than zero, or if maximumPoolSize less than or
-     * equal to zero, or if corePoolSize greater than maximumPoolSize.
-     * @throws NullPointerException if <tt>workQueue</tt>
-     * or <tt>threadFactory</tt> are null.
+     *        creates a new thread
+     * @throws IllegalArgumentException if one of the following holds:<br>
+     *         {@code corePoolSize < 0}<br>
+     *         {@code keepAliveTime < 0}<br>
+     *         {@code maximumPoolSize <= 0}<br>
+     *         {@code maximumPoolSize < corePoolSize}
+     * @throws NullPointerException if {@code workQueue}
+     *         or {@code threadFactory} is null
      */
     public ThreadPoolExecutor(int corePoolSize,
                               int maximumPoolSize,
@@ -750,28 +1158,29 @@
     }
 
     /**
-     * Creates a new <tt>ThreadPoolExecutor</tt> with the given initial
-     * parameters.
+     * Creates a new {@code ThreadPoolExecutor} with the given initial
+     * parameters and default thread factory.
      *
-     * @param corePoolSize the number of threads to keep in the
-     * pool, even if they are idle.
+     * @param corePoolSize the number of threads to keep in the pool, even
+     *        if they are idle
      * @param maximumPoolSize the maximum number of threads to allow in the
-     * pool.
+     *        pool
      * @param keepAliveTime when the number of threads is greater than
-     * the core, this is the maximum time that excess idle threads
-     * will wait for new tasks before terminating.
-     * @param unit the time unit for the keepAliveTime
-     * argument.
-     * @param workQueue the queue to use for holding tasks before they
-     * are executed. This queue will hold only the <tt>Runnable</tt>
-     * tasks submitted by the <tt>execute</tt> method.
+     *        the core, this is the maximum time that excess idle threads
+     *        will wait for new tasks before terminating.
+     * @param unit the time unit for the {@code keepAliveTime} argument
+     * @param workQueue the queue to use for holding tasks before they are
+     *        executed.  This queue will hold only the {@code Runnable}
+     *        tasks submitted by the {@code execute} method.
      * @param handler the handler to use when execution is blocked
-     * because the thread bounds and queue capacities are reached.
-     * @throws IllegalArgumentException if corePoolSize, or
-     * keepAliveTime less than zero, or if maximumPoolSize less than or
-     * equal to zero, or if corePoolSize greater than maximumPoolSize.
-     * @throws NullPointerException if <tt>workQueue</tt>
-     * or  <tt>handler</tt> are null.
+     *        because the thread bounds and queue capacities are reached
+     * @throws IllegalArgumentException if one of the following holds:<br>
+     *         {@code corePoolSize < 0}<br>
+     *         {@code keepAliveTime < 0}<br>
+     *         {@code maximumPoolSize <= 0}<br>
+     *         {@code maximumPoolSize < corePoolSize}
+     * @throws NullPointerException if {@code workQueue}
+     *         or {@code handler} is null
      */
     public ThreadPoolExecutor(int corePoolSize,
                               int maximumPoolSize,
@@ -784,30 +1193,31 @@
     }
 
     /**
-     * Creates a new <tt>ThreadPoolExecutor</tt> with the given initial
+     * Creates a new {@code ThreadPoolExecutor} with the given initial
      * parameters.
      *
-     * @param corePoolSize the number of threads to keep in the
-     * pool, even if they are idle.
+     * @param corePoolSize the number of threads to keep in the pool, even
+     *        if they are idle
      * @param maximumPoolSize the maximum number of threads to allow in the
-     * pool.
+     *        pool
      * @param keepAliveTime when the number of threads is greater than
-     * the core, this is the maximum time that excess idle threads
-     * will wait for new tasks before terminating.
-     * @param unit the time unit for the keepAliveTime
-     * argument.
-     * @param workQueue the queue to use for holding tasks before they
-     * are executed. This queue will hold only the <tt>Runnable</tt>
-     * tasks submitted by the <tt>execute</tt> method.
+     *        the core, this is the maximum time that excess idle threads
+     *        will wait for new tasks before terminating.
+     * @param unit the time unit for the {@code keepAliveTime} argument
+     * @param workQueue the queue to use for holding tasks before they are
+     *        executed.  This queue will hold only the {@code Runnable}
+     *        tasks submitted by the {@code execute} method.
      * @param threadFactory the factory to use when the executor
-     * creates a new thread.
+     *        creates a new thread
      * @param handler the handler to use when execution is blocked
-     * because the thread bounds and queue capacities are reached.
-     * @throws IllegalArgumentException if corePoolSize, or
-     * keepAliveTime less than zero, or if maximumPoolSize less than or
-     * equal to zero, or if corePoolSize greater than maximumPoolSize.
-     * @throws NullPointerException if <tt>workQueue</tt>
-     * or <tt>threadFactory</tt> or <tt>handler</tt> are null.
+     *        because the thread bounds and queue capacities are reached
+     * @throws IllegalArgumentException if one of the following holds:<br>
+     *         {@code corePoolSize < 0}<br>
+     *         {@code keepAliveTime < 0}<br>
+     *         {@code maximumPoolSize <= 0}<br>
+     *         {@code maximumPoolSize < corePoolSize}
+     * @throws NullPointerException if {@code workQueue}
+     *         or {@code threadFactory} or {@code handler} is null
      */
     public ThreadPoolExecutor(int corePoolSize,
                               int maximumPoolSize,
@@ -831,181 +1241,140 @@
         this.handler = handler;
     }
 
-
     /**
      * Executes the given task sometime in the future.  The task
      * may execute in a new thread or in an existing pooled thread.
      *
      * If the task cannot be submitted for execution, either because this
      * executor has been shutdown or because its capacity has been reached,
-     * the task is handled by the current <tt>RejectedExecutionHandler</tt>.
+     * the task is handled by the current {@code RejectedExecutionHandler}.
      *
      * @param command the task to execute
      * @throws RejectedExecutionException at discretion of
-     * <tt>RejectedExecutionHandler</tt>, if task cannot be accepted
-     * for execution
-     * @throws NullPointerException if command is null
+     *         {@code RejectedExecutionHandler}, if the task
+     *         cannot be accepted for execution
+     * @throws NullPointerException if {@code command} is null
      */
     public void execute(Runnable command) {
         if (command == null)
             throw new NullPointerException();
-        for (;;) {
-            if (runState != RUNNING) {
-                reject(command);
+        /*
+         * Proceed in 3 steps:
+         *
+         * 1. If fewer than corePoolSize threads are running, try to
+         * start a new thread with the given command as its first
+         * task.  The call to addWorker atomically checks runState and
+         * workerCount, and so prevents false alarms that would add
+         * threads when it shouldn't, by returning false.
+         *
+         * 2. If a task can be successfully queued, then we still need
+         * to double-check whether we should have added a thread
+         * (because existing ones died since last checking) or that
+         * the pool shut down since entry into this method. So we
+         * recheck state and if necessary roll back the enqueuing if
+         * stopped, or start a new thread if there are none.
+         *
+         * 3. If we cannot queue task, then we try to add a new
+         * thread.  If it fails, we know we are shut down or saturated
+         * and so reject the task.
+         */
+        int c = ctl.get();
+        if (workerCountOf(c) < corePoolSize) {
+            if (addWorker(command, true))
                 return;
-            }
-            if (poolSize < corePoolSize && addIfUnderCorePoolSize(command))
-                return;
-            if (workQueue.offer(command))
-                return;
-            Runnable r = addIfUnderMaximumPoolSize(command);
-            if (r == command)
-                return;
-            if (r == null) {
-                reject(command);
-                return;
-            }
-            // else retry
+            c = ctl.get();
         }
+        if (isRunning(c) && workQueue.offer(command)) {
+            int recheck = ctl.get();
+            if (! isRunning(recheck) && remove(command))
+                reject(command);
+            else if (workerCountOf(recheck) == 0)
+                addWorker(null, false);
+        }
+        else if (!addWorker(command, false))
+            reject(command);
     }
 
     /**
      * Initiates an orderly shutdown in which previously submitted
-     * tasks are executed, but no new tasks will be
-     * accepted. Invocation has no additional effect if already shut
-     * down.
-     * @throws SecurityException if a security manager exists and
-     * shutting down this ExecutorService may manipulate threads that
-     * the caller is not permitted to modify because it does not hold
-     * {@link java.lang.RuntimePermission}<tt>("modifyThread")</tt>,
-     * or the security manager's <tt>checkAccess</tt>  method denies access.
+     * tasks are executed, but no new tasks will be accepted.
+     * Invocation has no additional effect if already shut down.
+     *
+     * <p>This method does not wait for previously submitted tasks to
+     * complete execution.  Use {@link #awaitTermination awaitTermination}
+     * to do that.
+     *
+     * @throws SecurityException {@inheritDoc}
      */
     public void shutdown() {
-        // Fail if caller doesn't have modifyThread permission
-        SecurityManager security = System.getSecurityManager();
-        if (security != null) 
-            java.security.AccessController.checkPermission(shutdownPerm);
-
-        boolean fullyTerminated = false;
         final ReentrantLock mainLock = this.mainLock;
         mainLock.lock();
         try {
-            if (workers.size() > 0) {
-                // Check if caller can modify worker threads.  This
-                // might not be true even if passed above check, if
-                // the SecurityManager treats some threads specially.
-                if (security != null) {
-                    for (Worker w: workers)
-                        security.checkAccess(w.thread);
-                }
-
-                int state = runState;
-                if (state == RUNNING) // don't override shutdownNow
-                    runState = SHUTDOWN;
-
-                try {
-                    for (Worker w: workers)
-                        w.interruptIfIdle();
-                } catch(SecurityException se) {
-                    // If SecurityManager allows above checks, but
-                    // then unexpectedly throws exception when
-                    // interrupting threads (which it ought not do),
-                    // back out as cleanly as we can. Some threads may
-                    // have been killed but we remain in non-shutdown
-                    // state.
-                    runState = state; 
-                    throw se;
-                }
-            }
-            else { // If no workers, trigger full termination now
-                fullyTerminated = true;
-                runState = TERMINATED;
-                termination.signalAll();
-            }
+            checkShutdownAccess();
+            advanceRunState(SHUTDOWN);
+            interruptIdleWorkers();
+            onShutdown(); // hook for ScheduledThreadPoolExecutor
         } finally {
             mainLock.unlock();
         }
-        if (fullyTerminated)
-            terminated();
+        tryTerminate();
     }
 
-
     /**
      * Attempts to stop all actively executing tasks, halts the
-     * processing of waiting tasks, and returns a list of the tasks that were
-     * awaiting execution. 
-     *  
-     * <p>This implementation cancels tasks via {@link
-     * Thread#interrupt}, so if any tasks mask or fail to respond to
-     * interrupts, they may never terminate.
+     * processing of waiting tasks, and returns a list of the tasks
+     * that were awaiting execution. These tasks are drained (removed)
+     * from the task queue upon return from this method.
      *
-     * @return list of tasks that never commenced execution
-     * @throws SecurityException if a security manager exists and
-     * shutting down this ExecutorService may manipulate threads that
-     * the caller is not permitted to modify because it does not hold
-     * {@link java.lang.RuntimePermission}<tt>("modifyThread")</tt>,
-     * or the security manager's <tt>checkAccess</tt> method denies access.
+     * <p>This method does not wait for actively executing tasks to
+     * terminate.  Use {@link #awaitTermination awaitTermination} to
+     * do that.
+     *
+     * <p>There are no guarantees beyond best-effort attempts to stop
+     * processing actively executing tasks.  This implementation
+     * cancels tasks via {@link Thread#interrupt}, so any task that
+     * fails to respond to interrupts may never terminate.
+     *
+     * @throws SecurityException {@inheritDoc}
      */
     public List<Runnable> shutdownNow() {
-        // Almost the same code as shutdown()
-        SecurityManager security = System.getSecurityManager();
-        if (security != null) 
-            java.security.AccessController.checkPermission(shutdownPerm);
-
-        boolean fullyTerminated = false;
+        List<Runnable> tasks;
         final ReentrantLock mainLock = this.mainLock;
         mainLock.lock();
         try {
-            if (workers.size() > 0) {
-                if (security != null) {
-                    for (Worker w: workers)
-                        security.checkAccess(w.thread);
-                }
-
-                int state = runState;
-                if (state != TERMINATED)
-                    runState = STOP;
-                try {
-                    for (Worker w : workers)
-                        w.interruptNow();
-                } catch(SecurityException se) {
-                    runState = state; // back out;
-                    throw se;
-                }
-            }
-            else { // If no workers, trigger full termination now
-                fullyTerminated = true;
-                runState = TERMINATED;
-                termination.signalAll();
-            }
+            checkShutdownAccess();
+            advanceRunState(STOP);
+            interruptWorkers();
+            tasks = drainQueue();
         } finally {
             mainLock.unlock();
         }
-        if (fullyTerminated)
-            terminated();
-        return Arrays.asList(workQueue.toArray(EMPTY_RUNNABLE_ARRAY));
+        tryTerminate();
+        return tasks;
     }
 
     public boolean isShutdown() {
-        return runState != RUNNING;
+        return ! isRunning(ctl.get());
     }
 
-    /** 
+    /**
      * Returns true if this executor is in the process of terminating
-     * after <tt>shutdown</tt> or <tt>shutdownNow</tt> but has not
+     * after {@link #shutdown} or {@link #shutdownNow} but has not
      * completely terminated.  This method may be useful for
-     * debugging. A return of <tt>true</tt> reported a sufficient
+     * debugging. A return of {@code true} reported a sufficient
      * period after shutdown may indicate that submitted tasks have
      * ignored or suppressed interruption, causing this executor not
      * to properly terminate.
-     * @return true if terminating but not yet terminated.
+     *
+     * @return true if terminating but not yet terminated
      */
     public boolean isTerminating() {
-        return runState == STOP;
+        int c = ctl.get();
+        return ! isRunning(c) && runStateLessThan(c, TERMINATED);
     }
 
     public boolean isTerminated() {
-        return runState == TERMINATED;
+        return runStateAtLeast(ctl.get(), TERMINATED);
     }
 
     public boolean awaitTermination(long timeout, TimeUnit unit)
@@ -1015,7 +1384,7 @@
         mainLock.lock();
         try {
             for (;;) {
-                if (runState == TERMINATED) 
+                if (runStateAtLeast(ctl.get(), TERMINATED))
                     return true;
                 if (nanos <= 0)
                     return false;
@@ -1027,10 +1396,10 @@
     }
 
     /**
-     * Invokes <tt>shutdown</tt> when this executor is no longer
-     * referenced.
-     */ 
-    protected void finalize()  {
+     * Invokes {@code shutdown} when this executor is no longer
+     * referenced and it has no threads.
+     */
+    protected void finalize() {
         shutdown();
     }
 
@@ -1081,103 +1450,33 @@
     }
 
     /**
-     * Returns the task queue used by this executor. Access to the
-     * task queue is intended primarily for debugging and monitoring.
-     * This queue may be in active use.  Retrieving the task queue
-     * does not prevent queued tasks from executing.
-     *
-     * @return the task queue
-     */
-    public BlockingQueue<Runnable> getQueue() {
-        return workQueue;
-    }
-
-    /**
-     * Removes this task from the executor's internal queue if it is
-     * present, thus causing it not to be run if it has not already
-     * started.
-     * 
-     * <p> This method may be useful as one part of a cancellation
-     * scheme.  It may fail to remove tasks that have been converted
-     * into other forms before being placed on the internal queue. For
-     * example, a task entered using <tt>submit</tt> might be
-     * converted into a form that maintains <tt>Future</tt> status.
-     * However, in such cases, method {@link ThreadPoolExecutor#purge}
-     * may be used to remove those Futures that have been cancelled.
-     * 
-     *
-     * @param task the task to remove
-     * @return true if the task was removed
-     */
-    public boolean remove(Runnable task) {
-        return getQueue().remove(task);
-    }
-
-
-    /**
-     * Tries to remove from the work queue all {@link Future}
-     * tasks that have been cancelled. This method can be useful as a
-     * storage reclamation operation, that has no other impact on
-     * functionality. Cancelled tasks are never executed, but may
-     * accumulate in work queues until worker threads can actively
-     * remove them. Invoking this method instead tries to remove them now.
-     * However, this method may fail to remove tasks in
-     * the presence of interference by other threads.
-     */
-    public void purge() {
-        // Fail if we encounter interference during traversal
-        try {
-            Iterator<Runnable> it = getQueue().iterator();
-            while (it.hasNext()) {
-                Runnable r = it.next();
-                if (r instanceof Future<?>) {
-                    Future<?> c = (Future<?>)r;
-                    if (c.isCancelled())
-                        it.remove();
-                }
-            }
-        }
-        catch(ConcurrentModificationException ex) {
-            return; 
-        }
-    }
-
-    /**
      * Sets the core number of threads.  This overrides any value set
      * in the constructor.  If the new value is smaller than the
      * current value, excess existing threads will be terminated when
-     * they next become idle. If larger, new threads will, if needed,
+     * they next become idle.  If larger, new threads will, if needed,
      * be started to execute any queued tasks.
      *
      * @param corePoolSize the new core size
-     * @throws IllegalArgumentException if <tt>corePoolSize</tt>
-     * less than zero
+     * @throws IllegalArgumentException if {@code corePoolSize < 0}
      * @see #getCorePoolSize
      */
     public void setCorePoolSize(int corePoolSize) {
         if (corePoolSize < 0)
             throw new IllegalArgumentException();
-        final ReentrantLock mainLock = this.mainLock;
-        mainLock.lock();
-        try {
-            int extra = this.corePoolSize - corePoolSize;
-            this.corePoolSize = corePoolSize;
-            if (extra < 0) {
-                Runnable r;
-                while (extra++ < 0 && poolSize < corePoolSize &&
-                       (r = workQueue.poll()) != null)
-                    addThread(r).start();
+        int delta = corePoolSize - this.corePoolSize;
+        this.corePoolSize = corePoolSize;
+        if (workerCountOf(ctl.get()) > corePoolSize)
+            interruptIdleWorkers();
+        else if (delta > 0) {
+            // We don't really know how many new threads are "needed".
+            // As a heuristic, prestart enough new workers (up to new
+            // core size) to handle the current number of tasks in
+            // queue, but stop if queue becomes empty while doing so.
+            int k = Math.min(delta, workQueue.size());
+            while (k-- > 0 && addWorker(null, true)) {
+                if (workQueue.isEmpty())
+                    break;
             }
-            else if (extra > 0 && poolSize > corePoolSize) {
-                Iterator<Worker> it = workers.iterator();
-                while (it.hasNext() &&
-                       extra-- > 0 &&
-                       poolSize > corePoolSize &&
-                       workQueue.remainingCapacity() == 0) 
-                    it.next().interruptIfIdle();
-            }
-        } finally {
-            mainLock.unlock();
         }
     }
 
@@ -1194,23 +1493,26 @@
     /**
      * Starts a core thread, causing it to idly wait for work. This
      * overrides the default policy of starting core threads only when
-     * new tasks are executed. This method will return <tt>false</tt>
+     * new tasks are executed. This method will return {@code false}
      * if all core threads have already been started.
-     * @return true if a thread was started
-     */ 
+     *
+     * @return {@code true} if a thread was started
+     */
     public boolean prestartCoreThread() {
-        return addIfUnderCorePoolSize(null);
+        return workerCountOf(ctl.get()) < corePoolSize &&
+            addWorker(null, true);
     }
 
     /**
      * Starts all core threads, causing them to idly wait for work. This
      * overrides the default policy of starting core threads only when
-     * new tasks are executed. 
-     * @return the number of threads started.
-     */ 
+     * new tasks are executed.
+     *
+     * @return the number of threads started
+     */
     public int prestartAllCoreThreads() {
         int n = 0;
-        while (addIfUnderCorePoolSize(null))
+        while (addWorker(null, true))
             ++n;
         return n;
     }
@@ -1222,30 +1524,17 @@
      * terminated when they next become idle.
      *
      * @param maximumPoolSize the new maximum
-     * @throws IllegalArgumentException if maximumPoolSize less than zero or
-     * the {@link #getCorePoolSize core pool size}
+     * @throws IllegalArgumentException if the new maximum is
+     *         less than or equal to zero, or
+     *         less than the {@linkplain #getCorePoolSize core pool size}
      * @see #getMaximumPoolSize
      */
     public void setMaximumPoolSize(int maximumPoolSize) {
         if (maximumPoolSize <= 0 || maximumPoolSize < corePoolSize)
             throw new IllegalArgumentException();
-        final ReentrantLock mainLock = this.mainLock;
-        mainLock.lock();
-        try {
-            int extra = this.maximumPoolSize - maximumPoolSize;
-            this.maximumPoolSize = maximumPoolSize;
-            if (extra > 0 && poolSize > maximumPoolSize) {
-                Iterator<Worker> it = workers.iterator();
-                while (it.hasNext() &&
-                       extra > 0 &&
-                       poolSize > maximumPoolSize) {
-                    it.next().interruptIfIdle();
-                    --extra;
-                }
-            }
-        } finally {
-            mainLock.unlock();
-        }
+        this.maximumPoolSize = maximumPoolSize;
+        if (workerCountOf(ctl.get()) > maximumPoolSize)
+            interruptIdleWorkers();
     }
 
     /**
@@ -1264,21 +1553,27 @@
      * threads currently in the pool, after waiting this amount of
      * time without processing a task, excess threads will be
      * terminated.  This overrides any value set in the constructor.
+     *
      * @param time the time to wait.  A time value of zero will cause
-     * excess threads to terminate immediately after executing tasks.
-     * @param unit  the time unit of the time argument
-     * @throws IllegalArgumentException if time less than zero
+     *        excess threads to terminate immediately after executing tasks.
+     * @param unit the time unit of the {@code time} argument
+     * @throws IllegalArgumentException if {@code time} less than zero or
+     *         if {@code time} is zero and {@code allowsCoreThreadTimeOut}
      * @see #getKeepAliveTime
      */
     public void setKeepAliveTime(long time, TimeUnit unit) {
         if (time < 0)
             throw new IllegalArgumentException();
-        this.keepAliveTime = unit.toNanos(time);
+        long keepAliveTime = unit.toNanos(time);
+        long delta = keepAliveTime - this.keepAliveTime;
+        this.keepAliveTime = keepAliveTime;
+        if (delta < 0)
+            interruptIdleWorkers();
     }
 
     /**
      * Returns the thread keep-alive time, which is the amount of time
-     * which threads in excess of the core pool size may remain
+     * that threads in excess of the core pool size may remain
      * idle before being terminated.
      *
      * @param unit the desired time unit of the result
@@ -1289,6 +1584,73 @@
         return unit.convert(keepAliveTime, TimeUnit.NANOSECONDS);
     }
 
+    /* User-level queue utilities */
+
+    /**
+     * Returns the task queue used by this executor. Access to the
+     * task queue is intended primarily for debugging and monitoring.
+     * This queue may be in active use.  Retrieving the task queue
+     * does not prevent queued tasks from executing.
+     *
+     * @return the task queue
+     */
+    public BlockingQueue<Runnable> getQueue() {
+        return workQueue;
+    }
+
+    /**
+     * Removes this task from the executor's internal queue if it is
+     * present, thus causing it not to be run if it has not already
+     * started.
+     *
+     * <p> This method may be useful as one part of a cancellation
+     * scheme.  It may fail to remove tasks that have been converted
+     * into other forms before being placed on the internal queue. For
+     * example, a task entered using {@code submit} might be
+     * converted into a form that maintains {@code Future} status.
+     * However, in such cases, method {@link #purge} may be used to
+     * remove those Futures that have been cancelled.
+     *
+     * @param task the task to remove
+     * @return true if the task was removed
+     */
+    public boolean remove(Runnable task) {
+        boolean removed = workQueue.remove(task);
+        tryTerminate(); // In case SHUTDOWN and now empty
+        return removed;
+    }
+
+    /**
+     * Tries to remove from the work queue all {@link Future}
+     * tasks that have been cancelled. This method can be useful as a
+     * storage reclamation operation, that has no other impact on
+     * functionality. Cancelled tasks are never executed, but may
+     * accumulate in work queues until worker threads can actively
+     * remove them. Invoking this method instead tries to remove them now.
+     * However, this method may fail to remove tasks in
+     * the presence of interference by other threads.
+     */
+    public void purge() {
+        final BlockingQueue<Runnable> q = workQueue;
+        try {
+            Iterator<Runnable> it = q.iterator();
+            while (it.hasNext()) {
+                Runnable r = it.next();
+                if (r instanceof Future<?> && ((Future<?>)r).isCancelled())
+                    it.remove();
+            }
+        } catch (ConcurrentModificationException fallThrough) {
+            // Take slow path if we encounter interference during traversal.
+            // Make copy for traversal and call remove for cancelled entries.
+            // The slow path is more likely to be O(N*N).
+            for (Object r : q.toArray())
+                if (r instanceof Future<?> && ((Future<?>)r).isCancelled())
+                    q.remove(r);
+        }
+
+        tryTerminate(); // In case SHUTDOWN and now empty
+    }
+
     /* Statistics */
 
     /**
@@ -1297,7 +1659,16 @@
      * @return the number of threads
      */
     public int getPoolSize() {
-        return poolSize;
+        final ReentrantLock mainLock = this.mainLock;
+        mainLock.lock();
+        try {
+            // Remove rare and surprising possibility of
+            // isTerminated() && getPoolSize() > 0
+            return runStateAtLeast(ctl.get(), TIDYING) ? 0
+                : workers.size();
+        } finally {
+            mainLock.unlock();
+        }
     }
 
     /**
@@ -1311,10 +1682,9 @@
         mainLock.lock();
         try {
             int n = 0;
-            for (Worker w : workers) {
-                if (w.isActive())
+            for (Worker w : workers)
+                if (w.isLocked())
                     ++n;
-            }
             return n;
         } finally {
             mainLock.unlock();
@@ -1338,11 +1708,10 @@
     }
 
     /**
-     * Returns the approximate total number of tasks that have been
+     * Returns the approximate total number of tasks that have ever been
      * scheduled for execution. Because the states of tasks and
      * threads may change dynamically during computation, the returned
-     * value is only an approximation, but one that does not ever
-     * decrease across successive calls.
+     * value is only an approximation.
      *
      * @return the number of tasks
      */
@@ -1353,7 +1722,7 @@
             long n = completedTaskCount;
             for (Worker w : workers) {
                 n += w.completedTasks;
-                if (w.isActive())
+                if (w.isLocked())
                     ++n;
             }
             return n + workQueue.size();
@@ -1384,30 +1753,69 @@
         }
     }
 
+    /* Extension hooks */
+
     /**
      * Method invoked prior to executing the given Runnable in the
-     * given thread.  This method is invoked by thread <tt>t</tt> that
-     * will execute task <tt>r</tt>, and may be used to re-initialize
-     * ThreadLocals, or to perform logging. Note: To properly nest
-     * multiple overridings, subclasses should generally invoke
-     * <tt>super.beforeExecute</tt> at the end of this method.
+     * given thread.  This method is invoked by thread {@code t} that
+     * will execute task {@code r}, and may be used to re-initialize
+     * ThreadLocals, or to perform logging.
      *
-     * @param t the thread that will run task r.
-     * @param r the task that will be executed.
+     * <p>This implementation does nothing, but may be customized in
+     * subclasses. Note: To properly nest multiple overridings, subclasses
+     * should generally invoke {@code super.beforeExecute} at the end of
+     * this method.
+     *
+     * @param t the thread that will run task {@code r}
+     * @param r the task that will be executed
      */
     protected void beforeExecute(Thread t, Runnable r) { }
 
     /**
-     * Method invoked upon completion of execution of the given
-     * Runnable.  This method is invoked by the thread that executed
-     * the task. If non-null, the Throwable is the uncaught exception
-     * that caused execution to terminate abruptly. Note: To properly
-     * nest multiple overridings, subclasses should generally invoke
-     * <tt>super.afterExecute</tt> at the beginning of this method.
+     * Method invoked upon completion of execution of the given Runnable.
+     * This method is invoked by the thread that executed the task. If
+     * non-null, the Throwable is the uncaught {@code RuntimeException}
+     * or {@code Error} that caused execution to terminate abruptly.
      *
-     * @param r the runnable that has completed.
+     * <p>This implementation does nothing, but may be customized in
+     * subclasses. Note: To properly nest multiple overridings, subclasses
+     * should generally invoke {@code super.afterExecute} at the
+     * beginning of this method.
+     *
+     * <p><b>Note:</b> When actions are enclosed in tasks (such as
+     * {@link FutureTask}) either explicitly or via methods such as
+     * {@code submit}, these task objects catch and maintain
+     * computational exceptions, and so they do not cause abrupt
+     * termination, and the internal exceptions are <em>not</em>
+     * passed to this method. If you would like to trap both kinds of
+     * failures in this method, you can further probe for such cases,
+     * as in this sample subclass that prints either the direct cause
+     * or the underlying exception if a task has been aborted:
+     *
+     *  <pre> {@code
+     * class ExtendedExecutor extends ThreadPoolExecutor {
+     *   // ...
+     *   protected void afterExecute(Runnable r, Throwable t) {
+     *     super.afterExecute(r, t);
+     *     if (t == null && r instanceof Future<?>) {
+     *       try {
+     *         Object result = ((Future<?>) r).get();
+     *       } catch (CancellationException ce) {
+     *           t = ce;
+     *       } catch (ExecutionException ee) {
+     *           t = ee.getCause();
+     *       } catch (InterruptedException ie) {
+     *           Thread.currentThread().interrupt(); // ignore/reset
+     *       }
+     *     }
+     *     if (t != null)
+     *       System.out.println(t);
+     *   }
+     * }}</pre>
+     *
+     * @param r the runnable that has completed
      * @param t the exception that caused termination, or null if
-     * execution completed normally.
+     * execution completed normally
      */
     protected void afterExecute(Runnable r, Throwable t) { }
 
@@ -1415,25 +1823,28 @@
      * Method invoked when the Executor has terminated.  Default
      * implementation does nothing. Note: To properly nest multiple
      * overridings, subclasses should generally invoke
-     * <tt>super.terminated</tt> within this method.
+     * {@code super.terminated} within this method.
      */
     protected void terminated() { }
 
+    /* Predefined RejectedExecutionHandlers */
+
     /**
      * A handler for rejected tasks that runs the rejected task
-     * directly in the calling thread of the <tt>execute</tt> method,
+     * directly in the calling thread of the {@code execute} method,
      * unless the executor has been shut down, in which case the task
      * is discarded.
      */
-   public static class CallerRunsPolicy implements RejectedExecutionHandler {
+    public static class CallerRunsPolicy implements RejectedExecutionHandler {
         /**
-         * Creates a <tt>CallerRunsPolicy</tt>.
+         * Creates a {@code CallerRunsPolicy}.
          */
         public CallerRunsPolicy() { }
 
         /**
          * Executes task r in the caller's thread, unless the executor
          * has been shut down, in which case the task is discarded.
+         *
          * @param r the runnable task requested to be executed
          * @param e the executor attempting to execute this task
          */
@@ -1446,16 +1857,17 @@
 
     /**
      * A handler for rejected tasks that throws a
-     * <tt>RejectedExecutionException</tt>.
+     * {@code RejectedExecutionException}.
      */
     public static class AbortPolicy implements RejectedExecutionHandler {
         /**
-         * Creates an <tt>AbortPolicy</tt>.
+         * Creates an {@code AbortPolicy}.
          */
         public AbortPolicy() { }
 
         /**
          * Always throws RejectedExecutionException.
+         *
          * @param r the runnable task requested to be executed
          * @param e the executor attempting to execute this task
          * @throws RejectedExecutionException always.
@@ -1471,12 +1883,13 @@
      */
     public static class DiscardPolicy implements RejectedExecutionHandler {
         /**
-         * Creates a <tt>DiscardPolicy</tt>.
+         * Creates a {@code DiscardPolicy}.
          */
         public DiscardPolicy() { }
 
         /**
          * Does nothing, which has the effect of discarding task r.
+         *
          * @param r the runnable task requested to be executed
          * @param e the executor attempting to execute this task
          */
@@ -1486,12 +1899,12 @@
 
     /**
      * A handler for rejected tasks that discards the oldest unhandled
-     * request and then retries <tt>execute</tt>, unless the executor
+     * request and then retries {@code execute}, unless the executor
      * is shut down, in which case the task is discarded.
      */
     public static class DiscardOldestPolicy implements RejectedExecutionHandler {
         /**
-         * Creates a <tt>DiscardOldestPolicy</tt> for the given executor.
+         * Creates a {@code DiscardOldestPolicy} for the given executor.
          */
         public DiscardOldestPolicy() { }
 
@@ -1500,6 +1913,7 @@
          * would otherwise execute, if one is immediately available,
          * and then retries execution of task r, unless the executor
          * is shut down, in which case task r is instead discarded.
+         *
          * @param r the runnable task requested to be executed
          * @param e the executor attempting to execute this task
          */
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/TimeUnit.java b/libcore/concurrent/src/main/java/java/util/concurrent/TimeUnit.java
index b186aeb..412d28a 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/TimeUnit.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/TimeUnit.java
@@ -12,7 +12,11 @@
  * and to perform timing and delay operations in these units.  A
  * <tt>TimeUnit</tt> does not maintain time information, but only
  * helps organize and use time representations that may be maintained
- * separately across various contexts.
+ * separately across various contexts.  A nanosecond is defined as one
+ * thousandth of a microsecond, a microsecond as one thousandth of a
+ * millisecond, a millisecond as one thousandth of a second, a minute
+ * as sixty seconds, an hour as sixty minutes, and a day as twenty four
+ * hours.
  *
  * <p>A <tt>TimeUnit</tt> is mainly used to inform time-based methods
  * how a given timing parameter should be interpreted. For example,
@@ -37,61 +41,80 @@
  */
 public enum TimeUnit {
     /** TimeUnit which represents one nanosecond. */
-    NANOSECONDS(0), 
+    NANOSECONDS {
+        public long toNanos(long d)   { return d; }
+        public long toMicros(long d)  { return d/(C1/C0); }
+        public long toMillis(long d)  { return d/(C2/C0); }
+        public long toSeconds(long d) { return d/(C3/C0); }
+        public long toMinutes(long d) { return d/(C4/C0); }
+        public long toHours(long d)   { return d/(C5/C0); }
+        public long toDays(long d)    { return d/(C6/C0); }
+        public long convert(long d, TimeUnit u) { return u.toNanos(d); }
+        int excessNanos(long d, long m) { return (int)(d - (m*C2)); }
+    },
     /** TimeUnit which represents one microsecond. */
-    MICROSECONDS(1), 
+    MICROSECONDS {
+        public long toNanos(long d)   { return x(d, C1/C0, MAX/(C1/C0)); }
+        public long toMicros(long d)  { return d; }
+        public long toMillis(long d)  { return d/(C2/C1); }
+        public long toSeconds(long d) { return d/(C3/C1); }
+        public long toMinutes(long d) { return d/(C4/C1); }
+        public long toHours(long d)   { return d/(C5/C1); }
+        public long toDays(long d)    { return d/(C6/C1); }
+        public long convert(long d, TimeUnit u) { return u.toMicros(d); }
+        int excessNanos(long d, long m) { return (int)((d*C1) - (m*C2)); }
+    },
     /** TimeUnit which represents one millisecond. */
-    MILLISECONDS(2), 
+    MILLISECONDS {
+        public long toNanos(long d)   { return x(d, C2/C0, MAX/(C2/C0)); }
+        public long toMicros(long d)  { return x(d, C2/C1, MAX/(C2/C1)); }
+        public long toMillis(long d)  { return d; }
+        public long toSeconds(long d) { return d/(C3/C2); }
+        public long toMinutes(long d) { return d/(C4/C2); }
+        public long toHours(long d)   { return d/(C5/C2); }
+        public long toDays(long d)    { return d/(C6/C2); }
+        public long convert(long d, TimeUnit u) { return u.toMillis(d); }
+        int excessNanos(long d, long m) { return 0; }
+    },
     /** TimeUnit which represents one second. */
-    SECONDS(3);
-
-    /** the index of this unit */
-    private final int index;
-
-    /** Internal constructor */
-    TimeUnit(int index) { 
-        this.index = index; 
-    }
-
-    /** Lookup table for conversion factors */
-    private static final int[] multipliers = { 
-        1, 
-        1000, 
-        1000 * 1000, 
-        1000 * 1000 * 1000 
+    SECONDS {
+        public long toNanos(long d)   { return x(d, C3/C0, MAX/(C3/C0)); }
+        public long toMicros(long d)  { return x(d, C3/C1, MAX/(C3/C1)); }
+        public long toMillis(long d)  { return x(d, C3/C2, MAX/(C3/C2)); }
+        public long toSeconds(long d) { return d; }
+        public long toMinutes(long d) { return d/(C4/C3); }
+        public long toHours(long d)   { return d/(C5/C3); }
+        public long toDays(long d)    { return d/(C6/C3); }
+        public long convert(long d, TimeUnit u) { return u.toSeconds(d); }
+        int excessNanos(long d, long m) { return 0; }
     };
-    
-    /** 
-     * Lookup table to check saturation.  Note that because we are
-     * dividing these down, we don't have to deal with asymmetry of
-     * MIN/MAX values.
-     */
-    private static final long[] overflows = { 
-        0, // unused
-        Long.MAX_VALUE / 1000,
-        Long.MAX_VALUE / (1000 * 1000),
-        Long.MAX_VALUE / (1000 * 1000 * 1000) 
-    };
+
+    // Handy constants for conversion methods
+    static final long C0 = 1L;
+    static final long C1 = C0 * 1000L;
+    static final long C2 = C1 * 1000L;
+    static final long C3 = C2 * 1000L;
+    static final long C4 = C3 * 60L;
+    static final long C5 = C4 * 60L;
+    static final long C6 = C5 * 24L;
+
+    static final long MAX = Long.MAX_VALUE;
 
     /**
-     * Perform conversion based on given delta representing the
-     * difference between units
-     * @param delta the difference in index values of source and target units
-     * @param duration the duration
-     * @return converted duration or saturated value
+     * Scale d by m, checking for overflow.
+     * This has a short name to make above code more readable.
      */
-    private static long doConvert(int delta, long duration) {
-        if (delta == 0)
-            return duration;
-        if (delta < 0) 
-            return duration / multipliers[-delta];
-        if (duration > overflows[delta])
-            return Long.MAX_VALUE;
-        if (duration < -overflows[delta])
-            return Long.MIN_VALUE;
-        return duration * multipliers[delta];
+    static long x(long d, long m, long over) {
+        if (d >  over) return Long.MAX_VALUE;
+        if (d < -over) return Long.MIN_VALUE;
+        return d * m;
     }
 
+    // To maintain full signature compatibility with 1.5, and to improve the
+    // clarity of the generated javadoc (see 6287639: Abstract methods in
+    // enum classes should not be listed as abstract), method convert
+    // etc. are not declared abstract but otherwise act as abstract methods.
+
     /**
      * Convert the given time duration in the given unit to this
      * unit.  Conversions from finer to coarser granularities
@@ -102,14 +125,17 @@
      * <tt>Long.MIN_VALUE</tt> if negative or <tt>Long.MAX_VALUE</tt>
      * if positive.
      *
-     * @param duration the time duration in the given <tt>unit</tt>
-     * @param unit the unit of the <tt>duration</tt> argument
+     * <p>For example, to convert 10 minutes to milliseconds, use:
+     * <tt>TimeUnit.MILLISECONDS.convert(10L, TimeUnit.MINUTES)</tt>
+     *
+     * @param sourceDuration the time duration in the given <tt>sourceUnit</tt>
+     * @param sourceUnit the unit of the <tt>sourceDuration</tt> argument
      * @return the converted duration in this unit,
      * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
      * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
      */
-    public long convert(long duration, TimeUnit unit) {
-        return doConvert(unit.index - index, duration);
+    public long convert(long sourceDuration, TimeUnit sourceUnit) {
+        throw new AbstractMethodError();
     }
 
     /**
@@ -121,7 +147,7 @@
      * @see #convert
      */
     public long toNanos(long duration) {
-        return doConvert(index, duration);
+        throw new AbstractMethodError();
     }
 
     /**
@@ -133,7 +159,7 @@
      * @see #convert
      */
     public long toMicros(long duration) {
-        return doConvert(index - MICROSECONDS.index, duration);
+        throw new AbstractMethodError();
     }
 
     /**
@@ -145,34 +171,66 @@
      * @see #convert
      */
     public long toMillis(long duration) {
-        return doConvert(index - MILLISECONDS.index, duration);
+        throw new AbstractMethodError();
     }
 
     /**
      * Equivalent to <tt>SECONDS.convert(duration, this)</tt>.
      * @param duration the duration
-     * @return the converted duration.
+     * @return the converted duration,
+     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
+     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
      * @see #convert
      */
     public long toSeconds(long duration) {
-        return doConvert(index - SECONDS.index, duration);
+        throw new AbstractMethodError();
     }
 
-
     /**
-     * Utility method to compute the excess-nanosecond argument to
-     * wait, sleep, join.
+     * Equivalent to <tt>MINUTES.convert(duration, this)</tt>.
+     * @param duration the duration
+     * @return the converted duration,
+     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
+     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
+     * @see #convert
      */
-    private int excessNanos(long time, long ms) {
-        if (this == NANOSECONDS)
-            return (int) (time  - (ms * 1000 * 1000));
-        if (this == MICROSECONDS)
-            return (int) ((time * 1000) - (ms * 1000 * 1000));
-        return 0;
+    long toMinutes(long duration) {
+        throw new AbstractMethodError();
     }
 
     /**
-     * Perform a timed <tt>Object.wait</tt> using this time unit.
+     * Equivalent to <tt>HOURS.convert(duration, this)</tt>.
+     * @param duration the duration
+     * @return the converted duration,
+     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
+     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
+     * @see #convert
+     */
+    long toHours(long duration) {
+        throw new AbstractMethodError();
+    }
+
+    /**
+     * Equivalent to <tt>DAYS.convert(duration, this)</tt>.
+     * @param duration the duration
+     * @return the converted duration
+     * @see #convert
+     */
+    long toDays(long duration) {
+        throw new AbstractMethodError();
+    }
+
+    /**
+     * Utility to compute the excess-nanosecond argument to wait,
+     * sleep, join.
+     * @param d the duration
+     * @param m the number of milliseconds
+     * @return the number of nanoseconds
+     */
+    abstract int excessNanos(long d, long m);
+
+    /**
+     * Performs a timed <tt>Object.wait</tt> using this time unit.
      * This is a convenience method that converts timeout arguments
      * into the form required by the <tt>Object.wait</tt> method.
      *
@@ -180,7 +238,7 @@
      * method (see {@link BlockingQueue#poll BlockingQueue.poll})
      * using:
      *
-     * <pre>  public synchronized  Object poll(long timeout, TimeUnit unit) throws InterruptedException {
+     * <pre>  public synchronized Object poll(long timeout, TimeUnit unit) throws InterruptedException {
      *    while (empty) {
      *      unit.timedWait(this, timeout);
      *      ...
@@ -188,12 +246,13 @@
      *  }</pre>
      *
      * @param obj the object to wait on
-     * @param timeout the maximum time to wait. 
+     * @param timeout the maximum time to wait. If less than
+     * or equal to zero, do not wait at all.
      * @throws InterruptedException if interrupted while waiting.
      * @see Object#wait(long, int)
      */
     public void timedWait(Object obj, long timeout)
-        throws InterruptedException {
+    throws InterruptedException {
         if (timeout > 0) {
             long ms = toMillis(timeout);
             int ns = excessNanos(timeout, ms);
@@ -202,16 +261,17 @@
     }
 
     /**
-     * Perform a timed <tt>Thread.join</tt> using this time unit.
+     * Performs a timed <tt>Thread.join</tt> using this time unit.
      * This is a convenience method that converts time arguments into the
      * form required by the <tt>Thread.join</tt> method.
      * @param thread the thread to wait for
-     * @param timeout the maximum time to wait
+     * @param timeout the maximum time to wait. If less than
+     * or equal to zero, do not wait at all.
      * @throws InterruptedException if interrupted while waiting.
      * @see Thread#join(long, int)
      */
     public void timedJoin(Thread thread, long timeout)
-        throws InterruptedException {
+    throws InterruptedException {
         if (timeout > 0) {
             long ms = toMillis(timeout);
             int ns = excessNanos(timeout, ms);
@@ -220,10 +280,11 @@
     }
 
     /**
-     * Perform a <tt>Thread.sleep</tt> using this unit.
+     * Performs a <tt>Thread.sleep</tt> using this unit.
      * This is a convenience method that converts time arguments into the
      * form required by the <tt>Thread.sleep</tt> method.
-     * @param timeout the minimum time to sleep
+     * @param timeout the minimum time to sleep. If less than
+     * or equal to zero, do not sleep at all.
      * @throws InterruptedException if interrupted while sleeping.
      * @see Thread#sleep
      */
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicBoolean.java b/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicBoolean.java
index fdd3d49..ba60556 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicBoolean.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicBoolean.java
@@ -8,10 +8,10 @@
 import sun.misc.Unsafe;
 
 /**
- * A <tt>boolean</tt> value that may be updated atomically. See the
+ * A {@code boolean} value that may be updated atomically. See the
  * {@link java.util.concurrent.atomic} package specification for
  * description of the properties of atomic variables. An
- * <tt>AtomicBoolean</tt> is used in applications such as atomically
+ * {@code AtomicBoolean} is used in applications such as atomically
  * updated flags, and cannot be used as a replacement for a
  * {@link java.lang.Boolean}.
  *
@@ -37,7 +37,7 @@
     private volatile int value;
 
     /**
-     * Creates a new <tt>AtomicBoolean</tt> with the given initial value.
+     * Creates a new {@code AtomicBoolean} with the given initial value.
      *
      * @param initialValue the initial value
      */
@@ -46,7 +46,7 @@
     }
 
     /**
-     * Creates a new <tt>AtomicBoolean</tt> with initial value <tt>false</tt>.
+     * Creates a new {@code AtomicBoolean} with initial value {@code false}.
      */
     public AtomicBoolean() {
     }
@@ -61,16 +61,13 @@
     }
 
     /**
-     * Atomically sets the value to the given update value if the
-     * current value is equal to the expected value.  Any given
-     * invocation of this operation may fail (return
-     * <tt>false</tt>) spuriously, but repeated invocation when
-     * the current value holds the expected value and no other thread
-     * is also attempting to set the value will eventually succeed.
+     * Atomically sets the value to the given updated value
+     * if the current value {@code ==} the expected value.
      *
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful
+     * @return true if successful. False return indicates that
+     * the actual value was not equal to the expected value.
      */
     public final boolean compareAndSet(boolean expect, boolean update) {
         int e = expect ? 1 : 0;
@@ -79,9 +76,13 @@
     }
 
     /**
-     * Atomically set the value to the given updated value
-     * if the current value <tt>==</tt> the expected value.
-     * May fail spuriously.
+     * Atomically sets the value to the given updated value
+     * if the current value {@code ==} the expected value.
+     *
+     * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
+     * and does not provide ordering guarantees, so is only rarely an
+     * appropriate alternative to {@code compareAndSet}.
+     *
      * @param expect the expected value
      * @param update the new value
      * @return true if successful.
@@ -102,7 +103,7 @@
     }
 
     /**
-     * Sets to the given value and returns the previous value.
+     * Atomically sets to the given value and returns the previous value.
      *
      * @param newValue the new value
      * @return the previous value
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicInteger.java b/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicInteger.java
index 2b9d15c..1aa32f4 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicInteger.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicInteger.java
@@ -8,20 +8,19 @@
 import sun.misc.Unsafe;
 
 /**
- * An <tt>int</tt> value that may be updated atomically. See the
+ * An {@code int} value that may be updated atomically.  See the
  * {@link java.util.concurrent.atomic} package specification for
  * description of the properties of atomic variables. An
- * <tt>AtomicInteger</tt> is used in applications such as atomically
+ * {@code AtomicInteger} is used in applications such as atomically
  * incremented counters, and cannot be used as a replacement for an
  * {@link java.lang.Integer}. However, this class does extend
- * <tt>Number</tt> to allow uniform access by tools and utilities that
+ * {@code Number} to allow uniform access by tools and utilities that
  * deal with numerically-based classes.
- * 
  *
  * @since 1.5
  * @author Doug Lea
 */
-public class AtomicInteger extends Number implements java.io.Serializable { 
+public class AtomicInteger extends Number implements java.io.Serializable {
     private static final long serialVersionUID = 6214790243416807050L;
 
     // setup to use Unsafe.compareAndSwapInt for updates
@@ -34,13 +33,13 @@
       try {
         valueOffset = unsafe.objectFieldOffset
             (AtomicInteger.class.getDeclaredField("value"));
-      } catch(Exception ex) { throw new Error(ex); }
+      } catch (Exception ex) { throw new Error(ex); }
     }
 
     private volatile int value;
 
     /**
-     * Create a new AtomicInteger with the given initial value.
+     * Creates a new AtomicInteger with the given initial value.
      *
      * @param initialValue the initial value
      */
@@ -49,22 +48,22 @@
     }
 
     /**
-     * Create a new AtomicInteger with initial value <tt>0</tt>.
+     * Creates a new AtomicInteger with initial value {@code 0}.
      */
     public AtomicInteger() {
     }
 
     /**
-     * Get the current value.
+     * Gets the current value.
      *
      * @return the current value
      */
     public final int get() {
         return value;
     }
-  
+
     /**
-     * Set to the given value.
+     * Sets to the given value.
      *
      * @param newValue the new value
      */
@@ -73,7 +72,7 @@
     }
 
     /**
-     * Set to the give value and return the old value.
+     * Atomically sets to the given value and returns the old value.
      *
      * @param newValue the new value
      * @return the previous value
@@ -85,35 +84,39 @@
                 return current;
         }
     }
-  
-  
+
     /**
-     * Atomically set the value to the given updated value
-     * if the current value <tt>==</tt> the expected value.
+     * Atomically sets the value to the given updated value
+     * if the current value {@code ==} the expected value.
+     *
      * @param expect the expected value
      * @param update the new value
      * @return true if successful. False return indicates that
      * the actual value was not equal to the expected value.
      */
     public final boolean compareAndSet(int expect, int update) {
-      return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
+        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
     }
 
     /**
-     * Atomically set the value to the given updated value
-     * if the current value <tt>==</tt> the expected value.
-     * May fail spuriously.
+     * Atomically sets the value to the given updated value
+     * if the current value {@code ==} the expected value.
+     *
+     * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
+     * and does not provide ordering guarantees, so is only rarely an
+     * appropriate alternative to {@code compareAndSet}.
+     *
      * @param expect the expected value
      * @param update the new value
      * @return true if successful.
      */
     public final boolean weakCompareAndSet(int expect, int update) {
-      return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
+        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
     }
 
-
     /**
-     * Atomically increment by one the current value.
+     * Atomically increments by one the current value.
+     *
      * @return the previous value
      */
     public final int getAndIncrement() {
@@ -124,10 +127,10 @@
                 return current;
         }
     }
-  
-  
+
     /**
-     * Atomically decrement by one the current value.
+     * Atomically decrements by one the current value.
+     *
      * @return the previous value
      */
     public final int getAndDecrement() {
@@ -138,10 +141,10 @@
                 return current;
         }
     }
-  
-  
+
     /**
-     * Atomically add the given value to current value.
+     * Atomically adds the given value to the current value.
+     *
      * @param delta the value to add
      * @return the previous value
      */
@@ -155,7 +158,8 @@
     }
 
     /**
-     * Atomically increment by one the current value.
+     * Atomically increments by one the current value.
+     *
      * @return the updated value
      */
     public final int incrementAndGet() {
@@ -166,9 +170,10 @@
                 return next;
         }
     }
-    
+
     /**
-     * Atomically decrement by one the current value.
+     * Atomically decrements by one the current value.
+     *
      * @return the updated value
      */
     public final int decrementAndGet() {
@@ -179,10 +184,10 @@
                 return next;
         }
     }
-  
-  
+
     /**
-     * Atomically add the given value to current value.
+     * Atomically adds the given value to the current value.
+     *
      * @param delta the value to add
      * @return the updated value
      */
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java b/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java
index 95807f3..ee21b13 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java
@@ -9,14 +9,14 @@
 import java.util.*;
 
 /**
- * An <tt>int</tt> array in which elements may be updated atomically.
+ * An {@code int} array in which elements may be updated atomically.
  * See the {@link java.util.concurrent.atomic} package
  * specification for description of the properties of atomic
  * variables.
  * @since 1.5
  * @author Doug Lea
  */
-public class AtomicIntegerArray implements java.io.Serializable { 
+public class AtomicIntegerArray implements java.io.Serializable {
     private static final long serialVersionUID = 2862133569453604235L;
 
    // setup to use Unsafe.compareAndSwapInt for updates
@@ -34,7 +34,7 @@
     }
 
     /**
-     * Create a new AtomicIntegerArray of given length.
+     * Creates a new AtomicIntegerArray of given length.
      *
      * @param length the length of the array
      */
@@ -46,14 +46,14 @@
     }
 
     /**
-     * Create a new AtomicIntegerArray with the same length as, and
+     * Creates a new AtomicIntegerArray with the same length as, and
      * all elements copied from, the given array.
      *
      * @param array the array to copy elements from
      * @throws NullPointerException if array is null
      */
     public AtomicIntegerArray(int[] array) {
-        if (array == null) 
+        if (array == null)
             throw new NullPointerException();
         int length = array.length;
         this.array = new int[length];
@@ -76,7 +76,7 @@
     }
 
     /**
-     * Get the current value at position <tt>i</tt>.
+     * Gets the current value at position {@code i}.
      *
      * @param i the index
      * @return the current value
@@ -84,9 +84,9 @@
     public final int get(int i) {
         return unsafe.getIntVolatile(array, rawIndex(i));
     }
- 
+
     /**
-     * Set the element at position <tt>i</tt> to the given value.
+     * Sets the element at position {@code i} to the given value.
      *
      * @param i the index
      * @param newValue the new value
@@ -94,10 +94,10 @@
     public final void set(int i, int newValue) {
         unsafe.putIntVolatile(array, rawIndex(i), newValue);
     }
-  
+
     /**
-     * Set the element at position <tt>i</tt> to the given value and return the
-     * old value.
+     * Atomically sets the element at position {@code i} to the given
+     * value and returns the old value.
      *
      * @param i the index
      * @param newValue the new value
@@ -110,10 +110,10 @@
                 return current;
         }
     }
-  
+
     /**
-     * Atomically set the value to the given updated value
-     * if the current value <tt>==</tt> the expected value.
+     * Atomically sets the element at position {@code i} to the given
+     * updated value if the current value {@code ==} the expected value.
      *
      * @param i the index
      * @param expect the expected value
@@ -122,14 +122,17 @@
      * the actual value was not equal to the expected value.
      */
     public final boolean compareAndSet(int i, int expect, int update) {
-        return unsafe.compareAndSwapInt(array, rawIndex(i), 
+        return unsafe.compareAndSwapInt(array, rawIndex(i),
                                         expect, update);
     }
 
     /**
-     * Atomically set the value to the given updated value
-     * if the current value <tt>==</tt> the expected value.
-     * May fail spuriously.
+     * Atomically sets the element at position {@code i} to the given
+     * updated value if the current value {@code ==} the expected value.
+     *
+     * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
+     * and does not provide ordering guarantees, so is only rarely an
+     * appropriate alternative to {@code compareAndSet}.
      *
      * @param i the index
      * @param expect the expected value
@@ -141,10 +144,10 @@
     }
 
     /**
-     * Atomically increment by one the element at index <tt>i</tt>.
+     * Atomically increments by one the element at index {@code i}.
      *
      * @param i the index
-     * @return the previous value;
+     * @return the previous value
      */
     public final int getAndIncrement(int i) {
         while (true) {
@@ -154,12 +157,12 @@
                 return current;
         }
     }
-  
+
     /**
-     * Atomically decrement by one the element at index <tt>i</tt>.
+     * Atomically decrements by one the element at index {@code i}.
      *
      * @param i the index
-     * @return the previous value;
+     * @return the previous value
      */
     public final int getAndDecrement(int i) {
         while (true) {
@@ -169,13 +172,13 @@
                 return current;
         }
     }
-  
+
     /**
-     * Atomically add the given value to element at index <tt>i</tt>.
+     * Atomically adds the given value to the element at index {@code i}.
      *
      * @param i the index
      * @param delta the value to add
-     * @return the previous value;
+     * @return the previous value
      */
     public final int getAndAdd(int i, int delta) {
         while (true) {
@@ -187,10 +190,10 @@
     }
 
     /**
-     * Atomically increment by one the element at index <tt>i</tt>.
+     * Atomically increments by one the element at index {@code i}.
      *
      * @param i the index
-     * @return the updated value;
+     * @return the updated value
      */
     public final int incrementAndGet(int i) {
         while (true) {
@@ -200,12 +203,12 @@
                 return next;
         }
     }
-  
+
     /**
-     * Atomically decrement by one the element at index <tt>i</tt>.
+     * Atomically decrements by one the element at index {@code i}.
      *
      * @param i the index
-     * @return the updated value;
+     * @return the updated value
      */
     public final int decrementAndGet(int i) {
         while (true) {
@@ -215,13 +218,13 @@
                 return next;
         }
     }
-  
+
     /**
-     * Atomically add the given value to element at index <tt>i</tt>.
+     * Atomically adds the given value to the element at index {@code i}.
      *
      * @param i the index
      * @param delta the value to add
-     * @return the updated value;
+     * @return the updated value
      */
     public final int addAndGet(int i, int delta) {
         while (true) {
@@ -231,7 +234,7 @@
                 return next;
         }
     }
- 
+
     /**
      * Returns the String representation of the current values of array.
      * @return the String representation of the current values of array.
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java b/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java
index 5f289c2..f8d2c81 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java
@@ -8,35 +8,40 @@
 import sun.misc.Unsafe;
 import java.lang.reflect.*;
 
+import org.apache.harmony.kernel.vm.VM;
+import dalvik.system.VMStack;
+
 /**
  * A reflection-based utility that enables atomic updates to
- * designated <tt>volatile int</tt> fields of designated classes.
+ * designated {@code volatile int} fields of designated classes.
  * This class is designed for use in atomic data structures in which
  * several fields of the same node are independently subject to atomic
  * updates.
  *
- * <p> Note that the guarantees of the <tt>compareAndSet</tt> method
- * in this class are weaker than in other atomic classes. Because this
- * class cannot ensure that all uses of the field are appropriate for
- * purposes of atomic access, it can guarantee atomicity and volatile
- * semantics only with respect to other invocations of
- * <tt>compareAndSet</tt> and <tt>set</tt>.
+ * <p>Note that the guarantees of the {@code compareAndSet}
+ * method in this class are weaker than in other atomic classes.
+ * Because this class cannot ensure that all uses of the field
+ * are appropriate for purposes of atomic access, it can
+ * guarantee atomicity only with respect to other invocations of
+ * {@code compareAndSet} and {@code set} on the same updater.
+ *
  * @since 1.5
  * @author Doug Lea
  * @param <T> The type of the object holding the updatable field
  */
 public abstract class  AtomicIntegerFieldUpdater<T>  {
     /**
-     * Creates an updater for objects with the given field.  The Class
-     * argument is needed to check that reflective types and generic
-     * types match.
+     * Creates and returns an updater for objects with the given field.
+     * The Class argument is needed to check that reflective types and
+     * generic types match.
+     *
      * @param tclass the class of the objects holding the field
-     * @param fieldName the name of the field to be updated.
+     * @param fieldName the name of the field to be updated
      * @return the updater
      * @throws IllegalArgumentException if the field is not a
-     * volatile integer type.
+     * volatile integer type
      * @throws RuntimeException with a nested reflection-based
-     * exception if the class does not hold field or is the wrong type.
+     * exception if the class does not hold field or is the wrong type
      */
     public static <U> AtomicIntegerFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) {
         return new AtomicIntegerFieldUpdaterImpl<U>(tclass, fieldName);
@@ -49,57 +54,63 @@
     }
 
     /**
-     * Atomically set the value of the field of the given object managed
-     * by this Updater to the given updated value if the current value
-     * <tt>==</tt> the expected value. This method is guaranteed to be
-     * atomic with respect to other calls to <tt>compareAndSet</tt> and
-     * <tt>set</tt>, but not necessarily with respect to other
-     * changes in the field.
+     * Atomically sets the field of the given object managed by this updater
+     * to the given updated value if the current value {@code ==} the
+     * expected value. This method is guaranteed to be atomic with respect to
+     * other calls to {@code compareAndSet} and {@code set}, but not
+     * necessarily with respect to other changes in the field.
+     *
      * @param obj An object whose field to conditionally set
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful.
-     * @throws ClassCastException if <tt>obj</tt> is not an instance
-     * of the class possessing the field established in the constructor.
+     * @return true if successful
+     * @throws ClassCastException if {@code obj} is not an instance
+     * of the class possessing the field established in the constructor
      */
-
     public abstract boolean compareAndSet(T obj, int expect, int update);
 
     /**
-     * Atomically set the value of the field of the given object managed
-     * by this Updater to the given updated value if the current value
-     * <tt>==</tt> the expected value. This method is guaranteed to be
-     * atomic with respect to other calls to <tt>compareAndSet</tt> and
-     * <tt>set</tt>, but not necessarily with respect to other
-     * changes in the field, and may fail spuriously.
+     * Atomically sets the field of the given object managed by this updater
+     * to the given updated value if the current value {@code ==} the
+     * expected value. This method is guaranteed to be atomic with respect to
+     * other calls to {@code compareAndSet} and {@code set}, but not
+     * necessarily with respect to other changes in the field.
+     *
+     * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
+     * and does not provide ordering guarantees, so is only rarely an
+     * appropriate alternative to {@code compareAndSet}.
+     *
      * @param obj An object whose field to conditionally set
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful.
-     * @throws ClassCastException if <tt>obj</tt> is not an instance
-     * of the class possessing the field established in the constructor.
+     * @return true if successful
+     * @throws ClassCastException if {@code obj} is not an instance
+     * of the class possessing the field established in the constructor
      */
-
     public abstract boolean weakCompareAndSet(T obj, int expect, int update);
 
     /**
-     * Set the field of the given object managed by this updater. This
-     * operation is guaranteed to act as a volatile store with respect
-     * to subsequent invocations of <tt>compareAndSet</tt>.
+     * Sets the field of the given object managed by this updater to the
+     * given updated value. This operation is guaranteed to act as a volatile
+     * store with respect to subsequent invocations of {@code compareAndSet}.
+     *
      * @param obj An object whose field to set
      * @param newValue the new value
      */
     public abstract void set(T obj, int newValue);
 
     /**
-     * Get the current value held in the field by the given object.
+     * Gets the current value held in the field of the given object managed
+     * by this updater.
+     *
      * @param obj An object whose field to get
      * @return the current value
      */
     public abstract int get(T obj);
 
     /**
-     * Set to the given value and return the old value.
+     * Atomically sets the field of the given object managed by this updater
+     * to the given value and returns the old value.
      *
      * @param obj An object whose field to get and set
      * @param newValue the new value
@@ -114,9 +125,11 @@
     }
 
     /**
-     * Atomically increment by one the current value.
+     * Atomically increments by one the current value of the field of the
+     * given object managed by this updater.
+     *
      * @param obj An object whose field to get and set
-     * @return the previous value;
+     * @return the previous value
      */
     public int getAndIncrement(T obj) {
         for (;;) {
@@ -127,11 +140,12 @@
         }
     }
 
-
     /**
-     * Atomically decrement by one the current value.
+     * Atomically decrements by one the current value of the field of the
+     * given object managed by this updater.
+     *
      * @param obj An object whose field to get and set
-     * @return the previous value;
+     * @return the previous value
      */
     public int getAndDecrement(T obj) {
         for (;;) {
@@ -142,12 +156,13 @@
         }
     }
 
-
     /**
-     * Atomically add the given value to current value.
+     * Atomically adds the given value to the current value of the field of
+     * the given object managed by this updater.
+     *
      * @param obj An object whose field to get and set
      * @param delta the value to add
-     * @return the previous value;
+     * @return the previous value
      */
     public int getAndAdd(T obj, int delta) {
         for (;;) {
@@ -159,9 +174,11 @@
     }
 
     /**
-     * Atomically increment by one the current value.
+     * Atomically increments by one the current value of the field of the
+     * given object managed by this updater.
+     *
      * @param obj An object whose field to get and set
-     * @return the updated value;
+     * @return the updated value
      */
     public int incrementAndGet(T obj) {
         for (;;) {
@@ -172,11 +189,12 @@
         }
     }
 
-
     /**
-     * Atomically decrement by one the current value.
+     * Atomically decrements by one the current value of the field of the
+     * given object managed by this updater.
+     *
      * @param obj An object whose field to get and set
-     * @return the updated value;
+     * @return the updated value
      */
     public int decrementAndGet(T obj) {
         for (;;) {
@@ -187,12 +205,13 @@
         }
     }
 
-
     /**
-     * Atomically add the given value to current value.
+     * Atomically adds the given value to the current value of the field of
+     * the given object managed by this updater.
+     *
      * @param obj An object whose field to get and set
      * @param delta the value to add
-     * @return the updated value;
+     * @return the updated value
      */
     public int addAndGet(T obj, int delta) {
         for (;;) {
@@ -212,49 +231,83 @@
         // END android-changed
         private final long offset;
         private final Class<T> tclass;
+        private final Class cclass;
 
         AtomicIntegerFieldUpdaterImpl(Class<T> tclass, String fieldName) {
             Field field = null;
+            Class caller = null;
+            int modifiers = 0;
             try {
                 field = tclass.getDeclaredField(fieldName);
-            } catch(Exception ex) {
+                // BEGIN android-changed
+                caller = VMStack.getStackClass2();
+                // END android-changed
+                modifiers = field.getModifiers();
+
+                SecurityManager smgr = System.getSecurityManager();
+                if (smgr != null) {
+                    int type = Modifier.isPublic(modifiers)
+                            ? Member.PUBLIC : Member.DECLARED;
+                    smgr.checkMemberAccess(tclass, type);
+                    smgr.checkPackageAccess(tclass.getPackage().getName());
+                }
+            } catch (Exception ex) {
                 throw new RuntimeException(ex);
             }
-            
+
             Class fieldt = field.getType();
             if (fieldt != int.class)
                 throw new IllegalArgumentException("Must be integer type");
-            
-            if (!Modifier.isVolatile(field.getModifiers()))
+
+            if (!Modifier.isVolatile(modifiers))
                 throw new IllegalArgumentException("Must be volatile type");
-         
+
+            this.cclass = (Modifier.isProtected(modifiers) &&
+                           caller != tclass) ? caller : null;
             this.tclass = tclass;
             offset = unsafe.objectFieldOffset(field);
         }
 
-        public boolean compareAndSet(T obj, int expect, int update) {
+        private void fullCheck(T obj) {
             if (!tclass.isInstance(obj))
                 throw new ClassCastException();
+            if (cclass != null)
+                ensureProtectedAccess(obj);
+        }
+
+        public boolean compareAndSet(T obj, int expect, int update) {
+            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
             return unsafe.compareAndSwapInt(obj, offset, expect, update);
         }
 
         public boolean weakCompareAndSet(T obj, int expect, int update) {
-            if (!tclass.isInstance(obj))
-                throw new ClassCastException();
+            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
             return unsafe.compareAndSwapInt(obj, offset, expect, update);
         }
 
         public void set(T obj, int newValue) {
-            if (!tclass.isInstance(obj))
-                throw new ClassCastException();
+            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
             unsafe.putIntVolatile(obj, offset, newValue);
         }
 
         public final int get(T obj) {
-            if (!tclass.isInstance(obj))
-                throw new ClassCastException();
+            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
             return unsafe.getIntVolatile(obj, offset);
         }
+
+        private void ensureProtectedAccess(T obj) {
+            if (cclass.isInstance(obj)) {
+                return;
+            }
+            throw new RuntimeException(
+                new IllegalAccessException("Class " +
+                    cclass.getName() +
+                    " can not access a protected member of class " +
+                    tclass.getName() +
+                    " using an instance of " +
+                    obj.getClass().getName()
+                )
+            );
+        }
     }
 }
-
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLong.java b/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLong.java
index 7f41364..9b56002 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLong.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLong.java
@@ -8,19 +8,19 @@
 import sun.misc.Unsafe;
 
 /**
- * A <tt>long</tt> value that may be updated atomically.  See the
+ * A {@code long} value that may be updated atomically.  See the
  * {@link java.util.concurrent.atomic} package specification for
  * description of the properties of atomic variables. An
- * <tt>AtomicLong</tt> is used in applications such as atomically
+ * {@code AtomicLong} is used in applications such as atomically
  * incremented sequence numbers, and cannot be used as a replacement
  * for a {@link java.lang.Long}. However, this class does extend
- * <tt>Number</tt> to allow uniform access by tools and utilities that
+ * {@code Number} to allow uniform access by tools and utilities that
  * deal with numerically-based classes.
  *
  * @since 1.5
  * @author Doug Lea
  */
-public class AtomicLong extends Number implements java.io.Serializable { 
+public class AtomicLong extends Number implements java.io.Serializable {
     private static final long serialVersionUID = 1927816293512124184L;
 
     // setup to use Unsafe.compareAndSwapLong for updates
@@ -30,12 +30,14 @@
     private static final long valueOffset;
 
     /**
-     * Record whether the underlying JVM supports lockless
-     * CompareAndSet for longs. While the unsafe.CompareAndSetLong
+     * Records whether the underlying JVM supports lockless
+     * compareAndSwap for longs. While the Unsafe.compareAndSwapLong
      * method works in either case, some constructions should be
      * handled at Java level to avoid locking user-visible locks.
+     *
+     * Initialised in the static block.
      */
-    static final boolean VM_SUPPORTS_LONG_CAS = VMSupportsCS8();
+    static final boolean VM_SUPPORTS_LONG_CAS;
 
     /**
      * Returns whether underlying JVM supports lockless CompareAndSet
@@ -47,13 +49,22 @@
       try {
         valueOffset = unsafe.objectFieldOffset
             (AtomicLong.class.getDeclaredField("value"));
-      } catch(Exception ex) { throw new Error(ex); }
+      } catch (Exception ex) { throw new Error(ex); }
+
+      boolean longCASSupport;
+      try {
+         longCASSupport = VMSupportsCS8();
+      } catch (UnsatisfiedLinkError e) {
+         // assume there's support if the native isn't provided by the VM
+         longCASSupport = true;
+      }
+      VM_SUPPORTS_LONG_CAS = longCASSupport;
     }
 
     private volatile long value;
 
     /**
-     * Create a new AtomicLong with the given initial value.
+     * Creates a new AtomicLong with the given initial value.
      *
      * @param initialValue the initial value
      */
@@ -62,31 +73,31 @@
     }
 
     /**
-     * Create a new AtomicLong with initial value <tt>0</tt>.
+     * Creates a new AtomicLong with initial value {@code 0}.
      */
     public AtomicLong() {
     }
-  
+
     /**
-     * Get the current value.
+     * Gets the current value.
      *
      * @return the current value
      */
     public final long get() {
         return value;
     }
- 
+
     /**
-     * Set to the given value.
+     * Sets to the given value.
      *
      * @param newValue the new value
      */
     public final void set(long newValue) {
         value = newValue;
     }
-  
+
     /**
-     * Set to the give value and return the old value.
+     * Atomically sets to the given value and returns the old value.
      *
      * @param newValue the new value
      * @return the previous value
@@ -98,33 +109,39 @@
                 return current;
         }
     }
-  
+
     /**
-     * Atomically set the value to the given updated value
-     * if the current value <tt>==</tt> the expected value.
+     * Atomically sets the value to the given updated value
+     * if the current value {@code ==} the expected value.
+     *
      * @param expect the expected value
      * @param update the new value
      * @return true if successful. False return indicates that
      * the actual value was not equal to the expected value.
      */
     public final boolean compareAndSet(long expect, long update) {
-      return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
+        return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
     }
 
     /**
-     * Atomically set the value to the given updated value
-     * if the current value <tt>==</tt> the expected value.
-     * May fail spuriously.
+     * Atomically sets the value to the given updated value
+     * if the current value {@code ==} the expected value.
+     *
+     * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
+     * and does not provide ordering guarantees, so is only rarely an
+     * appropriate alternative to {@code compareAndSet}.
+     *
      * @param expect the expected value
      * @param update the new value
      * @return true if successful.
      */
     public final boolean weakCompareAndSet(long expect, long update) {
-      return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
+        return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
     }
-  
+
     /**
-     * Atomically increment by one the current value.
+     * Atomically increments by one the current value.
+     *
      * @return the previous value
      */
     public final long getAndIncrement() {
@@ -135,10 +152,10 @@
                 return current;
         }
     }
-  
-  
+
     /**
-     * Atomically decrement by one the current value.
+     * Atomically decrements by one the current value.
+     *
      * @return the previous value
      */
     public final long getAndDecrement() {
@@ -149,10 +166,10 @@
                 return current;
         }
     }
-  
-  
+
     /**
-     * Atomically add the given value to current value.
+     * Atomically adds the given value to the current value.
+     *
      * @param delta the value to add
      * @return the previous value
      */
@@ -164,9 +181,10 @@
                 return current;
         }
     }
-  
+
     /**
-     * Atomically increment by one the current value.
+     * Atomically increments by one the current value.
+     *
      * @return the updated value
      */
     public final long incrementAndGet() {
@@ -177,9 +195,10 @@
                 return next;
         }
     }
-    
+
     /**
-     * Atomically decrement by one the current value.
+     * Atomically decrements by one the current value.
+     *
      * @return the updated value
      */
     public final long decrementAndGet() {
@@ -190,10 +209,10 @@
                 return next;
         }
     }
-  
-  
+
     /**
-     * Atomically add the given value to current value.
+     * Atomically adds the given value to the current value.
+     *
      * @param delta the value to add
      * @return the updated value
      */
@@ -205,7 +224,7 @@
                 return next;
         }
     }
-  
+
     /**
      * Returns the String representation of the current value.
      * @return the String representation of the current value.
@@ -220,7 +239,7 @@
     }
 
     public long longValue() {
-        return (long)get();
+        return get();
     }
 
     public float floatValue() {
@@ -230,5 +249,5 @@
     public double doubleValue() {
         return (double)get();
     }
-  
+
 }
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java b/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java
index a0e76b4..d96f4c2 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java
@@ -9,13 +9,13 @@
 import java.util.*;
 
 /**
- * A <tt>long</tt> array in which elements may be updated atomically.
+ * A {@code long} array in which elements may be updated atomically.
  * See the {@link java.util.concurrent.atomic} package specification
  * for description of the properties of atomic variables.
  * @since 1.5
  * @author Doug Lea
  */
-public class AtomicLongArray implements java.io.Serializable { 
+public class AtomicLongArray implements java.io.Serializable {
     private static final long serialVersionUID = -2308431214976778248L;
 
     // setup to use Unsafe.compareAndSwapInt for updates
@@ -33,25 +33,26 @@
     }
 
     /**
-     * Create a new AtomicLongArray of given length.
+     * Creates a new AtomicLongArray of given length.
+     *
      * @param length the length of the array
      */
     public AtomicLongArray(int length) {
         array = new long[length];
         // must perform at least one volatile write to conform to JMM
-        if (length > 0) 
+        if (length > 0)
             unsafe.putLongVolatile(array, rawIndex(0), 0);
     }
 
     /**
-     * Create a new AtomicLongArray with the same length as, and
+     * Creates a new AtomicLongArray with the same length as, and
      * all elements copied from, the given array.
      *
      * @param array the array to copy elements from
      * @throws NullPointerException if array is null
      */
     public AtomicLongArray(long[] array) {
-        if (array == null) 
+        if (array == null)
             throw new NullPointerException();
         int length = array.length;
         this.array = new long[length];
@@ -74,7 +75,7 @@
     }
 
     /**
-     * Get the current value at position <tt>i</tt>.
+     * Gets the current value at position {@code i}.
      *
      * @param i the index
      * @return the current value
@@ -82,9 +83,9 @@
     public final long get(int i) {
         return unsafe.getLongVolatile(array, rawIndex(i));
     }
- 
+
     /**
-     * Set the element at position <tt>i</tt> to the given value.
+     * Sets the element at position {@code i} to the given value.
      *
      * @param i the index
      * @param newValue the new value
@@ -92,10 +93,10 @@
     public final void set(int i, long newValue) {
         unsafe.putLongVolatile(array, rawIndex(i), newValue);
     }
-  
+
     /**
-     * Set the element at position <tt>i</tt> to the given value and return the
-     * old value.
+     * Atomically sets the element at position {@code i} to the given value
+     * and returns the old value.
      *
      * @param i the index
      * @param newValue the new value
@@ -108,10 +109,11 @@
                 return current;
         }
     }
-  
+
     /**
-     * Atomically set the value to the given updated value
-     * if the current value <tt>==</tt> the expected value.
+     * Atomically sets the value to the given updated value
+     * if the current value {@code ==} the expected value.
+     *
      * @param i the index
      * @param expect the expected value
      * @param update the new value
@@ -119,14 +121,18 @@
      * the actual value was not equal to the expected value.
      */
     public final boolean compareAndSet(int i, long expect, long update) {
-        return unsafe.compareAndSwapLong(array, rawIndex(i), 
+        return unsafe.compareAndSwapLong(array, rawIndex(i),
                                          expect, update);
     }
 
     /**
-     * Atomically set the value to the given updated value
-     * if the current value <tt>==</tt> the expected value.
-     * May fail spuriously.
+     * Atomically sets the value to the given updated value
+     * if the current value {@code ==} the expected value.
+     *
+     * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
+     * and does not provide ordering guarantees, so is only rarely an
+     * appropriate alternative to {@code compareAndSet}.
+     *
      * @param i the index
      * @param expect the expected value
      * @param update the new value
@@ -137,10 +143,10 @@
     }
 
     /**
-     * Atomically increment by one the element at index <tt>i</tt>.
+     * Atomically increments by one the element at index {@code i}.
      *
      * @param i the index
-     * @return the previous value;
+     * @return the previous value
      */
     public final long getAndIncrement(int i) {
         while (true) {
@@ -150,12 +156,12 @@
                 return current;
         }
     }
-  
+
     /**
-     * Atomically decrement by one the element at index <tt>i</tt>.
+     * Atomically decrements by one the element at index {@code i}.
      *
      * @param i the index
-     * @return the previous value;
+     * @return the previous value
      */
     public final long getAndDecrement(int i) {
         while (true) {
@@ -165,13 +171,13 @@
                 return current;
         }
     }
-  
+
     /**
-     * Atomically add the given value to element at index <tt>i</tt>.
+     * Atomically adds the given value to the element at index {@code i}.
      *
      * @param i the index
      * @param delta the value to add
-     * @return the previous value;
+     * @return the previous value
      */
     public final long getAndAdd(int i, long delta) {
         while (true) {
@@ -181,13 +187,12 @@
                 return current;
         }
     }
-  
 
     /**
-     * Atomically increment the element at index <tt>i</tt>.
+     * Atomically increments by one the element at index {@code i}.
      *
      * @param i the index
-     * @return the updated value;
+     * @return the updated value
      */
     public final long incrementAndGet(int i) {
         while (true) {
@@ -197,12 +202,12 @@
                 return next;
         }
     }
-  
+
     /**
-     * Atomically decrement the element at index <tt>i</tt>.
+     * Atomically decrements by one the element at index {@code i}.
      *
      * @param i the index
-     * @return the updated value;
+     * @return the updated value
      */
     public final long decrementAndGet(int i) {
         while (true) {
@@ -212,13 +217,13 @@
                 return next;
         }
     }
-  
+
     /**
-     * Atomically add the given value to element at index <tt>i</tt>.
+     * Atomically adds the given value to the element at index {@code i}.
      *
      * @param i the index
      * @param delta the value to add
-     * @return the updated value;
+     * @return the updated value
      */
     public long addAndGet(int i, long delta) {
         while (true) {
@@ -238,5 +243,5 @@
             get(0);
         return Arrays.toString(array);
     }
-  
+
 }
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java b/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java
index dcb8b2e..d97c2e4 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java
@@ -8,19 +8,22 @@
 import sun.misc.Unsafe;
 import java.lang.reflect.*;
 
+import org.apache.harmony.kernel.vm.VM;
+import dalvik.system.VMStack;
+
 /**
  * A reflection-based utility that enables atomic updates to
- * designated <tt>volatile long</tt> fields of designated classes.
+ * designated {@code volatile long} fields of designated classes.
  * This class is designed for use in atomic data structures in which
  * several fields of the same node are independently subject to atomic
  * updates.
  *
- * <p> Note that the guarantees of the <tt>compareAndSet</tt> method
- * in this class are weaker than in other atomic classes. Because this
- * class cannot ensure that all uses of the field are appropriate for
- * purposes of atomic access, it can guarantee atomicity and volatile
- * semantics only with respect to other invocations of
- * <tt>compareAndSet</tt> and <tt>set</tt>.
+ * <p>Note that the guarantees of the {@code compareAndSet}
+ * method in this class are weaker than in other atomic classes.
+ * Because this class cannot ensure that all uses of the field
+ * are appropriate for purposes of atomic access, it can
+ * guarantee atomicity only with respect to other invocations of
+ * {@code compareAndSet} and {@code set} on the same updater.
  *
  * @since 1.5
  * @author Doug Lea
@@ -28,9 +31,10 @@
  */
 public abstract class  AtomicLongFieldUpdater<T>  {
     /**
-     * Creates an updater for objects with the given field.  The Class
-     * argument is needed to check that reflective types and generic
-     * types match.
+     * Creates and returns an updater for objects with the given field.
+     * The Class argument is needed to check that reflective types and
+     * generic types match.
+     *
      * @param tclass the class of the objects holding the field
      * @param fieldName the name of the field to be updated.
      * @return the updater
@@ -53,57 +57,63 @@
     }
 
     /**
-     * Atomically set the value of the field of the given object managed
-     * by this Updater to the given updated value if the current value
-     * <tt>==</tt> the expected value. This method is guaranteed to be
-     * atomic with respect to other calls to <tt>compareAndSet</tt> and
-     * <tt>set</tt>, but not necessarily with respect to other
-     * changes in the field.
+     * Atomically sets the field of the given object managed by this updater
+     * to the given updated value if the current value {@code ==} the
+     * expected value. This method is guaranteed to be atomic with respect to
+     * other calls to {@code compareAndSet} and {@code set}, but not
+     * necessarily with respect to other changes in the field.
+     *
      * @param obj An object whose field to conditionally set
      * @param expect the expected value
      * @param update the new value
      * @return true if successful.
-     * @throws ClassCastException if <tt>obj</tt> is not an instance
+     * @throws ClassCastException if {@code obj} is not an instance
      * of the class possessing the field established in the constructor.
      */
-
     public abstract boolean compareAndSet(T obj, long expect, long update);
 
     /**
-     * Atomically set the value of the field of the given object managed
-     * by this Updater to the given updated value if the current value
-     * <tt>==</tt> the expected value. This method is guaranteed to be
-     * atomic with respect to other calls to <tt>compareAndSet</tt> and
-     * <tt>set</tt>, but not necessarily with respect to other
-     * changes in the field, and may fail spuriously.
+     * Atomically sets the field of the given object managed by this updater
+     * to the given updated value if the current value {@code ==} the
+     * expected value. This method is guaranteed to be atomic with respect to
+     * other calls to {@code compareAndSet} and {@code set}, but not
+     * necessarily with respect to other changes in the field.
+     *
+     * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
+     * and does not provide ordering guarantees, so is only rarely an
+     * appropriate alternative to {@code compareAndSet}.
+     *
      * @param obj An object whose field to conditionally set
      * @param expect the expected value
      * @param update the new value
      * @return true if successful.
-     * @throws ClassCastException if <tt>obj</tt> is not an instance
+     * @throws ClassCastException if {@code obj} is not an instance
      * of the class possessing the field established in the constructor.
      */
-
     public abstract boolean weakCompareAndSet(T obj, long expect, long update);
 
     /**
-     * Set the field of the given object managed by this updater. This
-     * operation is guaranteed to act as a volatile store with respect
-     * to subsequent invocations of <tt>compareAndSet</tt>.
+     * Sets the field of the given object managed by this updater to the
+     * given updated value. This operation is guaranteed to act as a volatile
+     * store with respect to subsequent invocations of {@code compareAndSet}.
+     *
      * @param obj An object whose field to set
      * @param newValue the new value
      */
     public abstract void set(T obj, long newValue);
 
     /**
-     * Get the current value held in the field by the given object.
+     * Gets the current value held in the field of the given object managed
+     * by this updater.
+     *
      * @param obj An object whose field to get
      * @return the current value
      */
     public abstract long get(T obj);
 
     /**
-     * Set to the given value and return the old value.
+     * Atomically sets the field of the given object managed by this updater
+     * to the given value and returns the old value.
      *
      * @param obj An object whose field to get and set
      * @param newValue the new value
@@ -118,9 +128,11 @@
     }
 
     /**
-     * Atomically increment by one the current value.
+     * Atomically increments by one the current value of the field of the
+     * given object managed by this updater.
+     *
      * @param obj An object whose field to get and set
-     * @return the previous value;
+     * @return the previous value
      */
     public long getAndIncrement(T obj) {
         for (;;) {
@@ -131,11 +143,12 @@
         }
     }
 
-
     /**
-     * Atomically decrement by one the current value.
+     * Atomically decrements by one the current value of the field of the
+     * given object managed by this updater.
+     *
      * @param obj An object whose field to get and set
-     * @return the previous value;
+     * @return the previous value
      */
     public long getAndDecrement(T obj) {
         for (;;) {
@@ -146,12 +159,13 @@
         }
     }
 
-
     /**
-     * Atomically add the given value to current value.
+     * Atomically adds the given value to the current value of the field of
+     * the given object managed by this updater.
+     *
      * @param obj An object whose field to get and set
      * @param delta the value to add
-     * @return the previous value;
+     * @return the previous value
      */
     public long getAndAdd(T obj, long delta) {
         for (;;) {
@@ -163,9 +177,11 @@
     }
 
     /**
-     * Atomically increment by one the current value.
+     * Atomically increments by one the current value of the field of the
+     * given object managed by this updater.
+     *
      * @param obj An object whose field to get and set
-     * @return the updated value;
+     * @return the updated value
      */
     public long incrementAndGet(T obj) {
         for (;;) {
@@ -176,11 +192,12 @@
         }
     }
 
-
     /**
-     * Atomically decrement by one the current value.
+     * Atomically decrements by one the current value of the field of the
+     * given object managed by this updater.
+     *
      * @param obj An object whose field to get and set
-     * @return the updated value;
+     * @return the updated value
      */
     public long decrementAndGet(T obj) {
         for (;;) {
@@ -191,12 +208,13 @@
         }
     }
 
-
     /**
-     * Atomically add the given value to current value.
+     * Atomically adds the given value to the current value of the field of
+     * the given object managed by this updater.
+     *
      * @param obj An object whose field to get and set
      * @param delta the value to add
-     * @return the updated value;
+     * @return the updated value
      */
     public long addAndGet(T obj, long delta) {
         for (;;) {
@@ -213,49 +231,83 @@
         // END android-changed
         private final long offset;
         private final Class<T> tclass;
+        private final Class cclass;
 
         CASUpdater(Class<T> tclass, String fieldName) {
             Field field = null;
+            Class caller = null;
+            int modifiers = 0;
             try {
                 field = tclass.getDeclaredField(fieldName);
-            } catch(Exception ex) {
+                // BEGIN android-changed
+                caller = VMStack.getStackClass2();
+                // END android-changed
+                modifiers = field.getModifiers();
+                SecurityManager smgr = System.getSecurityManager();
+                if (smgr != null) {
+                    int type = Modifier.isPublic(modifiers)
+                            ? Member.PUBLIC : Member.DECLARED;
+                    smgr.checkMemberAccess(tclass, type);
+                    smgr.checkPackageAccess(tclass.getPackage().getName());
+                }
+            } catch (Exception ex) {
                 throw new RuntimeException(ex);
             }
-            
+
             Class fieldt = field.getType();
             if (fieldt != long.class)
                 throw new IllegalArgumentException("Must be long type");
-            
-            if (!Modifier.isVolatile(field.getModifiers()))
+
+            if (!Modifier.isVolatile(modifiers))
                 throw new IllegalArgumentException("Must be volatile type");
-            
+
+            this.cclass = (Modifier.isProtected(modifiers) &&
+                           caller != tclass) ? caller : null;
             this.tclass = tclass;
             offset = unsafe.objectFieldOffset(field);
         }
 
-        public boolean compareAndSet(T obj, long expect, long update) {
+        private void fullCheck(T obj) {
             if (!tclass.isInstance(obj))
                 throw new ClassCastException();
+            if (cclass != null)
+                ensureProtectedAccess(obj);
+        }
+
+        public boolean compareAndSet(T obj, long expect, long update) {
+            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
             return unsafe.compareAndSwapLong(obj, offset, expect, update);
         }
 
         public boolean weakCompareAndSet(T obj, long expect, long update) {
-            if (!tclass.isInstance(obj))
-                throw new ClassCastException();
+            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
             return unsafe.compareAndSwapLong(obj, offset, expect, update);
         }
 
         public void set(T obj, long newValue) {
-            if (!tclass.isInstance(obj))
-                throw new ClassCastException();
+            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
             unsafe.putLongVolatile(obj, offset, newValue);
         }
 
         public long get(T obj) {
-            if (!tclass.isInstance(obj))
-                throw new ClassCastException();
+            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
             return unsafe.getLongVolatile(obj, offset);
         }
+
+        private void ensureProtectedAccess(T obj) {
+            if (cclass.isInstance(obj)) {
+                return;
+            }
+            throw new RuntimeException (
+                new IllegalAccessException("Class " +
+                    cclass.getName() +
+                    " can not access a protected member of class " +
+                    tclass.getName() +
+                    " using an instance of " +
+                    obj.getClass().getName()
+                )
+            );
+        }
     }
 
 
@@ -265,32 +317,54 @@
         // END android-changed
         private final long offset;
         private final Class<T> tclass;
+        private final Class cclass;
 
         LockedUpdater(Class<T> tclass, String fieldName) {
             Field field = null;
+            Class caller = null;
+            int modifiers = 0;
             try {
                 field = tclass.getDeclaredField(fieldName);
-            } catch(Exception ex) {
+                // BEGIN android-changed
+                caller = VMStack.getStackClass2();
+                // END android-changed
+                modifiers = field.getModifiers();
+                SecurityManager smgr = System.getSecurityManager();
+                if (smgr != null) {
+                    int type = Modifier.isPublic(modifiers)
+                            ? Member.PUBLIC : Member.DECLARED;
+                    smgr.checkMemberAccess(tclass, type);
+                    smgr.checkPackageAccess(tclass.getPackage().getName());
+                }
+            } catch (Exception ex) {
                 throw new RuntimeException(ex);
             }
-            
+
             Class fieldt = field.getType();
             if (fieldt != long.class)
                 throw new IllegalArgumentException("Must be long type");
-            
-            if (!Modifier.isVolatile(field.getModifiers()))
+
+            if (!Modifier.isVolatile(modifiers))
                 throw new IllegalArgumentException("Must be volatile type");
-            
+
+            this.cclass = (Modifier.isProtected(modifiers) &&
+                           caller != tclass) ? caller : null;
             this.tclass = tclass;
             offset = unsafe.objectFieldOffset(field);
         }
 
-        public boolean compareAndSet(T obj, long expect, long update) {
+        private void fullCheck(T obj) {
             if (!tclass.isInstance(obj))
                 throw new ClassCastException();
+            if (cclass != null)
+                ensureProtectedAccess(obj);
+        }
+
+        public boolean compareAndSet(T obj, long expect, long update) {
+            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
             synchronized(this) {
                 long v = unsafe.getLong(obj, offset);
-                if (v != expect) 
+                if (v != expect)
                     return false;
                 unsafe.putLong(obj, offset, update);
                 return true;
@@ -302,20 +376,36 @@
         }
 
         public void set(T obj, long newValue) {
-            if (!tclass.isInstance(obj))
-                throw new ClassCastException();
+            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
             synchronized(this) {
                 unsafe.putLong(obj, offset, newValue);
             }
         }
 
+        public void lazySet(T obj, long newValue) {
+            set(obj, newValue);
+        }
+
         public long get(T obj) {
-            if (!tclass.isInstance(obj))
-                throw new ClassCastException();
+            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
             synchronized(this) {
                 return unsafe.getLong(obj, offset);
             }
         }
+
+        private void ensureProtectedAccess(T obj) {
+            if (cclass.isInstance(obj)) {
+                return;
+            }
+            throw new RuntimeException (
+                new IllegalAccessException("Class " +
+                    cclass.getName() +
+                    " can not access a protected member of class " +
+                    tclass.getName() +
+                    " using an instance of " +
+                    obj.getClass().getName()
+                )
+            );
+        }
     }
 }
-
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicMarkableReference.java b/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicMarkableReference.java
index 11c91ba..4877dc4 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicMarkableReference.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicMarkableReference.java
@@ -7,7 +7,7 @@
 package java.util.concurrent.atomic;
 
 /**
- * An <tt>AtomicMarkableReference</tt> maintains an object reference
+ * An {@code AtomicMarkableReference} maintains an object reference
  * along with a mark bit, that can be updated atomically.
  * <p>
  * <p> Implementation note. This implementation maintains markable
@@ -31,7 +31,7 @@
     private final AtomicReference<ReferenceBooleanPair<V>>  atomicRef;
 
     /**
-     * Creates a new <tt>AtomicMarkableReference</tt> with the given
+     * Creates a new {@code AtomicMarkableReference} with the given
      * initial values.
      *
      * @param initialRef the initial reference
@@ -61,10 +61,10 @@
 
     /**
      * Returns the current values of both the reference and the mark.
-     * Typical usage is <tt>boolean[1] holder; ref = v.get(holder); </tt>.
+     * Typical usage is {@code boolean[1] holder; ref = v.get(holder); }.
      *
      * @param markHolder an array of size of at least one. On return,
-     * <tt>markholder[0]</tt> will hold the value of the mark.
+     * {@code markholder[0]} will hold the value of the mark.
      * @return the current value of the reference
      */
     public V get(boolean[] markHolder) {
@@ -76,12 +76,12 @@
     /**
      * Atomically sets the value of both the reference and mark
      * to the given update values if the
-     * current reference is <tt>==</tt> to the expected reference
-     * and the current mark is equal to the expected mark.  Any given
-     * invocation of this operation may fail (return
-     * <tt>false</tt>) spuriously, but repeated invocation when
-     * the current value holds the expected value and no other thread
-     * is also attempting to set the value will eventually succeed.
+     * current reference is {@code ==} to the expected reference
+     * and the current mark is equal to the expected mark.
+     *
+     * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
+     * and does not provide ordering guarantees, so is only rarely an
+     * appropriate alternative to {@code compareAndSet}.
      *
      * @param expectedReference the expected value of the reference
      * @param newReference the new value for the reference
@@ -93,7 +93,7 @@
                                      V       newReference,
                                      boolean expectedMark,
                                      boolean newMark) {
-        ReferenceBooleanPair current = atomicRef.get();
+        ReferenceBooleanPair<V> current = atomicRef.get();
         return  expectedReference == current.reference &&
             expectedMark == current.bit &&
             ((newReference == current.reference && newMark == current.bit) ||
@@ -105,8 +105,8 @@
     /**
      * Atomically sets the value of both the reference and mark
      * to the given update values if the
-     * current reference is <tt>==</tt> to the expected reference
-     * and the current mark is equal to the expected mark.  
+     * current reference is {@code ==} to the expected reference
+     * and the current mark is equal to the expected mark.
      *
      * @param expectedReference the expected value of the reference
      * @param newReference the new value for the reference
@@ -118,7 +118,7 @@
                                  V       newReference,
                                  boolean expectedMark,
                                  boolean newMark) {
-        ReferenceBooleanPair current = atomicRef.get();
+        ReferenceBooleanPair<V> current = atomicRef.get();
         return  expectedReference == current.reference &&
             expectedMark == current.bit &&
             ((newReference == current.reference && newMark == current.bit) ||
@@ -134,16 +134,16 @@
      * @param newMark the new value for the mark
      */
     public void set(V newReference, boolean newMark) {
-        ReferenceBooleanPair current = atomicRef.get();
+        ReferenceBooleanPair<V> current = atomicRef.get();
         if (newReference != current.reference || newMark != current.bit)
             atomicRef.set(new ReferenceBooleanPair<V>(newReference, newMark));
     }
 
     /**
      * Atomically sets the value of the mark to the given update value
-     * if the current reference is <tt>==</tt> to the expected
+     * if the current reference is {@code ==} to the expected
      * reference.  Any given invocation of this operation may fail
-     * (return <tt>false</tt>) spuriously, but repeated invocation
+     * (return {@code false}) spuriously, but repeated invocation
      * when the current value holds the expected value and no other
      * thread is also attempting to set the value will eventually
      * succeed.
@@ -153,7 +153,7 @@
      * @return true if successful
      */
     public boolean attemptMark(V expectedReference, boolean newMark) {
-        ReferenceBooleanPair current = atomicRef.get();
+        ReferenceBooleanPair<V> current = atomicRef.get();
         return  expectedReference == current.reference &&
             (newMark == current.bit ||
              atomicRef.compareAndSet
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReference.java b/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReference.java
index 89c050c..1de9b1c 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReference.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReference.java
@@ -15,7 +15,7 @@
  * @author Doug Lea
  * @param <V> The type of object referred to by this reference
  */
-public class AtomicReference<V>  implements java.io.Serializable { 
+public class AtomicReference<V>  implements java.io.Serializable {
     private static final long serialVersionUID = -1848883965231344442L;
 
     // BEGIN android-changed
@@ -27,13 +27,13 @@
       try {
         valueOffset = unsafe.objectFieldOffset
             (AtomicReference.class.getDeclaredField("value"));
-      } catch(Exception ex) { throw new Error(ex); }
+      } catch (Exception ex) { throw new Error(ex); }
     }
 
     private volatile V value;
 
     /**
-     * Create a new AtomicReference with the given initial value.
+     * Creates a new AtomicReference with the given initial value.
      *
      * @param initialValue the initial value
      */
@@ -42,55 +42,59 @@
     }
 
     /**
-     * Create a new AtomicReference with null initial value.
+     * Creates a new AtomicReference with null initial value.
      */
     public AtomicReference() {
     }
-  
+
     /**
-     * Get the current value.
+     * Gets the current value.
      *
      * @return the current value
      */
     public final V get() {
         return value;
     }
-  
+
     /**
-     * Set to the given value.
+     * Sets to the given value.
      *
      * @param newValue the new value
      */
     public final void set(V newValue) {
         value = newValue;
     }
-  
+
     /**
-     * Atomically set the value to the given updated value
-     * if the current value <tt>==</tt> the expected value.
+     * Atomically sets the value to the given updated value
+     * if the current value {@code ==} the expected value.
      * @param expect the expected value
      * @param update the new value
      * @return true if successful. False return indicates that
      * the actual value was not equal to the expected value.
      */
     public final boolean compareAndSet(V expect, V update) {
-      return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
+        return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
     }
 
     /**
-     * Atomically set the value to the given updated value
-     * if the current value <tt>==</tt> the expected value.
-     * May fail spuriously.
+     * Atomically sets the value to the given updated value
+     * if the current value {@code ==} the expected value.
+     *
+     * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
+     * and does not provide ordering guarantees, so is only rarely an
+     * appropriate alternative to {@code compareAndSet}.
+     *
      * @param expect the expected value
      * @param update the new value
      * @return true if successful.
      */
     public final boolean weakCompareAndSet(V expect, V update) {
-      return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
+        return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
     }
 
     /**
-     * Set to the given value and return the old value.
+     * Atomically sets to the given value and returns the old value.
      *
      * @param newValue the new value
      * @return the previous value
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceArray.java b/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceArray.java
index 9ad800c..9a484e6 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceArray.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceArray.java
@@ -17,7 +17,7 @@
  * @author Doug Lea
  * @param <E> The base class of elements held in this array
  */
-public class AtomicReferenceArray<E> implements java.io.Serializable { 
+public class AtomicReferenceArray<E> implements java.io.Serializable {
     private static final long serialVersionUID = -6209656149925076980L;
 
     // BEGIN android-changed
@@ -34,25 +34,25 @@
     }
 
     /**
-     * Create a new AtomicReferenceArray of given length.
+     * Creates a new AtomicReferenceArray of given length.
      * @param length the length of the array
      */
     public AtomicReferenceArray(int length) {
         array = new Object[length];
         // must perform at least one volatile write to conform to JMM
-        if (length > 0) 
+        if (length > 0)
             unsafe.putObjectVolatile(array, rawIndex(0), null);
     }
 
     /**
-     * Create a new AtomicReferenceArray with the same length as, and
+     * Creates a new AtomicReferenceArray with the same length as, and
      * all elements copied from, the given array.
      *
      * @param array the array to copy elements from
      * @throws NullPointerException if array is null
      */
     public AtomicReferenceArray(E[] array) {
-        if (array == null) 
+        if (array == null)
             throw new NullPointerException();
         int length = array.length;
         this.array = new Object[length];
@@ -76,7 +76,7 @@
     }
 
     /**
-     * Get the current value at position <tt>i</tt>.
+     * Gets the current value at position {@code i}.
      *
      * @param i the index
      * @return the current value
@@ -84,9 +84,9 @@
     public final E get(int i) {
         return (E) unsafe.getObjectVolatile(array, rawIndex(i));
     }
- 
+
     /**
-     * Set the element at position <tt>i</tt> to the given value.
+     * Sets the element at position {@code i} to the given value.
      *
      * @param i the index
      * @param newValue the new value
@@ -94,10 +94,10 @@
     public final void set(int i, E newValue) {
         unsafe.putObjectVolatile(array, rawIndex(i), newValue);
     }
-  
+
     /**
-     * Set the element at position <tt>i</tt> to the given value and return the
-     * old value.
+     * Atomically sets the element at position {@code i} to the given
+     * value and returns the old value.
      *
      * @param i the index
      * @param newValue the new value
@@ -110,10 +110,10 @@
                 return current;
         }
     }
-  
+
     /**
-     * Atomically set the value to the given updated value
-     * if the current value <tt>==</tt> the expected value.
+     * Atomically sets the element at position {@code i} to the given
+     * updated value if the current value {@code ==} the expected value.
      * @param i the index
      * @param expect the expected value
      * @param update the new value
@@ -121,14 +121,18 @@
      * the actual value was not equal to the expected value.
      */
     public final boolean compareAndSet(int i, E expect, E update) {
-        return unsafe.compareAndSwapObject(array, rawIndex(i), 
+        return unsafe.compareAndSwapObject(array, rawIndex(i),
                                          expect, update);
     }
 
     /**
-     * Atomically set the value to the given updated value
-     * if the current value <tt>==</tt> the expected value.
-     * May fail spuriously.
+     * Atomically sets the element at position {@code i} to the given
+     * updated value if the current value {@code ==} the expected value.
+     *
+     * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
+     * and does not provide ordering guarantees, so is only rarely an
+     * appropriate alternative to {@code compareAndSet}.
+     *
      * @param i the index
      * @param expect the expected value
      * @param update the new value
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java b/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java
index f20661d..fae134f 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java
@@ -8,9 +8,12 @@
 import sun.misc.Unsafe;
 import java.lang.reflect.*;
 
+import org.apache.harmony.kernel.vm.VM;
+import dalvik.system.VMStack;
+
 /**
  * A reflection-based utility that enables atomic updates to
- * designated <tt>volatile</tt> reference fields of designated
+ * designated {@code volatile} reference fields of designated
  * classes.  This class is designed for use in atomic data structures
  * in which several reference fields of the same node are
  * independently subject to atomic updates. For example, a tree node
@@ -33,12 +36,13 @@
  * }
  * </pre>
  *
- * <p> Note that the guarantees of the <tt>compareAndSet</tt>
- * method in this class are weaker than in other atomic classes. Because this
- * class cannot ensure that all uses of the field are appropriate for
- * purposes of atomic access, it can guarantee atomicity and volatile
- * semantics only with respect to other invocations of
- * <tt>compareAndSet</tt> and <tt>set</tt>.
+ * <p>Note that the guarantees of the {@code compareAndSet}
+ * method in this class are weaker than in other atomic classes.
+ * Because this class cannot ensure that all uses of the field
+ * are appropriate for purposes of atomic access, it can
+ * guarantee atomicity only with respect to other invocations of
+ * {@code compareAndSet} and {@code set} on the same updater.
+ *
  * @since 1.5
  * @author Doug Lea
  * @param <T> The type of the object holding the updatable field
@@ -47,9 +51,10 @@
 public abstract class AtomicReferenceFieldUpdater<T, V>  {
 
     /**
-     * Creates an updater for objects with the given field.  The Class
-     * arguments are needed to check that reflective types and generic
-     * types match.
+     * Creates and returns an updater for objects with the given field.
+     * The Class arguments are needed to check that reflective types and
+     * generic types match.
+     *
      * @param tclass the class of the objects holding the field.
      * @param vclass the class of the field
      * @param fieldName the name of the field to be updated.
@@ -59,9 +64,8 @@
      * exception if the class does not hold field or is the wrong type.
      */
     public static <U, W> AtomicReferenceFieldUpdater<U,W> newUpdater(Class<U> tclass, Class<W> vclass, String fieldName) {
-        // Currently rely on standard intrinsics implementation
-        return new AtomicReferenceFieldUpdaterImpl<U,W>(tclass, 
-                                                        vclass, 
+        return new AtomicReferenceFieldUpdaterImpl<U,W>(tclass,
+                                                        vclass,
                                                         fieldName);
     }
 
@@ -72,27 +76,30 @@
     }
 
     /**
-     * Atomically set the value of the field of the given object managed
-     * by this Updater to the given updated value if the current value
-     * <tt>==</tt> the expected value. This method is guaranteed to be
-     * atomic with respect to other calls to <tt>compareAndSet</tt> and
-     * <tt>set</tt>, but not necessarily with respect to other
-     * changes in the field.
+     * Atomically sets the field of the given object managed by this updater
+     * to the given updated value if the current value {@code ==} the
+     * expected value. This method is guaranteed to be atomic with respect to
+     * other calls to {@code compareAndSet} and {@code set}, but not
+     * necessarily with respect to other changes in the field.
+     *
      * @param obj An object whose field to conditionally set
      * @param expect the expected value
      * @param update the new value
      * @return true if successful.
      */
-
     public abstract boolean compareAndSet(T obj, V expect, V update);
 
     /**
-     * Atomically set the value of the field of the given object managed
-     * by this Updater to the given updated value if the current value
-     * <tt>==</tt> the expected value. This method is guaranteed to be
-     * atomic with respect to other calls to <tt>compareAndSet</tt> and
-     * <tt>set</tt>, but not necessarily with respect to other
-     * changes in the field, and may fail spuriously.
+     * Atomically sets the field of the given object managed by this updater
+     * to the given updated value if the current value {@code ==} the
+     * expected value. This method is guaranteed to be atomic with respect to
+     * other calls to {@code compareAndSet} and {@code set}, but not
+     * necessarily with respect to other changes in the field.
+     *
+     * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
+     * and does not provide ordering guarantees, so is only rarely an
+     * appropriate alternative to {@code compareAndSet}.
+     *
      * @param obj An object whose field to conditionally set
      * @param expect the expected value
      * @param update the new value
@@ -101,23 +108,27 @@
     public abstract boolean weakCompareAndSet(T obj, V expect, V update);
 
     /**
-     * Set the field of the given object managed by this updater. This
-     * operation is guaranteed to act as a volatile store with respect
-     * to subsequent invocations of <tt>compareAndSet</tt>.
+     * Sets the field of the given object managed by this updater to the
+     * given updated value. This operation is guaranteed to act as a volatile
+     * store with respect to subsequent invocations of {@code compareAndSet}.
+     *
      * @param obj An object whose field to set
      * @param newValue the new value
      */
     public abstract void set(T obj, V newValue);
 
     /**
-     * Get the current value held in the field by the given object.
+     * Gets the current value held in the field of the given object managed
+     * by this updater.
+     *
      * @param obj An object whose field to get
      * @return the current value
      */
     public abstract V get(T obj);
 
     /**
-     * Set to the given value and return the old value.
+     * Atomically sets the field of the given object managed by this updater
+     * to the given value and returns the old value.
      *
      * @param obj An object whose field to get and set
      * @param newValue the new value
@@ -131,67 +142,128 @@
         }
     }
 
-    /**
-     * Standard hotspot implementation using intrinsics
-     */
-    private static class AtomicReferenceFieldUpdaterImpl<T,V> extends AtomicReferenceFieldUpdater<T,V> {
+    private static final class AtomicReferenceFieldUpdaterImpl<T,V>
+        extends AtomicReferenceFieldUpdater<T,V> {
         // BEGIN android-changed
         private static final Unsafe unsafe = UnsafeAccess.THE_ONE;
         // END android-changed
         private final long offset;
         private final Class<T> tclass;
         private final Class<V> vclass;
+        private final Class cclass;
 
-        AtomicReferenceFieldUpdaterImpl(Class<T> tclass, Class<V> vclass, String fieldName) {
+        /*
+         * Internal type checks within all update methods contain
+         * internal inlined optimizations checking for the common
+         * cases where the class is final (in which case a simple
+         * getClass comparison suffices) or is of type Object (in
+         * which case no check is needed because all objects are
+         * instances of Object). The Object case is handled simply by
+         * setting vclass to null in constructor.  The targetCheck and
+         * updateCheck methods are invoked when these faster
+         * screenings fail.
+         */
+
+        AtomicReferenceFieldUpdaterImpl(Class<T> tclass,
+                                        Class<V> vclass,
+                                        String fieldName) {
             Field field = null;
             Class fieldClass = null;
+            Class caller = null;
+            int modifiers = 0;
             try {
                 field = tclass.getDeclaredField(fieldName);
+                // BEGIN android-changed
+                caller = VMStack.getStackClass2();
+                // END android-changed
+                modifiers = field.getModifiers();
+                SecurityManager smgr = System.getSecurityManager();
+                if (smgr != null) {
+                    int type = Modifier.isPublic(modifiers)
+                            ? Member.PUBLIC : Member.DECLARED;
+                    smgr.checkMemberAccess(tclass, type);
+                    smgr.checkPackageAccess(tclass.getPackage().getName());
+                }
                 fieldClass = field.getType();
-            } catch(Exception ex) {
+            } catch (Exception ex) {
                 throw new RuntimeException(ex);
             }
-            
+
             if (vclass != fieldClass)
                 throw new ClassCastException();
-            
-            if (!Modifier.isVolatile(field.getModifiers()))
+
+            if (!Modifier.isVolatile(modifiers))
                 throw new IllegalArgumentException("Must be volatile type");
 
+            this.cclass = (Modifier.isProtected(modifiers) &&
+                           caller != tclass) ? caller : null;
             this.tclass = tclass;
-            this.vclass = vclass;
+            if (vclass == Object.class)
+                this.vclass = null;
+            else
+                this.vclass = vclass;
             offset = unsafe.objectFieldOffset(field);
         }
-        
+
+        void targetCheck(T obj) {
+            if (!tclass.isInstance(obj))
+                throw new ClassCastException();
+            if (cclass != null)
+                ensureProtectedAccess(obj);
+        }
+
+        void updateCheck(T obj, V update) {
+            if (!tclass.isInstance(obj) ||
+                (update != null && vclass != null && !vclass.isInstance(update)))
+                throw new ClassCastException();
+            if (cclass != null)
+                ensureProtectedAccess(obj);
+        }
 
         public boolean compareAndSet(T obj, V expect, V update) {
-            if (!tclass.isInstance(obj) ||
-                (update != null && !vclass.isInstance(update)))
-                throw new ClassCastException();
+            if (obj == null || obj.getClass() != tclass || cclass != null ||
+                (update != null && vclass != null &&
+                 vclass != update.getClass()))
+                updateCheck(obj, update);
             return unsafe.compareAndSwapObject(obj, offset, expect, update);
         }
 
         public boolean weakCompareAndSet(T obj, V expect, V update) {
             // same implementation as strong form for now
-            if (!tclass.isInstance(obj) ||
-                (update != null && !vclass.isInstance(update)))
-                throw new ClassCastException();
+            if (obj == null || obj.getClass() != tclass || cclass != null ||
+                (update != null && vclass != null &&
+                 vclass != update.getClass()))
+                updateCheck(obj, update);
             return unsafe.compareAndSwapObject(obj, offset, expect, update);
         }
 
-
         public void set(T obj, V newValue) {
-            if (!tclass.isInstance(obj) ||
-                (newValue != null && !vclass.isInstance(newValue)))
-                throw new ClassCastException();
+            if (obj == null || obj.getClass() != tclass || cclass != null ||
+                (newValue != null && vclass != null &&
+                 vclass != newValue.getClass()))
+                updateCheck(obj, newValue);
             unsafe.putObjectVolatile(obj, offset, newValue);
         }
 
         public V get(T obj) {
-            if (!tclass.isInstance(obj))
-                throw new ClassCastException();
+            if (obj == null || obj.getClass() != tclass || cclass != null)
+                targetCheck(obj);
             return (V)unsafe.getObjectVolatile(obj, offset);
         }
+
+        private void ensureProtectedAccess(T obj) {
+            if (cclass.isInstance(obj)) {
+                return;
+            }
+            throw new RuntimeException (
+                new IllegalAccessException("Class " +
+                    cclass.getName() +
+                    " can not access a protected member of class " +
+                    tclass.getName() +
+                    " using an instance of " +
+                    obj.getClass().getName()
+                )
+            );
+        }
     }
 }
-
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicStampedReference.java b/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicStampedReference.java
index b0a02c2..a1d535f 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicStampedReference.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/atomic/AtomicStampedReference.java
@@ -7,8 +7,8 @@
 package java.util.concurrent.atomic;
 
 /**
- * An <tt>AtomicStampedReference</tt> maintains an object reference
- * along with an integer "stamp", that can be updated atomically.  
+ * An {@code AtomicStampedReference} maintains an object reference
+ * along with an integer "stamp", that can be updated atomically.
  *
  * <p> Implementation note. This implementation maintains stamped
  * references by creating internal objects representing "boxed"
@@ -31,7 +31,7 @@
     private final AtomicReference<ReferenceIntegerPair<V>>  atomicRef;
 
     /**
-     * Creates a new <tt>AtomicStampedReference</tt> with the given
+     * Creates a new {@code AtomicStampedReference} with the given
      * initial values.
      *
      * @param initialRef the initial reference
@@ -62,10 +62,10 @@
 
     /**
      * Returns the current values of both the reference and the stamp.
-     * Typical usage is <tt>int[1] holder; ref = v.get(holder); </tt>.
+     * Typical usage is {@code int[1] holder; ref = v.get(holder); }.
      *
      * @param stampHolder an array of size of at least one.  On return,
-     * <tt>stampholder[0]</tt> will hold the value of the stamp.
+     * {@code stampholder[0]} will hold the value of the stamp.
      * @return the current value of the reference
      */
     public V get(int[] stampHolder) {
@@ -77,12 +77,12 @@
     /**
      * Atomically sets the value of both the reference and stamp
      * to the given update values if the
-     * current reference is <tt>==</tt> to the expected reference
-     * and the current stamp is equal to the expected stamp.  Any given
-     * invocation of this operation may fail (return
-     * <tt>false</tt>) spuriously, but repeated invocation when
-     * the current value holds the expected value and no other thread
-     * is also attempting to set the value will eventually succeed.
+     * current reference is {@code ==} to the expected reference
+     * and the current stamp is equal to the expected stamp.
+     *
+     * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
+     * and does not provide ordering guarantees, so is only rarely an
+     * appropriate alternative to {@code compareAndSet}.
      *
      * @param expectedReference the expected value of the reference
      * @param newReference the new value for the reference
@@ -94,7 +94,7 @@
                                      V      newReference,
                                      int    expectedStamp,
                                      int    newStamp) {
-        ReferenceIntegerPair current = atomicRef.get();
+        ReferenceIntegerPair<V> current = atomicRef.get();
         return  expectedReference == current.reference &&
             expectedStamp == current.integer &&
             ((newReference == current.reference &&
@@ -107,8 +107,8 @@
     /**
      * Atomically sets the value of both the reference and stamp
      * to the given update values if the
-     * current reference is <tt>==</tt> to the expected reference
-     * and the current stamp is equal to the expected stamp. 
+     * current reference is {@code ==} to the expected reference
+     * and the current stamp is equal to the expected stamp.
      *
      * @param expectedReference the expected value of the reference
      * @param newReference the new value for the reference
@@ -120,7 +120,7 @@
                                  V      newReference,
                                  int    expectedStamp,
                                  int    newStamp) {
-        ReferenceIntegerPair current = atomicRef.get();
+        ReferenceIntegerPair<V> current = atomicRef.get();
         return  expectedReference == current.reference &&
             expectedStamp == current.integer &&
             ((newReference == current.reference &&
@@ -138,16 +138,16 @@
      * @param newStamp the new value for the stamp
      */
     public void set(V newReference, int newStamp) {
-        ReferenceIntegerPair current = atomicRef.get();
+        ReferenceIntegerPair<V> current = atomicRef.get();
         if (newReference != current.reference || newStamp != current.integer)
             atomicRef.set(new ReferenceIntegerPair<V>(newReference, newStamp));
     }
 
     /**
      * Atomically sets the value of the stamp to the given update value
-     * if the current reference is <tt>==</tt> to the expected
+     * if the current reference is {@code ==} to the expected
      * reference.  Any given invocation of this operation may fail
-     * (return <tt>false</tt>) spuriously, but repeated invocation
+     * (return {@code false}) spuriously, but repeated invocation
      * when the current value holds the expected value and no other
      * thread is also attempting to set the value will eventually
      * succeed.
@@ -157,7 +157,7 @@
      * @return true if successful
      */
     public boolean attemptStamp(V expectedReference, int newStamp) {
-        ReferenceIntegerPair current = atomicRef.get();
+        ReferenceIntegerPair<V> current = atomicRef.get();
         return  expectedReference == current.reference &&
             (newStamp == current.integer ||
              atomicRef.compareAndSet(current,
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/atomic/package-info.java b/libcore/concurrent/src/main/java/java/util/concurrent/atomic/package-info.java
new file mode 100644
index 0000000..2252e5c
--- /dev/null
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/atomic/package-info.java
@@ -0,0 +1,163 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+/**
+ * A small toolkit of classes that support lock-free thread-safe
+ * programming on single variables.  In essence, the classes in this
+ * package extend the notion of {@code volatile} values, fields, and
+ * array elements to those that also provide an atomic conditional update
+ * operation of the form:
+ *
+ * <pre>
+ *   boolean compareAndSet(expectedValue, updateValue);
+ * </pre>
+ *
+ * <p>This method (which varies in argument types across different
+ * classes) atomically sets a variable to the {@code updateValue} if it
+ * currently holds the {@code expectedValue}, reporting {@code true} on
+ * success.  The classes in this package also contain methods to get and
+ * unconditionally set values, as well as a weaker conditional atomic
+ * update operation {@code weakCompareAndSet} described below.
+ *
+ * <p>The specifications of these methods enable implementations to
+ * employ efficient machine-level atomic instructions that are available
+ * on contemporary processors.  However on some platforms, support may
+ * entail some form of internal locking.  Thus the methods are not
+ * strictly guaranteed to be non-blocking --
+ * a thread may block transiently before performing the operation.
+ *
+ * <p>Instances of classes
+ * {@link java.util.concurrent.atomic.AtomicBoolean},
+ * {@link java.util.concurrent.atomic.AtomicInteger},
+ * {@link java.util.concurrent.atomic.AtomicLong}, and
+ * {@link java.util.concurrent.atomic.AtomicReference}
+ * each provide access and updates to a single variable of the
+ * corresponding type.  Each class also provides appropriate utility
+ * methods for that type.  For example, classes {@code AtomicLong} and
+ * {@code AtomicInteger} provide atomic increment methods.  One
+ * application is to generate sequence numbers, as in:
+ *
+ * <pre>
+ * class Sequencer {
+ *   private final AtomicLong sequenceNumber
+ *     = new AtomicLong(0);
+ *   public long next() {
+ *     return sequenceNumber.getAndIncrement();
+ *   }
+ * }
+ * </pre>
+ *
+ * <p>The memory effects for accesses and updates of atomics generally
+ * follow the rules for volatiles, as stated in
+ * <a href="http://java.sun.com/docs/books/jls/"> The Java Language
+ * Specification, Third Edition (17.4 Memory Model)</a>:
+ *
+ * <ul>
+ *
+ *   <li> {@code get} has the memory effects of reading a
+ * {@code volatile} variable.
+ *
+ *   <li> {@code set} has the memory effects of writing (assigning) a
+ * {@code volatile} variable.
+ *
+ *   <li>{@code weakCompareAndSet} atomically reads and conditionally
+ *   writes a variable but does <em>not</em>
+ *   create any happens-before orderings, so provides no guarantees
+ *   with respect to previous or subsequent reads and writes of any
+ *   variables other than the target of the {@code weakCompareAndSet}.
+ *
+ *   <li> {@code compareAndSet}
+ *   and all other read-and-update operations such as {@code getAndIncrement}
+ *   have the memory effects of both reading and
+ *   writing {@code volatile} variables.
+ * </ul>
+ *
+ * <p>In addition to classes representing single values, this package
+ * contains <em>Updater</em> classes that can be used to obtain
+ * {@code compareAndSet} operations on any selected {@code volatile}
+ * field of any selected class.
+ *
+ * {@link java.util.concurrent.atomic.AtomicReferenceFieldUpdater},
+ * {@link java.util.concurrent.atomic.AtomicIntegerFieldUpdater}, and
+ * {@link java.util.concurrent.atomic.AtomicLongFieldUpdater} are
+ * reflection-based utilities that provide access to the associated
+ * field types.  These are mainly of use in atomic data structures in
+ * which several {@code volatile} fields of the same node (for
+ * example, the links of a tree node) are independently subject to
+ * atomic updates.  These classes enable greater flexibility in how
+ * and when to use atomic updates, at the expense of more awkward
+ * reflection-based setup, less convenient usage, and weaker
+ * guarantees.
+ *
+ * <p>The
+ * {@link java.util.concurrent.atomic.AtomicIntegerArray},
+ * {@link java.util.concurrent.atomic.AtomicLongArray}, and
+ * {@link java.util.concurrent.atomic.AtomicReferenceArray} classes
+ * further extend atomic operation support to arrays of these types.
+ * These classes are also notable in providing {@code volatile} access
+ * semantics for their array elements, which is not supported for
+ * ordinary arrays.
+ *
+ * <a name="Spurious">
+ * <p>The atomic classes also support method {@code weakCompareAndSet},
+ * which has limited applicability.  On some platforms, the weak version
+ * may be more efficient than {@code compareAndSet} in the normal case,
+ * but differs in that any given invocation of the
+ * {@code weakCompareAndSet} method may return {@code false}
+ * <em>spuriously</em> (that is, for no apparent reason)</a>.  A
+ * {@code false} return means only that the operation may be retried if
+ * desired, relying on the guarantee that repeated invocation when the
+ * variable holds {@code expectedValue} and no other thread is also
+ * attempting to set the variable will eventually succeed.  (Such
+ * spurious failures may for example be due to memory contention effects
+ * that are unrelated to whether the expected and current values are
+ * equal.)  Additionally {@code weakCompareAndSet} does not provide
+ * ordering guarantees that are usually needed for synchronization
+ * control.  However, the method may be useful for updating counters and
+ * statistics when such updates are unrelated to the other
+ * happens-before orderings of a program.  When a thread sees an update
+ * to an atomic variable caused by a {@code weakCompareAndSet}, it does
+ * not necessarily see updates to any <em>other</em> variables that
+ * occurred before the {@code weakCompareAndSet}.  This may be
+ * acceptable when, for example, updating performance statistics, but
+ * rarely otherwise.
+ *
+ * <p>The {@link java.util.concurrent.atomic.AtomicMarkableReference}
+ * class associates a single boolean with a reference.  For example, this
+ * bit might be used inside a data structure to mean that the object
+ * being referenced has logically been deleted.
+ *
+ * The {@link java.util.concurrent.atomic.AtomicStampedReference}
+ * class associates an integer value with a reference.  This may be
+ * used for example, to represent version numbers corresponding to
+ * series of updates.
+ *
+ * <p>Atomic classes are designed primarily as building blocks for
+ * implementing non-blocking data structures and related infrastructure
+ * classes.  The {@code compareAndSet} method is not a general
+ * replacement for locking.  It applies only when critical updates for an
+ * object are confined to a <em>single</em> variable.
+ *
+ * <p>Atomic classes are not general purpose replacements for
+ * {@code java.lang.Integer} and related classes.  They do <em>not</em>
+ * define methods such as {@code hashCode} and
+ * {@code compareTo}.  (Because atomic variables are expected to be
+ * mutated, they are poor choices for hash table keys.)  Additionally,
+ * classes are provided only for those types that are commonly useful in
+ * intended applications.  For example, there is no atomic class for
+ * representing {@code byte}.  In those infrequent cases where you would
+ * like to do so, you can use an {@code AtomicInteger} to hold
+ * {@code byte} values, and cast appropriately.
+ *
+ * You can also hold floats using
+ * {@link java.lang.Float#floatToIntBits} and
+ * {@link java.lang.Float#intBitsToFloat} conversions, and doubles using
+ * {@link java.lang.Double#doubleToLongBits} and
+ * {@link java.lang.Double#longBitsToDouble} conversions.
+ *
+ * @since 1.5
+ */
+package java.util.concurrent.atomic;
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/atomic/package.html b/libcore/concurrent/src/main/java/java/util/concurrent/atomic/package.html
deleted file mode 100644
index bdb15e8..0000000
--- a/libcore/concurrent/src/main/java/java/util/concurrent/atomic/package.html
+++ /dev/null
@@ -1,132 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html> <head>
-<title>Atomics</title>
-</head>
-
-<body>
-
-A small toolkit of classes that support lock-free thread-safe
-programming on single variables. In essence, the classes in this
-package extend the notion of <tt>volatile</tt> values, fields, and
-array elements to those that also provide an atomic conditional update
-operation of the form:
-
-<pre>
-  boolean compareAndSet(expectedValue, updateValue);
-</pre>
-
-<p> This method (which varies in argument types across different
-classes) atomically sets a variable to the <tt>updateValue</tt> if it
-currently holds the <tt>expectedValue</tt>, reporting <tt>true</tt> on
-success.  The classes in this package also contain methods to get and
-unconditionally set values, as well as a weaker conditional atomic
-update operation <tt> weakCompareAndSet</tt>.  The weak version may be
-more efficient in the normal case, but differs in that any given
-invocation of <tt>weakCompareAndSet</tt> method may fail, even
-spuriously (that is, for no apparent reason). A <tt>false</tt> return
-means only that the operation may be retried if desired, relying on
-the guarantee that repeated invocation when the variable holds
-<tt>expectedValue</tt> and no other thread is also attempting to set
-the variable will eventually succeed.
-
-<p> The specifications of these methods enable implementations to
-employ efficient machine-level atomic instructions that are available
-on contemporary processors. However on some platforms, support may
-entail some form of internal locking. Thus the methods are not
-strictly guaranteed to be non-blocking --
-a thread may block transiently before performing the operation.
-
-<p> Instances of classes {@link
-java.util.concurrent.atomic.AtomicBoolean}, {@link
-java.util.concurrent.atomic.AtomicInteger}, {@link
-java.util.concurrent.atomic.AtomicLong}, and {@link
-java.util.concurrent.atomic.AtomicReference} each provide access and
-updates to a single variable of the corresponding type.  Each class
-also provides appropriate utility methods for that type.  For example,
-classes <tt>AtomicLong</tt> and <tt>AtomicInteger</tt> provide atomic
-increment methods.  One application is to generate sequence numbers,
-as in:
-
-<pre>
-class Sequencer {
-  private AtomicLong sequenceNumber = new AtomicLong(0);
-  public long next() { return sequenceNumber.getAndIncrement(); }
-}
-</pre>
-
-<p>The memory effects for accesses and updates of atomics generally follow the
-rules for volatiles:
-
-<ul>
-
-  <li> <tt>get</tt> has the memory effects of reading a
-<tt>volatile</tt> variable.
-
-  <li> <tt>set</tt> has the memory effects of writing (assigning) a
-<tt>volatile</tt> variable.
-
-  <li><tt>weakCompareAndSet</tt> atomically reads and conditionally
-  writes a variable, is ordered with respect to other
-  memory operations on that variable, but otherwise acts as an
-  ordinary non-volatile memory operation.
-
-  <li> <tt>compareAndSet</tt>
-  and all other read-and-update operations such as <tt>getAndIncrement</tt>
-  have the memory effects of both reading and
-  writing <tt>volatile</tt> variables.
-</ul> 
-
-<p>In addition to classes representing single values, this package
-contains <em>Updater</em> classes that can be used to obtain
-<tt>compareAndSet</tt> operations on any selected <tt>volatile</tt>
-field of any selected class.  {@link
-java.util.concurrent.atomic.AtomicReferenceFieldUpdater}, {@link
-java.util.concurrent.atomic.AtomicIntegerFieldUpdater}, and {@link
-java.util.concurrent.atomic.AtomicLongFieldUpdater} are
-reflection-based utilities that provide access to the associated field
-types. These are mainly of use in atomic data structures in which
-several <tt>volatile</tt> fields of the same node (for example, the
-links of a tree node) are independently subject to atomic
-updates. These classes enable greater flexibility in how and when to
-use atomic updates, at the expense of more awkward reflection-based
-setup, less convenient usage, and weaker guarantees.
-
-<p>The {@link java.util.concurrent.atomic.AtomicIntegerArray}, {@link
-java.util.concurrent.atomic.AtomicLongArray}, and {@link
-java.util.concurrent.atomic.AtomicReferenceArray} classes further
-extend atomic operation support to arrays of these types. These
-classes are also notable in providing <tt>volatile</tt> access
-semantics for their array elements, which is not supported for
-ordinary arrays.
-
-<p> The {@link java.util.concurrent.atomic.AtomicMarkableReference}
-class associates a single boolean with a reference. For example, this
-bit might be used inside a data structure to mean that the object
-being referenced has logically been deleted. The {@link
-java.util.concurrent.atomic.AtomicStampedReference} class associates
-an integer value with a reference. This may be used for example, to
-represent version numbers corresponding to series of updates.
-
-<p> Atomic classes are designed primarily as building blocks for
-implementing non-blocking data structures and related infrastructure
-classes.  The <tt>compareAndSet</tt> method is not a general
-replacement for locking. It applies only when critical updates for an
-object are confined to a <em>single</em> variable.
-
-<p> Atomic classes are not general purpose replacements for
-<tt>java.lang.Integer</tt> and related classes. They do <em>not</em>
-define methods such as <tt>hashCode</tt> and
-<tt>compareTo</tt>. (Because atomic variables are expected to be
-mutated, they are poor choices for hash table keys.)  Additionally,
-classes are provided only for those types that are commonly useful in
-intended applications. For example, there is no atomic class for
-representing <tt>byte</tt>. In those infrequent cases where you would
-like to do so, you can use an <tt>AtomicInteger</tt> to hold
-<tt>byte</tt> values, and cast appropriately. You can also hold floats
-using <tt>Float.floatToIntBits</tt> and <tt>Float.intBitstoFloat</tt>
-conversions, and doubles using <tt>Double.doubleToLongBits</tt> and
-<tt>Double.longBitsToDouble</tt> conversions.
-
-@since Android 1.0
-
-</body> </html>
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/locks/AbstractOwnableSynchronizer.java b/libcore/concurrent/src/main/java/java/util/concurrent/locks/AbstractOwnableSynchronizer.java
new file mode 100644
index 0000000..bf2fe16
--- /dev/null
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/locks/AbstractOwnableSynchronizer.java
@@ -0,0 +1,56 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.locks;
+
+/**
+ * A synchronizer that may be exclusively owned by a thread.  This
+ * class provides a basis for creating locks and related synchronizers
+ * that may entail a notion of ownership.  The
+ * <tt>AbstractOwnableSynchronizer</tt> class itself does not manage or
+ * use this information. However, subclasses and tools may use
+ * appropriately maintained values to help control and monitor access
+ * and provide diagnostics.
+ *
+ * @author Doug Lea
+ */
+abstract class AbstractOwnableSynchronizer
+        implements java.io.Serializable {
+
+    /** Use serial ID even though all fields transient. */
+    private static final long serialVersionUID = 3737899427754241961L;
+
+    /**
+     * Empty constructor for use by subclasses.
+     */
+    protected AbstractOwnableSynchronizer() { }
+
+    /**
+     * The current owner of exclusive mode synchronization.
+     */
+    private transient Thread exclusiveOwnerThread;
+
+    /**
+     * Sets the thread that currently owns exclusive access. A
+     * <tt>null</tt> argument indicates that no thread owns access.
+     * This method does not otherwise impose any synchronization or
+     * <tt>volatile</tt> field accesses.
+     */
+    protected final void setExclusiveOwnerThread(Thread t) {
+        exclusiveOwnerThread = t;
+    }
+
+    /**
+     * Returns the thread last set by
+     * <tt>setExclusiveOwnerThread</tt>, or <tt>null</tt> if never
+     * set.  This method does not otherwise impose any synchronization
+     * or <tt>volatile</tt> field accesses.
+     * @return the owner thread
+     */
+    protected final Thread getExclusiveOwnerThread() {
+        return exclusiveOwnerThread;
+    }
+}
\ No newline at end of file
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java b/libcore/concurrent/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
index 29e72b5..8b9821e 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
@@ -32,7 +32,7 @@
  * synchronization interface.  Instead it defines methods such as
  * {@link #acquireInterruptibly} that can be invoked as
  * appropriate by concrete locks and related synchronizers to
- * implement their public methods. 
+ * implement their public methods.
  *
  * <p>This class supports either or both a default <em>exclusive</em>
  * mode and a <em>shared</em> mode. When acquired in exclusive mode,
@@ -59,14 +59,14 @@
  * condition, so if this constraint cannot be met, do not use it.  The
  * behavior of {@link ConditionObject} depends of course on the
  * semantics of its synchronizer implementation.
- * 
- * <p> This class provides inspection, instrumentation, and monitoring
+ *
+ * <p>This class provides inspection, instrumentation, and monitoring
  * methods for the internal queue, as well as similar methods for
  * condition objects. These can be exported as desired into classes
  * using an <tt>AbstractQueuedSynchronizer</tt> for their
  * synchronization mechanics.
  *
- * <p> Serialization of this class stores only the underlying atomic
+ * <p>Serialization of this class stores only the underlying atomic
  * integer maintaining state, so deserialized objects have empty
  * thread queues. Typical subclasses requiring serializability will
  * define a <tt>readObject</tt> method that restores this to a known
@@ -74,10 +74,10 @@
  *
  * <h3>Usage</h3>
  *
- * <p> To use this class as the basis of a synchronizer, redefine the
+ * <p>To use this class as the basis of a synchronizer, redefine the
  * following methods, as applicable, by inspecting and/or modifying
  * the synchronization state using {@link #getState}, {@link
- * #setState} and/or {@link #compareAndSetState}: 
+ * #setState} and/or {@link #compareAndSetState}:
  *
  * <ul>
  * <li> {@link #tryAcquire}
@@ -94,7 +94,7 @@
  * means of using this class. All other methods are declared
  * <tt>final</tt> because they cannot be independently varied.
  *
- * <p> Even though this class is based on an internal FIFO queue, it
+ * <p>Even though this class is based on an internal FIFO queue, it
  * does not automatically enforce FIFO acquisition policies.  The core
  * of exclusive synchronization takes the form:
  *
@@ -112,22 +112,17 @@
  *
  * (Shared mode is similar but may involve cascading signals.)
  *
- * <p> Because checks in acquire are invoked before enqueuing, a newly
- * acquiring thread may <em>barge</em> ahead of others that are
- * blocked and queued. However, you can, if desired, define
- * <tt>tryAcquire</tt> and/or <tt>tryAcquireShared</tt> to disable
- * barging by internally invoking one or more of the inspection
- * methods. In particular, a strict FIFO lock can define
- * <tt>tryAcquire</tt> to immediately return <tt>false</tt> if {@link
- * #getFirstQueuedThread} does not return the current thread.  A
- * normally preferable non-strict fair version can immediately return
- * <tt>false</tt> only if {@link #hasQueuedThreads} returns
- * <tt>true</tt> and <tt>getFirstQueuedThread</tt> is not the current
- * thread; or equivalently, that <tt>getFirstQueuedThread</tt> is both
- * non-null and not the current thread.  Further variations are
- * possible.
+ * <p><a name="barging">Because checks in acquire are invoked before
+ * enqueuing, a newly acquiring thread may <em>barge</em> ahead of
+ * others that are blocked and queued.  However, you can, if desired,
+ * define <tt>tryAcquire</tt> and/or <tt>tryAcquireShared</tt> to
+ * disable barging by internally invoking one or more of the inspection
+ * methods, thereby providing a <em>fair</em> FIFO acquisition order.
+ * In particular, most fair synchronizers can define <tt>tryAcquire</tt>
+ * to return <tt>false</tt> if predecessors are queued.  Other variations
+ * are possible.
  *
- * <p> Throughput and scalability are generally highest for the
+ * <p>Throughput and scalability are generally highest for the
  * default barging (also known as <em>greedy</em>,
  * <em>renouncement</em>, and <em>convoy-avoidance</em>) strategy.
  * While this is not guaranteed to be fair or starvation-free, earlier
@@ -144,7 +139,7 @@
  * and/or {@link #hasQueuedThreads} to only do so if the synchronizer
  * is likely not to be contended.
  *
- * <p> This class provides an efficient and scalable basis for
+ * <p>This class provides an efficient and scalable basis for
  * synchronization in part by specializing its range of use to
  * synchronizers that can rely on <tt>int</tt> state, acquire, and
  * release parameters, and an internal FIFO wait queue. When this does
@@ -152,7 +147,7 @@
  * {@link java.util.concurrent.atomic atomic} classes, your own custom
  * {@link java.util.Queue} classes, and {@link LockSupport} blocking
  * support.
- * 
+ *
  * <h3>Usage Examples</h3>
  *
  * <p>Here is a non-reentrant mutual exclusion lock class that uses
@@ -163,56 +158,58 @@
  * <pre>
  * class Mutex implements Lock, java.io.Serializable {
  *
- *    // Our internal helper class
- *    private static class Sync extends AbstractQueuedSynchronizer {
- *      // Report whether in locked state
- *      protected boolean isHeldExclusively() { 
- *        return getState() == 1; 
- *      }
+ *   // Our internal helper class
+ *   private static class Sync extends AbstractQueuedSynchronizer {
+ *     // Report whether in locked state
+ *     protected boolean isHeldExclusively() {
+ *       return getState() == 1;
+ *     }
  *
- *      // Acquire the lock if state is zero
- *      public boolean tryAcquire(int acquires) {
- *        assert acquires == 1; // Otherwise unused
- *        return compareAndSetState(0, 1);
- *      }
+ *     // Acquire the lock if state is zero
+ *     public boolean tryAcquire(int acquires) {
+ *       assert acquires == 1; // Otherwise unused
+ *       return compareAndSetState(0, 1);
+ *     }
  *
- *      // Release the lock by setting state to zero
- *      protected boolean tryRelease(int releases) {
- *        assert releases == 1; // Otherwise unused
- *        if (getState() == 0) throw new IllegalMonitorStateException();
- *        setState(0);
- *        return true;
- *      }
- *       
- *      // Provide a Condition
- *      Condition newCondition() { return new ConditionObject(); }
+ *     // Release the lock by setting state to zero
+ *     protected boolean tryRelease(int releases) {
+ *       assert releases == 1; // Otherwise unused
+ *       if (getState() == 0) throw new IllegalMonitorStateException();
+ *       setState(0);
+ *       return true;
+ *     }
  *
- *      // Deserialize properly
- *      private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
- *        s.defaultReadObject();
- *        setState(0); // reset to unlocked state
- *      }
- *    }
+ *     // Provide a Condition
+ *     Condition newCondition() { return new ConditionObject(); }
  *
- *    // The sync object does all the hard work. We just forward to it.
- *    private final Sync sync = new Sync();
+ *     // Deserialize properly
+ *     private void readObject(ObjectInputStream s)
+ *         throws IOException, ClassNotFoundException {
+ *       s.defaultReadObject();
+ *       setState(0); // reset to unlocked state
+ *     }
+ *   }
  *
- *    public void lock()                { sync.acquire(1); }
- *    public boolean tryLock()          { return sync.tryAcquire(1); }
- *    public void unlock()              { sync.release(1); }
- *    public Condition newCondition()   { return sync.newCondition(); }
- *    public boolean isLocked()         { return sync.isHeldExclusively(); }
- *    public boolean hasQueuedThreads() { return sync.hasQueuedThreads(); }
- *    public void lockInterruptibly() throws InterruptedException { 
- *      sync.acquireInterruptibly(1);
- *    }
- *    public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
- *      return sync.tryAcquireNanos(1, unit.toNanos(timeout));
- *    }
+ *   // The sync object does all the hard work. We just forward to it.
+ *   private final Sync sync = new Sync();
+ *
+ *   public void lock()                { sync.acquire(1); }
+ *   public boolean tryLock()          { return sync.tryAcquire(1); }
+ *   public void unlock()              { sync.release(1); }
+ *   public Condition newCondition()   { return sync.newCondition(); }
+ *   public boolean isLocked()         { return sync.isHeldExclusively(); }
+ *   public boolean hasQueuedThreads() { return sync.hasQueuedThreads(); }
+ *   public void lockInterruptibly() throws InterruptedException {
+ *     sync.acquireInterruptibly(1);
+ *   }
+ *   public boolean tryLock(long timeout, TimeUnit unit)
+ *       throws InterruptedException {
+ *     return sync.tryAcquireNanos(1, unit.toNanos(timeout));
+ *   }
  * }
  * </pre>
  *
- * <p> Here is a latch class that is like a {@link CountDownLatch}
+ * <p>Here is a latch class that is like a {@link CountDownLatch}
  * except that it only requires a single <tt>signal</tt> to
  * fire. Because a latch is non-exclusive, it uses the <tt>shared</tt>
  * acquire and release methods.
@@ -220,33 +217,35 @@
  * <pre>
  * class BooleanLatch {
  *
- *    private static class Sync extends AbstractQueuedSynchronizer {
- *      boolean isSignalled() { return getState() != 0; }
+ *   private static class Sync extends AbstractQueuedSynchronizer {
+ *     boolean isSignalled() { return getState() != 0; }
  *
- *      protected int tryAcquireShared(int ignore) {
- *        return isSignalled()? 1 : -1;
- *      }
- *        
- *      protected boolean tryReleaseShared(int ignore) {
- *        setState(1);
- *        return true;
- *      }
- *    }
+ *     protected int tryAcquireShared(int ignore) {
+ *       return isSignalled()? 1 : -1;
+ *     }
  *
- *    private final Sync sync = new Sync();
- *    public boolean isSignalled() { return sync.isSignalled(); }
- *    public void signal()         { sync.releaseShared(1); }
- *    public void await() throws InterruptedException {
- *      sync.acquireSharedInterruptibly(1);
- *    }
+ *     protected boolean tryReleaseShared(int ignore) {
+ *       setState(1);
+ *       return true;
+ *     }
+ *   }
+ *
+ *   private final Sync sync = new Sync();
+ *   public boolean isSignalled() { return sync.isSignalled(); }
+ *   public void signal()         { sync.releaseShared(1); }
+ *   public void await() throws InterruptedException {
+ *     sync.acquireSharedInterruptibly(1);
+ *   }
  * }
- *
  * </pre>
  *
  * @since 1.5
  * @author Doug Lea
  */
-public abstract class AbstractQueuedSynchronizer implements java.io.Serializable {
+public abstract class AbstractQueuedSynchronizer
+    extends AbstractOwnableSynchronizer
+    implements java.io.Serializable {
+
     private static final long serialVersionUID = 7373984972572414691L;
 
     /**
@@ -258,7 +257,7 @@
     /**
      * Wait queue node class.
      *
-     * <p> The wait queue is a variant of a "CLH" (Craig, Landin, and
+     * <p>The wait queue is a variant of a "CLH" (Craig, Landin, and
      * Hagersten) lock queue. CLH locks are normally used for
      * spinlocks.  We instead use them for blocking synchronizers, but
      * use the same basic tactic of holding some of the control
@@ -274,7 +273,7 @@
      * contender thread may need to rewait.
      *
      * <p>To enqueue into a CLH lock, you atomically splice it in as new
-     * tail. To dequeue, you just set the head field.  
+     * tail. To dequeue, you just set the head field.
      * <pre>
      *      +------+  prev +-----+       +-----+
      * head |      | <---- |     | <---- |     |  tail
@@ -295,7 +294,7 @@
      * predecessor. For explanation of similar mechanics in the case
      * of spin locks, see the papers by Scott and Scherer at
      * http://www.cs.rochester.edu/u/scott/synchronization/
-     * 
+     *
      * <p>We also use "next" links to implement blocking mechanics.
      * The thread id for each node is kept in its own node, so a
      * predecessor signals the next node to wake up by traversing
@@ -312,7 +311,8 @@
      * nodes, we can miss noticing whether a cancelled node is
      * ahead or behind us. This is dealt with by always unparking
      * successors upon cancellation, allowing them to stabilize on
-     * a new predecessor.
+     * a new predecessor, unless we can identify an uncancelled
+     * predecessor who will carry this responsibility.
      *
      * <p>CLH queues need a dummy header node to get started. But
      * we don't create them on construction, because it would be wasted
@@ -334,34 +334,46 @@
      * on the design of this class.
      */
     static final class Node {
-        /** waitStatus value to indicate thread has cancelled */
-        static final int CANCELLED =  1;
-        /** waitStatus value to indicate thread needs unparking */
-        static final int SIGNAL    = -1;
-        /** waitStatus value to indicate thread is waiting on condition */
-        static final int CONDITION = -2;
         /** Marker to indicate a node is waiting in shared mode */
         static final Node SHARED = new Node();
         /** Marker to indicate a node is waiting in exclusive mode */
         static final Node EXCLUSIVE = null;
 
+        /** waitStatus value to indicate thread has cancelled */
+        static final int CANCELLED =  1;
+        /** waitStatus value to indicate successor's thread needs unparking */
+        static final int SIGNAL    = -1;
+        /** waitStatus value to indicate thread is waiting on condition */
+        static final int CONDITION = -2;
+        /**
+         * waitStatus value to indicate the next acquireShared should
+         * unconditionally propagate
+         */
+        static final int PROPAGATE = -3;
+
         /**
          * Status field, taking on only the values:
-         *   SIGNAL:     The successor of this node is (or will soon be) 
-         *               blocked (via park), so the current node must 
-         *               unpark its successor when it releases or 
+         *   SIGNAL:     The successor of this node is (or will soon be)
+         *               blocked (via park), so the current node must
+         *               unpark its successor when it releases or
          *               cancels. To avoid races, acquire methods must
-         *               first indicate they need a signal, 
-         *               then retry the atomic acquire, and then, 
+         *               first indicate they need a signal,
+         *               then retry the atomic acquire, and then,
          *               on failure, block.
-         *   CANCELLED:  Node is cancelled due to timeout or interrupt
+         *   CANCELLED:  This node is cancelled due to timeout or interrupt.
          *               Nodes never leave this state. In particular,
          *               a thread with cancelled node never again blocks.
-         *   CONDITION:  Node is currently on a condition queue
-         *               It will not be used as a sync queue node until
-         *               transferred. (Use of this value here
-         *               has nothing to do with the other uses
-         *               of the field, but simplifies mechanics.)
+         *   CONDITION:  This node is currently on a condition queue.
+         *               It will not be used as a sync queue node
+         *               until transferred, at which time the status
+         *               will be set to 0. (Use of this value here has
+         *               nothing to do with the other uses of the
+         *               field, but simplifies mechanics.)
+         *   PROPAGATE:  A releaseShared should be propagated to other
+         *               nodes. This is set (for head node only) in
+         *               doReleaseShared to ensure propagation
+         *               continues, even if other operations have
+         *               since intervened.
          *   0:          None of the above
          *
          * The values are arranged numerically to simplify use.
@@ -370,8 +382,8 @@
          * values, just for sign.
          *
          * The field is initialized to 0 for normal sync nodes, and
-         * CONDITION for condition nodes.  It is modified only using
-         * CAS.
+         * CONDITION for condition nodes.  It is modified using CAS
+         * (or when possible, unconditional volatile writes).
          */
         volatile int waitStatus;
 
@@ -390,25 +402,26 @@
 
         /**
          * Link to the successor node that the current node/thread
-         * unparks upon release. Assigned once during enqueuing, and
-         * nulled out (for sake of GC) when no longer needed.  Upon
-         * cancellation, we cannot adjust this field, but can notice
-         * status and bypass the node if cancelled.  The enq operation
-         * does not assign next field of a predecessor until after
-         * attachment, so seeing a null next field does not
-         * necessarily mean that node is at end of queue. However, if
-         * a next field appears to be null, we can scan prev's from
-         * the tail to double-check.
+         * unparks upon release. Assigned during enqueuing, adjusted
+         * when bypassing cancelled predecessors, and nulled out (for
+         * sake of GC) when dequeued.  The enq operation does not
+         * assign next field of a predecessor until after attachment,
+         * so seeing a null next field does not necessarily mean that
+         * node is at end of queue. However, if a next field appears
+         * to be null, we can scan prev's from the tail to
+         * double-check.  The next field of cancelled nodes is set to
+         * point to the node itself instead of null, to make life
+         * easier for isOnSyncQueue.
          */
         volatile Node next;
 
         /**
          * The thread that enqueued this node.  Initialized on
-         * construction and nulled out after use. 
+         * construction and nulled out after use.
          */
         volatile Thread thread;
 
-        /** 
+        /**
          * Link to next node waiting on condition, or the special
          * value SHARED.  Because condition queues are accessed only
          * when holding in exclusive mode, we just need a simple
@@ -428,14 +441,16 @@
         }
 
         /**
-         * Returns previous node, or throws NullPointerException if
-         * null.  Use when predecessor cannot be null.
+         * Returns previous node, or throws NullPointerException if null.
+         * Use when predecessor cannot be null.  The null check could
+         * be elided, but is present to help the VM.
+         *
          * @return the predecessor of this node
          */
         final Node predecessor() throws NullPointerException {
             Node p = prev;
             if (p == null)
-                throw new NullPointerException(); 
+                throw new NullPointerException();
             else
                 return p;
         }
@@ -450,11 +465,11 @@
 
         Node(Thread thread, int waitStatus) { // Used by Condition
             this.waitStatus = waitStatus;
-            this.thread = thread; 
+            this.thread = thread;
         }
     }
 
-    /** 
+    /**
      * Head of the wait queue, lazily initialized.  Except for
      * initialization, it is modified only via method setHead.  Note:
      * If head exists, its waitStatus is guaranteed not to be
@@ -462,11 +477,11 @@
      */
     private transient volatile Node head;
 
-    /** 
+    /**
      * Tail of the wait queue, lazily initialized.  Modified only via
      * method enq to add new wait node.
      */
-    private transient volatile Node tail; 
+    private transient volatile Node tail;
 
     /**
      * The synchronization state.
@@ -496,10 +511,11 @@
      * value if the current state value equals the expected value.
      * This operation has memory semantics of a <tt>volatile</tt> read
      * and write.
+     *
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful. False return indicates that
-     * the actual value was not equal to the expected value.
+     * @return true if successful. False return indicates that the actual
+     *         value was not equal to the expected value.
      */
     protected final boolean compareAndSetState(int expect, int update) {
         // See below for intrinsics setup to support this
@@ -509,7 +525,14 @@
     // Queuing utilities
 
     /**
-     * Insert node into queue, initializing if necessary. See picture above.
+     * The number of nanoseconds for which it is faster to spin
+     * rather than to use timed park. A rough estimate suffices
+     * to improve responsiveness with very short timeouts.
+     */
+    static final long spinForTimeoutThreshold = 1000L;
+
+    /**
+     * Inserts node into queue, initializing if necessary. See picture above.
      * @param node the node to insert
      * @return node's predecessor
      */
@@ -517,27 +540,21 @@
         for (;;) {
             Node t = tail;
             if (t == null) { // Must initialize
-                Node h = new Node(); // Dummy header
-                h.next = node;
-                node.prev = h;
-                if (compareAndSetHead(h)) {
-                    tail = node;
-                    return h;
-                }
-            }
-            else {
-                node.prev = t;     
+                if (compareAndSetHead(new Node()))
+                    tail = head;
+            } else {
+                node.prev = t;
                 if (compareAndSetTail(t, node)) {
-                    t.next = node; 
-                    return t; 
+                    t.next = node;
+                    return t;
                 }
             }
         }
     }
 
     /**
-     * Create and enq node for given thread and mode
-     * @param current the thread
+     * Creates and enqueues node for current thread and given mode.
+     *
      * @param mode Node.EXCLUSIVE for exclusive, Node.SHARED for shared
      * @return the new node
      */
@@ -546,9 +563,9 @@
         // Try the fast path of enq; backup to full enq on failure
         Node pred = tail;
         if (pred != null) {
-            node.prev = pred;     
+            node.prev = pred;
             if (compareAndSetTail(pred, node)) {
-                pred.next = node; 
+                pred.next = node;
                 return node;
             }
         }
@@ -557,79 +574,166 @@
     }
 
     /**
-     * Set head of queue to be node, thus dequeuing. Called only by
+     * Sets head of queue to be node, thus dequeuing. Called only by
      * acquire methods.  Also nulls out unused fields for sake of GC
      * and to suppress unnecessary signals and traversals.
-     * @param node the node 
+     *
+     * @param node the node
      */
     private void setHead(Node node) {
         head = node;
         node.thread = null;
-        node.prev = null; 
+        node.prev = null;
     }
 
     /**
-     * Wake up node's successor, if one exists.
+     * Wakes up node's successor, if one exists.
+     *
      * @param node the node
      */
     private void unparkSuccessor(Node node) {
         /*
-         * Try to clear status in anticipation of signalling.  It is
-         * OK if this fails or if status is changed by waiting thread.
+         * If status is negative (i.e., possibly needing signal) try
+         * to clear in anticipation of signalling.  It is OK if this
+         * fails or if status is changed by waiting thread.
          */
-        compareAndSetWaitStatus(node, Node.SIGNAL, 0);
-        
+        int ws = node.waitStatus;
+        if (ws < 0)
+            compareAndSetWaitStatus(node, ws, 0);
+
         /*
          * Thread to unpark is held in successor, which is normally
          * just the next node.  But if cancelled or apparently null,
          * traverse backwards from tail to find the actual
          * non-cancelled successor.
          */
-        Thread thread;
         Node s = node.next;
-        if (s != null && s.waitStatus <= 0)
-            thread = s.thread;
-        else {
-            thread = null;
-            for (s = tail; s != null && s != node; s = s.prev) 
-                if (s.waitStatus <= 0)
-                    thread = s.thread;
+        if (s == null || s.waitStatus > 0) {
+            s = null;
+            for (Node t = tail; t != null && t != node; t = t.prev)
+                if (t.waitStatus <= 0)
+                    s = t;
         }
-        LockSupport.unpark(thread);
+        if (s != null)
+            LockSupport.unpark(s.thread);
     }
 
     /**
-     * Set head of queue, and check if successor may be waiting
-     * in shared mode, if so propagating if propagate > 0.
-     * @param pred the node holding waitStatus for node
-     * @param node the node 
+     * Release action for shared mode -- signal successor and ensure
+     * propagation. (Note: For exclusive mode, release just amounts
+     * to calling unparkSuccessor of head if it needs signal.)
+     */
+    private void doReleaseShared() {
+        /*
+         * Ensure that a release propagates, even if there are other
+         * in-progress acquires/releases.  This proceeds in the usual
+         * way of trying to unparkSuccessor of head if it needs
+         * signal. But if it does not, status is set to PROPAGATE to
+         * ensure that upon release, propagation continues.
+         * Additionally, we must loop in case a new node is added
+         * while we are doing this. Also, unlike other uses of
+         * unparkSuccessor, we need to know if CAS to reset status
+         * fails, if so rechecking.
+         */
+        for (;;) {
+            Node h = head;
+            if (h != null && h != tail) {
+                int ws = h.waitStatus;
+                if (ws == Node.SIGNAL) {
+                    if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))
+                        continue;            // loop to recheck cases
+                    unparkSuccessor(h);
+                }
+                else if (ws == 0 &&
+                         !compareAndSetWaitStatus(h, 0, Node.PROPAGATE))
+                    continue;                // loop on failed CAS
+            }
+            if (h == head)                   // loop if head changed
+                break;
+        }
+    }
+
+    /**
+     * Sets head of queue, and checks if successor may be waiting
+     * in shared mode, if so propagating if either propagate > 0 or
+     * PROPAGATE status was set.
+     *
+     * @param node the node
      * @param propagate the return value from a tryAcquireShared
      */
     private void setHeadAndPropagate(Node node, int propagate) {
+        Node h = head; // Record old head for check below
         setHead(node);
-        if (propagate > 0 && node.waitStatus != 0) {
-            /*
-             * Don't bother fully figuring out successor.  If it
-             * looks null, call unparkSuccessor anyway to be safe.
-             */
-            Node s = node.next; 
+        /*
+         * Try to signal next queued node if:
+         *   Propagation was indicated by caller,
+         *     or was recorded (as h.waitStatus) by a previous operation
+         *     (note: this uses sign-check of waitStatus because
+         *      PROPAGATE status may transition to SIGNAL.)
+         * and
+         *   The next node is waiting in shared mode,
+         *     or we don't know, because it appears null
+         *
+         * The conservatism in both of these checks may cause
+         * unnecessary wake-ups, but only when there are multiple
+         * racing acquires/releases, so most need signals now or soon
+         * anyway.
+         */
+        if (propagate > 0 || h == null || h.waitStatus < 0) {
+            Node s = node.next;
             if (s == null || s.isShared())
-                unparkSuccessor(node);
+                doReleaseShared();
         }
     }
 
     // Utilities for various versions of acquire
 
     /**
-     * Cancel an ongoing attempt to acquire.
+     * Cancels an ongoing attempt to acquire.
+     *
      * @param node the node
      */
     private void cancelAcquire(Node node) {
-        if (node != null) { // Ignore if node doesn't exist
-            node.thread = null;
-            // Can use unconditional write instead of CAS here
-            node.waitStatus = Node.CANCELLED;
-            unparkSuccessor(node);
+        // Ignore if node doesn't exist
+        if (node == null)
+            return;
+
+        node.thread = null;
+
+        // Skip cancelled predecessors
+        Node pred = node.prev;
+        while (pred.waitStatus > 0)
+            node.prev = pred = pred.prev;
+
+        // predNext is the apparent node to unsplice. CASes below will
+        // fail if not, in which case, we lost race vs another cancel
+        // or signal, so no further action is necessary.
+        Node predNext = pred.next;
+
+        // Can use unconditional write instead of CAS here.
+        // After this atomic step, other Nodes can skip past us.
+        // Before, we are free of interference from other threads.
+        node.waitStatus = Node.CANCELLED;
+
+        // If we are the tail, remove ourselves.
+        if (node == tail && compareAndSetTail(node, pred)) {
+            compareAndSetNext(pred, predNext, null);
+        } else {
+            // If successor needs signal, try to set pred's next-link
+            // so it will get one. Otherwise wake it up to propagate.
+            int ws;
+            if (pred != head &&
+                ((ws = pred.waitStatus) == Node.SIGNAL ||
+                 (ws <= 0 && compareAndSetWaitStatus(pred, ws, Node.SIGNAL))) &&
+                pred.thread != null) {
+                Node next = node.next;
+                if (next != null && next.waitStatus <= 0)
+                    compareAndSetNext(pred, predNext, next);
+            } else {
+                unparkSuccessor(node);
+            }
+
+            node.next = node; // help GC
         }
     }
 
@@ -637,31 +741,36 @@
      * Checks and updates status for a node that failed to acquire.
      * Returns true if thread should block. This is the main signal
      * control in all acquire loops.  Requires that pred == node.prev
+     *
      * @param pred node's predecessor holding status
-     * @param node the node 
-     * @return true if thread should block
+     * @param node the node
+     * @return {@code true} if thread should block
      */
     private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
-        int s = pred.waitStatus;
-        if (s < 0)
+        int ws = pred.waitStatus;
+        if (ws == Node.SIGNAL)
             /*
              * This node has already set status asking a release
-             * to signal it, so it can safely park
+             * to signal it, so it can safely park.
              */
             return true;
-        if (s > 0) 
+        if (ws > 0) {
             /*
-             * Predecessor was cancelled. Move up to its predecessor
-             * and indicate retry.
+             * Predecessor was cancelled. Skip over predecessors and
+             * indicate retry.
              */
-            node.prev = pred.prev;
-        else
+            do {
+                node.prev = pred = pred.prev;
+            } while (pred.waitStatus > 0);
+            pred.next = node;
+        } else {
             /*
-             * Indicate that we need a signal, but don't park yet. Caller
-             * will need to retry to make sure it cannot acquire before
-             * parking.
+             * waitStatus must be 0 or PROPAGATE.  Indicate that we
+             * need a signal, but don't park yet.  Caller will need to
+             * retry to make sure it cannot acquire before parking.
              */
-            compareAndSetWaitStatus(pred, 0, Node.SIGNAL);
+            compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
+        }
         return false;
     }
 
@@ -674,9 +783,10 @@
 
     /**
      * Convenience method to park and then check if interrupted
-     * @return true if interrupted
+     *
+     * @return {@code true} if interrupted
      */
-    private static boolean parkAndCheckInterrupt() {
+    private final boolean parkAndCheckInterrupt() {
         LockSupport.park();
         return Thread.interrupted();
     }
@@ -687,17 +797,19 @@
      * different.  Only a little bit of factoring is possible due to
      * interactions of exception mechanics (including ensuring that we
      * cancel if tryAcquire throws exception) and other control, at
-     * least not without hurting performance too much. 
+     * least not without hurting performance too much.
      */
 
     /**
-     * Acquire in exclusive uninterruptible mode for thread already in
+     * Acquires in exclusive uninterruptible mode for thread already in
      * queue. Used by condition wait methods as well as acquire.
+     *
      * @param node the node
      * @param arg the acquire argument
-     * @return true if interrupted while waiting
+     * @return {@code true} if interrupted while waiting
      */
     final boolean acquireQueued(final Node node, int arg) {
+        boolean failed = true;
         try {
             boolean interrupted = false;
             for (;;) {
@@ -705,92 +817,91 @@
                 if (p == head && tryAcquire(arg)) {
                     setHead(node);
                     p.next = null; // help GC
+                    failed = false;
                     return interrupted;
                 }
-                if (shouldParkAfterFailedAcquire(p, node) && 
-                    parkAndCheckInterrupt()) 
+                if (shouldParkAfterFailedAcquire(p, node) &&
+                    parkAndCheckInterrupt())
                     interrupted = true;
             }
-        } catch (RuntimeException ex) {
-            cancelAcquire(node);
-            throw ex;
+        } finally {
+            if (failed)
+                cancelAcquire(node);
         }
     }
 
-    /** 
-     * Acquire in exclusive interruptible mode
+    /**
+     * Acquires in exclusive interruptible mode.
      * @param arg the acquire argument
      */
-    private void doAcquireInterruptibly(int arg) 
+    private void doAcquireInterruptibly(int arg)
         throws InterruptedException {
         final Node node = addWaiter(Node.EXCLUSIVE);
+        boolean failed = true;
         try {
             for (;;) {
                 final Node p = node.predecessor();
                 if (p == head && tryAcquire(arg)) {
                     setHead(node);
                     p.next = null; // help GC
+                    failed = false;
                     return;
                 }
-                if (shouldParkAfterFailedAcquire(p, node) && 
-                    parkAndCheckInterrupt()) 
-                    break;
+                if (shouldParkAfterFailedAcquire(p, node) &&
+                    parkAndCheckInterrupt())
+                    throw new InterruptedException();
             }
-        } catch (RuntimeException ex) {
-            cancelAcquire(node);
-            throw ex;
+        } finally {
+            if (failed)
+                cancelAcquire(node);
         }
-        // Arrive here only if interrupted
-        cancelAcquire(node);
-        throw new InterruptedException();
     }
 
-    /** 
-     * Acquire in exclusive timed mode
+    /**
+     * Acquires in exclusive timed mode.
+     *
      * @param arg the acquire argument
      * @param nanosTimeout max wait time
-     * @return true if acquired
+     * @return {@code true} if acquired
      */
-    private boolean doAcquireNanos(int arg, long nanosTimeout) 
+    private boolean doAcquireNanos(int arg, long nanosTimeout)
         throws InterruptedException {
         long lastTime = System.nanoTime();
         final Node node = addWaiter(Node.EXCLUSIVE);
+        boolean failed = true;
         try {
             for (;;) {
                 final Node p = node.predecessor();
                 if (p == head && tryAcquire(arg)) {
                     setHead(node);
                     p.next = null; // help GC
+                    failed = false;
                     return true;
                 }
-                if (nanosTimeout <= 0) {
-                    cancelAcquire(node);
+                if (nanosTimeout <= 0)
                     return false;
-                }
-                if (shouldParkAfterFailedAcquire(p, node)) {
+                if (shouldParkAfterFailedAcquire(p, node) &&
+                    nanosTimeout > spinForTimeoutThreshold)
                     LockSupport.parkNanos(nanosTimeout);
-                    if (Thread.interrupted()) 
-                        break;
-                    long now = System.nanoTime();
-                    nanosTimeout -= now - lastTime;
-                    lastTime = now;
-                }
+                long now = System.nanoTime();
+                nanosTimeout -= now - lastTime;
+                lastTime = now;
+                if (Thread.interrupted())
+                    throw new InterruptedException();
             }
-        } catch (RuntimeException ex) {
-            cancelAcquire(node);
-            throw ex;
+        } finally {
+            if (failed)
+                cancelAcquire(node);
         }
-        // Arrive here only if interrupted
-        cancelAcquire(node);
-        throw new InterruptedException();
     }
 
-    /** 
-     * Acquire in shared uninterruptible mode
+    /**
+     * Acquires in shared uninterruptible mode.
      * @param arg the acquire argument
      */
     private void doAcquireShared(int arg) {
         final Node node = addWaiter(Node.SHARED);
+        boolean failed = true;
         try {
             boolean interrupted = false;
             for (;;) {
@@ -802,26 +913,28 @@
                         p.next = null; // help GC
                         if (interrupted)
                             selfInterrupt();
+                        failed = false;
                         return;
                     }
                 }
-                if (shouldParkAfterFailedAcquire(p, node) && 
-                    parkAndCheckInterrupt()) 
+                if (shouldParkAfterFailedAcquire(p, node) &&
+                    parkAndCheckInterrupt())
                     interrupted = true;
             }
-        } catch (RuntimeException ex) {
-            cancelAcquire(node);
-            throw ex;
+        } finally {
+            if (failed)
+                cancelAcquire(node);
         }
     }
 
-    /** 
-     * Acquire in shared interruptible mode
+    /**
+     * Acquires in shared interruptible mode.
      * @param arg the acquire argument
      */
-    private void doAcquireSharedInterruptibly(int arg) 
+    private void doAcquireSharedInterruptibly(int arg)
         throws InterruptedException {
         final Node node = addWaiter(Node.SHARED);
+        boolean failed = true;
         try {
             for (;;) {
                 final Node p = node.predecessor();
@@ -830,33 +943,33 @@
                     if (r >= 0) {
                         setHeadAndPropagate(node, r);
                         p.next = null; // help GC
+                        failed = false;
                         return;
                     }
                 }
-                if (shouldParkAfterFailedAcquire(p, node) && 
-                    parkAndCheckInterrupt()) 
-                    break;
+                if (shouldParkAfterFailedAcquire(p, node) &&
+                    parkAndCheckInterrupt())
+                    throw new InterruptedException();
             }
-        } catch (RuntimeException ex) {
-            cancelAcquire(node);
-            throw ex;
+        } finally {
+            if (failed)
+                cancelAcquire(node);
         }
-        // Arrive here only if interrupted
-        cancelAcquire(node);
-        throw new InterruptedException();
     }
 
-    /** 
-     * Acquire in shared timed mode
+    /**
+     * Acquires in shared timed mode.
+     *
      * @param arg the acquire argument
      * @param nanosTimeout max wait time
-     * @return true if acquired
+     * @return {@code true} if acquired
      */
-    private boolean doAcquireSharedNanos(int arg, long nanosTimeout) 
+    private boolean doAcquireSharedNanos(int arg, long nanosTimeout)
         throws InterruptedException {
 
         long lastTime = System.nanoTime();
         final Node node = addWaiter(Node.SHARED);
+        boolean failed = true;
         try {
             for (;;) {
                 final Node p = node.predecessor();
@@ -865,32 +978,28 @@
                     if (r >= 0) {
                         setHeadAndPropagate(node, r);
                         p.next = null; // help GC
+                        failed = false;
                         return true;
                     }
                 }
-                if (nanosTimeout <= 0) {
-                    cancelAcquire(node);
+                if (nanosTimeout <= 0)
                     return false;
-                }
-                if (shouldParkAfterFailedAcquire(p, node)) {
+                if (shouldParkAfterFailedAcquire(p, node) &&
+                    nanosTimeout > spinForTimeoutThreshold)
                     LockSupport.parkNanos(nanosTimeout);
-                    if (Thread.interrupted()) 
-                        break;
-                    long now = System.nanoTime();
-                    nanosTimeout -= now - lastTime;
-                    lastTime = now;
-                }
+                long now = System.nanoTime();
+                nanosTimeout -= now - lastTime;
+                lastTime = now;
+                if (Thread.interrupted())
+                    throw new InterruptedException();
             }
-        } catch (RuntimeException ex) {
-            cancelAcquire(node);
-            throw ex;
+        } finally {
+            if (failed)
+                cancelAcquire(node);
         }
-        // Arrive here only if interrupted
-        cancelAcquire(node);
-        throw new InterruptedException();
     }
 
-    // Main exported methods 
+    // Main exported methods
 
     /**
      * Attempts to acquire in exclusive mode. This method should query
@@ -901,22 +1010,21 @@
      * acquire.  If this method reports failure, the acquire method
      * may queue the thread, if it is not already queued, until it is
      * signalled by a release from some other thread. This can be used
-     * to implement method {@link Lock#tryLock()}. 
+     * to implement method {@link Lock#tryLock()}.
      *
      * <p>The default
-     * implementation throws {@link UnsupportedOperationException}
+     * implementation throws {@link UnsupportedOperationException}.
      *
-     * @param arg the acquire argument. This value
-     * is always the one passed to an acquire method,
-     * or is the value saved on entry to a condition wait.
-     * The value is otherwise uninterpreted and can represent anything
-     * you like.
-     * @return true if successful. Upon success, this object has been
-     * acquired.
-     * @throws IllegalMonitorStateException if acquiring would place
-     * this synchronizer in an illegal state. This exception must be
-     * thrown in a consistent fashion for synchronization to work
-     * correctly.
+     * @param arg the acquire argument. This value is always the one
+     *        passed to an acquire method, or is the value saved on entry
+     *        to a condition wait.  The value is otherwise uninterpreted
+     *        and can represent anything you like.
+     * @return {@code true} if successful. Upon success, this object has
+     *         been acquired.
+     * @throws IllegalMonitorStateException if acquiring would place this
+     *         synchronizer in an illegal state. This exception must be
+     *         thrown in a consistent fashion for synchronization to work
+     *         correctly.
      * @throws UnsupportedOperationException if exclusive mode is not supported
      */
     protected boolean tryAcquire(int arg) {
@@ -925,23 +1033,24 @@
 
     /**
      * Attempts to set the state to reflect a release in exclusive
-     * mode.  <p>This method is always invoked by the thread
-     * performing release.  
+     * mode.
+     *
+     * <p>This method is always invoked by the thread performing release.
      *
      * <p>The default implementation throws
-     * {@link UnsupportedOperationException}
-     * @param arg the release argument. This value
-     * is always the one passed to a release method,
-     * or the current state value upon entry to a condition wait.
-     * The value is otherwise uninterpreted and can represent anything
-     * you like.
-     * @return <tt>true</tt> if this object is now in a fully released state, 
-     * so that any waiting threads may attempt to acquire; and <tt>false</tt>
-     * otherwise.
-     * @throws IllegalMonitorStateException if releasing would place
-     * this synchronizer in an illegal state. This exception must be
-     * thrown in a consistent fashion for synchronization to work
-     * correctly.
+     * {@link UnsupportedOperationException}.
+     *
+     * @param arg the release argument. This value is always the one
+     *        passed to a release method, or the current state value upon
+     *        entry to a condition wait.  The value is otherwise
+     *        uninterpreted and can represent anything you like.
+     * @return {@code true} if this object is now in a fully released
+     *         state, so that any waiting threads may attempt to acquire;
+     *         and {@code false} otherwise.
+     * @throws IllegalMonitorStateException if releasing would place this
+     *         synchronizer in an illegal state. This exception must be
+     *         thrown in a consistent fashion for synchronization to work
+     *         correctly.
      * @throws UnsupportedOperationException if exclusive mode is not supported
      */
     protected boolean tryRelease(int arg) {
@@ -951,7 +1060,7 @@
     /**
      * Attempts to acquire in shared mode. This method should query if
      * the state of the object permits it to be acquired in the shared
-     * mode, and if so to acquire it.  
+     * mode, and if so to acquire it.
      *
      * <p>This method is always invoked by the thread performing
      * acquire.  If this method reports failure, the acquire method
@@ -959,24 +1068,25 @@
      * signalled by a release from some other thread.
      *
      * <p>The default implementation throws {@link
-     * UnsupportedOperationException}
+     * UnsupportedOperationException}.
      *
-     * @param arg the acquire argument. This value
-     * is always the one passed to an acquire method,
-     * or is the value saved on entry to a condition wait.
-     * The value is otherwise uninterpreted and can represent anything
-     * you like.
-     * @return a negative value on failure, zero on exclusive success,
-     * and a positive value if non-exclusively successful, in which
-     * case a subsequent waiting thread must check
-     * availability. (Support for three different return values
-     * enables this method to be used in contexts where acquires only
-     * sometimes act exclusively.)  Upon success, this object has been
-     * acquired.
-     * @throws IllegalMonitorStateException if acquiring would place
-     * this synchronizer in an illegal state. This exception must be
-     * thrown in a consistent fashion for synchronization to work
-     * correctly.
+     * @param arg the acquire argument. This value is always the one
+     *        passed to an acquire method, or is the value saved on entry
+     *        to a condition wait.  The value is otherwise uninterpreted
+     *        and can represent anything you like.
+     * @return a negative value on failure; zero if acquisition in shared
+     *         mode succeeded but no subsequent shared-mode acquire can
+     *         succeed; and a positive value if acquisition in shared
+     *         mode succeeded and subsequent shared-mode acquires might
+     *         also succeed, in which case a subsequent waiting thread
+     *         must check availability. (Support for three different
+     *         return values enables this method to be used in contexts
+     *         where acquires only sometimes act exclusively.)  Upon
+     *         success, this object has been acquired.
+     * @throws IllegalMonitorStateException if acquiring would place this
+     *         synchronizer in an illegal state. This exception must be
+     *         thrown in a consistent fashion for synchronization to work
+     *         correctly.
      * @throws UnsupportedOperationException if shared mode is not supported
      */
     protected int tryAcquireShared(int arg) {
@@ -985,21 +1095,23 @@
 
     /**
      * Attempts to set the state to reflect a release in shared mode.
+     *
      * <p>This method is always invoked by the thread performing release.
-     * <p> The default implementation throws 
-     * {@link UnsupportedOperationException}
-     * @param arg the release argument. This value
-     * is always the one passed to a release method,
-     * or the current state value upon entry to a condition wait.
-     * The value is otherwise uninterpreted and can represent anything
-     * you like.
-     * @return <tt>true</tt> if this object is now in a fully released state, 
-     * so that any waiting threads may attempt to acquire; and <tt>false</tt>
-     * otherwise.
-     * @throws IllegalMonitorStateException if releasing would place
-     * this synchronizer in an illegal state. This exception must be
-     * thrown in a consistent fashion for synchronization to work
-     * correctly.
+     *
+     * <p>The default implementation throws
+     * {@link UnsupportedOperationException}.
+     *
+     * @param arg the release argument. This value is always the one
+     *        passed to a release method, or the current state value upon
+     *        entry to a condition wait.  The value is otherwise
+     *        uninterpreted and can represent anything you like.
+     * @return {@code true} if this release of shared mode may permit a
+     *         waiting acquire (shared or exclusive) to succeed; and
+     *         {@code false} otherwise
+     * @throws IllegalMonitorStateException if releasing would place this
+     *         synchronizer in an illegal state. This exception must be
+     *         thrown in a consistent fashion for synchronization to work
+     *         correctly.
      * @throws UnsupportedOperationException if shared mode is not supported
      */
     protected boolean tryReleaseShared(int arg) {
@@ -1007,17 +1119,18 @@
     }
 
     /**
-     * Returns true if synchronization is held exclusively with respect
-     * to the current (calling) thread.  This method is invoked
+     * Returns {@code true} if synchronization is held exclusively with
+     * respect to the current (calling) thread.  This method is invoked
      * upon each call to a non-waiting {@link ConditionObject} method.
      * (Waiting methods instead invoke {@link #release}.)
+     *
      * <p>The default implementation throws {@link
      * UnsupportedOperationException}. This method is invoked
      * internally only within {@link ConditionObject} methods, so need
      * not be defined if conditions are not used.
      *
-     * @return true if synchronization is held exclusively;
-     * else false
+     * @return {@code true} if synchronization is held exclusively;
+     *         {@code false} otherwise
      * @throws UnsupportedOperationException if conditions are not supported
      */
     protected boolean isHeldExclusively() {
@@ -1030,12 +1143,12 @@
      * returning on success.  Otherwise the thread is queued, possibly
      * repeatedly blocking and unblocking, invoking {@link
      * #tryAcquire} until success.  This method can be used
-     * to implement method {@link Lock#lock}
-     * @param arg the acquire argument.
-     * This value is conveyed to {@link #tryAcquire} but is
-     * otherwise uninterpreted and can represent anything
-     * you like.
-     */ 
+     * to implement method {@link Lock#lock}.
+     *
+     * @param arg the acquire argument.  This value is conveyed to
+     *        {@link #tryAcquire} but is otherwise uninterpreted and
+     *        can represent anything you like.
+     */
     public final void acquire(int arg) {
         if (!tryAcquire(arg) &&
             acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
@@ -1049,11 +1162,11 @@
      * success.  Otherwise the thread is queued, possibly repeatedly
      * blocking and unblocking, invoking {@link #tryAcquire}
      * until success or the thread is interrupted.  This method can be
-     * used to implement method {@link Lock#lockInterruptibly}
-     * @param arg the acquire argument.
-     * This value is conveyed to {@link #tryAcquire} but is
-     * otherwise uninterpreted and can represent anything
-     * you like.
+     * used to implement method {@link Lock#lockInterruptibly}.
+     *
+     * @param arg the acquire argument.  This value is conveyed to
+     *        {@link #tryAcquire} but is otherwise uninterpreted and
+     *        can represent anything you like.
      * @throws InterruptedException if the current thread is interrupted
      */
     public final void acquireInterruptibly(int arg) throws InterruptedException {
@@ -1072,35 +1185,35 @@
      * {@link #tryAcquire} until success or the thread is interrupted
      * or the timeout elapses.  This method can be used to implement
      * method {@link Lock#tryLock(long, TimeUnit)}.
-     * @param arg the acquire argument.
-     * This value is conveyed to {@link #tryAcquire} but is
-     * otherwise uninterpreted and can represent anything
-     * you like.
+     *
+     * @param arg the acquire argument.  This value is conveyed to
+     *        {@link #tryAcquire} but is otherwise uninterpreted and
+     *        can represent anything you like.
      * @param nanosTimeout the maximum number of nanoseconds to wait
-     * @return true if acquired; false if timed out
+     * @return {@code true} if acquired; {@code false} if timed out
      * @throws InterruptedException if the current thread is interrupted
      */
-   public final boolean tryAcquireNanos(int arg, long nanosTimeout) throws InterruptedException {
-       if (Thread.interrupted())
-           throw new InterruptedException();
-       return tryAcquire(arg) ||
-           doAcquireNanos(arg, nanosTimeout);
-   }
+    public final boolean tryAcquireNanos(int arg, long nanosTimeout) throws InterruptedException {
+        if (Thread.interrupted())
+            throw new InterruptedException();
+        return tryAcquire(arg) ||
+            doAcquireNanos(arg, nanosTimeout);
+    }
 
     /**
      * Releases in exclusive mode.  Implemented by unblocking one or
      * more threads if {@link #tryRelease} returns true.
-     * This method can be used to implement method {@link Lock#unlock}
-     * @param arg the release argument.
-     * This value is conveyed to {@link #tryRelease} but is
-     * otherwise uninterpreted and can represent anything
-     * you like.
-     * @return the value returned from {@link #tryRelease} 
+     * This method can be used to implement method {@link Lock#unlock}.
+     *
+     * @param arg the release argument.  This value is conveyed to
+     *        {@link #tryRelease} but is otherwise uninterpreted and
+     *        can represent anything you like.
+     * @return the value returned from {@link #tryRelease}
      */
     public final boolean release(int arg) {
         if (tryRelease(arg)) {
             Node h = head;
-            if (h != null && h.waitStatus != 0) 
+            if (h != null && h.waitStatus != 0)
                 unparkSuccessor(h);
             return true;
         }
@@ -1112,11 +1225,11 @@
      * first invoking at least once {@link #tryAcquireShared},
      * returning on success.  Otherwise the thread is queued, possibly
      * repeatedly blocking and unblocking, invoking {@link
-     * #tryAcquireShared} until success.  
-     * @param arg the acquire argument.
-     * This value is conveyed to {@link #tryAcquireShared} but is
-     * otherwise uninterpreted and can represent anything
-     * you like.
+     * #tryAcquireShared} until success.
+     *
+     * @param arg the acquire argument.  This value is conveyed to
+     *        {@link #tryAcquireShared} but is otherwise uninterpreted
+     *        and can represent anything you like.
      */
     public final void acquireShared(int arg) {
         if (tryAcquireShared(arg) < 0)
@@ -1129,8 +1242,8 @@
      * {@link #tryAcquireShared}, returning on success.  Otherwise the
      * thread is queued, possibly repeatedly blocking and unblocking,
      * invoking {@link #tryAcquireShared} until success or the thread
-     * is interrupted.  
-     * @param arg the acquire argument.
+     * is interrupted.
+     * @param arg the acquire argument
      * This value is conveyed to {@link #tryAcquireShared} but is
      * otherwise uninterpreted and can represent anything
      * you like.
@@ -1141,7 +1254,7 @@
             throw new InterruptedException();
         if (tryAcquireShared(arg) < 0)
             doAcquireSharedInterruptibly(arg);
-   }
+    }
 
     /**
      * Attempts to acquire in shared mode, aborting if interrupted, and
@@ -1151,35 +1264,33 @@
      * thread is queued, possibly repeatedly blocking and unblocking,
      * invoking {@link #tryAcquireShared} until success or the thread
      * is interrupted or the timeout elapses.
-     * @param arg the acquire argument.
-     * This value is conveyed to {@link #tryAcquireShared} but is
-     * otherwise uninterpreted and can represent anything
-     * you like.
+     *
+     * @param arg the acquire argument.  This value is conveyed to
+     *        {@link #tryAcquireShared} but is otherwise uninterpreted
+     *        and can represent anything you like.
      * @param nanosTimeout the maximum number of nanoseconds to wait
-     * @return true if acquired; false if timed out
+     * @return {@code true} if acquired; {@code false} if timed out
      * @throws InterruptedException if the current thread is interrupted
      */
-   public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout) throws InterruptedException {
-       if (Thread.interrupted())
-           throw new InterruptedException();
-       return tryAcquireShared(arg) >= 0 ||
-           doAcquireSharedNanos(arg, nanosTimeout);
-   }
+    public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout) throws InterruptedException {
+        if (Thread.interrupted())
+            throw new InterruptedException();
+        return tryAcquireShared(arg) >= 0 ||
+            doAcquireSharedNanos(arg, nanosTimeout);
+    }
 
     /**
      * Releases in shared mode.  Implemented by unblocking one or more
-     * threads if {@link #tryReleaseShared} returns true. 
-     * @param arg the release argument.
-     * This value is conveyed to {@link #tryReleaseShared} but is
-     * otherwise uninterpreted and can represent anything
-     * you like.
-     * @return the value returned from {@link #tryReleaseShared} 
+     * threads if {@link #tryReleaseShared} returns true.
+     *
+     * @param arg the release argument.  This value is conveyed to
+     *        {@link #tryReleaseShared} but is otherwise uninterpreted
+     *        and can represent anything you like.
+     * @return the value returned from {@link #tryReleaseShared}
      */
     public final boolean releaseShared(int arg) {
         if (tryReleaseShared(arg)) {
-            Node h = head;
-            if (h != null && h.waitStatus != 0) 
-                unparkSuccessor(h);
+            doReleaseShared();
             return true;
         }
         return false;
@@ -1190,16 +1301,15 @@
     /**
      * Queries whether any threads are waiting to acquire. Note that
      * because cancellations due to interrupts and timeouts may occur
-     * at any time, a <tt>true</tt> return does not guarantee that any
+     * at any time, a {@code true} return does not guarantee that any
      * other thread will ever acquire.
      *
-     * <p> In this implementation, this operation returns in
+     * <p>In this implementation, this operation returns in
      * constant time.
      *
-     * @return true if there may be other threads waiting to acquire
-     * the lock.
+     * @return {@code true} if there may be other threads waiting to acquire
      */
-    public final boolean hasQueuedThreads() { 
+    public final boolean hasQueuedThreads() {
         return head != tail;
     }
 
@@ -1207,10 +1317,10 @@
      * Queries whether any threads have ever contended to acquire this
      * synchronizer; that is if an acquire method has ever blocked.
      *
-     * <p> In this implementation, this operation returns in
+     * <p>In this implementation, this operation returns in
      * constant time.
      *
-     * @return true if there has ever been contention
+     * @return {@code true} if there has ever been contention
      */
     public final boolean hasContended() {
         return head != null;
@@ -1218,18 +1328,18 @@
 
     /**
      * Returns the first (longest-waiting) thread in the queue, or
-     * <tt>null</tt> if no threads are currently queued.
+     * {@code null} if no threads are currently queued.
      *
-     * <p> In this implementation, this operation normally returns in
+     * <p>In this implementation, this operation normally returns in
      * constant time, but may iterate upon contention if other threads are
      * concurrently modifying the queue.
      *
      * @return the first (longest-waiting) thread in the queue, or
-     * <tt>null</tt> if no threads are currently queued.
+     *         {@code null} if no threads are currently queued
      */
     public final Thread getFirstQueuedThread() {
         // handle only fast path, else relay
-        return (head == tail)? null : fullGetFirstQueuedThread();
+        return (head == tail) ? null : fullGetFirstQueuedThread();
     }
 
     /**
@@ -1237,57 +1347,49 @@
      */
     private Thread fullGetFirstQueuedThread() {
         /*
-         * This loops only if the queue changes while we read sets of
-         * fields.
+         * The first node is normally head.next. Try to get its
+         * thread field, ensuring consistent reads: If thread
+         * field is nulled out or s.prev is no longer head, then
+         * some other thread(s) concurrently performed setHead in
+         * between some of our reads. We try this twice before
+         * resorting to traversal.
          */
-        for (;;) {
-            Node h = head;
-            if (h == null)                    // No queue
-                return null;
+        Node h, s;
+        Thread st;
+        if (((h = head) != null && (s = h.next) != null &&
+             s.prev == head && (st = s.thread) != null) ||
+            ((h = head) != null && (s = h.next) != null &&
+             s.prev == head && (st = s.thread) != null))
+            return st;
 
-            /*
-             * The first node is normally h.next. Try to get its
-             * thread field, ensuring consistent reads: If thread
-             * field is nulled out or s.prev is no longer head, then
-             * some other thread(s) concurrently performed setHead in
-             * between some of our reads, so we must reread.
-             */
-            Node s = h.next;
-            if (s != null) {
-                Thread st = s.thread;
-                Node sp = s.prev;
-                if (st != null && sp == head)
-                    return st;
-            }
+        /*
+         * Head's next field might not have been set yet, or may have
+         * been unset after setHead. So we must check to see if tail
+         * is actually first node. If not, we continue on, safely
+         * traversing from tail back to head to find first,
+         * guaranteeing termination.
+         */
 
-            /*
-             * Head's next field might not have been set yet, or may
-             * have been unset after setHead. So we must check to see
-             * if tail is actually first node, in almost the same way
-             * as above.
-             */
-            Node t = tail; 
-            if (t == h)                       // Empty queue
-                return null;
-
-            if (t != null) {
-                Thread tt = t.thread;
-                Node tp = t.prev;
-                if (tt != null && tp == head)
-                    return tt;
-            }
+        Node t = tail;
+        Thread firstThread = null;
+        while (t != null && t != head) {
+            Thread tt = t.thread;
+            if (tt != null)
+                firstThread = tt;
+            t = t.prev;
         }
+        return firstThread;
     }
 
     /**
-     * Returns true if the given thread is currently queued. 
+     * Returns true if the given thread is currently queued.
      *
-     * <p> This implementation traverses the queue to determine
+     * <p>This implementation traverses the queue to determine
      * presence of the given thread.
      *
      * @param thread the thread
-     * @return true if the given thread in on the queue
-     * @throws NullPointerException if thread null
+     * @return {@code true} if the given thread is on the queue
+     * @throws NullPointerException if the thread is null
      */
     public final boolean isQueued(Thread thread) {
         if (thread == null)
@@ -1298,6 +1400,77 @@
         return false;
     }
 
+    /**
+     * Returns {@code true} if the apparent first queued thread, if one
+     * exists, is waiting in exclusive mode.  If this method returns
+     * {@code true}, and the current thread is attempting to acquire in
+     * shared mode (that is, this method is invoked from {@link
+     * #tryAcquireShared}) then it is guaranteed that the current thread
+     * is not the first queued thread.  Used only as a heuristic in
+     * ReentrantReadWriteLock.
+     */
+    final boolean apparentlyFirstQueuedIsExclusive() {
+        Node h, s;
+        return (h = head) != null &&
+            (s = h.next)  != null &&
+            !s.isShared()         &&
+            s.thread != null;
+    }
+
+    /**
+     * Queries whether any threads have been waiting to acquire longer
+     * than the current thread.
+     *
+     * <p>An invocation of this method is equivalent to (but may be
+     * more efficient than):
+     *  <pre> {@code
+     * getFirstQueuedThread() != Thread.currentThread() &&
+     * hasQueuedThreads()}</pre>
+     *
+     * <p>Note that because cancellations due to interrupts and
+     * timeouts may occur at any time, a {@code true} return does not
+     * guarantee that some other thread will acquire before the current
+     * thread.  Likewise, it is possible for another thread to win a
+     * race to enqueue after this method has returned {@code false},
+     * due to the queue being empty.
+     *
+     * <p>This method is designed to be used by a fair synchronizer to
+     * avoid <a href="AbstractQueuedSynchronizer#barging">barging</a>.
+     * Such a synchronizer's {@link #tryAcquire} method should return
+     * {@code false}, and its {@link #tryAcquireShared} method should
+     * return a negative value, if this method returns {@code true}
+     * (unless this is a reentrant acquire).  For example, the {@code
+     * tryAcquire} method for a fair, reentrant, exclusive mode
+     * synchronizer might look like this:
+     *
+     *  <pre> {@code
+     * protected boolean tryAcquire(int arg) {
+     *   if (isHeldExclusively()) {
+     *     // A reentrant acquire; increment hold count
+     *     return true;
+     *   } else if (hasQueuedPredecessors()) {
+     *     return false;
+     *   } else {
+     *     // try to acquire normally
+     *   }
+     * }}</pre>
+     *
+     * @return {@code true} if there is a queued thread preceding the
+     *         current thread, and {@code false} if the current thread
+     *         is at the head of the queue or the queue is empty
+     */
+    final boolean hasQueuedPredecessors() {
+        // The correctness of this depends on head being initialized
+        // before tail and on head.next being accurate if the current
+        // thread is first in queue.
+        Node t = tail; // Read fields in reverse initialization order
+        Node h = head;
+        Node s;
+        return h != t &&
+            ((s = h.next) == null || s.thread != Thread.currentThread());
+    }
+
+
     // Instrumentation and monitoring methods
 
     /**
@@ -1308,7 +1481,7 @@
      * monitoring system state, not for synchronization
      * control.
      *
-     * @return the estimated number of threads waiting for this lock
+     * @return the estimated number of threads waiting to acquire
      */
     public final int getQueueLength() {
         int n = 0;
@@ -1327,6 +1500,7 @@
      * returned collection are in no particular order.  This method is
      * designed to facilitate construction of subclasses that provide
      * more extensive monitoring facilities.
+     *
      * @return the collection of threads
      */
     public final Collection<Thread> getQueuedThreads() {
@@ -1344,6 +1518,7 @@
      * acquire in exclusive mode. This has the same properties
      * as {@link #getQueuedThreads} except that it only returns
      * those threads waiting due to an exclusive acquire.
+     *
      * @return the collection of threads
      */
     public final Collection<Thread> getExclusiveQueuedThreads() {
@@ -1363,6 +1538,7 @@
      * acquire in shared mode. This has the same properties
      * as {@link #getQueuedThreads} except that it only returns
      * those threads waiting due to a shared acquire.
+     *
      * @return the collection of threads
      */
     public final Collection<Thread> getSharedQueuedThreads() {
@@ -1378,18 +1554,18 @@
     }
 
     /**
-     * Returns a string identifying this synchronizer, as well as its
-     * state.  The state, in brackets, includes the String &quot;State
-     * =&quot; followed by the current value of {@link #getState}, and
-     * either &quot;nonempty&quot; or &quot;empty&quot; depending on
-     * whether the queue is empty.
+     * Returns a string identifying this synchronizer, as well as its state.
+     * The state, in brackets, includes the String {@code "State ="}
+     * followed by the current value of {@link #getState}, and either
+     * {@code "nonempty"} or {@code "empty"} depending on whether the
+     * queue is empty.
      *
-     * @return a string identifying this synchronizer, as well as its state.
+     * @return a string identifying this synchronizer, as well as its state
      */
     public String toString() {
         int s = getState();
-        String q  = hasQueuedThreads()? "non" : "";
-        return super.toString() + 
+        String q  = hasQueuedThreads() ? "non" : "";
+        return super.toString() +
             "[State = " + s + ", " + q + "empty queue]";
     }
 
@@ -1416,7 +1592,7 @@
          * there, so we hardly ever traverse much.
          */
         return findNodeFromTail(node);
-    } 
+    }
 
     /**
      * Returns true if node is on sync queue by searching backwards from tail.
@@ -1424,7 +1600,7 @@
      * @return true if present
      */
     private boolean findNodeFromTail(Node node) {
-        Node t = tail; 
+        Node t = tail;
         for (;;) {
             if (t == node)
                 return true;
@@ -1435,7 +1611,7 @@
     }
 
     /**
-     * Transfers a node from a condition queue onto sync queue. 
+     * Transfers a node from a condition queue onto sync queue.
      * Returns true if successful.
      * @param node the node
      * @return true if successfully transferred (else the node was
@@ -1455,8 +1631,8 @@
          * case the waitStatus can be transiently and harmlessly wrong).
          */
         Node p = enq(node);
-        int c = p.waitStatus;
-        if (c > 0 || !compareAndSetWaitStatus(p, c, Node.SIGNAL)) 
+        int ws = p.waitStatus;
+        if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))
             LockSupport.unpark(node.thread);
         return true;
     }
@@ -1465,9 +1641,8 @@
      * Transfers node, if necessary, to sync queue after a cancelled
      * wait. Returns true if thread was cancelled before being
      * signalled.
-     * @param current the waiting thread
      * @param node its node
-     * @return true if cancelled before the node was signalled.
+     * @return true if cancelled before the node was signalled
      */
     final boolean transferAfterCancelledWait(Node node) {
         if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) {
@@ -1480,39 +1655,42 @@
          * incomplete transfer is both rare and transient, so just
          * spin.
          */
-        while (!isOnSyncQueue(node)) 
+        while (!isOnSyncQueue(node))
             Thread.yield();
         return false;
     }
 
     /**
-     * Invoke release with current state value; return saved state.
-     * Cancel node and throw exception on failure.
+     * Invokes release with current state value; returns saved state.
+     * Cancels node and throws exception on failure.
      * @param node the condition node for this wait
      * @return previous sync state
      */
     final int fullyRelease(Node node) {
+        boolean failed = true;
         try {
             int savedState = getState();
-            if (release(savedState))
+            if (release(savedState)) {
+                failed = false;
                 return savedState;
-        } catch(RuntimeException ex) {
-            node.waitStatus = Node.CANCELLED;
-            throw ex;
+            } else {
+                throw new IllegalMonitorStateException();
+            }
+        } finally {
+            if (failed)
+                node.waitStatus = Node.CANCELLED;
         }
-        // reach here if release fails
-        node.waitStatus = Node.CANCELLED;
-        throw new IllegalMonitorStateException();
     }
 
     // Instrumentation methods for conditions
 
     /**
-     * Queries whether the given ConditionObject 
+     * Queries whether the given ConditionObject
      * uses this synchronizer as its lock.
+     *
      * @param condition the condition
      * @return <tt>true</tt> if owned
-     * @throws NullPointerException if condition null
+     * @throws NullPointerException if the condition is null
      */
     public final boolean owns(ConditionObject condition) {
         if (condition == null)
@@ -1527,14 +1705,15 @@
      * does not guarantee that a future <tt>signal</tt> will awaken
      * any threads.  This method is designed primarily for use in
      * monitoring of the system state.
+     *
      * @param condition the condition
-     * @return <tt>true</tt> if there are any waiting threads.
-     * @throws IllegalMonitorStateException if exclusive synchronization 
-     * is not held
+     * @return <tt>true</tt> if there are any waiting threads
+     * @throws IllegalMonitorStateException if exclusive synchronization
+     *         is not held
      * @throws IllegalArgumentException if the given condition is
-     * not associated with this synchronizer
-     * @throws NullPointerException if condition null
-     */ 
+     *         not associated with this synchronizer
+     * @throws NullPointerException if the condition is null
+     */
     public final boolean hasWaiters(ConditionObject condition) {
         if (!owns(condition))
             throw new IllegalArgumentException("Not owner");
@@ -1548,14 +1727,15 @@
      * estimate serves only as an upper bound on the actual number of
      * waiters.  This method is designed for use in monitoring of the
      * system state, not for synchronization control.
+     *
      * @param condition the condition
-     * @return the estimated number of waiting threads.
-     * @throws IllegalMonitorStateException if exclusive synchronization 
-     * is not held
+     * @return the estimated number of waiting threads
+     * @throws IllegalMonitorStateException if exclusive synchronization
+     *         is not held
      * @throws IllegalArgumentException if the given condition is
-     * not associated with this synchronizer
-     * @throws NullPointerException if condition null
-     */ 
+     *         not associated with this synchronizer
+     * @throws NullPointerException if the condition is null
+     */
     public final int getWaitQueueLength(ConditionObject condition) {
         if (!owns(condition))
             throw new IllegalArgumentException("Not owner");
@@ -1568,14 +1748,15 @@
      * synchronizer.  Because the actual set of threads may change
      * dynamically while constructing this result, the returned
      * collection is only a best-effort estimate. The elements of the
-     * returned collection are in no particular order.  
+     * returned collection are in no particular order.
+     *
      * @param condition the condition
      * @return the collection of threads
-     * @throws IllegalMonitorStateException if exclusive synchronization 
-     * is not held
+     * @throws IllegalMonitorStateException if exclusive synchronization
+     *         is not held
      * @throws IllegalArgumentException if the given condition is
-     * not associated with this synchronizer
-     * @throws NullPointerException if condition null
+     *         not associated with this synchronizer
+     * @throws NullPointerException if the condition is null
      */
     public final Collection<Thread> getWaitingThreads(ConditionObject condition) {
         if (!owns(condition))
@@ -1588,14 +1769,14 @@
      * AbstractQueuedSynchronizer} serving as the basis of a {@link
      * Lock} implementation.
      *
-     * <p> Method documentation for this class describes mechanics,
+     * <p>Method documentation for this class describes mechanics,
      * not behavioral specifications from the point of view of Lock
      * and Condition users. Exported versions of this class will in
      * general need to be accompanied by documentation describing
      * condition semantics that rely on those of the associated
      * <tt>AbstractQueuedSynchronizer</tt>.
-     * 
-     * <p> This class is Serializable, but all fields are transient,
+     *
+     * <p>This class is Serializable, but all fields are transient,
      * so deserialized conditions have no waiters.
      */
     public class ConditionObject implements Condition, java.io.Serializable {
@@ -1613,29 +1794,34 @@
         // Internal methods
 
         /**
-         * Add a new waiter to wait queue
+         * Adds a new waiter to wait queue.
          * @return its new wait node
          */
         private Node addConditionWaiter() {
-            Node node = new Node(Thread.currentThread(), Node.CONDITION);
             Node t = lastWaiter;
-            if (t == null) 
+            // If lastWaiter is cancelled, clean out.
+            if (t != null && t.waitStatus != Node.CONDITION) {
+                unlinkCancelledWaiters();
+                t = lastWaiter;
+            }
+            Node node = new Node(Thread.currentThread(), Node.CONDITION);
+            if (t == null)
                 firstWaiter = node;
-            else 
+            else
                 t.nextWaiter = node;
             lastWaiter = node;
             return node;
         }
 
         /**
-         * Remove and transfer nodes until hit non-cancelled one or
+         * Removes and transfers nodes until hit non-cancelled one or
          * null. Split out from signal in part to encourage compilers
          * to inline the case of no waiters.
          * @param first (non-null) the first node on condition queue
          */
         private void doSignal(Node first) {
             do {
-                if ( (firstWaiter = first.nextWaiter) == null) 
+                if ( (firstWaiter = first.nextWaiter) == null)
                     lastWaiter = null;
                 first.nextWaiter = null;
             } while (!transferForSignal(first) &&
@@ -1643,11 +1829,11 @@
         }
 
         /**
-         * Remove and transfer all nodes.
+         * Removes and transfers all nodes.
          * @param first (non-null) the first node on condition queue
          */
         private void doSignalAll(Node first) {
-            lastWaiter = firstWaiter  = null;
+            lastWaiter = firstWaiter = null;
             do {
                 Node next = first.nextWaiter;
                 first.nextWaiter = null;
@@ -1656,45 +1842,81 @@
             } while (first != null);
         }
 
+        /**
+         * Unlinks cancelled waiter nodes from condition queue.
+         * Called only while holding lock. This is called when
+         * cancellation occurred during condition wait, and upon
+         * insertion of a new waiter when lastWaiter is seen to have
+         * been cancelled. This method is needed to avoid garbage
+         * retention in the absence of signals. So even though it may
+         * require a full traversal, it comes into play only when
+         * timeouts or cancellations occur in the absence of
+         * signals. It traverses all nodes rather than stopping at a
+         * particular target to unlink all pointers to garbage nodes
+         * without requiring many re-traversals during cancellation
+         * storms.
+         */
+        private void unlinkCancelledWaiters() {
+            Node t = firstWaiter;
+            Node trail = null;
+            while (t != null) {
+                Node next = t.nextWaiter;
+                if (t.waitStatus != Node.CONDITION) {
+                    t.nextWaiter = null;
+                    if (trail == null)
+                        firstWaiter = next;
+                    else
+                        trail.nextWaiter = next;
+                    if (next == null)
+                        lastWaiter = trail;
+                }
+                else
+                    trail = t;
+                t = next;
+            }
+        }
+
         // public methods
 
         /**
          * Moves the longest-waiting thread, if one exists, from the
          * wait queue for this condition to the wait queue for the
          * owning lock.
+         *
          * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
-         * returns false
+         *         returns {@code false}
          */
         public final void signal() {
-            if (!isHeldExclusively()) 
+            if (!isHeldExclusively())
                 throw new IllegalMonitorStateException();
             Node first = firstWaiter;
             if (first != null)
                 doSignal(first);
         }
-         
+
         /**
          * Moves all threads from the wait queue for this condition to
          * the wait queue for the owning lock.
+         *
          * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
-         * returns false
+         *         returns {@code false}
          */
         public final void signalAll() {
-            if (!isHeldExclusively()) 
+            if (!isHeldExclusively())
                 throw new IllegalMonitorStateException();
             Node first = firstWaiter;
-            if (first != null) 
+            if (first != null)
                 doSignalAll(first);
         }
 
         /**
          * Implements uninterruptible condition wait.
          * <ol>
-         * <li> Save lock state returned by {@link #getState} 
-         * <li> Invoke {@link #release} with 
-         *      saved state as argument, throwing 
-         *      IllegalMonitorStateException  if it fails.
-         * <li> Block until signalled
+         * <li> Save lock state returned by {@link #getState}.
+         * <li> Invoke {@link #release} with
+         *      saved state as argument, throwing
+         *      IllegalMonitorStateException if it fails.
+         * <li> Block until signalled.
          * <li> Reacquire by invoking specialized version of
          *      {@link #acquire} with saved state as argument.
          * </ol>
@@ -1705,7 +1927,7 @@
             boolean interrupted = false;
             while (!isOnSyncQueue(node)) {
                 LockSupport.park();
-                if (Thread.interrupted()) 
+                if (Thread.interrupted())
                     interrupted = true;
             }
             if (acquireQueued(node, savedState) || interrupted)
@@ -1725,47 +1947,47 @@
         private static final int THROW_IE    = -1;
 
         /**
-         * Check for interrupt, returning THROW_IE if interrupted
+         * Checks for interrupt, returning THROW_IE if interrupted
          * before signalled, REINTERRUPT if after signalled, or
          * 0 if not interrupted.
          */
         private int checkInterruptWhileWaiting(Node node) {
-            return (Thread.interrupted()) ?
-                ((transferAfterCancelledWait(node))? THROW_IE : REINTERRUPT) :
+            return Thread.interrupted() ?
+                (transferAfterCancelledWait(node) ? THROW_IE : REINTERRUPT) :
                 0;
         }
 
         /**
-         * Throw InterruptedException, reinterrupt current thread, or
-         * do nothing, depending on mode.
+         * Throws InterruptedException, reinterrupts current thread, or
+         * does nothing, depending on mode.
          */
-        private void reportInterruptAfterWait(int interruptMode) 
+        private void reportInterruptAfterWait(int interruptMode)
             throws InterruptedException {
             if (interruptMode == THROW_IE)
                 throw new InterruptedException();
             else if (interruptMode == REINTERRUPT)
-                Thread.currentThread().interrupt();
+                selfInterrupt();
         }
 
         /**
          * Implements interruptible condition wait.
          * <ol>
-         * <li> If current thread is interrupted, throw InterruptedException
-         * <li> Save lock state returned by {@link #getState} 
-         * <li> Invoke {@link #release} with 
-         *      saved state as argument, throwing 
-         *      IllegalMonitorStateException  if it fails.
-         * <li> Block until signalled or interrupted
+         * <li> If current thread is interrupted, throw InterruptedException.
+         * <li> Save lock state returned by {@link #getState}.
+         * <li> Invoke {@link #release} with
+         *      saved state as argument, throwing
+         *      IllegalMonitorStateException if it fails.
+         * <li> Block until signalled or interrupted.
          * <li> Reacquire by invoking specialized version of
          *      {@link #acquire} with saved state as argument.
-         * <li> If interrupted while blocked in step 4, throw exception
+         * <li> If interrupted while blocked in step 4, throw InterruptedException.
          * </ol>
-         * 
+         *
          * @throws InterruptedException if the current thread is interrupted (and
          * interruption of thread suspension is supported).
          */
         public final void await() throws InterruptedException {
-            if (Thread.interrupted()) 
+            if (Thread.interrupted())
                 throw new InterruptedException();
             Node node = addConditionWaiter();
             int savedState = fullyRelease(node);
@@ -1777,6 +1999,8 @@
             }
             if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
                 interruptMode = REINTERRUPT;
+            if (node.nextWaiter != null) // clean up if cancelled
+                unlinkCancelledWaiters();
             if (interruptMode != 0)
                 reportInterruptAfterWait(interruptMode);
         }
@@ -1784,17 +2008,17 @@
         /**
          * Implements timed condition wait.
          * <ol>
-         * <li> If current thread is interrupted, throw InterruptedException
-         * <li> Save lock state returned by {@link #getState} 
-         * <li> Invoke {@link #release} with 
-         *      saved state as argument, throwing 
-         *      IllegalMonitorStateException  if it fails.
-         * <li> Block until signalled, interrupted, or timed out
+         * <li> If current thread is interrupted, throw InterruptedException.
+         * <li> Save lock state returned by {@link #getState}.
+         * <li> Invoke {@link #release} with
+         *      saved state as argument, throwing
+         *      IllegalMonitorStateException if it fails.
+         * <li> Block until signalled, interrupted, or timed out.
          * <li> Reacquire by invoking specialized version of
          *      {@link #acquire} with saved state as argument.
-         * <li> If interrupted while blocked in step 4, throw InterruptedException
+         * <li> If interrupted while blocked in step 4, throw InterruptedException.
          * </ol>
-         * 
+         *
          * @param nanosTimeout the maximum time to wait, in nanoseconds
          * @return A value less than or equal to zero if the wait has
          * timed out; otherwise an estimate, that
@@ -1805,7 +2029,7 @@
          * interruption of thread suspension is supported).
          */
         public final long awaitNanos(long nanosTimeout) throws InterruptedException {
-            if (Thread.interrupted()) 
+            if (Thread.interrupted())
                 throw new InterruptedException();
             Node node = addConditionWaiter();
             int savedState = fullyRelease(node);
@@ -1813,18 +2037,21 @@
             int interruptMode = 0;
             while (!isOnSyncQueue(node)) {
                 if (nanosTimeout <= 0L) {
-                    transferAfterCancelledWait(node); 
+                    transferAfterCancelledWait(node);
                     break;
                 }
                 LockSupport.parkNanos(nanosTimeout);
                 if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
                     break;
+
                 long now = System.nanoTime();
                 nanosTimeout -= now - lastTime;
                 lastTime = now;
             }
             if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
                 interruptMode = REINTERRUPT;
+            if (node.nextWaiter != null)
+                unlinkCancelledWaiters();
             if (interruptMode != 0)
                 reportInterruptAfterWait(interruptMode);
             return nanosTimeout - (System.nanoTime() - lastTime);
@@ -1833,18 +2060,18 @@
         /**
          * Implements absolute timed condition wait.
          * <ol>
-         * <li> If current thread is interrupted, throw InterruptedException
-         * <li> Save lock state returned by {@link #getState} 
-         * <li> Invoke {@link #release} with 
-         *      saved state as argument, throwing 
-         *      IllegalMonitorStateException  if it fails.
-         * <li> Block until signalled, interrupted, or timed out
+         * <li> If current thread is interrupted, throw InterruptedException.
+         * <li> Save lock state returned by {@link #getState}.
+         * <li> Invoke {@link #release} with
+         *      saved state as argument, throwing
+         *      IllegalMonitorStateException if it fails.
+         * <li> Block until signalled, interrupted, or timed out.
          * <li> Reacquire by invoking specialized version of
          *      {@link #acquire} with saved state as argument.
-         * <li> If interrupted while blocked in step 4, throw InterruptedException
-         * <li> If timed out while blocked in step 4, return false, else true
+         * <li> If interrupted while blocked in step 4, throw InterruptedException.
+         * <li> If timed out while blocked in step 4, return false, else true.
          * </ol>
-         * 
+         *
          * @param deadline the absolute time to wait until
          * @return <tt>false</tt> if the deadline has
          * elapsed upon return, else <tt>true</tt>.
@@ -1856,7 +2083,7 @@
             if (deadline == null)
                 throw new NullPointerException();
             long abstime = deadline.getTime();
-            if (Thread.interrupted()) 
+            if (Thread.interrupted())
                 throw new InterruptedException();
             Node node = addConditionWaiter();
             int savedState = fullyRelease(node);
@@ -1864,7 +2091,7 @@
             int interruptMode = 0;
             while (!isOnSyncQueue(node)) {
                 if (System.currentTimeMillis() > abstime) {
-                    timedout = transferAfterCancelledWait(node); 
+                    timedout = transferAfterCancelledWait(node);
                     break;
                 }
                 LockSupport.parkUntil(abstime);
@@ -1873,26 +2100,28 @@
             }
             if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
                 interruptMode = REINTERRUPT;
+            if (node.nextWaiter != null)
+                unlinkCancelledWaiters();
             if (interruptMode != 0)
                 reportInterruptAfterWait(interruptMode);
             return !timedout;
         }
-        
+
         /**
-         * Implements timed condition wait. 
+         * Implements timed condition wait.
          * <ol>
-         * <li> If current thread is interrupted, throw InterruptedException
-         * <li> Save lock state returned by {@link #getState} 
-         * <li> Invoke {@link #release} with 
-         *      saved state as argument, throwing 
-         *      IllegalMonitorStateException  if it fails.
-         * <li> Block until signalled, interrupted, or timed out
+         * <li> If current thread is interrupted, throw InterruptedException.
+         * <li> Save lock state returned by {@link #getState}.
+         * <li> Invoke {@link #release} with
+         *      saved state as argument, throwing
+         *      IllegalMonitorStateException if it fails.
+         * <li> Block until signalled, interrupted, or timed out.
          * <li> Reacquire by invoking specialized version of
          *      {@link #acquire} with saved state as argument.
-         * <li> If interrupted while blocked in step 4, throw InterruptedException
-         * <li> If timed out while blocked in step 4, return false, else true
+         * <li> If interrupted while blocked in step 4, throw InterruptedException.
+         * <li> If timed out while blocked in step 4, return false, else true.
          * </ol>
-         * 
+         *
          * @param time the maximum time to wait
          * @param unit the time unit of the <tt>time</tt> argument.
          * @return <tt>false</tt> if the waiting time detectably elapsed
@@ -1904,7 +2133,7 @@
             if (unit == null)
                 throw new NullPointerException();
             long nanosTimeout = unit.toNanos(time);
-            if (Thread.interrupted()) 
+            if (Thread.interrupted())
                 throw new InterruptedException();
             Node node = addConditionWaiter();
             int savedState = fullyRelease(node);
@@ -1913,10 +2142,11 @@
             int interruptMode = 0;
             while (!isOnSyncQueue(node)) {
                 if (nanosTimeout <= 0L) {
-                    timedout = transferAfterCancelledWait(node); 
+                    timedout = transferAfterCancelledWait(node);
                     break;
                 }
-                LockSupport.parkNanos(nanosTimeout);
+                if (nanosTimeout >= spinForTimeoutThreshold)
+                    LockSupport.parkNanos(nanosTimeout);
                 if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
                     break;
                 long now = System.nanoTime();
@@ -1925,6 +2155,8 @@
             }
             if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
                 interruptMode = REINTERRUPT;
+            if (node.nextWaiter != null)
+                unlinkCancelledWaiters();
             if (interruptMode != 0)
                 reportInterruptAfterWait(interruptMode);
             return !timedout;
@@ -1934,8 +2166,9 @@
 
         /**
          * Returns true if this condition was created by the given
-         * synchronization object
-         * @return true if owned
+         * synchronization object.
+         *
+         * @return {@code true} if owned
          */
         final boolean isOwnedBy(AbstractQueuedSynchronizer sync) {
             return sync == AbstractQueuedSynchronizer.this;
@@ -1943,13 +2176,14 @@
 
         /**
          * Queries whether any threads are waiting on this condition.
-         * Implements {@link AbstractQueuedSynchronizer#hasWaiters}
-         * @return <tt>true</tt> if there are any waiting threads.
+         * Implements {@link AbstractQueuedSynchronizer#hasWaiters}.
+         *
+         * @return {@code true} if there are any waiting threads
          * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
-         * returns false
-         */ 
+         *         returns {@code false}
+         */
         protected final boolean hasWaiters() {
-            if (!isHeldExclusively()) 
+            if (!isHeldExclusively())
                 throw new IllegalMonitorStateException();
             for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
                 if (w.waitStatus == Node.CONDITION)
@@ -1960,14 +2194,15 @@
 
         /**
          * Returns an estimate of the number of threads waiting on
-         * this condition. 
-         * Implements {@link AbstractQueuedSynchronizer#getWaitQueueLength}
-         * @return the estimated number of waiting threads.
+         * this condition.
+         * Implements {@link AbstractQueuedSynchronizer#getWaitQueueLength}.
+         *
+         * @return the estimated number of waiting threads
          * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
-         * returns false
-         */ 
+         *         returns {@code false}
+         */
         protected final int getWaitQueueLength() {
-            if (!isHeldExclusively()) 
+            if (!isHeldExclusively())
                 throw new IllegalMonitorStateException();
             int n = 0;
             for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
@@ -1979,14 +2214,15 @@
 
         /**
          * Returns a collection containing those threads that may be
-         * waiting on this Condition.  
-         * Implements {@link AbstractQueuedSynchronizer#getWaitingThreads}
+         * waiting on this Condition.
+         * Implements {@link AbstractQueuedSynchronizer#getWaitingThreads}.
+         *
          * @return the collection of threads
          * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
-         * returns false
+         *         returns {@code false}
          */
         protected final Collection<Thread> getWaitingThreads() {
-            if (!isHeldExclusively()) 
+            if (!isHeldExclusively())
                 throw new IllegalMonitorStateException();
             ArrayList<Thread> list = new ArrayList<Thread>();
             for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
@@ -2016,6 +2252,7 @@
     private static final long headOffset;
     private static final long tailOffset;
     private static final long waitStatusOffset;
+    private static final long nextOffset;
 
     static {
         try {
@@ -2027,19 +2264,21 @@
                 (AbstractQueuedSynchronizer.class.getDeclaredField("tail"));
             waitStatusOffset = unsafe.objectFieldOffset
                 (Node.class.getDeclaredField("waitStatus"));
-            
-        } catch(Exception ex) { throw new Error(ex); }
+            nextOffset = unsafe.objectFieldOffset
+                (Node.class.getDeclaredField("next"));
+
+        } catch (Exception ex) { throw new Error(ex); }
     }
 
     /**
-     * CAS head field. Used only by enq
+     * CAS head field. Used only by enq.
      */
     private final boolean compareAndSetHead(Node update) {
         return unsafe.compareAndSwapObject(this, headOffset, null, update);
     }
-    
+
     /**
-     * CAS tail field. Used only by enq
+     * CAS tail field. Used only by enq.
      */
     private final boolean compareAndSetTail(Node expect, Node update) {
         return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
@@ -2048,11 +2287,19 @@
     /**
      * CAS waitStatus field of a node.
      */
-    private final static boolean compareAndSetWaitStatus(Node node, 
-                                                         int expect, 
+    private final static boolean compareAndSetWaitStatus(Node node,
+                                                         int expect,
                                                          int update) {
-        return unsafe.compareAndSwapInt(node, waitStatusOffset, 
+        return unsafe.compareAndSwapInt(node, waitStatusOffset,
                                         expect, update);
     }
 
+    /**
+     * CAS next field of a node.
+     */
+    private final static boolean compareAndSetNext(Node node,
+                                                   Node expect,
+                                                   Node update) {
+        return unsafe.compareAndSwapObject(node, nextOffset, expect, update);
+    }
 }
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/locks/Condition.java b/libcore/concurrent/src/main/java/java/util/concurrent/locks/Condition.java
index 7a8ca5b..03be58f 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/locks/Condition.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/locks/Condition.java
@@ -9,13 +9,13 @@
 import java.util.Date;
 
 /**
- * <tt>Condition</tt> factors out the <tt>Object</tt> monitor
+ * {@code Condition} factors out the {@code Object} monitor
  * methods ({@link Object#wait() wait}, {@link Object#notify notify}
  * and {@link Object#notifyAll notifyAll}) into distinct objects to
  * give the effect of having multiple wait-sets per object, by
  * combining them with the use of arbitrary {@link Lock} implementations.
- * Where a <tt>Lock</tt> replaces the use of <tt>synchronized</tt> methods
- * and statements, a <tt>Condition</tt> replaces the use of the Object
+ * Where a {@code Lock} replaces the use of {@code synchronized} methods
+ * and statements, a {@code Condition} replaces the use of the Object
  * monitor methods.
  *
  * <p>Conditions (also known as <em>condition queues</em> or
@@ -26,37 +26,37 @@
  * must be protected, so a lock of some form is associated with the
  * condition. The key property that waiting for a condition provides
  * is that it <em>atomically</em> releases the associated lock and
- * suspends the current thread, just like <tt>Object.wait</tt>.
+ * suspends the current thread, just like {@code Object.wait}.
  *
- * <p>A <tt>Condition</tt> instance is intrinsically bound to a lock.
- * To obtain a <tt>Condition</tt> instance for a particular {@link Lock} 
+ * <p>A {@code Condition} instance is intrinsically bound to a lock.
+ * To obtain a {@code Condition} instance for a particular {@link Lock}
  * instance use its {@link Lock#newCondition newCondition()} method.
  *
  * <p>As an example, suppose we have a bounded buffer which supports
- * <tt>put</tt> and <tt>take</tt> methods.  If a
- * <tt>take</tt> is attempted on an empty buffer, then the thread will block
- * until an item becomes available; if a <tt>put</tt> is attempted on a
+ * {@code put} and {@code take} methods.  If a
+ * {@code take} is attempted on an empty buffer, then the thread will block
+ * until an item becomes available; if a {@code put} is attempted on a
  * full buffer, then the thread will block until a space becomes available.
- * We would like to keep waiting <tt>put</tt> threads and <tt>take</tt>
+ * We would like to keep waiting {@code put} threads and {@code take}
  * threads in separate wait-sets so that we can use the optimization of
  * only notifying a single thread at a time when items or spaces become
- * available in the buffer. This can be achieved using two 
+ * available in the buffer. This can be achieved using two
  * {@link Condition} instances.
  * <pre>
  * class BoundedBuffer {
- *   <b>Lock lock = new ReentrantLock();</b>
+ *   <b>final Lock lock = new ReentrantLock();</b>
  *   final Condition notFull  = <b>lock.newCondition(); </b>
  *   final Condition notEmpty = <b>lock.newCondition(); </b>
  *
- *   Object[] items = new Object[100];
+ *   final Object[] items = new Object[100];
  *   int putptr, takeptr, count;
  *
  *   public void put(Object x) throws InterruptedException {
  *     <b>lock.lock();
  *     try {</b>
- *       while (count == items.length) 
+ *       while (count == items.length)
  *         <b>notFull.await();</b>
- *       items[putptr] = x; 
+ *       items[putptr] = x;
  *       if (++putptr == items.length) putptr = 0;
  *       ++count;
  *       <b>notEmpty.signal();</b>
@@ -68,9 +68,9 @@
  *   public Object take() throws InterruptedException {
  *     <b>lock.lock();
  *     try {</b>
- *       while (count == 0) 
+ *       while (count == 0)
  *         <b>notEmpty.await();</b>
- *       Object x = items[takeptr]; 
+ *       Object x = items[takeptr];
  *       if (++takeptr == items.length) takeptr = 0;
  *       --count;
  *       <b>notFull.signal();</b>
@@ -78,7 +78,7 @@
  *     <b>} finally {
  *       lock.unlock();
  *     }</b>
- *   } 
+ *   }
  * }
  * </pre>
  *
@@ -86,61 +86,63 @@
  * this functionality, so there is no reason to implement this
  * sample usage class.)
  *
- * <p>A <tt>Condition</tt> implementation can provide behavior and semantics 
- * that is 
- * different from that of the <tt>Object</tt> monitor methods, such as 
- * guaranteed ordering for notifications, or not requiring a lock to be held 
+ * <p>A {@code Condition} implementation can provide behavior and semantics
+ * that is
+ * different from that of the {@code Object} monitor methods, such as
+ * guaranteed ordering for notifications, or not requiring a lock to be held
  * when performing notifications.
- * If an implementation provides such specialized semantics then the 
+ * If an implementation provides such specialized semantics then the
  * implementation must document those semantics.
  *
- * <p>Note that <tt>Condition</tt> instances are just normal objects and can 
- * themselves be used as the target in a <tt>synchronized</tt> statement,
+ * <p>Note that {@code Condition} instances are just normal objects and can
+ * themselves be used as the target in a {@code synchronized} statement,
  * and can have their own monitor {@link Object#wait wait} and
  * {@link Object#notify notification} methods invoked.
- * Acquiring the monitor lock of a <tt>Condition</tt> instance, or using its
+ * Acquiring the monitor lock of a {@code Condition} instance, or using its
  * monitor methods, has no specified relationship with acquiring the
- * {@link Lock} associated with that <tt>Condition</tt> or the use of its
- * {@link #await waiting} and {@link #signal signalling} methods.
- * It is recommended that to avoid confusion you never use <tt>Condition</tt>
+ * {@link Lock} associated with that {@code Condition} or the use of its
+ * {@linkplain #await waiting} and {@linkplain #signal signalling} methods.
+ * It is recommended that to avoid confusion you never use {@code Condition}
  * instances in this way, except perhaps within their own implementation.
  *
- * <p>Except where noted, passing a <tt>null</tt> value for any parameter 
+ * <p>Except where noted, passing a {@code null} value for any parameter
  * will result in a {@link NullPointerException} being thrown.
  *
  * <h3>Implementation Considerations</h3>
  *
- * <p>When waiting upon a <tt>Condition</tt>, a &quot;<em>spurious
- * wakeup</em>&quot; is permitted to occur, in 
+ * <p>When waiting upon a {@code Condition}, a &quot;<em>spurious
+ * wakeup</em>&quot; is permitted to occur, in
  * general, as a concession to the underlying platform semantics.
  * This has little practical impact on most application programs as a
- * <tt>Condition</tt> should always be waited upon in a loop, testing
+ * {@code Condition} should always be waited upon in a loop, testing
  * the state predicate that is being waited for.  An implementation is
- * free to remove the possibility of spurious wakeups but it is 
+ * free to remove the possibility of spurious wakeups but it is
  * recommended that applications programmers always assume that they can
  * occur and so always wait in a loop.
  *
- * <p>The three forms of condition waiting 
- * (interruptible, non-interruptible, and timed) may differ in their ease of 
+ * <p>The three forms of condition waiting
+ * (interruptible, non-interruptible, and timed) may differ in their ease of
  * implementation on some platforms and in their performance characteristics.
- * In particular, it may be difficult to provide these features and maintain 
- * specific semantics such as ordering guarantees. 
- * Further, the ability to interrupt the actual suspension of the thread may 
+ * In particular, it may be difficult to provide these features and maintain
+ * specific semantics such as ordering guarantees.
+ * Further, the ability to interrupt the actual suspension of the thread may
  * not always be feasible to implement on all platforms.
- * <p>Consequently, an implementation is not required to define exactly the 
- * same guarantees or semantics for all three forms of waiting, nor is it 
+ *
+ * <p>Consequently, an implementation is not required to define exactly the
+ * same guarantees or semantics for all three forms of waiting, nor is it
  * required to support interruption of the actual suspension of the thread.
+ *
  * <p>An implementation is required to
- * clearly document the semantics and guarantees provided by each of the 
- * waiting methods, and when an implementation does support interruption of 
- * thread suspension then it must obey the interruption semantics as defined 
+ * clearly document the semantics and guarantees provided by each of the
+ * waiting methods, and when an implementation does support interruption of
+ * thread suspension then it must obey the interruption semantics as defined
  * in this interface.
- * <p>As interruption generally implies cancellation, and checks for 
+ *
+ * <p>As interruption generally implies cancellation, and checks for
  * interruption are often infrequent, an implementation can favor responding
  * to an interrupt over normal method return. This is true even if it can be
- * shown that the interrupt occurred after another action may have unblocked
- * the thread. An implementation should document this behavior. 
- *
+ * shown that the interrupt occurred after another action that may have
+ * unblocked the thread. An implementation should document this behavior.
  *
  * @since 1.5
  * @author Doug Lea
@@ -148,21 +150,21 @@
 public interface Condition {
 
     /**
-     * Causes the current thread to wait until it is signalled or 
-     * {@link Thread#interrupt interrupted}.
+     * Causes the current thread to wait until it is signalled or
+     * {@linkplain Thread#interrupt interrupted}.
      *
-     * <p>The lock associated with this <tt>Condition</tt> is atomically 
-     * released and the current thread becomes disabled for thread scheduling 
+     * <p>The lock associated with this {@code Condition} is atomically
+     * released and the current thread becomes disabled for thread scheduling
      * purposes and lies dormant until <em>one</em> of four things happens:
      * <ul>
-     * <li>Some other thread invokes the {@link #signal} method for this 
-     * <tt>Condition</tt> and the current thread happens to be chosen as the 
+     * <li>Some other thread invokes the {@link #signal} method for this
+     * {@code Condition} and the current thread happens to be chosen as the
      * thread to be awakened; or
-     * <li>Some other thread invokes the {@link #signalAll} method for this 
-     * <tt>Condition</tt>; or
-     * <li>Some other thread {@link Thread#interrupt interrupts} the current
-     * thread, and interruption of thread suspension is supported; or
-     * <li>A &quot;<em>spurious wakeup</em>&quot; occurs
+     * <li>Some other thread invokes the {@link #signalAll} method for this
+     * {@code Condition}; or
+     * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
+     * current thread, and interruption of thread suspension is supported; or
+     * <li>A &quot;<em>spurious wakeup</em>&quot; occurs.
      * </ul>
      *
      * <p>In all cases, before this method can return the current thread must
@@ -171,20 +173,21 @@
      *
      * <p>If the current thread:
      * <ul>
-     * <li>has its interrupted status set on entry to this method; or 
-     * <li>is {@link Thread#interrupt interrupted} while waiting 
-     * and interruption of thread suspension is supported, 
+     * <li>has its interrupted status set on entry to this method; or
+     * <li>is {@linkplain Thread#interrupt interrupted} while waiting
+     * and interruption of thread suspension is supported,
      * </ul>
-     * then {@link InterruptedException} is thrown and the current thread's 
+     * then {@link InterruptedException} is thrown and the current thread's
      * interrupted status is cleared. It is not specified, in the first
      * case, whether or not the test for interruption occurs before the lock
      * is released.
-     * 
+     *
      * <p><b>Implementation Considerations</b>
+     *
      * <p>The current thread is assumed to hold the lock associated with this
-     * <tt>Condition</tt> when this method is called.
+     * {@code Condition} when this method is called.
      * It is up to the implementation to determine if this is
-     * the case and if not, how to respond. Typically, an exception will be 
+     * the case and if not, how to respond. Typically, an exception will be
      * thrown (such as {@link IllegalMonitorStateException}) and the
      * implementation must document that fact.
      *
@@ -193,62 +196,62 @@
      * must ensure that the signal is redirected to another waiting thread, if
      * there is one.
      *
-     * @throws InterruptedException if the current thread is interrupted (and
-     * interruption of thread suspension is supported).
-     **/
+     * @throws InterruptedException if the current thread is interrupted
+     *         (and interruption of thread suspension is supported)
+     */
     void await() throws InterruptedException;
 
     /**
      * Causes the current thread to wait until it is signalled.
      *
-     * <p>The lock associated with this condition is atomically 
-     * released and the current thread becomes disabled for thread scheduling 
+     * <p>The lock associated with this condition is atomically
+     * released and the current thread becomes disabled for thread scheduling
      * purposes and lies dormant until <em>one</em> of three things happens:
      * <ul>
-     * <li>Some other thread invokes the {@link #signal} method for this 
-     * <tt>Condition</tt> and the current thread happens to be chosen as the 
+     * <li>Some other thread invokes the {@link #signal} method for this
+     * {@code Condition} and the current thread happens to be chosen as the
      * thread to be awakened; or
-     * <li>Some other thread invokes the {@link #signalAll} method for this 
-     * <tt>Condition</tt>; or
-     * <li>A &quot;<em>spurious wakeup</em>&quot; occurs
+     * <li>Some other thread invokes the {@link #signalAll} method for this
+     * {@code Condition}; or
+     * <li>A &quot;<em>spurious wakeup</em>&quot; occurs.
      * </ul>
      *
      * <p>In all cases, before this method can return the current thread must
      * re-acquire the lock associated with this condition. When the
      * thread returns it is <em>guaranteed</em> to hold this lock.
      *
-     * <p>If the current thread's interrupt status is set when it enters
-     * this method, or it is {@link Thread#interrupt interrupted} 
+     * <p>If the current thread's interrupted status is set when it enters
+     * this method, or it is {@linkplain Thread#interrupt interrupted}
      * while waiting, it will continue to wait until signalled. When it finally
-     * returns from this method its <em>interrupted status</em> will still
+     * returns from this method its interrupted status will still
      * be set.
-     * 
+     *
      * <p><b>Implementation Considerations</b>
+     *
      * <p>The current thread is assumed to hold the lock associated with this
-     * <tt>Condition</tt> when this method is called.
+     * {@code Condition} when this method is called.
      * It is up to the implementation to determine if this is
-     * the case and if not, how to respond. Typically, an exception will be 
+     * the case and if not, how to respond. Typically, an exception will be
      * thrown (such as {@link IllegalMonitorStateException}) and the
      * implementation must document that fact.
-     *
-     **/
+     */
     void awaitUninterruptibly();
 
     /**
      * Causes the current thread to wait until it is signalled or interrupted,
      * or the specified waiting time elapses.
      *
-     * <p>The lock associated with this condition is atomically 
-     * released and the current thread becomes disabled for thread scheduling 
+     * <p>The lock associated with this condition is atomically
+     * released and the current thread becomes disabled for thread scheduling
      * purposes and lies dormant until <em>one</em> of five things happens:
      * <ul>
-     * <li>Some other thread invokes the {@link #signal} method for this 
-     * <tt>Condition</tt> and the current thread happens to be chosen as the 
-     * thread to be awakened; or 
-     * <li>Some other thread invokes the {@link #signalAll} method for this 
-     * <tt>Condition</tt>; or
-     * <li>Some other thread {@link Thread#interrupt interrupts} the current
-     * thread, and interruption of thread suspension is supported; or
+     * <li>Some other thread invokes the {@link #signal} method for this
+     * {@code Condition} and the current thread happens to be chosen as the
+     * thread to be awakened; or
+     * <li>Some other thread invokes the {@link #signalAll} method for this
+     * {@code Condition}; or
+     * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
+     * current thread, and interruption of thread suspension is supported; or
      * <li>The specified waiting time elapses; or
      * <li>A &quot;<em>spurious wakeup</em>&quot; occurs.
      * </ul>
@@ -259,17 +262,17 @@
      *
      * <p>If the current thread:
      * <ul>
-     * <li>has its interrupted status set on entry to this method; or 
-     * <li>is {@link Thread#interrupt interrupted} while waiting 
-     * and interruption of thread suspension is supported, 
+     * <li>has its interrupted status set on entry to this method; or
+     * <li>is {@linkplain Thread#interrupt interrupted} while waiting
+     * and interruption of thread suspension is supported,
      * </ul>
-     * then {@link InterruptedException} is thrown and the current thread's 
+     * then {@link InterruptedException} is thrown and the current thread's
      * interrupted status is cleared. It is not specified, in the first
      * case, whether or not the test for interruption occurs before the lock
      * is released.
      *
      * <p>The method returns an estimate of the number of nanoseconds
-     * remaining to wait given the supplied <tt>nanosTimeout</tt>
+     * remaining to wait given the supplied {@code nanosTimeout}
      * value upon return, or a value less than or equal to zero if it
      * timed out. This value can be used to determine whether and how
      * long to re-wait in cases where the wait returns but an awaited
@@ -285,7 +288,7 @@
      *      else
      *        return false;
      *   }
-     *   // ... 
+     *   // ...
      * }
      * </pre>
      *
@@ -296,10 +299,11 @@
      * than specified when re-waits occur.
      *
      * <p><b>Implementation Considerations</b>
+     *
      * <p>The current thread is assumed to hold the lock associated with this
-     * <tt>Condition</tt> when this method is called.
+     * {@code Condition} when this method is called.
      * It is up to the implementation to determine if this is
-     * the case and if not, how to respond. Typically, an exception will be 
+     * the case and if not, how to respond. Typically, an exception will be
      * thrown (such as {@link IllegalMonitorStateException}) and the
      * implementation must document that fact.
      *
@@ -310,13 +314,14 @@
      * there is one.
      *
      * @param nanosTimeout the maximum time to wait, in nanoseconds
-     * @return A value less than or equal to zero if the wait has
-     * timed out; otherwise an estimate, that
-     * is strictly less than the <tt>nanosTimeout</tt> argument,
-     * of the time still remaining when this method returned.
-     *
-     * @throws InterruptedException if the current thread is interrupted (and
-     * interruption of thread suspension is supported).
+     * @return an estimate of the {@code nanosTimeout} value minus
+     *         the time spent waiting upon return from this method.
+     *         A positive value may be used as the argument to a
+     *         subsequent call to this method to finish waiting out
+     *         the desired time.  A value less than or equal to zero
+     *         indicates that no time remains.
+     * @throws InterruptedException if the current thread is interrupted
+     *         (and interruption of thread suspension is supported)
      */
     long awaitNanos(long nanosTimeout) throws InterruptedException;
 
@@ -328,29 +333,29 @@
      *   awaitNanos(unit.toNanos(time)) &gt; 0
      * </pre>
      * @param time the maximum time to wait
-     * @param unit the time unit of the <tt>time</tt> argument.
-     * @return <tt>false</tt> if the waiting time detectably elapsed
-     * before return from the method, else <tt>true</tt>.
-     * @throws InterruptedException if the current thread is interrupted (and
-     * interruption of thread suspension is supported).
+     * @param unit the time unit of the {@code time} argument
+     * @return {@code false} if the waiting time detectably elapsed
+     *         before return from the method, else {@code true}
+     * @throws InterruptedException if the current thread is interrupted
+     *         (and interruption of thread suspension is supported)
      */
     boolean await(long time, TimeUnit unit) throws InterruptedException;
-    
+
     /**
      * Causes the current thread to wait until it is signalled or interrupted,
      * or the specified deadline elapses.
      *
-     * <p>The lock associated with this condition is atomically 
-     * released and the current thread becomes disabled for thread scheduling 
+     * <p>The lock associated with this condition is atomically
+     * released and the current thread becomes disabled for thread scheduling
      * purposes and lies dormant until <em>one</em> of five things happens:
      * <ul>
-     * <li>Some other thread invokes the {@link #signal} method for this 
-     * <tt>Condition</tt> and the current thread happens to be chosen as the 
-     * thread to be awakened; or 
-     * <li>Some other thread invokes the {@link #signalAll} method for this 
-     * <tt>Condition</tt>; or
-     * <li>Some other thread {@link Thread#interrupt interrupts} the current
-     * thread, and interruption of thread suspension is supported; or
+     * <li>Some other thread invokes the {@link #signal} method for this
+     * {@code Condition} and the current thread happens to be chosen as the
+     * thread to be awakened; or
+     * <li>Some other thread invokes the {@link #signalAll} method for this
+     * {@code Condition}; or
+     * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
+     * current thread, and interruption of thread suspension is supported; or
      * <li>The specified deadline elapses; or
      * <li>A &quot;<em>spurious wakeup</em>&quot; occurs.
      * </ul>
@@ -362,11 +367,11 @@
      *
      * <p>If the current thread:
      * <ul>
-     * <li>has its interrupted status set on entry to this method; or 
-     * <li>is {@link Thread#interrupt interrupted} while waiting 
-     * and interruption of thread suspension is supported, 
+     * <li>has its interrupted status set on entry to this method; or
+     * <li>is {@linkplain Thread#interrupt interrupted} while waiting
+     * and interruption of thread suspension is supported,
      * </ul>
-     * then {@link InterruptedException} is thrown and the current thread's 
+     * then {@link InterruptedException} is thrown and the current thread's
      * interrupted status is cleared. It is not specified, in the first
      * case, whether or not the test for interruption occurs before the lock
      * is released.
@@ -378,20 +383,21 @@
      * synchronized boolean aMethod(Date deadline) {
      *   boolean stillWaiting = true;
      *   while (!conditionBeingWaitedFor) {
-     *     if (stillwaiting)
+     *     if (stillWaiting)
      *         stillWaiting = theCondition.awaitUntil(deadline);
      *      else
      *        return false;
      *   }
-     *   // ... 
+     *   // ...
      * }
      * </pre>
      *
      * <p><b>Implementation Considerations</b>
+     *
      * <p>The current thread is assumed to hold the lock associated with this
-     * <tt>Condition</tt> when this method is called.
+     * {@code Condition} when this method is called.
      * It is up to the implementation to determine if this is
-     * the case and if not, how to respond. Typically, an exception will be 
+     * the case and if not, how to respond. Typically, an exception will be
      * thrown (such as {@link IllegalMonitorStateException}) and the
      * implementation must document that fact.
      *
@@ -401,13 +407,11 @@
      * must ensure that the signal is redirected to another waiting thread, if
      * there is one.
      *
-     *
      * @param deadline the absolute time to wait until
-     * @return <tt>false</tt> if the deadline has
-     * elapsed upon return, else <tt>true</tt>.
-     *
-     * @throws InterruptedException if the current thread is interrupted (and
-     * interruption of thread suspension is supported).
+     * @return {@code false} if the deadline has elapsed upon return, else
+     *         {@code true}
+     * @throws InterruptedException if the current thread is interrupted
+     *         (and interruption of thread suspension is supported)
      */
     boolean awaitUntil(Date deadline) throws InterruptedException;
 
@@ -416,8 +420,8 @@
      *
      * <p>If any threads are waiting on this condition then one
      * is selected for waking up. That thread must then re-acquire the
-     * lock before returning from <tt>await</tt>.
-     **/
+     * lock before returning from {@code await}.
+     */
     void signal();
 
     /**
@@ -425,15 +429,7 @@
      *
      * <p>If any threads are waiting on this condition then they are
      * all woken up. Each thread must re-acquire the lock before it can
-     * return from <tt>await</tt>.
-     **/
+     * return from {@code await}.
+     */
     void signalAll();
-
 }
-
-
-
-
-
-
-
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/locks/Lock.java b/libcore/concurrent/src/main/java/java/util/concurrent/locks/Lock.java
index f07b72e..4b9abd6 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/locks/Lock.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/locks/Lock.java
@@ -8,8 +8,8 @@
 import java.util.concurrent.TimeUnit;
 
 /**
- * <tt>Lock</tt> implementations provide more extensive locking
- * operations than can be obtained using <tt>synchronized</tt> methods
+ * {@code Lock} implementations provide more extensive locking
+ * operations than can be obtained using {@code synchronized} methods
  * and statements.  They allow more flexible structuring, may have
  * quite different properties, and may support multiple associated
  * {@link Condition} objects.
@@ -19,17 +19,16 @@
  * shared resource: only one thread at a time can acquire the lock and
  * all access to the shared resource requires that the lock be
  * acquired first. However, some locks may allow concurrent access to
- * a shared resource, such as the read lock of a {@link
- * ReadWriteLock}.
+ * a shared resource, such as the read lock of a {@link ReadWriteLock}.
  *
- * <p>The use of <tt>synchronized</tt> methods or statements provides 
+ * <p>The use of {@code synchronized} methods or statements provides
  * access to the implicit monitor lock associated with every object, but
  * forces all lock acquisition and release to occur in a block-structured way:
  * when multiple locks are acquired they must be released in the opposite
  * order, and all locks must be released in the same lexical scope in which
  * they were acquired.
  *
- * <p>While the scoping mechanism for <tt>synchronized</tt> methods
+ * <p>While the scoping mechanism for {@code synchronized} methods
  * and statements makes it much easier to program with monitor locks,
  * and helps avoid many common programming errors involving locks,
  * there are occasions where you need to work with locks in a more
@@ -38,18 +37,18 @@
  * &quot;hand-over-hand&quot; or &quot;chain locking&quot;: you
  * acquire the lock of node A, then node B, then release A and acquire
  * C, then release B and acquire D and so on.  Implementations of the
- * <tt>Lock</tt> interface enable the use of such techniques by
+ * {@code Lock} interface enable the use of such techniques by
  * allowing a lock to be acquired and released in different scopes,
  * and allowing multiple locks to be acquired and released in any
  * order.
  *
  * <p>With this increased flexibility comes additional
  * responsibility. The absence of block-structured locking removes the
- * automatic release of locks that occurs with <tt>synchronized</tt>
+ * automatic release of locks that occurs with {@code synchronized}
  * methods and statements. In most cases, the following idiom
  * should be used:
  *
- * <pre><tt>     Lock l = ...; 
+ * <pre><tt>     Lock l = ...;
  *     l.lock();
  *     try {
  *         // access the resource protected by this lock
@@ -63,39 +62,42 @@
  * held is protected by try-finally or try-catch to ensure that the
  * lock is released when necessary.
  *
- * <p><tt>Lock</tt> implementations provide additional functionality
- * over the use of <tt>synchronized</tt> methods and statements by
+ * <p>{@code Lock} implementations provide additional functionality
+ * over the use of {@code synchronized} methods and statements by
  * providing a non-blocking attempt to acquire a lock ({@link
  * #tryLock()}), an attempt to acquire the lock that can be
  * interrupted ({@link #lockInterruptibly}, and an attempt to acquire
  * the lock that can timeout ({@link #tryLock(long, TimeUnit)}).
  *
- * <p>A <tt>Lock</tt> class can also provide behavior and semantics
+ * <p>A {@code Lock} class can also provide behavior and semantics
  * that is quite different from that of the implicit monitor lock,
  * such as guaranteed ordering, non-reentrant usage, or deadlock
  * detection. If an implementation provides such specialized semantics
  * then the implementation must document those semantics.
  *
- * <p>Note that <tt>Lock</tt> instances are just normal objects and can 
- * themselves be used as the target in a <tt>synchronized</tt> statement.
+ * <p>Note that {@code Lock} instances are just normal objects and can
+ * themselves be used as the target in a {@code synchronized} statement.
  * Acquiring the
- * monitor lock of a <tt>Lock</tt> instance has no specified relationship
- * with invoking any of the {@link #lock} methods of that instance. 
- * It is recommended that to avoid confusion you never use <tt>Lock</tt>
+ * monitor lock of a {@code Lock} instance has no specified relationship
+ * with invoking any of the {@link #lock} methods of that instance.
+ * It is recommended that to avoid confusion you never use {@code Lock}
  * instances in this way, except within their own implementation.
  *
- * <p>Except where noted, passing a <tt>null</tt> value for any
+ * <p>Except where noted, passing a {@code null} value for any
  * parameter will result in a {@link NullPointerException} being
  * thrown.
  *
  * <h3>Memory Synchronization</h3>
- * <p>All <tt>Lock</tt> implementations <em>must</em> enforce the same
- * memory synchronization semantics as provided by the built-in monitor lock:
+ *
+ * <p>All {@code Lock} implementations <em>must</em> enforce the same
+ * memory synchronization semantics as provided by the built-in monitor
+ * lock, as described in <a href="http://java.sun.com/docs/books/jls/">
+ * The Java Language Specification, Third Edition (17.4 Memory Model)</a>:
  * <ul>
- * <li>A successful lock operation acts like a successful 
- * <tt>monitorEnter</tt> action
- * <li>A successful <tt>unlock</tt> operation acts like a successful
- * <tt>monitorExit</tt> action
+ * <li>A successful {@code lock} operation has the same memory
+ * synchronization effects as a successful <em>Lock</em> action.
+ * <li>A successful {@code unlock} operation has the same
+ * memory synchronization effects as a successful <em>Unlock</em> action.
  * </ul>
  *
  * Unsuccessful locking and unlocking operations, and reentrant
@@ -108,7 +110,7 @@
  * non-interruptible, and timed) may differ in their performance
  * characteristics, ordering guarantees, or other implementation
  * qualities.  Further, the ability to interrupt the <em>ongoing</em>
- * acquisition of a lock may not be available in a given <tt>Lock</tt>
+ * acquisition of a lock may not be available in a given {@code Lock}
  * class.  Consequently, an implementation is not required to define
  * exactly the same guarantees or semantics for all three forms of
  * lock acquisition, nor is it required to support interruption of an
@@ -119,12 +121,11 @@
  * acquisition is supported: which is either totally, or only on
  * method entry.
  *
- * <p>As interruption generally implies cancellation, and checks for 
+ * <p>As interruption generally implies cancellation, and checks for
  * interruption are often infrequent, an implementation can favor responding
  * to an interrupt over normal method return. This is true even if it can be
  * shown that the interrupt occurred after another action may have unblocked
- * the thread. An implementation should document this behavior. 
- *
+ * the thread. An implementation should document this behavior.
  *
  * @see ReentrantLock
  * @see Condition
@@ -132,45 +133,50 @@
  *
  * @since 1.5
  * @author Doug Lea
- *
- **/
+ */
 public interface Lock {
 
     /**
      * Acquires the lock.
-     * <p>If the lock is not available then
-     * the current thread becomes disabled for thread scheduling 
-     * purposes and lies dormant until the lock has been acquired.
-     * <p><b>Implementation Considerations</b>
-     * <p>A <tt>Lock</tt> implementation may be able to detect 
-     * erroneous use of the lock, such as an invocation that would cause 
-     * deadlock, and may throw an (unchecked) exception in such circumstances. 
-     * The circumstances and the exception type must be documented by that 
-     * <tt>Lock</tt> implementation.
      *
-     **/
+     * <p>If the lock is not available then the current thread becomes
+     * disabled for thread scheduling purposes and lies dormant until the
+     * lock has been acquired.
+     *
+     * <p><b>Implementation Considerations</b>
+     *
+     * <p>A {@code Lock} implementation may be able to detect erroneous use
+     * of the lock, such as an invocation that would cause deadlock, and
+     * may throw an (unchecked) exception in such circumstances.  The
+     * circumstances and the exception type must be documented by that
+     * {@code Lock} implementation.
+     */
     void lock();
 
     /**
-     * Acquires the lock unless the current thread is  
-     * {@link Thread#interrupt interrupted}. 
+     * Acquires the lock unless the current thread is
+     * {@linkplain Thread#interrupt interrupted}.
+     *
      * <p>Acquires the lock if it is available and returns immediately.
-     * <p>If the lock is not available then
-     * the current thread becomes disabled for thread scheduling 
-     * purposes and lies dormant until one of two things happens:
+     *
+     * <p>If the lock is not available then the current thread becomes
+     * disabled for thread scheduling purposes and lies dormant until
+     * one of two things happens:
+     *
      * <ul>
      * <li>The lock is acquired by the current thread; or
-     * <li>Some other thread {@link Thread#interrupt interrupts} the current
-     * thread, and interruption of lock acquisition is supported.
+     * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
+     * current thread, and interruption of lock acquisition is supported.
      * </ul>
+     *
      * <p>If the current thread:
      * <ul>
-     * <li>has its interrupted status set on entry to this method; or 
-     * <li>is {@link Thread#interrupt interrupted} while acquiring 
-     * the lock, and interruption of lock acquisition is supported, 
+     * <li>has its interrupted status set on entry to this method; or
+     * <li>is {@linkplain Thread#interrupt interrupted} while acquiring the
+     * lock, and interruption of lock acquisition is supported,
      * </ul>
-     * then {@link InterruptedException} is thrown and the current thread's 
-     * interrupted status is cleared. 
+     * then {@link InterruptedException} is thrown and the current thread's
+     * interrupted status is cleared.
      *
      * <p><b>Implementation Considerations</b>
      *
@@ -183,28 +189,26 @@
      * <p>An implementation can favor responding to an interrupt over
      * normal method return.
      *
-     * <p>A <tt>Lock</tt> implementation may be able to detect
+     * <p>A {@code Lock} implementation may be able to detect
      * erroneous use of the lock, such as an invocation that would
      * cause deadlock, and may throw an (unchecked) exception in such
      * circumstances.  The circumstances and the exception type must
-     * be documented by that <tt>Lock</tt> implementation.
+     * be documented by that {@code Lock} implementation.
      *
-     * @throws InterruptedException if the current thread is interrupted
-     * while acquiring the lock (and interruption of lock acquisition is 
-     * supported).
-     *
-     * @see Thread#interrupt
-     *
-     **/
+     * @throws InterruptedException if the current thread is
+     *         interrupted while acquiring the lock (and interruption
+     *         of lock acquisition is supported).
+     */
     void lockInterruptibly() throws InterruptedException;
 
-
     /**
      * Acquires the lock only if it is free at the time of invocation.
+     *
      * <p>Acquires the lock if it is available and returns immediately
-     * with the value <tt>true</tt>.
-     * If the lock is not available then this method will return 
-     * immediately with the value <tt>false</tt>.
+     * with the value {@code true}.
+     * If the lock is not available then this method will return
+     * immediately with the value {@code false}.
+     *
      * <p>A typical usage idiom for this method would be:
      * <pre>
      *      Lock lock = ...;
@@ -221,109 +225,103 @@
      * This usage ensures that the lock is unlocked if it was acquired, and
      * doesn't try to unlock if the lock was not acquired.
      *
-     * @return <tt>true</tt> if the lock was acquired and <tt>false</tt>
-     * otherwise.
-     **/
+     * @return {@code true} if the lock was acquired and
+     *         {@code false} otherwise
+     */
     boolean tryLock();
 
     /**
      * Acquires the lock if it is free within the given waiting time and the
-     * current thread has not been {@link Thread#interrupt interrupted}.
+     * current thread has not been {@linkplain Thread#interrupt interrupted}.
      *
      * <p>If the lock is available this method returns immediately
-     * with the value <tt>true</tt>.
+     * with the value {@code true}.
      * If the lock is not available then
-     * the current thread becomes disabled for thread scheduling 
+     * the current thread becomes disabled for thread scheduling
      * purposes and lies dormant until one of three things happens:
      * <ul>
      * <li>The lock is acquired by the current thread; or
-     * <li>Some other thread {@link Thread#interrupt interrupts} the current
-     * thread, and interruption of lock acquisition is supported; or
+     * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
+     * current thread, and interruption of lock acquisition is supported; or
      * <li>The specified waiting time elapses
      * </ul>
-     * <p>If the lock is acquired then the value <tt>true</tt> is returned.
+     *
+     * <p>If the lock is acquired then the value {@code true} is returned.
+     *
      * <p>If the current thread:
      * <ul>
-     * <li>has its interrupted status set on entry to this method; or 
-     * <li>is {@link Thread#interrupt interrupted} while acquiring 
-     * the lock, and interruption of lock acquisition is supported, 
+     * <li>has its interrupted status set on entry to this method; or
+     * <li>is {@linkplain Thread#interrupt interrupted} while acquiring
+     * the lock, and interruption of lock acquisition is supported,
      * </ul>
-     * then {@link InterruptedException} is thrown and the current thread's 
-     * interrupted status is cleared. 
-     * <p>If the specified waiting time elapses then the value <tt>false</tt>
+     * then {@link InterruptedException} is thrown and the current thread's
+     * interrupted status is cleared.
+     *
+     * <p>If the specified waiting time elapses then the value {@code false}
      * is returned.
-     * If the time is 
+     * If the time is
      * less than or equal to zero, the method will not wait at all.
      *
      * <p><b>Implementation Considerations</b>
+     *
      * <p>The ability to interrupt a lock acquisition in some implementations
-     * may not be possible, and if possible may 
-     * be an expensive operation. 
+     * may not be possible, and if possible may
+     * be an expensive operation.
      * The programmer should be aware that this may be the case. An
      * implementation should document when this is the case.
-     * <p>An implementation can favor responding to an interrupt over normal 
+     *
+     * <p>An implementation can favor responding to an interrupt over normal
      * method return, or reporting a timeout.
-     * <p>A <tt>Lock</tt> implementation may be able to detect 
-     * erroneous use of the lock, such as an invocation that would cause 
-     * deadlock, and may throw an (unchecked) exception in such circumstances. 
-     * The circumstances and the exception type must be documented by that 
-     * <tt>Lock</tt> implementation.
+     *
+     * <p>A {@code Lock} implementation may be able to detect
+     * erroneous use of the lock, such as an invocation that would cause
+     * deadlock, and may throw an (unchecked) exception in such circumstances.
+     * The circumstances and the exception type must be documented by that
+     * {@code Lock} implementation.
      *
      * @param time the maximum time to wait for the lock
-     * @param unit the time unit of the <tt>time</tt> argument.
-     * @return <tt>true</tt> if the lock was acquired and <tt>false</tt>
-     * if the waiting time elapsed before the lock was acquired.
+     * @param unit the time unit of the {@code time} argument
+     * @return {@code true} if the lock was acquired and {@code false}
+     *         if the waiting time elapsed before the lock was acquired
      *
      * @throws InterruptedException if the current thread is interrupted
-     * while acquiring the lock (and interruption of lock acquisition is 
-     * supported).
-     *
-     * @see Thread#interrupt
-     *
-     **/
+     *         while acquiring the lock (and interruption of lock
+     *         acquisition is supported)
+     */
     boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
 
     /**
      * Releases the lock.
+     *
      * <p><b>Implementation Considerations</b>
-     * <p>A <tt>Lock</tt> implementation will usually impose
+     *
+     * <p>A {@code Lock} implementation will usually impose
      * restrictions on which thread can release a lock (typically only the
      * holder of the lock can release it) and may throw
      * an (unchecked) exception if the restriction is violated.
      * Any restrictions and the exception
-     * type must be documented by that <tt>Lock</tt> implementation.
-     **/
+     * type must be documented by that {@code Lock} implementation.
+     */
     void unlock();
 
     /**
-     * Returns a new {@link Condition} instance that is bound to this 
-     * <tt>Lock</tt> instance.
-     * <p>Before waiting on the condition the lock must be held by the 
-     * current thread. 
-     * A call to {@link Condition#await()} will atomically release the lock 
+     * Returns a new {@link Condition} instance that is bound to this
+     * {@code Lock} instance.
+     *
+     * <p>Before waiting on the condition the lock must be held by the
+     * current thread.
+     * A call to {@link Condition#await()} will atomically release the lock
      * before waiting and re-acquire the lock before the wait returns.
+     *
      * <p><b>Implementation Considerations</b>
-     * <p>The exact operation of the {@link Condition} instance depends on the
-     * <tt>Lock</tt> implementation and must be documented by that
+     *
+     * <p>The exact operation of the {@link Condition} instance depends on
+     * the {@code Lock} implementation and must be documented by that
      * implementation.
-     * 
-     * @return A new {@link Condition} instance for this <tt>Lock</tt> 
-     * instance.
-     * @throws UnsupportedOperationException if this <tt>Lock</tt> 
-     * implementation does not support conditions.
-     **/
+     *
+     * @return A new {@link Condition} instance for this {@code Lock} instance
+     * @throws UnsupportedOperationException if this {@code Lock}
+     *         implementation does not support conditions
+     */
     Condition newCondition();
-
 }
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/locks/LockSupport.java b/libcore/concurrent/src/main/java/java/util/concurrent/locks/LockSupport.java
index 8603785..b55b874 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/locks/LockSupport.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/locks/LockSupport.java
@@ -13,48 +13,56 @@
  * Basic thread blocking primitives for creating locks and other
  * synchronization classes.
  *
- * <p>This class associates with each thread that uses it, a permit
+ * <p>This class associates, with each thread that uses it, a permit
  * (in the sense of the {@link java.util.concurrent.Semaphore
- * Semaphore} class). A call to <tt>park</tt> will return immediately
+ * Semaphore} class). A call to {@code park} will return immediately
  * if the permit is available, consuming it in the process; otherwise
- * it <em>may</em> block.  A call to <tt>unpark</tt> makes the permit
+ * it <em>may</em> block.  A call to {@code unpark} makes the permit
  * available, if it was not already available. (Unlike with Semaphores
  * though, permits do not accumulate. There is at most one.)
  *
- * <p>Methods <tt>park</tt> and <tt>unpark</tt> provide efficient
+ * <p>Methods {@code park} and {@code unpark} provide efficient
  * means of blocking and unblocking threads that do not encounter the
- * problems that cause the deprecated methods <tt>Thread.suspend</tt>
- * and <tt>Thread.resume</tt> to be unusable for such purposes: Races
- * between one thread invoking <tt>park</tt> and another thread trying
- * to <tt>unpark</tt> it will preserve liveness, due to the
- * permit. Additionally, <tt>park</tt> will return if the caller's
+ * problems that cause the deprecated methods {@code Thread.suspend}
+ * and {@code Thread.resume} to be unusable for such purposes: Races
+ * between one thread invoking {@code park} and another thread trying
+ * to {@code unpark} it will preserve liveness, due to the
+ * permit. Additionally, {@code park} will return if the caller's
  * thread was interrupted, and timeout versions are supported. The
- * <tt>park</tt> method may also return at any other time, for "no
+ * {@code park} method may also return at any other time, for "no
  * reason", so in general must be invoked within a loop that rechecks
- * conditions upon return. In this sense <tt>park</tt> serves as an
+ * conditions upon return. In this sense {@code park} serves as an
  * optimization of a "busy wait" that does not waste as much time
- * spinning, but must be paired with an <tt>unpark</tt> to be
+ * spinning, but must be paired with an {@code unpark} to be
  * effective.
  *
  * <p>These methods are designed to be used as tools for creating
  * higher-level synchronization utilities, and are not in themselves
- * useful for most concurrency control applications.
+ * useful for most concurrency control applications.  The {@code park}
+ * method is designed for use only in constructions of the form:
+ * <pre>while (!canProceed()) { ... LockSupport.park(this); }</pre>
+ * where neither {@code canProceed} nor any other actions prior to the
+ * call to {@code park} entail locking or blocking.  Because only one
+ * permit is associated with each thread, any intermediary uses of
+ * {@code park} could interfere with its intended effects.
  *
- * <p><b>Sample Usage.</b> Here is a sketch of a First-in-first-out
- * non-reentrant lock class.
- * <pre>
- *   private AtomicBoolean locked = new AtomicBoolean(false);
- *   private Queue&lt;Thread&gt; waiters = new ConcurrentLinkedQueue&lt;Thread&gt;();
+ * <p><b>Sample Usage.</b> Here is a sketch of a first-in-first-out
+ * non-reentrant lock class:
+ * <pre>{@code
+ * class FIFOMutex {
+ *   private final AtomicBoolean locked = new AtomicBoolean(false);
+ *   private final Queue<Thread> waiters
+ *     = new ConcurrentLinkedQueue<Thread>();
  *
- *   public void lock() { 
+ *   public void lock() {
  *     boolean wasInterrupted = false;
  *     Thread current = Thread.currentThread();
  *     waiters.add(current);
  *
  *     // Block while not first in queue or cannot acquire lock
- *     while (waiters.peek() != current || 
- *            !locked.compareAndSet(false, true)) { 
- *        LockSupport.park();
+ *     while (waiters.peek() != current ||
+ *            !locked.compareAndSet(false, true)) {
+ *        LockSupport.park(this);
  *        if (Thread.interrupted()) // ignore interrupts while waiting
  *          wasInterrupted = true;
  *     }
@@ -67,9 +75,8 @@
  *   public void unlock() {
  *     locked.set(false);
  *     LockSupport.unpark(waiters.peek());
- *   } 
- * }
- * </pre>
+ *   }
+ * }}</pre>
  */
 @SuppressWarnings("all")
 public class LockSupport {
@@ -80,14 +87,15 @@
     // END android-changed
 
     /**
-     * Make available the permit for the given thread, if it
+     * Makes available the permit for the given thread, if it
      * was not already available.  If the thread was blocked on
-     * <tt>park</tt> then it will unblock.  Otherwise, its next call
-     * to <tt>park</tt> is guaranteed not to block. This operation
+     * {@code park} then it will unblock.  Otherwise, its next call
+     * to {@code park} is guaranteed not to block. This operation
      * is not guaranteed to have any effect at all if the given
      * thread has not been started.
-     * @param thread the thread to unpark, or <tt>null</tt>, in which case
-     * this operation has no effect. 
+     *
+     * @param thread the thread to unpark, or {@code null}, in which case
+     *        this operation has no effect
      */
     public static void unpark(Thread thread) {
         if (thread != null)
@@ -97,20 +105,26 @@
     /**
      * Disables the current thread for thread scheduling purposes unless the
      * permit is available.
-     * <p>If the permit is available then it is consumed and the call returns
-     * immediately; otherwise 
-     * the current thread becomes disabled for thread scheduling 
-     * purposes and lies dormant until one of three things happens:
+     *
+     * <p>If the permit is available then it is consumed and the call
+     * returns immediately; otherwise the current thread becomes disabled
+     * for thread scheduling purposes and lies dormant until one of three
+     * things happens:
+     *
      * <ul>
-     * <li>Some other thread invokes <tt>unpark</tt> with the current thread 
-     * as the target; or
-     * <li>Some other thread {@link Thread#interrupt interrupts} the current
-     * thread; or
+     *
+     * <li>Some other thread invokes {@link #unpark unpark} with the
+     * current thread as the target; or
+     *
+     * <li>Some other thread {@linkplain Thread#interrupt interrupts}
+     * the current thread; or
+     *
      * <li>The call spuriously (that is, for no reason) returns.
      * </ul>
-     * <p>This method does <em>not</em> report which of these caused the 
-     * method to return. Callers should re-check the conditions which caused 
-     * the thread to park in the first place. Callers may also determine, 
+     *
+     * <p>This method does <em>not</em> report which of these caused the
+     * method to return. Callers should re-check the conditions which caused
+     * the thread to park in the first place. Callers may also determine,
      * for example, the interrupt status of the thread upon return.
      */
     public static void park() {
@@ -120,21 +134,27 @@
     /**
      * Disables the current thread for thread scheduling purposes, for up to
      * the specified waiting time, unless the permit is available.
-     * <p>If the permit is available then it is consumed and the call returns
-     * immediately; otherwise 
-     * the current thread becomes disabled for thread scheduling 
-     * purposes and lies dormant until one of four things happens:
+     *
+     * <p>If the permit is available then it is consumed and the call
+     * returns immediately; otherwise the current thread becomes disabled
+     * for thread scheduling purposes and lies dormant until one of four
+     * things happens:
+     *
      * <ul>
-     * <li>Some other thread invokes <tt>unpark</tt> with the current thread 
-     * as the target; or
-     * <li>Some other thread {@link Thread#interrupt interrupts} the current
-     * thread; or
+     * <li>Some other thread invokes {@link #unpark unpark} with the
+     * current thread as the target; or
+     *
+     * <li>Some other thread {@linkplain Thread#interrupt interrupts}
+     * the current thread; or
+     *
      * <li>The specified waiting time elapses; or
+     *
      * <li>The call spuriously (that is, for no reason) returns.
      * </ul>
-     * <p>This method does <em>not</em> report which of these caused the 
-     * method to return. Callers should re-check the conditions which caused 
-     * the thread to park in the first place. Callers may also determine, 
+     *
+     * <p>This method does <em>not</em> report which of these caused the
+     * method to return. Callers should re-check the conditions which caused
+     * the thread to park in the first place. Callers may also determine,
      * for example, the interrupt status of the thread, or the elapsed time
      * upon return.
      *
@@ -142,37 +162,40 @@
      */
     public static void parkNanos(long nanos) {
         if (nanos > 0)
-            unsafe.park(false, nanos);   
+            unsafe.park(false, nanos);
     }
 
     /**
      * Disables the current thread for thread scheduling purposes, until
      * the specified deadline, unless the permit is available.
-     * <p>If the permit is available then it is consumed and the call returns
-     * immediately; otherwise 
-     * the current thread becomes disabled for thread scheduling 
-     * purposes and lies dormant until one of four things happens:
+     *
+     * <p>If the permit is available then it is consumed and the call
+     * returns immediately; otherwise the current thread becomes disabled
+     * for thread scheduling purposes and lies dormant until one of four
+     * things happens:
+     *
      * <ul>
-     * <li>Some other thread invokes <tt>unpark</tt> with the current thread 
-     * as the target; or
-     * <li>Some other thread {@link Thread#interrupt interrupts} the current
-     * thread; or
+     * <li>Some other thread invokes {@link #unpark unpark} with the
+     * current thread as the target; or
+     *
+     * <li>Some other thread {@linkplain Thread#interrupt interrupts}
+     * the current thread; or
+     *
      * <li>The specified deadline passes; or
+     *
      * <li>The call spuriously (that is, for no reason) returns.
      * </ul>
-     * <p>This method does <em>not</em> report which of these caused the 
-     * method to return. Callers should re-check the conditions which caused 
-     * the thread to park in the first place. Callers may also determine, 
+     *
+     * <p>This method does <em>not</em> report which of these caused the
+     * method to return. Callers should re-check the conditions which caused
+     * the thread to park in the first place. Callers may also determine,
      * for example, the interrupt status of the thread, or the current time
      * upon return.
      *
-     * @param deadline the absolute time, in milliseconds from the Epoch, to
-     * wait until
+     * @param deadline the absolute time, in milliseconds from the Epoch,
+     *        to wait until
      */
     public static void parkUntil(long deadline) {
-        unsafe.park(true, deadline);   
+        unsafe.park(true, deadline);
     }
-
 }
-
-
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/locks/ReadWriteLock.java b/libcore/concurrent/src/main/java/java/util/concurrent/locks/ReadWriteLock.java
index c7116d5..484f68d 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/locks/ReadWriteLock.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/locks/ReadWriteLock.java
@@ -12,11 +12,18 @@
  * The {@link #readLock read lock} may be held simultaneously by
  * multiple reader threads, so long as there are no writers.  The
  * {@link #writeLock write lock} is exclusive.
- * 
+ *
+ * <p>All <tt>ReadWriteLock</tt> implementations must guarantee that
+ * the memory synchronization effects of <tt>writeLock</tt> operations
+ * (as specified in the {@link Lock} interface) also hold with respect
+ * to the associated <tt>readLock</tt>. That is, a thread successfully
+ * acquiring the read lock will see all updates made upon previous
+ * release of the write lock.
+ *
  * <p>A read-write lock allows for a greater level of concurrency in
- * accessing shared data, than that permitted by a mutual exclusion lock.
+ * accessing shared data than that permitted by a mutual exclusion lock.
  * It exploits the fact that while only a single thread at a time (a
- * <em>writer</em> thread) can modify the shared data, in many cases any 
+ * <em>writer</em> thread) can modify the shared data, in many cases any
  * number of threads can concurrently read the data (hence <em>reader</em>
  * threads).
  * In theory, the increase in concurrency permitted by the use of a read-write
@@ -27,7 +34,7 @@
  *
  * <p>Whether or not a read-write lock will improve performance over the use
  * of a mutual exclusion lock depends on the frequency that the data is
- * read compared to being modified, the duration of the read and write 
+ * read compared to being modified, the duration of the read and write
  * operations, and the contention for the data - that is, the number of
  * threads that will try to read or write the data at the same time.
  * For example, a collection that is initially populated with data and
@@ -56,14 +63,14 @@
  * lengthy delays for a write if the readers are frequent and long-lived as
  * expected. Fair, or &quot;in-order&quot; implementations are also possible.
  *
- * <li>Determining whether readers that request the read lock while a 
+ * <li>Determining whether readers that request the read lock while a
  * reader is active and a writer is waiting, are granted the read lock.
  * Preference to the reader can delay the writer indefinitely, while
- * preference to the write can reduce the potential for concurrency.
+ * preference to the writer can reduce the potential for concurrency.
  *
  * <li>Determining whether the locks are reentrant: can a thread with the
- * write lock reacquire it? can it acquire a read lock while holding the
- * write lock? is the read lock itself reentrant?
+ * write lock reacquire it? Can it acquire a read lock while holding the
+ * write lock? Is the read lock itself reentrant?
  *
  * <li>Can the write lock be downgraded to a read lock without allowing
  * an intervening writer? Can a read lock be upgraded to a write lock,
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/locks/ReentrantLock.java b/libcore/concurrent/src/main/java/java/util/concurrent/locks/ReentrantLock.java
index bf3d653..bf2ac38 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/locks/ReentrantLock.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/locks/ReentrantLock.java
@@ -12,19 +12,19 @@
 /**
  * A reentrant mutual exclusion {@link Lock} with the same basic
  * behavior and semantics as the implicit monitor lock accessed using
- * <tt>synchronized</tt> methods and statements, but with extended
+ * {@code synchronized} methods and statements, but with extended
  * capabilities.
  *
- * <p> A <tt>ReentrantLock</tt> is <em>owned</em> by the thread last
+ * <p>A {@code ReentrantLock} is <em>owned</em> by the thread last
  * successfully locking, but not yet unlocking it. A thread invoking
- * <tt>lock</tt> will return, successfully acquiring the lock, when
+ * {@code lock} will return, successfully acquiring the lock, when
  * the lock is not owned by another thread. The method will return
  * immediately if the current thread already owns the lock. This can
  * be checked using methods {@link #isHeldByCurrentThread}, and {@link
- * #getHoldCount}.  
+ * #getHoldCount}.
  *
- * <p> The constructor for this class accepts an optional
- * <em>fairness</em> parameter.  When set <tt>true</tt>, under
+ * <p>The constructor for this class accepts an optional
+ * <em>fairness</em> parameter.  When set {@code true}, under
  * contention, locks favor granting access to the longest-waiting
  * thread.  Otherwise this lock does not guarantee any particular
  * access order.  Programs using fair locks accessed by many threads
@@ -36,9 +36,12 @@
  * fair lock may obtain it multiple times in succession while other
  * active threads are not progressing and not currently holding the
  * lock.
+ * Also note that the untimed {@link #tryLock() tryLock} method does not
+ * honor the fairness setting. It will succeed if the lock
+ * is available even if other threads are waiting.
  *
- * <p> It is recommended practice to <em>always</em> immediately
- * follow a call to <tt>lock</tt> with a <tt>try</tt> block, most
+ * <p>It is recommended practice to <em>always</em> immediately
+ * follow a call to {@code lock} with a {@code try} block, most
  * typically in a before/after construction such as:
  *
  * <pre>
@@ -46,7 +49,7 @@
  *   private final ReentrantLock lock = new ReentrantLock();
  *   // ...
  *
- *   public void m() { 
+ *   public void m() {
  *     lock.lock();  // block until condition holds
  *     try {
  *       // ... method body
@@ -58,21 +61,21 @@
  * </pre>
  *
  * <p>In addition to implementing the {@link Lock} interface, this
- * class defines methods <tt>isLocked</tt> and
- * <tt>getLockQueueLength</tt>, as well as some associated
- * <tt>protected</tt> access methods that may be useful for
+ * class defines methods {@code isLocked} and
+ * {@code getLockQueueLength}, as well as some associated
+ * {@code protected} access methods that may be useful for
  * instrumentation and monitoring.
  *
- * <p> Serialization of this class behaves in the same way as built-in
+ * <p>Serialization of this class behaves in the same way as built-in
  * locks: a deserialized lock is in the unlocked state, regardless of
  * its state when serialized.
  *
- * <p> This lock supports a maximum of 2147483648 recursive locks by
- * the same thread. 
+ * <p>This lock supports a maximum of 2147483647 recursive locks by
+ * the same thread. Attempts to exceed this limit result in
+ * {@link Error} throws from locking methods.
  *
  * @since 1.5
  * @author Doug Lea
- * 
  */
 public class ReentrantLock implements Lock, java.io.Serializable {
     private static final long serialVersionUID = 7373984872572414699L;
@@ -84,32 +87,34 @@
      * into fair and nonfair versions below. Uses AQS state to
      * represent the number of holds on the lock.
      */
-    static abstract class Sync  extends AbstractQueuedSynchronizer {
-        /** Current owner thread */
-        transient Thread owner;
+    static abstract class Sync extends AbstractQueuedSynchronizer {
+        private static final long serialVersionUID = -5179523762034025860L;
 
         /**
-         * Perform {@link Lock#lock}. The main reason for subclassing
+         * Performs {@link Lock#lock}. The main reason for subclassing
          * is to allow fast path for nonfair version.
          */
         abstract void lock();
 
-        /** 
-         * Perform non-fair tryLock.  tryAcquire is
+        /**
+         * Performs non-fair tryLock.  tryAcquire is
          * implemented in subclasses, but both need nonfair
-         * try for trylock method
+         * try for trylock method.
          */
-        final boolean nonfairTryAcquire(int acquires) { 
+        final boolean nonfairTryAcquire(int acquires) {
             final Thread current = Thread.currentThread();
             int c = getState();
             if (c == 0) {
                 if (compareAndSetState(0, acquires)) {
-                    owner = current;
+                    setExclusiveOwnerThread(current);
                     return true;
                 }
             }
-            else if (current == owner) {
-                setState(c+acquires);
+            else if (current == getExclusiveOwnerThread()) {
+                int nextc = c + acquires;
+                if (nextc < 0) // overflow
+                    throw new Error("Maximum lock count exceeded");
+                setState(nextc);
                 return true;
             }
             return false;
@@ -117,19 +122,21 @@
 
         protected final boolean tryRelease(int releases) {
             int c = getState() - releases;
-            if (Thread.currentThread() != owner)
+            if (Thread.currentThread() != getExclusiveOwnerThread())
                 throw new IllegalMonitorStateException();
             boolean free = false;
             if (c == 0) {
                 free = true;
-                owner = null;
+                setExclusiveOwnerThread(null);
             }
             setState(c);
             return free;
         }
 
         protected final boolean isHeldExclusively() {
-            return getState() != 0 && owner == Thread.currentThread();
+            // While we must in general read state before owner,
+            // we don't need to do so to check if current thread is owner
+            return getExclusiveOwnerThread() == Thread.currentThread();
         }
 
         final ConditionObject newCondition() {
@@ -139,23 +146,19 @@
         // Methods relayed from outer class
 
         final Thread getOwner() {
-            int c = getState();
-            Thread o = owner;
-            return (c == 0)? null : o;
+            return getState() == 0 ? null : getExclusiveOwnerThread();
         }
-        
+
         final int getHoldCount() {
-            int c = getState();
-            Thread o = owner;
-            return (o == Thread.currentThread())? c : 0;
+            return isHeldExclusively() ? getState() : 0;
         }
-        
+
         final boolean isLocked() {
             return getState() != 0;
         }
 
         /**
-         * Reconstitute this lock instance from a stream
+         * Reconstitutes this lock instance from a stream.
          * @param s the stream
          */
         private void readObject(java.io.ObjectInputStream s)
@@ -169,18 +172,20 @@
      * Sync object for non-fair locks
      */
     final static class NonfairSync extends Sync {
+        private static final long serialVersionUID = 7316153563782823691L;
+
         /**
-         * Perform lock.  Try immediate barge, backing up to normal
+         * Performs lock.  Try immediate barge, backing up to normal
          * acquire on failure.
          */
         final void lock() {
             if (compareAndSetState(0, 1))
-                owner = Thread.currentThread();
+                setExclusiveOwnerThread(Thread.currentThread());
             else
                 acquire(1);
         }
 
-        protected final boolean tryAcquire(int acquires) { 
+        protected final boolean tryAcquire(int acquires) {
             return nonfairTryAcquire(acquires);
         }
     }
@@ -188,28 +193,32 @@
     /**
      * Sync object for fair locks
      */
-    final static class FairSync  extends Sync {
-        final void lock() { 
-            acquire(1); 
+    final static class FairSync extends Sync {
+        private static final long serialVersionUID = -3000897897090466540L;
+
+        final void lock() {
+            acquire(1);
         }
 
         /**
          * Fair version of tryAcquire.  Don't grant access unless
          * recursive call or no waiters or is first.
          */
-        protected final boolean tryAcquire(int acquires) { 
+        protected final boolean tryAcquire(int acquires) {
             final Thread current = Thread.currentThread();
             int c = getState();
             if (c == 0) {
-                Thread first = getFirstQueuedThread();
-                if ((first == null || first == current) && 
+                if (!hasQueuedPredecessors() &&
                     compareAndSetState(0, acquires)) {
-                    owner = current;
+                    setExclusiveOwnerThread(current);
                     return true;
                 }
             }
-            else if (current == owner) {
-                setState(c+acquires);
+            else if (current == getExclusiveOwnerThread()) {
+                int nextc = c + acquires;
+                if (nextc < 0)
+                    throw new Error("Maximum lock count exceeded");
+                setState(nextc);
                 return true;
             }
             return false;
@@ -217,89 +226,88 @@
     }
 
     /**
-     * Creates an instance of <tt>ReentrantLock</tt>.
-     * This is equivalent to using <tt>ReentrantLock(false)</tt>.
+     * Creates an instance of {@code ReentrantLock}.
+     * This is equivalent to using {@code ReentrantLock(false)}.
      */
-    public ReentrantLock() { 
+    public ReentrantLock() {
         sync = new NonfairSync();
     }
 
     /**
-     * Creates an instance of <tt>ReentrantLock</tt> with the
+     * Creates an instance of {@code ReentrantLock} with the
      * given fairness policy.
-     * @param fair true if this lock will be fair; else false
+     *
+     * @param fair {@code true} if this lock should use a fair ordering policy
      */
-    public ReentrantLock(boolean fair) { 
+    public ReentrantLock(boolean fair) {
         sync = (fair)? new FairSync() : new NonfairSync();
     }
 
     /**
-     * Acquires the lock. 
+     * Acquires the lock.
      *
-     * <p>Acquires the lock if it is not held by another thread and returns 
+     * <p>Acquires the lock if it is not held by another thread and returns
      * immediately, setting the lock hold count to one.
      *
-     * <p>If the current thread
-     * already holds the lock then the hold count is incremented by one and
-     * the method returns immediately.
+     * <p>If the current thread already holds the lock then the hold
+     * count is incremented by one and the method returns immediately.
      *
      * <p>If the lock is held by another thread then the
-     * current thread becomes disabled for thread scheduling 
+     * current thread becomes disabled for thread scheduling
      * purposes and lies dormant until the lock has been acquired,
-     * at which time the lock hold count is set to one. 
+     * at which time the lock hold count is set to one.
      */
     public void lock() {
         sync.lock();
     }
 
     /**
-     * Acquires the lock unless the current thread is 
-     * {@link Thread#interrupt interrupted}.
+     * Acquires the lock unless the current thread is
+     * {@linkplain Thread#interrupt interrupted}.
      *
-     * <p>Acquires the lock if it is not held by another thread and returns 
+     * <p>Acquires the lock if it is not held by another thread and returns
      * immediately, setting the lock hold count to one.
      *
-     * <p>If the current thread already holds this lock then the hold count 
+     * <p>If the current thread already holds this lock then the hold count
      * is incremented by one and the method returns immediately.
      *
      * <p>If the lock is held by another thread then the
-     * current thread becomes disabled for thread scheduling 
+     * current thread becomes disabled for thread scheduling
      * purposes and lies dormant until one of two things happens:
      *
      * <ul>
      *
      * <li>The lock is acquired by the current thread; or
      *
-     * <li>Some other thread {@link Thread#interrupt interrupts} the current
-     * thread.
+     * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
+     * current thread.
      *
      * </ul>
      *
-     * <p>If the lock is acquired by the current thread then the lock hold 
+     * <p>If the lock is acquired by the current thread then the lock hold
      * count is set to one.
      *
      * <p>If the current thread:
      *
      * <ul>
      *
-     * <li>has its interrupted status set on entry to this method; or 
+     * <li>has its interrupted status set on entry to this method; or
      *
-     * <li>is {@link Thread#interrupt interrupted} while acquiring 
+     * <li>is {@linkplain Thread#interrupt interrupted} while acquiring
      * the lock,
      *
      * </ul>
      *
-     * then {@link InterruptedException} is thrown and the current thread's 
-     * interrupted status is cleared. 
+     * then {@link InterruptedException} is thrown and the current thread's
+     * interrupted status is cleared.
      *
-     * <p>In this implementation, as this method is an explicit interruption 
-     * point, preference is 
-     * given to responding to the interrupt over normal or reentrant 
-     * acquisition of the lock.
+     * <p>In this implementation, as this method is an explicit
+     * interruption point, preference is given to responding to the
+     * interrupt over normal or reentrant acquisition of the lock.
      *
      * @throws InterruptedException if the current thread is interrupted
      */
-    public void lockInterruptibly() throws InterruptedException { 
+    public void lockInterruptibly() throws InterruptedException {
         sync.acquireInterruptibly(1);
     }
 
@@ -308,43 +316,42 @@
      * of invocation.
      *
      * <p>Acquires the lock if it is not held by another thread and
-     * returns immediately with the value <tt>true</tt>, setting the
+     * returns immediately with the value {@code true}, setting the
      * lock hold count to one. Even when this lock has been set to use a
-     * fair ordering policy, a call to <tt>tryLock()</tt> <em>will</em>
+     * fair ordering policy, a call to {@code tryLock()} <em>will</em>
      * immediately acquire the lock if it is available, whether or not
-     * other threads are currently waiting for the lock. 
-     * This &quot;barging&quot; behavior can be useful in certain 
+     * other threads are currently waiting for the lock.
+     * This &quot;barging&quot; behavior can be useful in certain
      * circumstances, even though it breaks fairness. If you want to honor
-     * the fairness setting for this lock, then use 
+     * the fairness setting for this lock, then use
      * {@link #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
      * which is almost equivalent (it also detects interruption).
      *
-     * <p> If the current thread
-     * already holds this lock then the hold count is incremented by one and
-     * the method returns <tt>true</tt>.
+     * <p> If the current thread already holds this lock then the hold
+     * count is incremented by one and the method returns {@code true}.
      *
-     * <p>If the lock is held by another thread then this method will return 
-     * immediately with the value <tt>false</tt>.  
+     * <p>If the lock is held by another thread then this method will return
+     * immediately with the value {@code false}.
      *
-     * @return <tt>true</tt> if the lock was free and was acquired by the
-     * current thread, or the lock was already held by the current thread; and
-     * <tt>false</tt> otherwise.
+     * @return {@code true} if the lock was free and was acquired by the
+     *         current thread, or the lock was already held by the current
+     *         thread; and {@code false} otherwise
      */
     public boolean tryLock() {
         return sync.nonfairTryAcquire(1);
     }
 
     /**
-     * Acquires the lock if it is not held by another thread within the given 
-     * waiting time and the current thread has not been 
-     * {@link Thread#interrupt interrupted}.
+     * Acquires the lock if it is not held by another thread within the given
+     * waiting time and the current thread has not been
+     * {@linkplain Thread#interrupt interrupted}.
      *
-     * <p>Acquires the lock if it is not held by another thread and returns 
-     * immediately with the value <tt>true</tt>, setting the lock hold count 
+     * <p>Acquires the lock if it is not held by another thread and returns
+     * immediately with the value {@code true}, setting the lock hold count
      * to one. If this lock has been set to use a fair ordering policy then
      * an available lock <em>will not</em> be acquired if any other threads
      * are waiting for the lock. This is in contrast to the {@link #tryLock()}
-     * method. If you want a timed <tt>tryLock</tt> that does permit barging on
+     * method. If you want a timed {@code tryLock} that does permit barging on
      * a fair lock then combine the timed and un-timed forms together:
      *
      * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
@@ -352,60 +359,56 @@
      *
      * <p>If the current thread
      * already holds this lock then the hold count is incremented by one and
-     * the method returns <tt>true</tt>.
+     * the method returns {@code true}.
      *
      * <p>If the lock is held by another thread then the
-     * current thread becomes disabled for thread scheduling 
+     * current thread becomes disabled for thread scheduling
      * purposes and lies dormant until one of three things happens:
      *
      * <ul>
      *
      * <li>The lock is acquired by the current thread; or
      *
-     * <li>Some other thread {@link Thread#interrupt interrupts} the current
-     * thread; or
+     * <li>Some other thread {@linkplain Thread#interrupt interrupts}
+     * the current thread; or
      *
      * <li>The specified waiting time elapses
      *
      * </ul>
      *
-     * <p>If the lock is acquired then the value <tt>true</tt> is returned and
+     * <p>If the lock is acquired then the value {@code true} is returned and
      * the lock hold count is set to one.
      *
      * <p>If the current thread:
      *
      * <ul>
      *
-     * <li>has its interrupted status set on entry to this method; or 
+     * <li>has its interrupted status set on entry to this method; or
      *
-     * <li>is {@link Thread#interrupt interrupted} while acquiring
-     * the lock,
+     * <li>is {@linkplain Thread#interrupt interrupted} while
+     * acquiring the lock,
      *
      * </ul>
-     * then {@link InterruptedException} is thrown and the current thread's 
-     * interrupted status is cleared. 
+     * then {@link InterruptedException} is thrown and the current thread's
+     * interrupted status is cleared.
      *
-     * <p>If the specified waiting time elapses then the value <tt>false</tt>
-     * is returned.
-     * If the time is 
-     * less than or equal to zero, the method will not wait at all.
+     * <p>If the specified waiting time elapses then the value {@code false}
+     * is returned.  If the time is less than or equal to zero, the method
+     * will not wait at all.
      *
-     * <p>In this implementation, as this method is an explicit interruption 
-     * point, preference is 
-     * given to responding to the interrupt over normal or reentrant 
-     * acquisition of the lock, and over reporting the elapse of the waiting
-     * time.
+     * <p>In this implementation, as this method is an explicit
+     * interruption point, preference is given to responding to the
+     * interrupt over normal or reentrant acquisition of the lock, and
+     * over reporting the elapse of the waiting time.
      *
      * @param timeout the time to wait for the lock
      * @param unit the time unit of the timeout argument
-     *
-     * @return <tt>true</tt> if the lock was free and was acquired by the
-     * current thread, or the lock was already held by the current thread; and
-     * <tt>false</tt> if the waiting time elapsed before the lock could be 
-     * acquired.
-     *
+     * @return {@code true} if the lock was free and was acquired by the
+     *         current thread, or the lock was already held by the current
+     *         thread; and {@code false} if the waiting time elapsed before
+     *         the lock could be acquired
      * @throws InterruptedException if the current thread is interrupted
-     * @throws NullPointerException if unit is null
+     * @throws NullPointerException if the time unit is null
      *
      */
     public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
@@ -413,22 +416,22 @@
     }
 
     /**
-     * Attempts to release this lock.  
+     * Attempts to release this lock.
      *
-     * <p>If the current thread is the
-     * holder of this lock then the hold count is decremented. If the
-     * hold count is now zero then the lock is released.  If the
-     * current thread is not the holder of this lock then {@link
-     * IllegalMonitorStateException} is thrown.
+     * <p>If the current thread is the holder of this lock then the hold
+     * count is decremented.  If the hold count is now zero then the lock
+     * is released.  If the current thread is not the holder of this
+     * lock then {@link IllegalMonitorStateException} is thrown.
+     *
      * @throws IllegalMonitorStateException if the current thread does not
-     * hold this lock.
+     *         hold this lock
      */
     public void unlock() {
         sync.release(1);
     }
 
     /**
-     * Returns a {@link Condition} instance for use with this 
+     * Returns a {@link Condition} instance for use with this
      * {@link Lock} instance.
      *
      * <p>The returned {@link Condition} instance supports the same
@@ -440,28 +443,28 @@
      * <ul>
      *
      * <li>If this lock is not held when any of the {@link Condition}
-     * {@link Condition#await() waiting} or {@link Condition#signal
-     * signalling} methods are called, then an {@link
+     * {@linkplain Condition#await() waiting} or {@linkplain
+     * Condition#signal signalling} methods are called, then an {@link
      * IllegalMonitorStateException} is thrown.
      *
-     * <li>When the condition {@link Condition#await() waiting}
+     * <li>When the condition {@linkplain Condition#await() waiting}
      * methods are called the lock is released and, before they
      * return, the lock is reacquired and the lock hold count restored
      * to what it was when the method was called.
      *
-     * <li>If a thread is {@link Thread#interrupt interrupted} while
-     * waiting then the wait will terminate, an {@link
+     * <li>If a thread is {@linkplain Thread#interrupt interrupted}
+     * while waiting then the wait will terminate, an {@link
      * InterruptedException} will be thrown, and the thread's
      * interrupted status will be cleared.
      *
-     * <li> Waiting threads are signalled in FIFO order
+     * <li> Waiting threads are signalled in FIFO order.
      *
      * <li>The ordering of lock reacquisition for threads returning
      * from waiting methods is the same as for threads initially
      * acquiring the lock, which is in the default case not specified,
      * but for <em>fair</em> locks favors those threads that have been
      * waiting the longest.
-     * 
+     *
      * </ul>
      *
      * @return the Condition object
@@ -473,7 +476,7 @@
     /**
      * Queries the number of holds on this lock by the current thread.
      *
-     * <p>A thread has a hold on a lock for each lock action that is not 
+     * <p>A thread has a hold on a lock for each lock action that is not
      * matched by an unlock action.
      *
      * <p>The hold count information is typically only used for testing and
@@ -484,8 +487,8 @@
      * <pre>
      * class X {
      *   ReentrantLock lock = new ReentrantLock();
-     *   // ...     
-     *   public void m() { 
+     *   // ...
+     *   public void m() {
      *     assert lock.getHoldCount() == 0;
      *     lock.lock();
      *     try {
@@ -498,7 +501,7 @@
      * </pre>
      *
      * @return the number of holds on this lock by the current thread,
-     * or zero if this lock is not held by the current thread.
+     *         or zero if this lock is not held by the current thread
      */
     public int getHoldCount() {
         return sync.getHoldCount();
@@ -517,7 +520,7 @@
      *   ReentrantLock lock = new ReentrantLock();
      *   // ...
      *
-     *   public void m() { 
+     *   public void m() {
      *       assert lock.isHeldByCurrentThread();
      *       // ... method body
      *   }
@@ -532,7 +535,7 @@
      *   ReentrantLock lock = new ReentrantLock();
      *   // ...
      *
-     *   public void m() { 
+     *   public void m() {
      *       assert !lock.isHeldByCurrentThread();
      *       lock.lock();
      *       try {
@@ -543,8 +546,9 @@
      *   }
      * }
      * </pre>
-     * @return <tt>true</tt> if current thread holds this lock and 
-     * <tt>false</tt> otherwise.
+     *
+     * @return {@code true} if current thread holds this lock and
+     *         {@code false} otherwise
      */
     public boolean isHeldByCurrentThread() {
         return sync.isHeldExclusively();
@@ -552,47 +556,53 @@
 
     /**
      * Queries if this lock is held by any thread. This method is
-     * designed for use in monitoring of the system state, 
+     * designed for use in monitoring of the system state,
      * not for synchronization control.
-     * @return <tt>true</tt> if any thread holds this lock and 
-     * <tt>false</tt> otherwise.
+     *
+     * @return {@code true} if any thread holds this lock and
+     *         {@code false} otherwise
      */
     public boolean isLocked() {
         return sync.isLocked();
     }
 
     /**
-     * Returns true if this lock has fairness set true.
-     * @return true if this lock has fairness set true.
+     * Returns {@code true} if this lock has fairness set true.
+     *
+     * @return {@code true} if this lock has fairness set true
      */
     public final boolean isFair() {
         return sync instanceof FairSync;
     }
 
     /**
-     * Returns the thread that currently owns the exclusive lock, or
-     * <tt>null</tt> if not owned. Note that the owner may be
-     * momentarily <tt>null</tt> even if there are threads trying to
-     * acquire the lock but have not yet done so.  This method is
-     * designed to facilitate construction of subclasses that provide
-     * more extensive lock monitoring facilities.
-     * @return the owner, or <tt>null</tt> if not owned.
+     * Returns the thread that currently owns this lock, or
+     * {@code null} if not owned. When this method is called by a
+     * thread that is not the owner, the return value reflects a
+     * best-effort approximation of current lock status. For example,
+     * the owner may be momentarily {@code null} even if there are
+     * threads trying to acquire the lock but have not yet done so.
+     * This method is designed to facilitate construction of
+     * subclasses that provide more extensive lock monitoring
+     * facilities.
+     *
+     * @return the owner, or {@code null} if not owned
      */
     protected Thread getOwner() {
         return sync.getOwner();
     }
 
     /**
-     * Queries whether any threads are waiting to acquire. Note that
-     * because cancellations may occur at any time, a <tt>true</tt>
+     * Queries whether any threads are waiting to acquire this lock. Note that
+     * because cancellations may occur at any time, a {@code true}
      * return does not guarantee that any other thread will ever
-     * acquire.  This method is designed primarily for use in
+     * acquire this lock.  This method is designed primarily for use in
      * monitoring of the system state.
      *
-     * @return true if there may be other threads waiting to acquire
-     * the lock.
+     * @return {@code true} if there may be other threads waiting to
+     *         acquire the lock
      */
-    public final boolean hasQueuedThreads() { 
+    public final boolean hasQueuedThreads() {
         return sync.hasQueuedThreads();
     }
 
@@ -600,26 +610,27 @@
     /**
      * Queries whether the given thread is waiting to acquire this
      * lock. Note that because cancellations may occur at any time, a
-     * <tt>true</tt> return does not guarantee that this thread
-     * will ever acquire.  This method is designed primarily for use
+     * {@code true} return does not guarantee that this thread
+     * will ever acquire this lock.  This method is designed primarily for use
      * in monitoring of the system state.
      *
      * @param thread the thread
-     * @return true if the given thread is queued waiting for this lock.
-     * @throws NullPointerException if thread is null
+     * @return {@code true} if the given thread is queued waiting for this lock
+     * @throws NullPointerException if the thread is null
      */
-    public final boolean hasQueuedThread(Thread thread) { 
+    public final boolean hasQueuedThread(Thread thread) {
         return sync.isQueued(thread);
     }
 
 
     /**
      * Returns an estimate of the number of threads waiting to
-     * acquire.  The value is only an estimate because the number of
+     * acquire this lock.  The value is only an estimate because the number of
      * threads may change dynamically while this method traverses
      * internal data structures.  This method is designed for use in
      * monitoring of the system state, not for synchronization
      * control.
+     *
      * @return the estimated number of threads waiting for this lock
      */
     public final int getQueueLength() {
@@ -628,12 +639,13 @@
 
     /**
      * Returns a collection containing threads that may be waiting to
-     * acquire.  Because the actual set of threads may change
+     * acquire this lock.  Because the actual set of threads may change
      * dynamically while constructing this result, the returned
      * collection is only a best-effort estimate.  The elements of the
      * returned collection are in no particular order.  This method is
      * designed to facilitate construction of subclasses that provide
      * more extensive monitoring facilities.
+     *
      * @return the collection of threads
      */
     protected Collection<Thread> getQueuedThreads() {
@@ -643,18 +655,18 @@
     /**
      * Queries whether any threads are waiting on the given condition
      * associated with this lock. Note that because timeouts and
-     * interrupts may occur at any time, a <tt>true</tt> return does
-     * not guarantee that a future <tt>signal</tt> will awaken any
+     * interrupts may occur at any time, a {@code true} return does
+     * not guarantee that a future {@code signal} will awaken any
      * threads.  This method is designed primarily for use in
      * monitoring of the system state.
+     *
      * @param condition the condition
-     * @return <tt>true</tt> if there are any waiting threads.
-     * @throws IllegalMonitorStateException if this lock 
-     * is not held
+     * @return {@code true} if there are any waiting threads
+     * @throws IllegalMonitorStateException if this lock is not held
      * @throws IllegalArgumentException if the given condition is
-     * not associated with this lock
-     * @throws NullPointerException if condition null
-     */ 
+     *         not associated with this lock
+     * @throws NullPointerException if the condition is null
+     */
     public boolean hasWaiters(Condition condition) {
         if (condition == null)
             throw new NullPointerException();
@@ -670,14 +682,14 @@
      * serves only as an upper bound on the actual number of waiters.
      * This method is designed for use in monitoring of the system
      * state, not for synchronization control.
+     *
      * @param condition the condition
-     * @return the estimated number of waiting threads.
-     * @throws IllegalMonitorStateException if this lock 
-     * is not held
+     * @return the estimated number of waiting threads
+     * @throws IllegalMonitorStateException if this lock is not held
      * @throws IllegalArgumentException if the given condition is
-     * not associated with this lock
-     * @throws NullPointerException if condition null
-     */ 
+     *         not associated with this lock
+     * @throws NullPointerException if the condition is null
+     */
     public int getWaitQueueLength(Condition condition) {
         if (condition == null)
             throw new NullPointerException();
@@ -695,13 +707,13 @@
      * are in no particular order.  This method is designed to
      * facilitate construction of subclasses that provide more
      * extensive condition monitoring facilities.
+     *
      * @param condition the condition
      * @return the collection of threads
-     * @throws IllegalMonitorStateException if this lock 
-     * is not held
+     * @throws IllegalMonitorStateException if this lock is not held
      * @throws IllegalArgumentException if the given condition is
-     * not associated with this lock
-     * @throws NullPointerException if condition null
+     *         not associated with this lock
+     * @throws NullPointerException if the condition is null
      */
     protected Collection<Thread> getWaitingThreads(Condition condition) {
         if (condition == null)
@@ -712,16 +724,17 @@
     }
 
     /**
-     * Returns a string identifying this lock, as well as its lock
-     * state.  The state, in brackets, includes either the String
-     * &quot;Unlocked&quot; or the String &quot;Locked by&quot;
-     * followed by the {@link Thread#getName} of the owning thread.
-     * @return a string identifying this lock, as well as its lock state.
+     * Returns a string identifying this lock, as well as its lock state.
+     * The state, in brackets, includes either the String {@code "Unlocked"}
+     * or the String {@code "Locked by"} followed by the
+     * {@linkplain Thread#getName name} of the owning thread.
+     *
+     * @return a string identifying this lock, as well as its lock state
      */
     public String toString() {
-        Thread owner = sync.getOwner();
-        return super.toString() + ((owner == null) ?
+        Thread o = sync.getOwner();
+        return super.toString() + ((o == null) ?
                                    "[Unlocked]" :
-                                   "[Locked by thread " + owner.getName() + "]");
+                                   "[Locked by thread " + o.getName() + "]");
     }
 }
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java b/libcore/concurrent/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java
index 95fc7af..c923944 100644
--- a/libcore/concurrent/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java
@@ -19,32 +19,60 @@
  *
  * <p> This class does not impose a reader or writer preference
  * ordering for lock access.  However, it does support an optional
- * <em>fairness</em> policy.  When constructed as fair, threads
- * contend for entry using an approximately arrival-order policy. When
- * the write lock is released either the longest-waiting single writer
- * will be assigned the write lock, or if there is a reader waiting
- * longer than any writer, the set of readers will be assigned the
- * read lock.  When constructed as non-fair, the order of entry to the
- * lock need not be in arrival order.  In either case, if readers are
- * active and a writer enters the lock then no subsequent readers will
- * be granted the read lock until after that writer has acquired and
- * released the write lock.
- * 
+ * <em>fairness</em> policy.
+ *
+ * <dl>
+ * <dt><b><i>Non-fair mode (default)</i></b>
+ * <dd>When constructed as non-fair (the default), the order of entry
+ * to the read and write lock is unspecified, subject to reentrancy
+ * constraints.  A nonfair lock that is continuously contended may
+ * indefinitely postpone one or more reader or writer threads, but
+ * will normally have higher throughput than a fair lock.
+ * <p>
+ *
+ * <dt><b><i>Fair mode</i></b>
+ * <dd> When constructed as fair, threads contend for entry using an
+ * approximately arrival-order policy. When the currently held lock
+ * is released either the longest-waiting single writer thread will
+ * be assigned the write lock, or if there is a group of reader threads
+ * waiting longer than all waiting writer threads, that group will be
+ * assigned the read lock.
+ *
+ * <p>A thread that tries to acquire a fair read lock (non-reentrantly)
+ * will block if either the write lock is held, or there is a waiting
+ * writer thread. The thread will not acquire the read lock until
+ * after the oldest currently waiting writer thread has acquired and
+ * released the write lock. Of course, if a waiting writer abandons
+ * its wait, leaving one or more reader threads as the longest waiters
+ * in the queue with the write lock free, then those readers will be
+ * assigned the read lock.
+ *
+ * <p>A thread that tries to acquire a fair write lock (non-reentrantly)
+ * will block unless both the read lock and write lock are free (which
+ * implies there are no waiting threads).  (Note that the non-blocking
+ * {@link ReadLock#tryLock()} and {@link WriteLock#tryLock()} methods
+ * do not honor this fair setting and will acquire the lock if it is
+ * possible, regardless of waiting threads.)
+ * <p>
+ * </dl>
+ *
  * <li><b>Reentrancy</b>
+ *
  * <p>This lock allows both readers and writers to reacquire read or
- * write locks in the style of a {@link ReentrantLock}. Readers are not
- * allowed until all write locks held by the writing thread have been
- * released.  
- * <p>Additionally, a writer can acquire the read lock - but not vice-versa.
- * Among other applications, reentrancy can be useful when
- * write locks are held during calls or callbacks to methods that
- * perform reads under read locks. 
- * If a reader tries to acquire the write lock it will never succeed.
- * 
+ * write locks in the style of a {@link ReentrantLock}. Non-reentrant
+ * readers are not allowed until all write locks held by the writing
+ * thread have been released.
+ *
+ * <p>Additionally, a writer can acquire the read lock, but not
+ * vice-versa.  Among other applications, reentrancy can be useful
+ * when write locks are held during calls or callbacks to methods that
+ * perform reads under read locks.  If a reader tries to acquire the
+ * write lock it will never succeed.
+ *
  * <li><b>Lock downgrading</b>
  * <p>Reentrancy also allows downgrading from the write lock to a read lock,
  * by acquiring the write lock, then the read lock and then releasing the
- * write lock. However, upgrading from a read lock to the write lock, is
+ * write lock. However, upgrading from a read lock to the write lock is
  * <b>not</b> possible.
  *
  * <li><b>Interruption of lock acquisition</b>
@@ -53,96 +81,105 @@
  *
  * <li><b>{@link Condition} support</b>
  * <p>The write lock provides a {@link Condition} implementation that
- * behaves in the same way, with respect to the write lock, as the 
+ * behaves in the same way, with respect to the write lock, as the
  * {@link Condition} implementation provided by
  * {@link ReentrantLock#newCondition} does for {@link ReentrantLock}.
  * This {@link Condition} can, of course, only be used with the write lock.
+ *
  * <p>The read lock does not support a {@link Condition} and
- * <tt>readLock().newCondition()</tt> throws 
- * <tt>UnsupportedOperationException</tt>.
+ * {@code readLock().newCondition()} throws
+ * {@code UnsupportedOperationException}.
  *
  * <li><b>Instrumentation</b>
- * <P> This class supports methods to determine whether locks
+ * <p>This class supports methods to determine whether locks
  * are held or contended. These methods are designed for monitoring
  * system state, not for synchronization control.
  * </ul>
  *
- * <p> Serialization of this class behaves in the same way as built-in
+ * <p>Serialization of this class behaves in the same way as built-in
  * locks: a deserialized lock is in the unlocked state, regardless of
  * its state when serialized.
  *
- * <p><b>Sample usages</b>. Here is a code sketch showing how to exploit
- * reentrancy to perform lock downgrading after updating a cache (exception
- * handling is elided for simplicity):
- * <pre>
+ * <p><b>Sample usages</b>. Here is a code sketch showing how to perform
+ * lock downgrading after updating a cache (exception handling is
+ * particularly tricky when handling multiple locks in a non-nested
+ * fashion):
+ *
+ * <pre> {@code
  * class CachedData {
  *   Object data;
  *   volatile boolean cacheValid;
- *   ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
+ *   final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
  *
  *   void processCachedData() {
  *     rwl.readLock().lock();
  *     if (!cacheValid) {
- *        // upgrade lock manually
- *        rwl.readLock().unlock();   // must unlock first to obtain writelock
+ *        // Must release read lock before acquiring write lock
+ *        rwl.readLock().unlock();
  *        rwl.writeLock().lock();
- *        if (!cacheValid) { // recheck
- *          data = ...
- *          cacheValid = true;
+ *        try {
+ *          // Recheck state because another thread might have
+ *          // acquired write lock and changed state before we did.
+ *          if (!cacheValid) {
+ *            data = ...
+ *            cacheValid = true;
+ *          }
+ *          // Downgrade by acquiring read lock before releasing write lock
+ *          rwl.readLock().lock();
+ *        } finally  {
+ *          rwl.writeLock().unlock(); // Unlock write, still hold read
  *        }
- *        // downgrade lock
- *        rwl.readLock().lock();  // reacquire read without giving up write lock
- *        rwl.writeLock().unlock(); // unlock write, still hold read
  *     }
  *
- *     use(data);
- *     rwl.readLock().unlock();
+ *     try {
+ *       use(data);
+ *     } finally {
+ *       rwl.readLock().unlock();
+ *     }
  *   }
- * }
- * </pre>
+ * }}</pre>
  *
  * ReentrantReadWriteLocks can be used to improve concurrency in some
  * uses of some kinds of Collections. This is typically worthwhile
  * only when the collections are expected to be large, accessed by
  * more reader threads than writer threads, and entail operations with
  * overhead that outweighs synchronization overhead. For example, here
- * is a class using a TreeMap that is expected to be large and 
+ * is a class using a TreeMap that is expected to be large and
  * concurrently accessed.
  *
- * <pre>
+ * <pre>{@code
  * class RWDictionary {
- *    private final Map&lt;String, Data&gt;  m = new TreeMap&lt;String, Data&gt;();
+ *    private final Map<String, Data> m = new TreeMap<String, Data>();
  *    private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
  *    private final Lock r = rwl.readLock();
  *    private final Lock w = rwl.writeLock();
  *
  *    public Data get(String key) {
- *        r.lock(); try { return m.get(key); } finally { r.unlock(); }
+ *        r.lock();
+ *        try { return m.get(key); }
+ *        finally { r.unlock(); }
  *    }
  *    public String[] allKeys() {
- *        r.lock(); try { return m.keySet().toArray(); } finally { r.unlock(); }
+ *        r.lock();
+ *        try { return m.keySet().toArray(); }
+ *        finally { r.unlock(); }
  *    }
  *    public Data put(String key, Data value) {
- *        w.lock(); try { return m.put(key, value); } finally { w.unlock(); }
+ *        w.lock();
+ *        try { return m.put(key, value); }
+ *        finally { w.unlock(); }
  *    }
  *    public void clear() {
- *        w.lock(); try { m.clear(); } finally { w.unlock(); }
+ *        w.lock();
+ *        try { m.clear(); }
+ *        finally { w.unlock(); }
  *    }
- * }
- * </pre>
- * 
+ * }}</pre>
  *
  * <h3>Implementation Notes</h3>
  *
- * <p>A reentrant write lock intrinsically defines an owner and can
- * only be released by the thread that acquired it.  In contrast, in
- * this implementation, the read lock has no concept of ownership, and
- * there is no requirement that the thread releasing a read lock is
- * the same as the one that acquired it.  However, this property is
- * not guaranteed to hold in future implementations of this class.
- *
- * <p> This lock supports a maximum of 65536 recursive write locks
- * and 65536 read locks. Attempts to exceed these limits result in
+ * <p>This lock supports a maximum of 65535 recursive write locks
+ * and 65535 read locks. Attempts to exceed these limits result in
  * {@link Error} throws from locking methods.
  *
  * @since 1.5
@@ -156,26 +193,24 @@
     /** Inner class providing writelock */
     private final ReentrantReadWriteLock.WriteLock writerLock;
     /** Performs all synchronization mechanics */
-    private final Sync sync;
+    final Sync sync;
 
     /**
-     * Creates a new <tt>ReentrantReadWriteLock</tt> with
-     * default ordering properties.
+     * Creates a new {@code ReentrantReadWriteLock} with
+     * default (nonfair) ordering properties.
      */
     public ReentrantReadWriteLock() {
-        sync = new NonfairSync();
-        readerLock = new ReadLock(this);
-        writerLock = new WriteLock(this);
+        this(false);
     }
 
     /**
-     * Creates a new <tt>ReentrantReadWriteLock</tt> with
+     * Creates a new {@code ReentrantReadWriteLock} with
      * the given fairness policy.
      *
-     * @param fair true if this lock should use a fair ordering policy
+     * @param fair {@code true} if this lock should use a fair ordering policy
      */
     public ReentrantReadWriteLock(boolean fair) {
-        sync = (fair)? new FairSync() : new NonfairSync();
+        sync = fair ? new FairSync() : new NonfairSync();
         readerLock = new ReadLock(this);
         writerLock = new WriteLock(this);
     }
@@ -183,129 +218,409 @@
     public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; }
     public ReentrantReadWriteLock.ReadLock  readLock()  { return readerLock; }
 
-    /* 
-     * Read vs write count extraction constants and functions.
-     * Lock state is logically divided into two shorts: The lower
-     * one representing the exclusive (writer) lock hold count,
-     * and the upper the shared (reader) hold count.
-     */
-    
-    static final int SHARED_SHIFT   = 16;
-    static final int SHARED_UNIT    = (1 << SHARED_SHIFT);
-    static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;
-    
-    /** Returns the number of shared holds represented in count  */
-    static int sharedCount(int c)    { return c >>> SHARED_SHIFT; }
-    /** Returns the number of exclusive holds represented in count  */
-    static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; }
-
-    /** 
+    /**
      * Synchronization implementation for ReentrantReadWriteLock.
      * Subclassed into fair and nonfair versions.
      */
-    abstract static class Sync extends AbstractQueuedSynchronizer {
-        /** Current (exclusive) owner thread */
-        transient Thread owner;
+    static abstract class Sync extends AbstractQueuedSynchronizer {
+        private static final long serialVersionUID = 6317671515068378041L;
+
+        /*
+         * Read vs write count extraction constants and functions.
+         * Lock state is logically divided into two unsigned shorts:
+         * The lower one representing the exclusive (writer) lock hold count,
+         * and the upper the shared (reader) hold count.
+         */
+
+        static final int SHARED_SHIFT   = 16;
+        static final int SHARED_UNIT    = (1 << SHARED_SHIFT);
+        static final int MAX_COUNT      = (1 << SHARED_SHIFT) - 1;
+        static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;
+
+        /** Returns the number of shared holds represented in count  */
+        static int sharedCount(int c)    { return c >>> SHARED_SHIFT; }
+        /** Returns the number of exclusive holds represented in count  */
+        static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; }
 
         /**
-         * Perform write lock. Allows fast path in non-fair version.
+         * A counter for per-thread read hold counts.
+         * Maintained as a ThreadLocal; cached in cachedHoldCounter
          */
-        abstract void wlock();
-
-        /** 
-         * Perform non-fair tryLock for write.  tryAcquire is
-         * implemented in subclasses, but both versions need nonfair
-         * try for trylock method
-         */
-        final boolean nonfairTryAcquire(int acquires) {
-            // mask out readlocks if called from condition methods
-            acquires = exclusiveCount(acquires);
-            Thread current = Thread.currentThread();
-            int c = getState();
-            int w = exclusiveCount(c);
-            if (w + acquires >= SHARED_UNIT)
-                throw new Error("Maximum lock count exceeded");
-            if (c != 0 && (w == 0 || current != owner))
-                return false;
-            if (!compareAndSetState(c, c + acquires)) 
-                return false;
-            owner = current;
-            return true;
+        static final class HoldCounter {
+            int count = 0;
+            // Use id, not reference, to avoid garbage retention
+            final long tid = Thread.currentThread().getId();
         }
 
-        /** 
-         * Perform nonfair tryLock for read. 
+        /**
+         * ThreadLocal subclass. Easiest to explicitly define for sake
+         * of deserialization mechanics.
          */
-        final int nonfairTryAcquireShared(int acquires) {
-            for (;;) {
-                int c = getState();
-                int nextc = c + (acquires << SHARED_SHIFT);
-                if (nextc < c)
-                    throw new Error("Maximum lock count exceeded");
-                if (exclusiveCount(c) != 0 && 
-                    owner != Thread.currentThread())
-                    return -1;
-                if (compareAndSetState(c, nextc)) 
-                    return 1;
-                // Recheck count if lost CAS
+        static final class ThreadLocalHoldCounter
+            extends ThreadLocal<HoldCounter> {
+            public HoldCounter initialValue() {
+                return new HoldCounter();
             }
         }
 
+        /**
+         * The number of reentrant read locks held by current thread.
+         * Initialized only in constructor and readObject.
+         * Removed whenever a thread's read hold count drops to 0.
+         */
+        private transient ThreadLocalHoldCounter readHolds;
+
+        /**
+         * The hold count of the last thread to successfully acquire
+         * readLock. This saves ThreadLocal lookup in the common case
+         * where the next thread to release is the last one to
+         * acquire. This is non-volatile since it is just used
+         * as a heuristic, and would be great for threads to cache.
+         *
+         * <p>Can outlive the Thread for which it is caching the read
+         * hold count, but avoids garbage retention by not retaining a
+         * reference to the Thread.
+         *
+         * <p>Accessed via a benign data race; relies on the memory
+         * model's final field and out-of-thin-air guarantees.
+         */
+        private transient HoldCounter cachedHoldCounter;
+
+        /**
+         * firstReader is the first thread to have acquired the read lock.
+         * firstReaderHoldCount is firstReader's hold count.
+         *
+         * <p>More precisely, firstReader is the unique thread that last
+         * changed the shared count from 0 to 1, and has not released the
+         * read lock since then; null if there is no such thread.
+         *
+         * <p>Cannot cause garbage retention unless the thread terminated
+         * without relinquishing its read locks, since tryReleaseShared
+         * sets it to null.
+         *
+         * <p>Accessed via a benign data race; relies on the memory
+         * model's out-of-thin-air guarantees for references.
+         *
+         * <p>This allows tracking of read holds for uncontended read
+         * locks to be very cheap.
+         */
+        private transient Thread firstReader = null;
+        private transient int firstReaderHoldCount;
+
+        Sync() {
+            readHolds = new ThreadLocalHoldCounter();
+            setState(getState()); // ensures visibility of readHolds
+        }
+
+        /*
+         * Acquires and releases use the same code for fair and
+         * nonfair locks, but differ in whether/how they allow barging
+         * when queues are non-empty.
+         */
+
+        /**
+         * Returns true if the current thread, when trying to acquire
+         * the read lock, and otherwise eligible to do so, should block
+         * because of policy for overtaking other waiting threads.
+         */
+        abstract boolean readerShouldBlock();
+
+        /**
+         * Returns true if the current thread, when trying to acquire
+         * the write lock, and otherwise eligible to do so, should block
+         * because of policy for overtaking other waiting threads.
+         */
+        abstract boolean writerShouldBlock();
+
+        /*
+         * Note that tryRelease and tryAcquire can be called by
+         * Conditions. So it is possible that their arguments contain
+         * both read and write holds that are all released during a
+         * condition wait and re-established in tryAcquire.
+         */
+
         protected final boolean tryRelease(int releases) {
-            Thread current = Thread.currentThread();
-            int c = getState();
-            if (owner != current)
+            if (!isHeldExclusively())
                 throw new IllegalMonitorStateException();
-            int nextc = c - releases;
-            boolean free = false;
-            if (exclusiveCount(c) == releases) {
-                free = true;
-                owner = null;
-            }
+            int nextc = getState() - releases;
+            boolean free = exclusiveCount(nextc) == 0;
+            if (free)
+                setExclusiveOwnerThread(null);
             setState(nextc);
             return free;
         }
 
-        protected final boolean tryReleaseShared(int releases) {
+        protected final boolean tryAcquire(int acquires) {
+            /*
+             * Walkthrough:
+             * 1. If read count nonzero or write count nonzero
+             *    and owner is a different thread, fail.
+             * 2. If count would saturate, fail. (This can only
+             *    happen if count is already nonzero.)
+             * 3. Otherwise, this thread is eligible for lock if
+             *    it is either a reentrant acquire or
+             *    queue policy allows it. If so, update state
+             *    and set owner.
+             */
+            Thread current = Thread.currentThread();
+            int c = getState();
+            int w = exclusiveCount(c);
+            if (c != 0) {
+                // (Note: if c != 0 and w == 0 then shared count != 0)
+                if (w == 0 || current != getExclusiveOwnerThread())
+                    return false;
+                if (w + exclusiveCount(acquires) > MAX_COUNT)
+                    throw new Error("Maximum lock count exceeded");
+                // Reentrant acquire
+                setState(c + acquires);
+                return true;
+            }
+            if (writerShouldBlock() ||
+                !compareAndSetState(c, c + acquires))
+                return false;
+            setExclusiveOwnerThread(current);
+            return true;
+        }
+
+        protected final boolean tryReleaseShared(int unused) {
+            Thread current = Thread.currentThread();
+            if (firstReader == current) {
+                // assert firstReaderHoldCount > 0;
+                if (firstReaderHoldCount == 1)
+                    firstReader = null;
+                else
+                    firstReaderHoldCount--;
+            } else {
+                HoldCounter rh = cachedHoldCounter;
+                if (rh == null || rh.tid != current.getId())
+                    rh = readHolds.get();
+                int count = rh.count;
+                if (count <= 1) {
+                    readHolds.remove();
+                    if (count <= 0)
+                        throw unmatchedUnlockException();
+                }
+                --rh.count;
+            }
             for (;;) {
                 int c = getState();
-                int nextc = c - (releases << SHARED_SHIFT);
-                if (nextc < 0)
-                    throw new IllegalMonitorStateException();
-                if (compareAndSetState(c, nextc)) 
+                int nextc = c - SHARED_UNIT;
+                if (compareAndSetState(c, nextc))
+                    // Releasing the read lock has no effect on readers,
+                    // but it may allow waiting writers to proceed if
+                    // both read and write locks are now free.
                     return nextc == 0;
             }
         }
-    
+
+        private IllegalMonitorStateException unmatchedUnlockException() {
+            return new IllegalMonitorStateException(
+                "attempt to unlock read lock, not locked by current thread");
+        }
+
+        protected final int tryAcquireShared(int unused) {
+            /*
+             * Walkthrough:
+             * 1. If write lock held by another thread, fail.
+             * 2. Otherwise, this thread is eligible for
+             *    lock wrt state, so ask if it should block
+             *    because of queue policy. If not, try
+             *    to grant by CASing state and updating count.
+             *    Note that step does not check for reentrant
+             *    acquires, which is postponed to full version
+             *    to avoid having to check hold count in
+             *    the more typical non-reentrant case.
+             * 3. If step 2 fails either because thread
+             *    apparently not eligible or CAS fails or count
+             *    saturated, chain to version with full retry loop.
+             */
+            Thread current = Thread.currentThread();
+            int c = getState();
+            if (exclusiveCount(c) != 0 &&
+                getExclusiveOwnerThread() != current)
+                return -1;
+            int r = sharedCount(c);
+            if (!readerShouldBlock() &&
+                r < MAX_COUNT &&
+                compareAndSetState(c, c + SHARED_UNIT)) {
+                if (r == 0) {
+                    firstReader = current;
+                    firstReaderHoldCount = 1;
+                } else if (firstReader == current) {
+                    firstReaderHoldCount++;
+                } else {
+                    HoldCounter rh = cachedHoldCounter;
+                    if (rh == null || rh.tid != current.getId())
+                        cachedHoldCounter = rh = readHolds.get();
+                    else if (rh.count == 0)
+                        readHolds.set(rh);
+                    rh.count++;
+                }
+                return 1;
+            }
+            return fullTryAcquireShared(current);
+        }
+
+        /**
+         * Full version of acquire for reads, that handles CAS misses
+         * and reentrant reads not dealt with in tryAcquireShared.
+         */
+        final int fullTryAcquireShared(Thread current) {
+            /*
+             * This code is in part redundant with that in
+             * tryAcquireShared but is simpler overall by not
+             * complicating tryAcquireShared with interactions between
+             * retries and lazily reading hold counts.
+             */
+            HoldCounter rh = null;
+            for (;;) {
+                int c = getState();
+                if (exclusiveCount(c) != 0) {
+                    if (getExclusiveOwnerThread() != current)
+                        return -1;
+                    // else we hold the exclusive lock; blocking here
+                    // would cause deadlock.
+                } else if (readerShouldBlock()) {
+                    // Make sure we're not acquiring read lock reentrantly
+                    if (firstReader == current) {
+                        // assert firstReaderHoldCount > 0;
+                    } else {
+                        if (rh == null) {
+                            rh = cachedHoldCounter;
+                            if (rh == null || rh.tid != current.getId()) {
+                                rh = readHolds.get();
+                                if (rh.count == 0)
+                                    readHolds.remove();
+                            }
+                        }
+                        if (rh.count == 0)
+                            return -1;
+                    }
+                }
+                if (sharedCount(c) == MAX_COUNT)
+                    throw new Error("Maximum lock count exceeded");
+                if (compareAndSetState(c, c + SHARED_UNIT)) {
+                    if (sharedCount(c) == 0) {
+                        firstReader = current;
+                        firstReaderHoldCount = 1;
+                    } else if (firstReader == current) {
+                        firstReaderHoldCount++;
+                    } else {
+                        if (rh == null)
+                            rh = cachedHoldCounter;
+                        if (rh == null || rh.tid != current.getId())
+                            rh = readHolds.get();
+                        else if (rh.count == 0)
+                            readHolds.set(rh);
+                        rh.count++;
+                        cachedHoldCounter = rh; // cache for release
+                    }
+                    return 1;
+                }
+            }
+        }
+
+        /**
+         * Performs tryLock for write, enabling barging in both modes.
+         * This is identical in effect to tryAcquire except for lack
+         * of calls to writerShouldBlock.
+         */
+        final boolean tryWriteLock() {
+            Thread current = Thread.currentThread();
+            int c = getState();
+            if (c != 0) {
+                int w = exclusiveCount(c);
+                if (w == 0 || current != getExclusiveOwnerThread())
+                    return false;
+                if (w == MAX_COUNT)
+                    throw new Error("Maximum lock count exceeded");
+            }
+            if (!compareAndSetState(c, c + 1))
+                return false;
+            setExclusiveOwnerThread(current);
+            return true;
+        }
+
+        /**
+         * Performs tryLock for read, enabling barging in both modes.
+         * This is identical in effect to tryAcquireShared except for
+         * lack of calls to readerShouldBlock.
+         */
+        final boolean tryReadLock() {
+            Thread current = Thread.currentThread();
+            for (;;) {
+                int c = getState();
+                if (exclusiveCount(c) != 0 &&
+                    getExclusiveOwnerThread() != current)
+                    return false;
+                int r = sharedCount(c);
+                if (r == MAX_COUNT)
+                    throw new Error("Maximum lock count exceeded");
+                if (compareAndSetState(c, c + SHARED_UNIT)) {
+                    if (r == 0) {
+                        firstReader = current;
+                        firstReaderHoldCount = 1;
+                    } else if (firstReader == current) {
+                        firstReaderHoldCount++;
+                    } else {
+                        HoldCounter rh = cachedHoldCounter;
+                        if (rh == null || rh.tid != current.getId())
+                            cachedHoldCounter = rh = readHolds.get();
+                        else if (rh.count == 0)
+                            readHolds.set(rh);
+                        rh.count++;
+                    }
+                    return true;
+                }
+            }
+        }
+
         protected final boolean isHeldExclusively() {
-            return exclusiveCount(getState()) != 0 && 
-                owner == Thread.currentThread();
+            // While we must in general read state before owner,
+            // we don't need to do so to check if current thread is owner
+            return getExclusiveOwnerThread() == Thread.currentThread();
         }
 
         // Methods relayed to outer class
-        
-        final ConditionObject newCondition() { 
-            return new ConditionObject(); 
+
+        final ConditionObject newCondition() {
+            return new ConditionObject();
         }
 
         final Thread getOwner() {
-            int c = exclusiveCount(getState());
-            Thread o = owner;
-            return (c == 0)? null : o;
+            // Must read state before owner to ensure memory consistency
+            return ((exclusiveCount(getState()) == 0)?
+                    null :
+                    getExclusiveOwnerThread());
         }
-        
+
         final int getReadLockCount() {
             return sharedCount(getState());
         }
-        
+
         final boolean isWriteLocked() {
             return exclusiveCount(getState()) != 0;
         }
 
         final int getWriteHoldCount() {
-            int c = exclusiveCount(getState());
-            Thread o = owner;
-            return (o == Thread.currentThread())? c : 0;
+            return isHeldExclusively() ? exclusiveCount(getState()) : 0;
+        }
+
+        final int getReadHoldCount() {
+            if (getReadLockCount() == 0)
+                return 0;
+
+            Thread current = Thread.currentThread();
+            if (firstReader == current)
+                return firstReaderHoldCount;
+
+            HoldCounter rh = cachedHoldCounter;
+            if (rh != null && rh.tid == current.getId())
+                return rh.count;
+
+            int count = readHolds.get().count;
+            if (count == 0) readHolds.remove();
+            return count;
         }
 
         /**
@@ -315,78 +630,43 @@
         private void readObject(java.io.ObjectInputStream s)
             throws java.io.IOException, ClassNotFoundException {
             s.defaultReadObject();
+            readHolds = new ThreadLocalHoldCounter();
             setState(0); // reset to unlocked state
         }
 
         final int getCount() { return getState(); }
     }
 
-    /** 
+    /**
      * Nonfair version of Sync
      */
     final static class NonfairSync extends Sync {
-        protected final boolean tryAcquire(int acquires) { 
-            return nonfairTryAcquire(acquires);
+        private static final long serialVersionUID = -8159625535654395037L;
+        final boolean writerShouldBlock() {
+            return false; // writers can always barge
         }
-
-        protected final int tryAcquireShared(int acquires) {
-            return nonfairTryAcquireShared(acquires);
-        }
-
-        // Use fastpath for main write lock method
-        final void wlock() {
-            if (compareAndSetState(0, 1))
-                owner = Thread.currentThread();
-            else
-                acquire(1);
+        final boolean readerShouldBlock() {
+            /* As a heuristic to avoid indefinite writer starvation,
+             * block if the thread that momentarily appears to be head
+             * of queue, if one exists, is a waiting writer.  This is
+             * only a probabilistic effect since a new reader will not
+             * block if there is a waiting writer behind other enabled
+             * readers that have not yet drained from the queue.
+             */
+            return apparentlyFirstQueuedIsExclusive();
         }
     }
 
-    /** 
+    /**
      * Fair version of Sync
      */
     final static class FairSync extends Sync {
-        protected final boolean tryAcquire(int acquires) { 
-            // mask out readlocks if called from condition methods
-            acquires = exclusiveCount(acquires);
-            Thread current = Thread.currentThread();
-            Thread first;
-            int c = getState();
-            int w = exclusiveCount(c);
-            if (w + acquires >= SHARED_UNIT)
-                throw new Error("Maximum lock count exceeded");
-            if ((w == 0 || current != owner) &&
-                (c != 0 || 
-                 ((first = getFirstQueuedThread()) != null && 
-                  first != current)))
-                return false;
-            if (!compareAndSetState(c, c + acquires)) 
-                return false;
-            owner = current;
-            return true;
+        private static final long serialVersionUID = -2274990926593161451L;
+        final boolean writerShouldBlock() {
+            return hasQueuedPredecessors();
         }
-
-        protected final int tryAcquireShared(int acquires) {
-            Thread current = Thread.currentThread();
-            for (;;) {
-                Thread first = getFirstQueuedThread();
-                if (first != null && first != current)
-                    return -1;
-                int c = getState();
-                int nextc = c + (acquires << SHARED_SHIFT);
-                if (nextc < c)
-                    throw new Error("Maximum lock count exceeded");
-                if (exclusiveCount(c) != 0 && 
-                    owner != Thread.currentThread())
-                    return -1;
-                if (compareAndSetState(c, nextc)) 
-                    return 1;
-                // Recheck count if lost CAS
-            }
-        }
-
-        final void wlock() { // no fast path
-            acquire(1);
+        final boolean readerShouldBlock() {
+            return hasQueuedPredecessors();
         }
     }
 
@@ -396,46 +676,47 @@
     public static class ReadLock implements Lock, java.io.Serializable  {
         private static final long serialVersionUID = -5992448646407690164L;
         private final Sync sync;
-        
-        /** 
-         * Constructor for use by subclasses.
+
+        /**
+         * Constructor for use by subclasses
+         *
          * @param lock the outer lock object
-         * @throws NullPointerException if lock null
+         * @throws NullPointerException if the lock is null
          */
         protected ReadLock(ReentrantReadWriteLock lock) {
             sync = lock.sync;
         }
 
         /**
-         * Acquires the shared lock. 
+         * Acquires the read lock.
          *
-         * <p>Acquires the lock if it is not held exclusively by
+         * <p>Acquires the read lock if the write lock is not held by
          * another thread and returns immediately.
          *
-         * <p>If the lock is held exclusively by another thread then
+         * <p>If the write lock is held by another thread then
          * the current thread becomes disabled for thread scheduling
-         * purposes and lies dormant until the lock has been acquired.
+         * purposes and lies dormant until the read lock has been acquired.
          */
-        public void lock() { 
+        public void lock() {
             sync.acquireShared(1);
         }
 
         /**
-         * Acquires the shared lock unless the current thread is 
-         * {@link Thread#interrupt interrupted}.
+         * Acquires the read lock unless the current thread is
+         * {@linkplain Thread#interrupt interrupted}.
          *
-         * <p>Acquires the shared lock if it is not held exclusively
+         * <p>Acquires the read lock if the write lock is not held
          * by another thread and returns immediately.
          *
-         * <p>If the lock is held by another thread then the
-         * current thread becomes disabled for thread scheduling 
+         * <p>If the write lock is held by another thread then the
+         * current thread becomes disabled for thread scheduling
          * purposes and lies dormant until one of two things happens:
          *
          * <ul>
          *
-         * <li>The lock is acquired by the current thread; or
+         * <li>The read lock is acquired by the current thread; or
          *
-         * <li>Some other thread {@link Thread#interrupt interrupts}
+         * <li>Some other thread {@linkplain Thread#interrupt interrupts}
          * the current thread.
          *
          * </ul>
@@ -444,10 +725,10 @@
          *
          * <ul>
          *
-         * <li>has its interrupted status set on entry to this method; or 
+         * <li>has its interrupted status set on entry to this method; or
          *
-         * <li>is {@link Thread#interrupt interrupted} while acquiring 
-         * the lock,
+         * <li>is {@linkplain Thread#interrupt interrupted} while
+         * acquiring the read lock,
          *
          * </ul>
          *
@@ -466,83 +747,83 @@
         }
 
         /**
-         * Acquires the shared lock only if it is not held exclusively by
+         * Acquires the read lock only if the write lock is not held by
          * another thread at the time of invocation.
          *
-         * <p>Acquires the lock if it is not held exclusively by
+         * <p>Acquires the read lock if the write lock is not held by
          * another thread and returns immediately with the value
-         * <tt>true</tt>. Even when this lock has been set to use a
-         * fair ordering policy, a call to <tt>tryLock()</tt>
-         * <em>will</em> immediately acquire the lock if it is
+         * {@code true}. Even when this lock has been set to use a
+         * fair ordering policy, a call to {@code tryLock()}
+         * <em>will</em> immediately acquire the read lock if it is
          * available, whether or not other threads are currently
-         * waiting for the lock.  This &quot;barging&quot; behavior
+         * waiting for the read lock.  This &quot;barging&quot; behavior
          * can be useful in certain circumstances, even though it
          * breaks fairness. If you want to honor the fairness setting
          * for this lock, then use {@link #tryLock(long, TimeUnit)
          * tryLock(0, TimeUnit.SECONDS) } which is almost equivalent
          * (it also detects interruption).
          *
-         * <p>If the lock is held exclusively by another thread then
+         * <p>If the write lock is held by another thread then
          * this method will return immediately with the value
-         * <tt>false</tt>.
+         * {@code false}.
          *
-         * @return <tt>true</tt> if the lock was acquired.
+         * @return {@code true} if the read lock was acquired
          */
         public  boolean tryLock() {
-            return sync.nonfairTryAcquireShared(1) >= 0;
+            return sync.tryReadLock();
         }
 
         /**
-         * Acquires the shared lock if it is not held exclusively by
+         * Acquires the read lock if the write lock is not held by
          * another thread within the given waiting time and the
-         * current thread has not been {@link Thread#interrupt
+         * current thread has not been {@linkplain Thread#interrupt
          * interrupted}.
          *
-         * <p>Acquires the lock if it is not held exclusively by
+         * <p>Acquires the read lock if the write lock is not held by
          * another thread and returns immediately with the value
-         * <tt>true</tt>. If this lock has been set to use a fair
+         * {@code true}. If this lock has been set to use a fair
          * ordering policy then an available lock <em>will not</em> be
          * acquired if any other threads are waiting for the
          * lock. This is in contrast to the {@link #tryLock()}
-         * method. If you want a timed <tt>tryLock</tt> that does
+         * method. If you want a timed {@code tryLock} that does
          * permit barging on a fair lock then combine the timed and
          * un-timed forms together:
          *
          * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
          * </pre>
          *
-         * <p>If the lock is held exclusively by another thread then the
-         * current thread becomes disabled for thread scheduling 
+         * <p>If the write lock is held by another thread then the
+         * current thread becomes disabled for thread scheduling
          * purposes and lies dormant until one of three things happens:
          *
          * <ul>
          *
-         * <li>The lock is acquired by the current thread; or
+         * <li>The read lock is acquired by the current thread; or
          *
-         * <li>Some other thread {@link Thread#interrupt interrupts} the current
-         * thread; or
+         * <li>Some other thread {@linkplain Thread#interrupt interrupts}
+         * the current thread; or
          *
-         * <li>The specified waiting time elapses
+         * <li>The specified waiting time elapses.
          *
          * </ul>
          *
-         * <p>If the lock is acquired then the value <tt>true</tt> is
+         * <p>If the read lock is acquired then the value {@code true} is
          * returned.
          *
          * <p>If the current thread:
          *
          * <ul>
          *
-         * <li>has its interrupted status set on entry to this method; or 
+         * <li>has its interrupted status set on entry to this method; or
          *
-         * <li>is {@link Thread#interrupt interrupted} while acquiring
-         * the lock,
+         * <li>is {@linkplain Thread#interrupt interrupted} while
+         * acquiring the read lock,
          *
          * </ul> then {@link InterruptedException} is thrown and the
          * current thread's interrupted status is cleared.
          *
          * <p>If the specified waiting time elapses then the value
-         * <tt>false</tt> is returned.  If the time is less than or
+         * {@code false} is returned.  If the time is less than or
          * equal to zero, the method will not wait at all.
          *
          * <p>In this implementation, as this method is an explicit
@@ -550,13 +831,11 @@
          * the interrupt over normal or reentrant acquisition of the
          * lock, and over reporting the elapse of the waiting time.
          *
-         * @param timeout the time to wait for the lock
+         * @param timeout the time to wait for the read lock
          * @param unit the time unit of the timeout argument
-         *
-         * @return <tt>true</tt> if the lock was acquired.
-         *
+         * @return {@code true} if the read lock was acquired
          * @throws InterruptedException if the current thread is interrupted
-         * @throws NullPointerException if unit is null
+         * @throws NullPointerException if the time unit is null
          *
          */
         public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
@@ -564,20 +843,19 @@
         }
 
         /**
-         * Attempts to release this lock.  
+         * Attempts to release this lock.
          *
          * <p> If the number of readers is now zero then the lock
-         * is made available for other lock attempts.
+         * is made available for write lock attempts.
          */
         public  void unlock() {
             sync.releaseShared(1);
         }
 
         /**
-         * Throws UnsupportedOperationException because ReadLocks
-         * do not support conditions.
-         * @return A new {@link Condition} instance for this <tt>Lock</tt> 
-         * instance.
+         * Throws {@code UnsupportedOperationException} because
+         * {@code ReadLocks} do not support conditions.
+         *
          * @throws UnsupportedOperationException always
          */
         public Condition newCondition() {
@@ -586,17 +864,16 @@
 
         /**
          * Returns a string identifying this lock, as well as its lock state.
-         * The state, in brackets, includes the String 
-         * &quot;Read locks =&quot; followed by the number of held
-         * read locks.
-         * @return a string identifying this lock, as well as its lock state.
+         * The state, in brackets, includes the String {@code "Read locks ="}
+         * followed by the number of held read locks.
+         *
+         * @return a string identifying this lock, as well as its lock state
          */
         public String toString() {
             int r = sync.getReadLockCount();
-            return super.toString() + 
+            return super.toString() +
                 "[Read locks = " + r + "]";
         }
-
     }
 
     /**
@@ -605,42 +882,45 @@
     public static class WriteLock implements Lock, java.io.Serializable  {
         private static final long serialVersionUID = -4992448646407690164L;
         private final Sync sync;
-        
-        /** 
-         * Constructor for use by subclasses.
+
+        /**
+         * Constructor for use by subclasses
+         *
          * @param lock the outer lock object
-         * @throws NullPointerException if lock null
+         * @throws NullPointerException if the lock is null
          */
         protected WriteLock(ReentrantReadWriteLock lock) {
             sync = lock.sync;
         }
 
         /**
-         * Acquire the lock. 
+         * Acquires the write lock.
          *
-         * <p>Acquires the lock if it is not held by another thread
-         * and returns immediately, setting the lock hold count to
+         * <p>Acquires the write lock if neither the read nor write lock
+         * are held by another thread
+         * and returns immediately, setting the write lock hold count to
          * one.
          *
-         * <p>If the current thread already holds the lock then the
+         * <p>If the current thread already holds the write lock then the
          * hold count is incremented by one and the method returns
          * immediately.
          *
          * <p>If the lock is held by another thread then the current
          * thread becomes disabled for thread scheduling purposes and
-         * lies dormant until the lock has been acquired, at which
-         * time the lock hold count is set to one.
+         * lies dormant until the write lock has been acquired, at which
+         * time the write lock hold count is set to one.
          */
         public void lock() {
-            sync.wlock();
+            sync.acquire(1);
         }
 
         /**
-         * Acquires the lock unless the current thread is {@link
-         * Thread#interrupt interrupted}.
+         * Acquires the write lock unless the current thread is
+         * {@linkplain Thread#interrupt interrupted}.
          *
-         * <p>Acquires the lock if it is not held by another thread
-         * and returns immediately, setting the lock hold count to
+         * <p>Acquires the write lock if neither the read nor write lock
+         * are held by another thread
+         * and returns immediately, setting the write lock hold count to
          * one.
          *
          * <p>If the current thread already holds this lock then the
@@ -653,14 +933,14 @@
          *
          * <ul>
          *
-         * <li>The lock is acquired by the current thread; or
+         * <li>The write lock is acquired by the current thread; or
          *
-         * <li>Some other thread {@link Thread#interrupt interrupts}
+         * <li>Some other thread {@linkplain Thread#interrupt interrupts}
          * the current thread.
          *
          * </ul>
          *
-         * <p>If the lock is acquired by the current thread then the
+         * <p>If the write lock is acquired by the current thread then the
          * lock hold count is set to one.
          *
          * <p>If the current thread:
@@ -670,8 +950,8 @@
          * <li>has its interrupted status set on entry to this method;
          * or
          *
-         * <li>is {@link Thread#interrupt interrupted} while acquiring
-         * the lock,
+         * <li>is {@linkplain Thread#interrupt interrupted} while
+         * acquiring the write lock,
          *
          * </ul>
          *
@@ -690,16 +970,17 @@
         }
 
         /**
-         * Acquires the lock only if it is not held by another thread
+         * Acquires the write lock only if it is not held by another thread
          * at the time of invocation.
          *
-         * <p>Acquires the lock if it is not held by another thread
-         * and returns immediately with the value <tt>true</tt>,
-         * setting the lock hold count to one. Even when this lock has
+         * <p>Acquires the write lock if neither the read nor write lock
+         * are held by another thread
+         * and returns immediately with the value {@code true},
+         * setting the write lock hold count to one. Even when this lock has
          * been set to use a fair ordering policy, a call to
-         * <tt>tryLock()</tt> <em>will</em> immediately acquire the
+         * {@code tryLock()} <em>will</em> immediately acquire the
          * lock if it is available, whether or not other threads are
-         * currently waiting for the lock.  This &quot;barging&quot;
+         * currently waiting for the write lock.  This &quot;barging&quot;
          * behavior can be useful in certain circumstances, even
          * though it breaks fairness. If you want to honor the
          * fairness setting for this lock, then use {@link
@@ -708,31 +989,32 @@
          *
          * <p> If the current thread already holds this lock then the
          * hold count is incremented by one and the method returns
-         * <tt>true</tt>.
+         * {@code true}.
          *
          * <p>If the lock is held by another thread then this method
-         * will return immediately with the value <tt>false</tt>.
+         * will return immediately with the value {@code false}.
          *
-         * @return <tt>true</tt> if the lock was free and was acquired by the
-         * current thread, or the lock was already held by the current thread; and
-         * <tt>false</tt> otherwise.
+         * @return {@code true} if the lock was free and was acquired
+         * by the current thread, or the write lock was already held
+         * by the current thread; and {@code false} otherwise.
          */
         public boolean tryLock( ) {
-            return sync.nonfairTryAcquire(1);
+            return sync.tryWriteLock();
         }
 
         /**
-         * Acquires the lock if it is not held by another thread
+         * Acquires the write lock if it is not held by another thread
          * within the given waiting time and the current thread has
-         * not been {@link Thread#interrupt interrupted}.
+         * not been {@linkplain Thread#interrupt interrupted}.
          *
-         * <p>Acquires the lock if it is not held by another thread
-         * and returns immediately with the value <tt>true</tt>,
-         * setting the lock hold count to one. If this lock has been
+         * <p>Acquires the write lock if neither the read nor write lock
+         * are held by another thread
+         * and returns immediately with the value {@code true},
+         * setting the write lock hold count to one. If this lock has been
          * set to use a fair ordering policy then an available lock
          * <em>will not</em> be acquired if any other threads are
-         * waiting for the lock. This is in contrast to the {@link
-         * #tryLock()} method. If you want a timed <tt>tryLock</tt>
+         * waiting for the write lock. This is in contrast to the {@link
+         * #tryLock()} method. If you want a timed {@code tryLock}
          * that does permit barging on a fair lock then combine the
          * timed and un-timed forms together:
          *
@@ -741,7 +1023,7 @@
          *
          * <p>If the current thread already holds this lock then the
          * hold count is incremented by one and the method returns
-         * <tt>true</tt>.
+         * {@code true}.
          *
          * <p>If the lock is held by another thread then the current
          * thread becomes disabled for thread scheduling purposes and
@@ -749,17 +1031,17 @@
          *
          * <ul>
          *
-         * <li>The lock is acquired by the current thread; or
+         * <li>The write lock is acquired by the current thread; or
          *
-         * <li>Some other thread {@link Thread#interrupt interrupts}
+         * <li>Some other thread {@linkplain Thread#interrupt interrupts}
          * the current thread; or
          *
          * <li>The specified waiting time elapses
          *
          * </ul>
          *
-         * <p>If the lock is acquired then the value <tt>true</tt> is
-         * returned and the lock hold count is set to one.
+         * <p>If the write lock is acquired then the value {@code true} is
+         * returned and the write lock hold count is set to one.
          *
          * <p>If the current thread:
          *
@@ -768,16 +1050,16 @@
          * <li>has its interrupted status set on entry to this method;
          * or
          *
-         * <li>is {@link Thread#interrupt interrupted} while acquiring
-         * the lock,
+         * <li>is {@linkplain Thread#interrupt interrupted} while
+         * acquiring the write lock,
          *
-         * </ul> 
+         * </ul>
          *
          * then {@link InterruptedException} is thrown and the current
          * thread's interrupted status is cleared.
          *
          * <p>If the specified waiting time elapses then the value
-         * <tt>false</tt> is returned.  If the time is less than or
+         * {@code false} is returned.  If the time is less than or
          * equal to zero, the method will not wait at all.
          *
          * <p>In this implementation, as this method is an explicit
@@ -785,30 +1067,31 @@
          * the interrupt over normal or reentrant acquisition of the
          * lock, and over reporting the elapse of the waiting time.
          *
-         * @param timeout the time to wait for the lock
+         * @param timeout the time to wait for the write lock
          * @param unit the time unit of the timeout argument
          *
-         * @return <tt>true</tt> if the lock was free and was acquired
-         * by the current thread, or the lock was already held by the
-         * current thread; and <tt>false</tt> if the waiting time
+         * @return {@code true} if the lock was free and was acquired
+         * by the current thread, or the write lock was already held by the
+         * current thread; and {@code false} if the waiting time
          * elapsed before the lock could be acquired.
          *
          * @throws InterruptedException if the current thread is interrupted
-         * @throws NullPointerException if unit is null
+         * @throws NullPointerException if the time unit is null
          *
          */
         public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
             return sync.tryAcquireNanos(1, unit.toNanos(timeout));
         }
-        
+
         /**
-         * Attempts to release this lock.  
+         * Attempts to release this lock.
          *
          * <p>If the current thread is the holder of this lock then
          * the hold count is decremented. If the hold count is now
          * zero then the lock is released.  If the current thread is
          * not the holder of this lock then {@link
          * IllegalMonitorStateException} is thrown.
+         *
          * @throws IllegalMonitorStateException if the current thread does not
          * hold this lock.
          */
@@ -818,7 +1101,7 @@
 
         /**
          * Returns a {@link Condition} instance for use with this
-         * {@link Lock} instance. 
+         * {@link Lock} instance.
          * <p>The returned {@link Condition} instance supports the same
          * usages as do the {@link Object} monitor methods ({@link
          * Object#wait() wait}, {@link Object#notify notify}, and {@link
@@ -834,74 +1117,80 @@
          * affected. However it is essentially always an error to
          * invoke a condition waiting method when the current thread
          * has also acquired read locks, since other threads that
-         * could unblock it will not be able to access the write
+         * could unblock it will not be able to acquire the write
          * lock.)
          *
-         * <li>When the condition {@link Condition#await() waiting}
+         * <li>When the condition {@linkplain Condition#await() waiting}
          * methods are called the write lock is released and, before
          * they return, the write lock is reacquired and the lock hold
          * count restored to what it was when the method was called.
          *
-         * <li>If a thread is {@link Thread#interrupt interrupted} while
+         * <li>If a thread is {@linkplain Thread#interrupt interrupted} while
          * waiting then the wait will terminate, an {@link
          * InterruptedException} will be thrown, and the thread's
          * interrupted status will be cleared.
          *
-         * <li> Waiting threads are signalled in FIFO order
+         * <li> Waiting threads are signalled in FIFO order.
          *
          * <li>The ordering of lock reacquisition for threads returning
          * from waiting methods is the same as for threads initially
          * acquiring the lock, which is in the default case not specified,
          * but for <em>fair</em> locks favors those threads that have been
          * waiting the longest.
-         * 
+         *
          * </ul>
+         *
          * @return the Condition object
          */
-        public Condition newCondition() { 
+        public Condition newCondition() {
             return sync.newCondition();
         }
 
         /**
          * Returns a string identifying this lock, as well as its lock
          * state.  The state, in brackets includes either the String
-         * &quot;Unlocked&quot; or the String &quot;Locked by&quot;
-         * followed by the {@link Thread#getName} of the owning thread.
-         * @return a string identifying this lock, as well as its lock state.
+         * {@code "Unlocked"} or the String {@code "Locked by"}
+         * followed by the {@linkplain Thread#getName name} of the owning thread.
+         *
+         * @return a string identifying this lock, as well as its lock state
          */
         public String toString() {
-            Thread owner = sync.getOwner();
-            return super.toString() + ((owner == null) ?
+            Thread o = sync.getOwner();
+            return super.toString() + ((o == null) ?
                                        "[Unlocked]" :
-                                       "[Locked by thread " + owner.getName() + "]");
+                                       "[Locked by thread " + o.getName() + "]");
         }
 
     }
 
-
     // Instrumentation and status
 
     /**
-     * Returns true if this lock has fairness set true.
-     * @return true if this lock has fairness set true.
+     * Returns {@code true} if this lock has fairness set true.
+     *
+     * @return {@code true} if this lock has fairness set true
      */
     public final boolean isFair() {
         return sync instanceof FairSync;
     }
 
     /**
-     * Returns the thread that currently owns the exclusive lock, or
-     * <tt>null</tt> if not owned. Note that the owner may be
-     * momentarily <tt>null</tt> even if there are threads trying to
-     * acquire the lock but have not yet done so.  This method is
-     * designed to facilitate construction of subclasses that provide
-     * more extensive lock monitoring facilities.
-     * @return the owner, or <tt>null</tt> if not owned.
+     * Returns the thread that currently owns the write lock, or
+     * {@code null} if not owned. When this method is called by a
+     * thread that is not the owner, the return value reflects a
+     * best-effort approximation of current lock status. For example,
+     * the owner may be momentarily {@code null} even if there are
+     * threads trying to acquire the lock but have not yet done so.
+     * This method is designed to facilitate construction of
+     * subclasses that provide more extensive lock monitoring
+     * facilities.
+     *
+     * @return the owner, or {@code null} if not owned
      */
     protected Thread getOwner() {
         return sync.getOwner();
     }
-    
+
     /**
      * Queries the number of read locks held for this lock. This
      * method is designed for use in monitoring system state, not for
@@ -916,17 +1205,19 @@
      * Queries if the write lock is held by any thread. This method is
      * designed for use in monitoring system state, not for
      * synchronization control.
-     * @return <tt>true</tt> if any thread holds write lock and 
-     * <tt>false</tt> otherwise.
+     *
+     * @return {@code true} if any thread holds the write lock and
+     *         {@code false} otherwise
      */
     public boolean isWriteLocked() {
         return sync.isWriteLocked();
     }
 
     /**
-     * Queries if the write lock is held by the current thread. 
-     * @return <tt>true</tt> if current thread holds this lock and 
-     * <tt>false</tt> otherwise.
+     * Queries if the write lock is held by the current thread.
+     *
+     * @return {@code true} if the current thread holds the write lock and
+     *         {@code false} otherwise
      */
     public boolean isWriteLockedByCurrentThread() {
         return sync.isHeldExclusively();
@@ -937,8 +1228,8 @@
      * current thread.  A writer thread has a hold on a lock for
      * each lock action that is not matched by an unlock action.
      *
-     * @return the number of holds on this lock by the current thread,
-     * or zero if this lock is not held by the current thread.
+     * @return the number of holds on the write lock by the current thread,
+     *         or zero if the write lock is not held by the current thread
      */
     public int getWriteHoldCount() {
         return sync.getWriteHoldCount();
@@ -952,6 +1243,7 @@
      * returned collection are in no particular order.  This method is
      * designed to facilitate construction of subclasses that provide
      * more extensive lock monitoring facilities.
+     *
      * @return the collection of threads
      */
     protected Collection<Thread> getQueuedWriterThreads() {
@@ -966,6 +1258,7 @@
      * returned collection are in no particular order.  This method is
      * designed to facilitate construction of subclasses that provide
      * more extensive lock monitoring facilities.
+     *
      * @return the collection of threads
      */
     protected Collection<Thread> getQueuedReaderThreads() {
@@ -973,41 +1266,42 @@
     }
 
     /**
-     * Queries whether any threads are waiting to acquire. Note that
-     * because cancellations may occur at any time, a <tt>true</tt>
-     * return does not guarantee that any other thread will ever
-     * acquire.  This method is designed primarily for use in
-     * monitoring of the system state.
+     * Queries whether any threads are waiting to acquire the read or
+     * write lock. Note that because cancellations may occur at any
+     * time, a {@code true} return does not guarantee that any other
+     * thread will ever acquire a lock.  This method is designed
+     * primarily for use in monitoring of the system state.
      *
-     * @return true if there may be other threads waiting to acquire
-     * the lock.
+     * @return {@code true} if there may be other threads waiting to
+     *         acquire the lock
      */
-    public final boolean hasQueuedThreads() { 
+    public final boolean hasQueuedThreads() {
         return sync.hasQueuedThreads();
     }
 
     /**
-     * Queries whether the given thread is waiting to acquire this
-     * lock. Note that because cancellations may occur at any time, a
-     * <tt>true</tt> return does not guarantee that this thread
-     * will ever acquire.  This method is designed primarily for use
-     * in monitoring of the system state.
+     * Queries whether the given thread is waiting to acquire either
+     * the read or write lock. Note that because cancellations may
+     * occur at any time, a {@code true} return does not guarantee
+     * that this thread will ever acquire a lock.  This method is
+     * designed primarily for use in monitoring of the system state.
      *
      * @param thread the thread
-     * @return true if the given thread is queued waiting for this lock.
-     * @throws NullPointerException if thread is null
+     * @return {@code true} if the given thread is queued waiting for this lock
+     * @throws NullPointerException if the thread is null
      */
-    public final boolean hasQueuedThread(Thread thread) { 
+    public final boolean hasQueuedThread(Thread thread) {
         return sync.isQueued(thread);
     }
 
     /**
-     * Returns an estimate of the number of threads waiting to
-     * acquire.  The value is only an estimate because the number of
-     * threads may change dynamically while this method traverses
-     * internal data structures.  This method is designed for use in
-     * monitoring of the system state, not for synchronization
-     * control.
+     * Returns an estimate of the number of threads waiting to acquire
+     * either the read or write lock.  The value is only an estimate
+     * because the number of threads may change dynamically while this
+     * method traverses internal data structures.  This method is
+     * designed for use in monitoring of the system state, not for
+     * synchronization control.
+     *
      * @return the estimated number of threads waiting for this lock
      */
     public final int getQueueLength() {
@@ -1016,12 +1310,13 @@
 
     /**
      * Returns a collection containing threads that may be waiting to
-     * acquire.  Because the actual set of threads may change
-     * dynamically while constructing this result, the returned
-     * collection is only a best-effort estimate.  The elements of the
-     * returned collection are in no particular order.  This method is
-     * designed to facilitate construction of subclasses that provide
-     * more extensive monitoring facilities.
+     * acquire either the read or write lock.  Because the actual set
+     * of threads may change dynamically while constructing this
+     * result, the returned collection is only a best-effort estimate.
+     * The elements of the returned collection are in no particular
+     * order.  This method is designed to facilitate construction of
+     * subclasses that provide more extensive monitoring facilities.
+     *
      * @return the collection of threads
      */
     protected Collection<Thread> getQueuedThreads() {
@@ -1031,18 +1326,18 @@
     /**
      * Queries whether any threads are waiting on the given condition
      * associated with the write lock. Note that because timeouts and
-     * interrupts may occur at any time, a <tt>true</tt> return does
-     * not guarantee that a future <tt>signal</tt> will awaken any
+     * interrupts may occur at any time, a {@code true} return does
+     * not guarantee that a future {@code signal} will awaken any
      * threads.  This method is designed primarily for use in
      * monitoring of the system state.
+     *
      * @param condition the condition
-     * @return <tt>true</tt> if there are any waiting threads.
-     * @throws IllegalMonitorStateException if this lock 
-     * is not held
+     * @return {@code true} if there are any waiting threads
+     * @throws IllegalMonitorStateException if this lock is not held
      * @throws IllegalArgumentException if the given condition is
-     * not associated with this lock
-     * @throws NullPointerException if condition null
-     */ 
+     *         not associated with this lock
+     * @throws NullPointerException if the condition is null
+     */
     public boolean hasWaiters(Condition condition) {
         if (condition == null)
             throw new NullPointerException();
@@ -1058,14 +1353,14 @@
      * serves only as an upper bound on the actual number of waiters.
      * This method is designed for use in monitoring of the system
      * state, not for synchronization control.
+     *
      * @param condition the condition
-     * @return the estimated number of waiting threads.
-     * @throws IllegalMonitorStateException if this lock 
-     * is not held
+     * @return the estimated number of waiting threads
+     * @throws IllegalMonitorStateException if this lock is not held
      * @throws IllegalArgumentException if the given condition is
-     * not associated with this lock
-     * @throws NullPointerException if condition null
-     */ 
+     *         not associated with this lock
+     * @throws NullPointerException if the condition is null
+     */
     public int getWaitQueueLength(Condition condition) {
         if (condition == null)
             throw new NullPointerException();
@@ -1083,13 +1378,13 @@
      * are in no particular order.  This method is designed to
      * facilitate construction of subclasses that provide more
      * extensive condition monitoring facilities.
+     *
      * @param condition the condition
      * @return the collection of threads
-     * @throws IllegalMonitorStateException if this lock 
-     * is not held
+     * @throws IllegalMonitorStateException if this lock is not held
      * @throws IllegalArgumentException if the given condition is
-     * not associated with this lock
-     * @throws NullPointerException if condition null
+     *         not associated with this lock
+     * @throws NullPointerException if the condition is null
      */
     protected Collection<Thread> getWaitingThreads(Condition condition) {
         if (condition == null)
@@ -1101,18 +1396,19 @@
 
     /**
      * Returns a string identifying this lock, as well as its lock state.
-     * The state, in brackets, includes the String &quot;Write locks =&quot;
-     * follwed by the number of reentrantly held write locks, and the
-     * String &quot;Read locks =&quot; followed by the number of held
+     * The state, in brackets, includes the String {@code "Write locks ="}
+     * followed by the number of reentrantly held write locks, and the
+     * String {@code "Read locks ="} followed by the number of held
      * read locks.
-     * @return a string identifying this lock, as well as its lock state.
+     *
+     * @return a string identifying this lock, as well as its lock state
      */
     public String toString() {
         int c = sync.getCount();
-        int w = exclusiveCount(c);
-        int r = sharedCount(c);
-        
-        return super.toString() + 
+        int w = Sync.exclusiveCount(c);
+        int r = Sync.sharedCount(c);
+
+        return super.toString() +
             "[Write locks = " + w + ", Read locks = " + r + "]";
     }
 
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/locks/package-info.java b/libcore/concurrent/src/main/java/java/util/concurrent/locks/package-info.java
new file mode 100644
index 0000000..12560af
--- /dev/null
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/locks/package-info.java
@@ -0,0 +1,47 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+/**
+ * Interfaces and classes providing a framework for locking and waiting
+ * for conditions that is distinct from built-in synchronization and
+ * monitors.  The framework permits much greater flexibility in the use of
+ * locks and conditions, at the expense of more awkward syntax.
+ *
+ * <p>The {@link java.util.concurrent.locks.Lock} interface supports
+ * locking disciplines that differ in semantics (reentrant, fair, etc),
+ * and that can be used in non-block-structured contexts including
+ * hand-over-hand and lock reordering algorithms.  The main implementation
+ * is {@link java.util.concurrent.locks.ReentrantLock}.
+ *
+ * <p>The {@link java.util.concurrent.locks.ReadWriteLock} interface
+ * similarly defines locks that may be shared among readers but are
+ * exclusive to writers.  Only a single implementation, {@link
+ * java.util.concurrent.locks.ReentrantReadWriteLock}, is provided, since
+ * it covers most standard usage contexts.  But programmers may create
+ * their own implementations to cover nonstandard requirements.
+ *
+ * <p>The {@link java.util.concurrent.locks.Condition} interface
+ * describes condition variables that may be associated with Locks.
+ * These are similar in usage to the implicit monitors accessed using
+ * {@code Object.wait}, but offer extended capabilities.
+ * In particular, multiple {@code Condition} objects may be associated
+ * with a single {@code Lock}.  To avoid compatibility issues, the
+ * names of {@code Condition} methods are different from the
+ * corresponding {@code Object} versions.
+ *
+ * <p>The {@link java.util.concurrent.locks.AbstractQueuedSynchronizer}
+ * class serves as a useful superclass for defining locks and other
+ * synchronizers that rely on queuing blocked threads.  The {@link
+ * java.util.concurrent.locks.AbstractQueuedLongSynchronizer} class
+ * provides the same functionality but extends support to 64 bits of
+ * synchronization state. The {@link java.util.concurrent.locks.LockSupport}
+ * class provides lower-level blocking and unblocking support that is
+ * useful for those developers implementing their own customized lock
+ * classes.
+ *
+ * @since 1.5
+ */
+package java.util.concurrent.locks;
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/locks/package.html b/libcore/concurrent/src/main/java/java/util/concurrent/locks/package.html
deleted file mode 100644
index 1cc156f..0000000
--- a/libcore/concurrent/src/main/java/java/util/concurrent/locks/package.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html> <head>
-<title>Locks</title>
-</head>
-
-<body>
-
-Interfaces and classes providing a framework for locking and waiting
-for conditions that is distinct from built-in synchronization and
-monitors. The framework permits much greater flexibility in the use of
-locks and conditions, at the expense of more awkward syntax.
-
-<p> The {@link java.util.concurrent.locks.Lock} interface supports
-locking disciplines that differ in semantics (reentrant, fair, etc),
-and that can be used in non-block-structured contexts including
-hand-over-hand and lock reordering algorithms. The main implementation
-is {@link java.util.concurrent.locks.ReentrantLock}. 
-
-<p> The {@link java.util.concurrent.locks.ReadWriteLock} interface
-similarly defines locks that may be shared among readers but are
-exclusive to writers.  Only a single implementation, {@link
-java.util.concurrent.locks.ReentrantReadWriteLock}, is provided, since
-it covers most standard usage contexts. But programmers may create
-their own implementations to cover nonstandard requirements.
-
-<p> The {@link java.util.concurrent.locks.Condition} interface
-describes condition variables that may be associated with Locks.
-These are similar in usage to the implicit monitors accessed using
-<tt>Object.wait</tt>, but offer extended capabilities.  In particular,
-multiple <tt>Condition</tt> objects may be associated with a single
-<tt>Lock</tt>.  To avoid compatibility issues, the names of
-<tt>Condition</tt> methods are different than the corresponding
-<tt>Object</tt> versions.
-
-<p> The {@link java.util.concurrent.locks.AbstractQueuedSynchronizer}
-class serves as a useful superclass for defining locks and other
-synchronizers that rely on queuing blocked threads.  The {@link
-java.util.concurrent.locks.LockSupport} class provides lower-level
-blocking and unblocking support that is useful for those developers
-implementing their own customized lock classes.
-
-@since Android 1.0
-
-</body> </html>
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/package-info.java b/libcore/concurrent/src/main/java/java/util/concurrent/package-info.java
new file mode 100644
index 0000000..f77e16a
--- /dev/null
+++ b/libcore/concurrent/src/main/java/java/util/concurrent/package-info.java
@@ -0,0 +1,233 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+/**
+ * Utility classes commonly useful in concurrent programming.  This
+ * package includes a few small standardized extensible frameworks, as
+ * well as some classes that provide useful functionality and are
+ * otherwise tedious or difficult to implement.  Here are brief
+ * descriptions of the main components.  See also the
+ * {@link java.util.concurrent.locks} and
+ * {@link java.util.concurrent.atomic} packages.
+ *
+ * <h2>Executors</h2>
+ *
+ * <b>Interfaces.</b>
+ *
+ * {@link java.util.concurrent.Executor} is a simple standardized
+ * interface for defining custom thread-like subsystems, including
+ * thread pools, asynchronous IO, and lightweight task frameworks.
+ * Depending on which concrete Executor class is being used, tasks may
+ * execute in a newly created thread, an existing task-execution thread,
+ * or the thread calling {@link java.util.concurrent.Executor#execute
+ * execute}, and may execute sequentially or concurrently.
+ *
+ * {@link java.util.concurrent.ExecutorService} provides a more
+ * complete asynchronous task execution framework.  An
+ * ExecutorService manages queuing and scheduling of tasks,
+ * and allows controlled shutdown.
+ *
+ * The {@link java.util.concurrent.ScheduledExecutorService}
+ * subinterface and associated interfaces add support for
+ * delayed and periodic task execution.  ExecutorServices
+ * provide methods arranging asynchronous execution of any
+ * function expressed as {@link java.util.concurrent.Callable},
+ * the result-bearing analog of {@link java.lang.Runnable}.
+ *
+ * A {@link java.util.concurrent.Future} returns the results of
+ * a function, allows determination of whether execution has
+ * completed, and provides a means to cancel execution.
+ *
+ * A {@link java.util.concurrent.RunnableFuture} is a {@code Future}
+ * that possesses a {@code run} method that upon execution,
+ * sets its results.
+ *
+ * <p>
+ *
+ * <b>Implementations.</b>
+ *
+ * Classes {@link java.util.concurrent.ThreadPoolExecutor} and
+ * {@link java.util.concurrent.ScheduledThreadPoolExecutor}
+ * provide tunable, flexible thread pools.
+ *
+ * The {@link java.util.concurrent.Executors} class provides
+ * factory methods for the most common kinds and configurations
+ * of Executors, as well as a few utility methods for using
+ * them.  Other utilities based on {@code Executors} include the
+ * concrete class {@link java.util.concurrent.FutureTask}
+ * providing a common extensible implementation of Futures, and
+ * {@link java.util.concurrent.ExecutorCompletionService}, that
+ * assists in coordinating the processing of groups of
+ * asynchronous tasks.
+ *
+ * <h2>Queues</h2>
+ *
+ * The {@link java.util.concurrent.ConcurrentLinkedQueue} class
+ * supplies an efficient scalable thread-safe non-blocking FIFO
+ * queue.
+ *
+ * <p>Five implementations in {@code java.util.concurrent} support
+ * the extended {@link java.util.concurrent.BlockingQueue}
+ * interface, that defines blocking versions of put and take:
+ * {@link java.util.concurrent.LinkedBlockingQueue},
+ * {@link java.util.concurrent.ArrayBlockingQueue},
+ * {@link java.util.concurrent.SynchronousQueue},
+ * {@link java.util.concurrent.PriorityBlockingQueue}, and
+ * {@link java.util.concurrent.DelayQueue}.
+ * The different classes cover the most common usage contexts
+ * for producer-consumer, messaging, parallel tasking, and
+ * related concurrent designs.
+ *
+ * <h2>Timing</h2>
+ *
+ * The {@link java.util.concurrent.TimeUnit} class provides
+ * multiple granularities (including nanoseconds) for
+ * specifying and controlling time-out based operations.  Most
+ * classes in the package contain operations based on time-outs
+ * in addition to indefinite waits.  In all cases that
+ * time-outs are used, the time-out specifies the minimum time
+ * that the method should wait before indicating that it
+ * timed-out.  Implementations make a &quot;best effort&quot;
+ * to detect time-outs as soon as possible after they occur.
+ * However, an indefinite amount of time may elapse between a
+ * time-out being detected and a thread actually executing
+ * again after that time-out.  All methods that accept timeout
+ * parameters treat values less than or equal to zero to mean
+ * not to wait at all.  To wait "forever", you can use a value
+ * of {@code Long.MAX_VALUE}.
+ *
+ * <h2>Synchronizers</h2>
+ *
+ * Four classes aid common special-purpose synchronization idioms.
+ * {@link java.util.concurrent.Semaphore} is a classic concurrency tool.
+ * {@link java.util.concurrent.CountDownLatch} is a very simple yet very
+ * common utility for blocking until a given number of signals, events,
+ * or conditions hold.  A {@link java.util.concurrent.CyclicBarrier} is a
+ * resettable multiway synchronization point useful in some styles of
+ * parallel programming.  An {@link java.util.concurrent.Exchanger} allows
+ * two threads to exchange objects at a rendezvous point, and is useful
+ * in several pipeline designs.
+ *
+ * <h2>Concurrent Collections</h2>
+ *
+ * Besides Queues, this package supplies Collection implementations
+ * designed for use in multithreaded contexts:
+ * {@link java.util.concurrent.ConcurrentHashMap},
+ * {@link java.util.concurrent.CopyOnWriteArrayList}, and
+ * {@link java.util.concurrent.CopyOnWriteArraySet}.
+ * When many threads are expected to access a given collection, a
+ * {@code ConcurrentHashMap} is normally preferable to a synchronized
+ * {@code HashMap}. A {@code CopyOnWriteArrayList} is preferable to a
+ * synchronized {@code ArrayList} when the expected number of reads and
+ * traversals greatly outnumber the number of updates to a list.
+
+ * <p>The "Concurrent" prefix used with some classes in this package
+ * is a shorthand indicating several differences from similar
+ * "synchronized" classes.  For example {@code java.util.Hashtable} and
+ * {@code Collections.synchronizedMap(new HashMap())} are
+ * synchronized.  But {@link
+ * java.util.concurrent.ConcurrentHashMap} is "concurrent".  A
+ * concurrent collection is thread-safe, but not governed by a
+ * single exclusion lock.  In the particular case of
+ * ConcurrentHashMap, it safely permits any number of
+ * concurrent reads as well as a tunable number of concurrent
+ * writes.  "Synchronized" classes can be useful when you need
+ * to prevent all access to a collection via a single lock, at
+ * the expense of poorer scalability.  In other cases in which
+ * multiple threads are expected to access a common collection,
+ * "concurrent" versions are normally preferable.  And
+ * unsynchronized collections are preferable when either
+ * collections are unshared, or are accessible only when
+ * holding other locks.
+ *
+ * <p>Most concurrent Collection implementations (including most
+ * Queues) also differ from the usual java.util conventions in that
+ * their Iterators provide <em>weakly consistent</em> rather than
+ * fast-fail traversal.  A weakly consistent iterator is thread-safe,
+ * but does not necessarily freeze the collection while iterating, so
+ * it may (or may not) reflect any updates since the iterator was
+ * created.
+ *
+ * <h2><a name="MemoryVisibility">Memory Consistency Properties</a></h2>
+ *
+ * <a href="http://java.sun.com/docs/books/jls/third_edition/html/memory.html">
+ * Chapter 17 of the Java Language Specification</a> defines the
+ * <i>happens-before</i> relation on memory operations such as reads and
+ * writes of shared variables.  The results of a write by one thread are
+ * guaranteed to be visible to a read by another thread only if the write
+ * operation <i>happens-before</i> the read operation.  The
+ * {@code synchronized} and {@code volatile} constructs, as well as the
+ * {@code Thread.start()} and {@code Thread.join()} methods, can form
+ * <i>happens-before</i> relationships.  In particular:
+ *
+ * <ul>
+ *   <li>Each action in a thread <i>happens-before</i> every action in that
+ *   thread that comes later in the program's order.
+ *
+ *   <li>An unlock ({@code synchronized} block or method exit) of a
+ *   monitor <i>happens-before</i> every subsequent lock ({@code synchronized}
+ *   block or method entry) of that same monitor.  And because
+ *   the <i>happens-before</i> relation is transitive, all actions
+ *   of a thread prior to unlocking <i>happen-before</i> all actions
+ *   subsequent to any thread locking that monitor.
+ *
+ *   <li>A write to a {@code volatile} field <i>happens-before</i> every
+ *   subsequent read of that same field.  Writes and reads of
+ *   {@code volatile} fields have similar memory consistency effects
+ *   as entering and exiting monitors, but do <em>not</em> entail
+ *   mutual exclusion locking.
+ *
+ *   <li>A call to {@code start} on a thread <i>happens-before</i> any
+ *   action in the started thread.
+ *
+ *   <li>All actions in a thread <i>happen-before</i> any other thread
+ *   successfully returns from a {@code join} on that thread.
+ *
+ * </ul>
+ *
+ *
+ * The methods of all classes in {@code java.util.concurrent} and its
+ * subpackages extend these guarantees to higher-level
+ * synchronization.  In particular:
+ *
+ * <ul>
+ *
+ *   <li>Actions in a thread prior to placing an object into any concurrent
+ *   collection <i>happen-before</i> actions subsequent to the access or
+ *   removal of that element from the collection in another thread.
+ *
+ *   <li>Actions in a thread prior to the submission of a {@code Runnable}
+ *   to an {@code Executor} <i>happen-before</i> its execution begins.
+ *   Similarly for {@code Callables} submitted to an {@code ExecutorService}.
+ *
+ *   <li>Actions taken by the asynchronous computation represented by a
+ *   {@code Future} <i>happen-before</i> actions subsequent to the
+ *   retrieval of the result via {@code Future.get()} in another thread.
+ *
+ *   <li>Actions prior to "releasing" synchronizer methods such as
+ *   {@code Lock.unlock}, {@code Semaphore.release}, and
+ *   {@code CountDownLatch.countDown} <i>happen-before</i> actions
+ *   subsequent to a successful "acquiring" method such as
+ *   {@code Lock.lock}, {@code Semaphore.acquire},
+ *   {@code Condition.await}, and {@code CountDownLatch.await} on the
+ *   same synchronizer object in another thread.
+ *
+ *   <li>For each pair of threads that successfully exchange objects via
+ *   an {@code Exchanger}, actions prior to the {@code exchange()}
+ *   in each thread <i>happen-before</i> those subsequent to the
+ *   corresponding {@code exchange()} in another thread.
+ *
+ *   <li>Actions prior to calling {@code CyclicBarrier.await}
+ *   <i>happen-before</i> actions performed by the barrier action, and
+ *   actions performed by the barrier action <i>happen-before</i> actions
+ *   subsequent to a successful return from the corresponding {@code await}
+ *   in other threads.
+ *
+ * </ul>
+ *
+ * @since 1.5
+ */
+package java.util.concurrent;
diff --git a/libcore/concurrent/src/main/java/java/util/concurrent/package.html b/libcore/concurrent/src/main/java/java/util/concurrent/package.html
deleted file mode 100644
index a5bb8d2..0000000
--- a/libcore/concurrent/src/main/java/java/util/concurrent/package.html
+++ /dev/null
@@ -1,125 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html> <head>
-<title>Concurrency Utilities</title>
-</head>
-
-<body>
-
-<p> Utility classes commonly useful in concurrent programming.  This
-package includes a few small standardized extensible frameworks, as
-well as some classes that provide useful functionality and are
-otherwise tedious or difficult to implement.  Here are brief
-descriptions of the main components. See also the <tt>locks</tt> and
-<tt>atomic</tt> packages.
-
-<h2>Executors</h2>
-
-<b>Interfaces.</b> {@link java.util.concurrent.Executor} is a simple
-standardized interface for defining custom thread-like subsystems,
-including thread pools, asynchronous IO, and lightweight task
-frameworks.  Depending on which concrete Executor class is being used,
-tasks may execute in a newly created thread, an existing
-task-execution thread, or the thread calling <tt>execute()</tt>, and
-may execute sequentially or concurrently.  {@link
-java.util.concurrent.ExecutorService} provides a more complete
-asynchronous task execution framework.  An ExecutorService manages
-queuing and scheduling of tasks, and allows controlled shutdown.  The
-{@link java.util.concurrent.ScheduledExecutorService} subinterface
-adds support for delayed and periodic task execution.
-ExecutorServices provide methods arranging asynchronous execution of
-any function expressed as {@link java.util.concurrent.Callable}, the
-result-bearing analog of {@link java.lang.Runnable}.  A {@link
-java.util.concurrent.Future} returns the results of a function, allows
-determination of whether execution has completed, and provides a means to
-cancel execution.
-
-<p>
-
-<b>Implementations.</b> Classes {@link
-java.util.concurrent.ThreadPoolExecutor} and {@link
-java.util.concurrent.ScheduledThreadPoolExecutor} provide tunable,
-flexible thread pools. The {@link java.util.concurrent.Executors}
-class provides factory methods for the most common kinds and
-configurations of Executors, as well as a few utility methods for
-using them. Other utilities based on Executors include the concrete
-class {@link java.util.concurrent.FutureTask} providing a common
-extensible implementation of Futures, and {@link
-java.util.concurrent.ExecutorCompletionService}, that assists in
-coordinating the processing of groups of asynchronous tasks.
-
-<h2>Queues</h2>
-
-The java.util.concurrent {@link
-java.util.concurrent.ConcurrentLinkedQueue} class supplies an
-efficient scalable thread-safe non-blocking FIFO queue.  Five
-implementations in java.util.concurrent support the extended {@link
-java.util.concurrent.BlockingQueue} interface, that defines blocking
-versions of put and take: {@link
-java.util.concurrent.LinkedBlockingQueue}, {@link
-java.util.concurrent.ArrayBlockingQueue}, {@link
-java.util.concurrent.SynchronousQueue}, {@link
-java.util.concurrent.PriorityBlockingQueue}, and {@link
-java.util.concurrent.DelayQueue}. The different classes cover the most
-common usage contexts for producer-consumer, messaging, parallel
-tasking, and related concurrent designs.
-
-
-<h2>Timing</h2>
-
-The {@link java.util.concurrent.TimeUnit} class provides multiple
-granularities (including nanoseconds) for specifying and controlling
-time-out based operations. Most classes in the package contain
-operations based on time-outs in addition to indefinite waits.  In all
-cases that time-outs are used, the time-out specifies the minimum time
-that the method should wait before indicating that it
-timed-out. Implementations make a &quot;best effort&quot; to detect
-time-outs as soon as possible after they occur. However, an indefinite
-amount of time may elapse between a time-out being detected and a
-thread actually executing again after that time-out.
-
-<h2>Synchronizers</h2>
-
-Four classes aid common special-purpose synchronization idioms.
-{@link java.util.concurrent.Semaphore} is a classic concurrency tool.
-{@link java.util.concurrent.CountDownLatch} is a very simple yet very
-common utility for blocking until a given number of signals, events,
-or conditions hold.  A {@link java.util.concurrent.CyclicBarrier} is a
-resettable multiway synchronization point useful in some styles of
-parallel programming. An {@link java.util.concurrent.Exchanger} allows
-two threads to exchange objects at a rendezvous point, and is useful
-in several pipeline designs.
-
-<h2>Concurrent Collections</h2>
-
-Besides Queues, this package supplies a few Collection implementations
-designed for use in multithreaded contexts: {@link
-java.util.concurrent.ConcurrentHashMap}, {@link
-java.util.concurrent.CopyOnWriteArrayList}, and {@link
-java.util.concurrent.CopyOnWriteArraySet}.
-
-<p>The "Concurrent" prefix used with some classes in this package is a
-shorthand indicating several differences from similar "synchronized"
-classes. For example <tt>java.util.Hashtable</tt> and
-<tt>Collections.synchronizedMap(new HashMap())</tt> are
-synchronized. But {@link java.util.concurrent.ConcurrentHashMap} is
-"concurrent".  A concurrent collection is thread-safe, but not
-governed by a single exclusion lock. In the particular case of
-ConcurrentHashMap, it safely permits any number of concurrent reads as
-well as a tunable number of concurrent writes.  "Synchronized" classes
-can be useful when you need to prevent all access to a collection via
-a single lock, at the expense of poorer scalability. In other cases in
-which multiple threads are expected to access a common collection,
-"concurrent" versions are normally preferable. And unsynchronized
-collections are preferable when either collections are unshared, or
-are accessible only when holding other locks.
-
-<p> Most concurrent Collection implementations (including most Queues)
-also differ from the usual java.util conventions in that their Iterators
-provide <em>weakly consistent</em> rather than fast-fail traversal. A
-weakly consistent iterator is thread-safe, but does not necessarily
-freeze the collection while iterating, so it may (or may not) reflect
-any updates since the iterator was created.
-
-@since Android 1.0
-
-</body> </html>
diff --git a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AbstractQueuedSynchronizerTest.java b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AbstractQueuedSynchronizerTest.java
index 7102c14..db89645 100644
--- a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AbstractQueuedSynchronizerTest.java
+++ b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AbstractQueuedSynchronizerTest.java
@@ -462,7 +462,9 @@
         Thread t = new Thread(new InterruptedSyncRunnable(sync));
         try {
             t.start();
+            Thread.sleep(SHORT_DELAY_MS);
             t.interrupt();
+            Thread.sleep(SHORT_DELAY_MS);
             sync.release(1);
             t.join();
         } catch(Exception e){
@@ -951,7 +953,6 @@
             sync.acquire(1);
             c.signal();
             sync.release(1);
-            assert(t.isInterrupted());
             t.join(SHORT_DELAY_MS);
             assertFalse(t.isAlive());
         }
diff --git a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ArrayBlockingQueueTest.java b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ArrayBlockingQueueTest.java
index da6988f..b650ede 100755
--- a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ArrayBlockingQueueTest.java
+++ b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ArrayBlockingQueueTest.java
@@ -651,6 +651,7 @@
         assertEquals(SIZE, q.remainingCapacity());
         q.add(one);
         assertFalse(q.isEmpty());
+        assertTrue(q.contains(one));
         q.clear();
         assertTrue(q.isEmpty());
     }
@@ -971,6 +972,17 @@
         assertEquals(l.size(), SIZE);
         for (int i = 0; i < SIZE; ++i) 
             assertEquals(l.get(i), new Integer(i));
+        q.add(zero);
+        q.add(one);
+        assertFalse(q.isEmpty());
+        assertTrue(q.contains(zero));
+        assertTrue(q.contains(one));
+        l.clear();
+        q.drainTo(l);
+        assertEquals(q.size(), 0);
+        assertEquals(l.size(), 2);
+        for (int i = 0; i < 2; ++i) 
+            assertEquals(l.get(i), new Integer(i));
     }
 
     /**
@@ -1029,15 +1041,18 @@
      * drainTo(c, n) empties first max {n, size} elements of queue into c
      */ 
     public void testDrainToN() {
+        ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE*2);
         for (int i = 0; i < SIZE + 2; ++i) {
-            ArrayBlockingQueue q = populatedQueue(SIZE);
+            for(int j = 0; j < SIZE; j++)
+                assertTrue(q.offer(new Integer(j)));
             ArrayList l = new ArrayList();
             q.drainTo(l, i);
             int k = (i < SIZE)? i : SIZE;
-            assertEquals(q.size(), SIZE-k);
             assertEquals(l.size(), k);
+            assertEquals(q.size(), SIZE-k);
             for (int j = 0; j < k; ++j) 
                 assertEquals(l.get(j), new Integer(j));
+            while (q.poll() != null) ;
         }
     }
 
diff --git a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicIntegerFieldUpdaterTest.java b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicIntegerFieldUpdaterTest.java
index 03fd2c8..4c3ecb4 100755
--- a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicIntegerFieldUpdaterTest.java
+++ b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicIntegerFieldUpdaterTest.java
@@ -62,6 +62,27 @@
         catch (RuntimeException rt) {}
     }
 
+    static class Base {
+        protected volatile int f = 0;
+    }
+    static class Sub1 extends Base {
+        AtomicIntegerFieldUpdater<Base> fUpdater
+                = AtomicIntegerFieldUpdater.newUpdater(Base.class, "f");
+    }
+    static class Sub2 extends Base {}
+
+    public void testProtectedFieldOnAnotherSubtype() {
+        Sub1 sub1 = new Sub1();
+        Sub2 sub2 = new Sub2();
+
+        sub1.fUpdater.set(sub1, 1);
+        try {
+            sub1.fUpdater.set(sub2, 2);
+            shouldThrow();
+        } 
+        catch (RuntimeException rt) {}
+    }
+
     /**
      *  get returns the last value set or assigned
      */
@@ -80,6 +101,7 @@
         assertEquals(-3,a.get(this));
         
     }
+
     /**
      * compareAndSet succeeds in changing value if equal to expected else fails
      */
diff --git a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicIntegerTest.java b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicIntegerTest.java
index 1771d80..d484785 100755
--- a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicIntegerTest.java
+++ b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicIntegerTest.java
@@ -48,6 +48,7 @@
         assertEquals(-3,ai.get());
         
     }
+
     /**
      * compareAndSet succeeds in changing value if equal to expected else fails
      */
diff --git a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicLongFieldUpdaterTest.java b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicLongFieldUpdaterTest.java
index 8076f7b..9310795 100755
--- a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicLongFieldUpdaterTest.java
+++ b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicLongFieldUpdaterTest.java
@@ -29,7 +29,7 @@
      */
     public void testConstructor(){
         try{
-            AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> 
+            AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest>
                 a = AtomicLongFieldUpdater.newUpdater
                 (AtomicLongFieldUpdaterTest.class, "y");
             shouldThrow();
@@ -42,7 +42,7 @@
      */
     public void testConstructor2(){
         try{
-            AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> 
+            AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest>
                 a = AtomicLongFieldUpdater.newUpdater
                 (AtomicLongFieldUpdaterTest.class, "z");
             shouldThrow();
@@ -55,7 +55,7 @@
      */
     public void testConstructor3(){
         try{
-            AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> 
+            AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest>
                 a = AtomicLongFieldUpdater.newUpdater
                 (AtomicLongFieldUpdaterTest.class, "w");
             shouldThrow();
@@ -64,6 +64,27 @@
         catch (RuntimeException rt) {}
     }
 
+    static class Base {
+        protected volatile long f = 0;
+    }
+    static class Sub1 extends Base {
+        AtomicLongFieldUpdater<Base> fUpdater
+                = AtomicLongFieldUpdater.newUpdater(Base.class, "f");
+    }
+    static class Sub2 extends Base {}
+
+    public void testProtectedFieldOnAnotherSubtype() {
+        Sub1 sub1 = new Sub1();
+        Sub2 sub2 = new Sub2();
+
+        sub1.fUpdater.set(sub1, 1);
+        try {
+            sub1.fUpdater.set(sub2, 2);
+            shouldThrow();
+        }
+        catch (RuntimeException rt) {}
+    }
+
     /**
      *  get returns the last value set or assigned
      */
@@ -75,12 +96,12 @@
             return;
         }
         x = 1;
-        assertEquals(1,a.get(this));
-        a.set(this,2);
-        assertEquals(2,a.get(this));
-        a.set(this,-3);
-        assertEquals(-3,a.get(this));
-        
+	assertEquals(1,a.get(this));
+	a.set(this,2);
+	assertEquals(2,a.get(this));
+	a.set(this,-3);
+	assertEquals(-3,a.get(this));
+
     }
     /**
      * compareAndSet succeeds in changing value if equal to expected else fails
@@ -134,7 +155,7 @@
 
     /**
      * repeated weakCompareAndSet succeeds in changing value when equal
-     * to expected 
+     * to expected
      */
     public void testWeakCompareAndSet(){
         AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
diff --git a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicLongTest.java b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicLongTest.java
index 55b8a49..143c84a 100755
--- a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicLongTest.java
+++ b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicLongTest.java
@@ -48,6 +48,7 @@
         assertEquals(-3,ai.get());
         
     }
+
     /**
      * compareAndSet succeeds in changing value if equal to expected else fails
      */
diff --git a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceFieldUpdaterTest.java b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceFieldUpdaterTest.java
index 183ca21..feddce7 100755
--- a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceFieldUpdaterTest.java
+++ b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceFieldUpdaterTest.java
@@ -64,6 +64,27 @@
         catch (RuntimeException rt) {}
     }
 
+    static class Base {
+        protected volatile Object f = null;
+    }
+    static class Sub1 extends Base {
+        AtomicReferenceFieldUpdater<Base, Object> fUpdater
+                = AtomicReferenceFieldUpdater.newUpdater(Base.class, Object.class, "f");
+    }
+    static class Sub2 extends Base {}
+
+    public void testProtectedFieldOnAnotherSubtype() {
+        Sub1 sub1 = new Sub1();
+        Sub2 sub2 = new Sub2();
+
+        sub1.fUpdater.set(sub1, "f");
+        try {
+            sub1.fUpdater.set(sub2, "g");
+            shouldThrow();
+        }
+        catch (RuntimeException rt) {}
+    }
+
     /**
      *  get returns the last value set or assigned
      */
@@ -75,14 +96,11 @@
             return;
         }
         x = one;
-        assertEquals(one,a.get(this));
-        a.set(this,two);
-        assertEquals(two,a.get(this));
-        a.set(this,-3);
-        // BEGIN android-changed
-        assertEquals(new Integer(-3),a.get(this));
-        // END android-changed
-        
+	assertEquals(one,a.get(this));
+	a.set(this,two);
+	assertEquals(two,a.get(this));
+	a.set(this,m3);
+	assertEquals(m3,a.get(this));
     }
     /**
      * compareAndSet succeeds in changing value if equal to expected else fails
@@ -135,7 +153,7 @@
 
     /**
      * repeated weakCompareAndSet succeeds in changing value when equal
-     * to expected 
+     * to expected
      */
     public void testWeakCompareAndSet(){
         AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer>a;
diff --git a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceTest.java b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceTest.java
index 0aa48cd..33da30d 100755
--- a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceTest.java
+++ b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceTest.java
@@ -46,7 +46,7 @@
         assertEquals(two,ai.get());
         ai.set(m3);
         assertEquals(m3,ai.get());
-        
+
     }
     /**
      * compareAndSet succeeds in changing value if equal to expected else fails
@@ -86,7 +86,7 @@
 
     /**
      * repeated weakCompareAndSet succeeds in changing value when equal
-     * to expected 
+     * to expected
      */
     public void testWeakCompareAndSet(){
         AtomicReference ai = new AtomicReference(one);
diff --git a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentHashMapTest.java b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentHashMapTest.java
index 9b3ec52..d7f2210 100755
--- a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentHashMapTest.java
+++ b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentHashMapTest.java
@@ -16,59 +16,16 @@
 
 public class ConcurrentHashMapTest extends JSR166TestCase{
     public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());        
+        junit.textui.TestRunner.run (suite());
     }
     public static Test suite() {
         return new TestSuite(ConcurrentHashMapTest.class);
     }
-    // BEGIN android-added
-    static class MyConcurrentHashMap<V, K> extends ConcurrentHashMap<K, V>
-            implements Cloneable {
-
-        public MyConcurrentHashMap() {
-            super();
-        }
-
-        public MyConcurrentHashMap(int initialCapacity, float loadFactor,
-                int concurrencyLevel) {
-            super(initialCapacity, loadFactor, concurrencyLevel);
-        }
-
-        public MyConcurrentHashMap(int initialCapacity) {
-            super(initialCapacity);
-        }
-
-        public MyConcurrentHashMap(Map<? extends K, ? extends V> t) {
-            super(t);
-        }
-
-        @Override
-        protected Object clone() throws CloneNotSupportedException {
-            return super.clone();
-        }
-
-    }
 
     /**
      * Create a map from Integers 1-5 to Strings "A"-"E".
      */
-    private static MyConcurrentHashMap myMap5() {
-        MyConcurrentHashMap map = new MyConcurrentHashMap(5);
-        assertTrue(map.isEmpty());
-        map.put(one, "A");
-        map.put(two, "B");
-        map.put(three, "C");
-        map.put(four, "D");
-        map.put(five, "E");
-        assertFalse(map.isEmpty());
-        assertEquals(5, map.size());
-        return map;
-    }
-    // END android-added
-    /**
-     * Create a map from Integers 1-5 to Strings "A"-"E".
-     */
-    private static ConcurrentHashMap map5() {   
+    private static ConcurrentHashMap map5() {
         ConcurrentHashMap map = new ConcurrentHashMap(5);
         assertTrue(map.isEmpty());
         map.put(one, "A");
@@ -111,7 +68,7 @@
         assertTrue(map.contains("A"));
         assertFalse(map.contains("Z"));
     }
-    
+
     /**
      *  containsKey returns true for contained key
      */
@@ -126,8 +83,8 @@
      */
     public void testContainsValue() {
         ConcurrentHashMap map = map5();
-        assertTrue(map.contains("A"));
-        assertFalse(map.contains("Z"));
+	assertTrue(map.containsValue("A"));
+        assertFalse(map.containsValue("Z"));
     }
 
     /**
@@ -146,21 +103,6 @@
     }
 
     /**
-     *   Clone creates an equal map
-     */
-    public void testClone() {
-        // BEGIN android-changed
-        MyConcurrentHashMap map =myMap5();
-        try {
-            MyConcurrentHashMap m2 = (MyConcurrentHashMap)(map.clone());
-            assertEquals(map, m2);
-        } catch (CloneNotSupportedException e) {
-            fail("clone not supported");
-        }
-        // END android-changed
-    }
-
-    /**
      *  get returns the correct element at the given key,
      *  or null if not present
      */
@@ -210,6 +152,49 @@
     }
 
     /**
+     *  keySet.toArray returns contains all keys
+     */
+    public void testKeySetToArray() {
+        ConcurrentHashMap map = map5();
+	Set s = map.keySet();
+        Object[] ar = s.toArray();
+        assertTrue(s.containsAll(Arrays.asList(ar)));
+	assertEquals(5, ar.length);
+        ar[0] = m10;
+        assertFalse(s.containsAll(Arrays.asList(ar)));
+    }
+
+    /**
+     *  Values.toArray contains all values
+     */
+    public void testValuesToArray() {
+        ConcurrentHashMap map = map5();
+	Collection v = map.values();
+        Object[] ar = v.toArray();
+        ArrayList s = new ArrayList(Arrays.asList(ar));
+	assertEquals(5, ar.length);
+	assertTrue(s.contains("A"));
+	assertTrue(s.contains("B"));
+	assertTrue(s.contains("C"));
+	assertTrue(s.contains("D"));
+	assertTrue(s.contains("E"));
+    }
+
+    /**
+     *  entrySet.toArray contains all entries
+     */
+    public void testEntrySetToArray() {
+        ConcurrentHashMap map = map5();
+	Set s = map.entrySet();
+        Object[] ar = s.toArray();
+        assertEquals(5, ar.length);
+        for (int i = 0; i < 5; ++i) {
+            assertTrue(map.containsKey(((Map.Entry)(ar[i])).getKey()));
+            assertTrue(map.containsValue(((Map.Entry)(ar[i])).getValue()));
+        }
+    }
+
+    /**
      * values collection contains all values
      */
     public void testValues() {
@@ -233,7 +218,7 @@
         Iterator it = s.iterator();
         while (it.hasNext()) {
             Map.Entry e = (Map.Entry) it.next();
-            assertTrue( 
+            assertTrue(
                        (e.getKey().equals(one) && e.getValue().equals("A")) ||
                        (e.getKey().equals(two) && e.getValue().equals("B")) ||
                        (e.getKey().equals(three) && e.getValue().equals("C")) ||
@@ -357,12 +342,12 @@
         for (int i = 1; i <= 5; ++i) {
             assertTrue(s.indexOf(String.valueOf(i)) >= 0);
         }
-    }        
+    }
 
     // Exception tests
-    
+
     /**
-     * Cannot create with negative capacity 
+     * Cannot create with negative capacity
      */
     public void testConstructor1() {
         try {
@@ -561,6 +546,19 @@
     }
 
     /**
+     * remove(x, null) returns false
+     */
+    public void testRemove3() {
+        try {
+            ConcurrentHashMap c = new ConcurrentHashMap(5);
+            c.put("sadsdf", "asdads");
+            assertFalse(c.remove("sadsdf", null));
+        } catch(NullPointerException e){
+            fail();
+        }
+    }
+
+    /**
      * A deserialized map equals original
      */
     public void testSerialization() {
diff --git a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/CyclicBarrierTest.java b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/CyclicBarrierTest.java
index 9eac1a7..ecd6e45 100755
--- a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/CyclicBarrierTest.java
+++ b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/CyclicBarrierTest.java
@@ -11,6 +11,8 @@
 import junit.framework.*;
 import java.util.*;
 import java.util.concurrent.*;
+import java.util.concurrent.locks.*;
+import java.util.concurrent.atomic.*;
 
 public class CyclicBarrierTest extends JSR166TestCase{
     public static void main(String[] args) {
@@ -164,7 +166,7 @@
      * throw BrokenBarrierException
      */
     public void testAwait2_Interrupted_BrokenBarrier() {
-      final CyclicBarrier c = new CyclicBarrier(3);
+        final CyclicBarrier c = new CyclicBarrier(3);
         Thread t1 = new Thread(new Runnable() {
                 public void run() {
                     try {
@@ -229,7 +231,7 @@
      * throw BrokenBarrierException
      */
     public void testAwait4_Timeout_BrokenBarrier() {
-      final CyclicBarrier c = new CyclicBarrier(3);
+        final CyclicBarrier c = new CyclicBarrier(3);
         Thread t1 = new Thread(new Runnable() {
                 public void run() {
                     try {
@@ -267,7 +269,7 @@
      * throw BrokenBarrierException
      */
     public void testAwait5_Timeout_BrokenBarrier() {
-      final CyclicBarrier c = new CyclicBarrier(3);
+        final CyclicBarrier c = new CyclicBarrier(3);
         Thread t1 = new Thread(new Runnable() {
                 public void run() {
                     try {
@@ -376,4 +378,249 @@
         }
     }
 
+    /**
+     * All threads block while a barrier is broken.
+     */
+    public void testReset_Leakage() {
+        try {
+            final CyclicBarrier c = new CyclicBarrier(2);
+            final AtomicBoolean done = new AtomicBoolean();
+            Thread t = new Thread() {
+                    public void run() {
+                        while (!done.get()) {
+                            try {
+                                while (c.isBroken())
+                                    c.reset();
+                                
+                                c.await();
+                                threadFail("await should not return");
+                            }
+                            catch (BrokenBarrierException e) {
+                            }
+                            catch (InterruptedException ie) {
+                            }
+                        }
+                    }
+                };
+            
+            t.start();
+            for( int i = 0; i < 4; i++) {
+                Thread.sleep(SHORT_DELAY_MS);
+                t.interrupt();
+            }
+            done.set(true);
+            t.interrupt();
+        }
+        catch (Exception ex) {
+            unexpectedException();
+        }
+    }
+
+    /**
+     * Reset of a non-broken barrier does not break barrier
+     */
+    public void testResetWithoutBreakage() {
+        try {
+            final CyclicBarrier start = new CyclicBarrier(3);
+            final CyclicBarrier barrier = new CyclicBarrier(3);
+            for (int i = 0; i < 3; i++) {
+                Thread t1 = new Thread(new Runnable() {
+                        public void run() {
+                            try { start.await(); }
+                            catch (Exception ie) { 
+                                threadFail("start barrier"); 
+                            }
+                            try { barrier.await(); }
+                            catch (Throwable thrown) { 
+                                unexpectedException(); 
+                            }}});
+                
+                Thread t2 = new Thread(new Runnable() {
+                        public void run() {
+                            try { start.await(); }
+                            catch (Exception ie) { 
+                                threadFail("start barrier"); 
+                            }
+                            try { barrier.await(); }
+                            catch (Throwable thrown) { 
+                                unexpectedException(); 
+                            }}});
+                
+                
+                t1.start();
+                t2.start();
+                try { start.await(); }
+                catch (Exception ie) { threadFail("start barrier"); }
+                barrier.await();
+                t1.join();
+                t2.join();
+                assertFalse(barrier.isBroken());
+                assertEquals(0, barrier.getNumberWaiting());
+                if (i == 1) barrier.reset();
+                assertFalse(barrier.isBroken());
+                assertEquals(0, barrier.getNumberWaiting());
+            }
+        }
+        catch (Exception ex) {
+            unexpectedException();
+        }
+    }
+        
+    /**
+     * Reset of a barrier after interruption reinitializes it.
+     */
+    public void testResetAfterInterrupt() {
+        try {
+            final CyclicBarrier start = new CyclicBarrier(3);
+            final CyclicBarrier barrier = new CyclicBarrier(3);
+            for (int i = 0; i < 2; i++) {
+                Thread t1 = new Thread(new Runnable() {
+                        public void run() {
+                            try { start.await(); }
+                            catch (Exception ie) { 
+                                threadFail("start barrier"); 
+                            }
+                            try { barrier.await(); }
+                            catch(InterruptedException ok) {}
+                            catch (Throwable thrown) { 
+                                unexpectedException(); 
+                            }}});
+                
+                Thread t2 = new Thread(new Runnable() {
+                        public void run() {
+                            try { start.await(); }
+                            catch (Exception ie) { 
+                                threadFail("start barrier"); 
+                            }
+                            try { barrier.await(); }
+                            catch(BrokenBarrierException ok) {}
+                            catch (Throwable thrown) { 
+                                unexpectedException(); 
+                            }}});
+                
+                t1.start();
+                t2.start();
+                try { start.await(); }
+                catch (Exception ie) { threadFail("start barrier"); }
+                t1.interrupt();
+                t1.join();
+                t2.join();
+                assertTrue(barrier.isBroken());
+                assertEquals(0, barrier.getNumberWaiting());
+                barrier.reset();
+                assertFalse(barrier.isBroken());
+                assertEquals(0, barrier.getNumberWaiting());
+            }
+        }
+        catch (Exception ex) {
+            unexpectedException();
+        }
+    }
+        
+    /**
+     * Reset of a barrier after timeout reinitializes it.
+     */
+    public void testResetAfterTimeout() {
+        try {
+            final CyclicBarrier start = new CyclicBarrier(3);
+            final CyclicBarrier barrier = new CyclicBarrier(3);
+            for (int i = 0; i < 2; i++) {
+                Thread t1 = new Thread(new Runnable() {
+                        public void run() {
+                            try { start.await(); }
+                            catch (Exception ie) { 
+                                threadFail("start barrier"); 
+                            }
+                            try { barrier.await(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); }
+                            catch(TimeoutException ok) {}
+                            catch (Throwable thrown) { 
+                                unexpectedException(); 
+                            }}});
+                
+                Thread t2 = new Thread(new Runnable() {
+                        public void run() {
+                            try { start.await(); }
+                            catch (Exception ie) { 
+                                threadFail("start barrier"); 
+                            }
+                            try { barrier.await(); }
+                            catch(BrokenBarrierException ok) {}
+                            catch (Throwable thrown) { 
+                                unexpectedException(); 
+                            }}});
+                
+                t1.start();
+                t2.start();
+                try { start.await(); }
+                catch (Exception ie) { threadFail("start barrier"); }
+                t1.join();
+                t2.join();
+                assertTrue(barrier.isBroken());
+                assertEquals(0, barrier.getNumberWaiting());
+                barrier.reset();
+                assertFalse(barrier.isBroken());
+                assertEquals(0, barrier.getNumberWaiting());
+            }
+        }
+        catch (Exception ex) {
+            unexpectedException();
+        }
+    }
+
+    
+    /**
+     * Reset of a barrier after a failed command reinitializes it.
+     */
+    public void testResetAfterCommandException() {
+        try {
+            final CyclicBarrier start = new CyclicBarrier(3);
+            final CyclicBarrier barrier = 
+                new CyclicBarrier(3, new Runnable() {
+                        public void run() { 
+                            throw new NullPointerException(); }});
+            for (int i = 0; i < 2; i++) {
+                Thread t1 = new Thread(new Runnable() {
+                        public void run() {
+                            try { start.await(); }
+                            catch (Exception ie) { 
+                                threadFail("start barrier"); 
+                            }
+                            try { barrier.await(); }
+                            catch(BrokenBarrierException ok) {}
+                            catch (Throwable thrown) { 
+                                unexpectedException(); 
+                            }}});
+                
+                Thread t2 = new Thread(new Runnable() {
+                        public void run() {
+                            try { start.await(); }
+                            catch (Exception ie) { 
+                                threadFail("start barrier"); 
+                            }
+                            try { barrier.await(); }
+                            catch(BrokenBarrierException ok) {}
+                            catch (Throwable thrown) { 
+                                unexpectedException(); 
+                            }}});
+                
+                t1.start();
+                t2.start();
+                try { start.await(); }
+                catch (Exception ie) { threadFail("start barrier"); }
+                while (barrier.getNumberWaiting() < 2) { Thread.yield(); }
+                try { barrier.await(); }
+                catch (Exception ok) { }
+                t1.join();
+                t2.join();
+                assertTrue(barrier.isBroken());
+                assertEquals(0, barrier.getNumberWaiting());
+                barrier.reset();
+                assertFalse(barrier.isBroken());
+                assertEquals(0, barrier.getNumberWaiting());
+            }
+        }
+        catch (Exception ex) {
+            unexpectedException();
+        }
+    }
 }
diff --git a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/DelayQueueTest.java b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/DelayQueueTest.java
index e332513..978edb4 100755
--- a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/DelayQueueTest.java
+++ b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/DelayQueueTest.java
@@ -14,11 +14,11 @@
 
 public class DelayQueueTest extends JSR166TestCase {
     public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());        
+	junit.textui.TestRunner.run (suite());
     }
 
     public static Test suite() {
-        return new TestSuite(DelayQueueTest.class);
+	return new TestSuite(DelayQueueTest.class);
     }
 
     private static final int NOCAP = Integer.MAX_VALUE;
@@ -27,20 +27,19 @@
      * A delayed implementation for testing.
      * Most  tests use Pseudodelays, where delays are all elapsed
      * (so, no blocking solely for delays) but are still ordered
-     */ 
-    static class PDelay implements Delayed { 
+     */
+    static class PDelay implements Delayed {
         int pseudodelay;
         PDelay(int i) { pseudodelay = Integer.MIN_VALUE + i; }
-        // BEGIN android-changed
-        public int compareTo(Delayed y) {
+        public int compareTo(PDelay y) {
             int i = pseudodelay;
             int j = ((PDelay)y).pseudodelay;
             if (i < j) return -1;
             if (i > j) return 1;
             return 0;
         }
-        // END android-changed
-        public int compareTo(PDelay y) {
+
+        public int compareTo(Delayed y) {
             int i = pseudodelay;
             int j = ((PDelay)y).pseudodelay;
             if (i < j) return -1;
@@ -72,21 +71,20 @@
     /**
      * Delayed implementation that actually delays
      */
-    static class NanoDelay implements Delayed { 
+    static class NanoDelay implements Delayed {
         long trigger;
-        NanoDelay(long i) { 
+        NanoDelay(long i) {
             trigger = System.nanoTime() + i;
         }
-        // BEGIN android-changed
-        public int compareTo(Delayed y) {
+        public int compareTo(NanoDelay y) {
             long i = trigger;
             long j = ((NanoDelay)y).trigger;
             if (i < j) return -1;
             if (i > j) return 1;
             return 0;
         }
-        // END android-changed
-        public int compareTo(NanoDelay y) {
+
+        public int compareTo(Delayed y) {
             long i = trigger;
             long j = ((NanoDelay)y).trigger;
             if (i < j) return -1;
@@ -123,16 +121,16 @@
     private DelayQueue populatedQueue(int n) {
         DelayQueue q = new DelayQueue();
         assertTrue(q.isEmpty());
-        for(int i = n-1; i >= 0; i-=2)
-            assertTrue(q.offer(new PDelay(i)));
-        for(int i = (n & 1); i < n; i+=2)
-            assertTrue(q.offer(new PDelay(i)));
+	for(int i = n-1; i >= 0; i-=2)
+	    assertTrue(q.offer(new PDelay(i)));
+	for(int i = (n & 1); i < n; i+=2)
+	    assertTrue(q.offer(new PDelay(i)));
         assertFalse(q.isEmpty());
         assertEquals(NOCAP, q.remainingCapacity());
-        assertEquals(n, q.size());
+	assertEquals(n, q.size());
         return q;
     }
- 
+
     /**
      * A new queue has unbounded capacity
      */
@@ -229,22 +227,22 @@
      * offer(null) throws NPE
      */
     public void testOfferNull() {
-        try {
+	try {
             DelayQueue q = new DelayQueue();
             q.offer(null);
             shouldThrow();
-        } catch (NullPointerException success) { }   
+        } catch (NullPointerException success) { }
     }
 
     /**
      * add(null) throws NPE
      */
     public void testAddNull() {
-        try {
+	try {
             DelayQueue q = new DelayQueue();
             q.add(null);
             shouldThrow();
-        } catch (NullPointerException success) { }   
+        } catch (NullPointerException success) { }
     }
 
     /**
@@ -342,13 +340,13 @@
      * put(null) throws NPE
      */
      public void testPutNull() {
-        try {
+	try {
             DelayQueue q = new DelayQueue();
             q.put(null);
             shouldThrow();
-        } 
+        }
         catch (NullPointerException success){
-        }   
+	}
      }
 
     /**
@@ -416,7 +414,7 @@
                     } finally { }
                 }
             });
-        
+
         try {
             t.start();
             Thread.sleep(SMALL_DELAY_MS);
@@ -431,14 +429,14 @@
      * take retrieves elements in priority order
      */
     public void testTake() {
-        try {
+	try {
             DelayQueue q = populatedQueue(SIZE);
             for (int i = 0; i < SIZE; ++i) {
                 assertEquals(new PDelay(i), ((PDelay)q.take()));
             }
         } catch (InterruptedException e){
-            unexpectedException();
-        }   
+	    unexpectedException();
+	}
     }
 
     /**
@@ -450,8 +448,8 @@
                 public void run() {
                     try {
                         q.take();
-                        threadShouldThrow();
-                    } catch (InterruptedException success){ }                
+			threadShouldThrow();
+                    } catch (InterruptedException success){ }
                 }
             });
         try {
@@ -478,16 +476,16 @@
                         q.take();
                         threadShouldThrow();
                     } catch (InterruptedException success){
-                    }   
+                    }
                 }});
         t.start();
-        try { 
-           Thread.sleep(SHORT_DELAY_MS); 
+        try {
+           Thread.sleep(SHORT_DELAY_MS);
            t.interrupt();
            t.join();
         }
         catch (InterruptedException ie) {
-            unexpectedException();
+	    unexpectedException();
         }
     }
 
@@ -500,7 +498,7 @@
         for (int i = 0; i < SIZE; ++i) {
             assertEquals(new PDelay(i), ((PDelay)q.poll()));
         }
-        assertNull(q.poll());
+	assertNull(q.poll());
     }
 
     /**
@@ -514,8 +512,8 @@
             }
             assertNull(q.poll(0, TimeUnit.MILLISECONDS));
         } catch (InterruptedException e){
-            unexpectedException();
-        }   
+	    unexpectedException();
+	}
     }
 
     /**
@@ -529,8 +527,8 @@
             }
             assertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
         } catch (InterruptedException e){
-            unexpectedException();
-        }   
+	    unexpectedException();
+	}
     }
 
     /**
@@ -547,16 +545,16 @@
                         }
                         threadAssertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
                     } catch (InterruptedException success){
-                    }   
+                    }
                 }});
         t.start();
-        try { 
-           Thread.sleep(SHORT_DELAY_MS); 
+        try {
+           Thread.sleep(SHORT_DELAY_MS);
            t.interrupt();
            t.join();
         }
         catch (InterruptedException ie) {
-            unexpectedException();
+	    unexpectedException();
         }
     }
 
@@ -572,8 +570,8 @@
                         threadAssertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
                         q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS);
                         q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS);
-                        threadFail("Should block");
-                    } catch (InterruptedException success) { }                
+			threadFail("Should block");
+                    } catch (InterruptedException success) { }
                 }
             });
         try {
@@ -585,7 +583,7 @@
         } catch (Exception e){
             unexpectedException();
         }
-    }  
+    }
 
 
     /**
@@ -596,10 +594,12 @@
         for (int i = 0; i < SIZE; ++i) {
             assertEquals(new PDelay(i), ((PDelay)q.peek()));
             q.poll();
-            assertTrue(q.peek() == null ||
-                       i != ((PDelay)q.peek()).intValue());
+            if (q.isEmpty())
+                assertNull(q.peek());
+            else
+                assertTrue(i != ((PDelay)q.peek()).intValue());
         }
-        assertNull(q.peek());
+	assertNull(q.peek());
     }
 
     /**
@@ -630,7 +630,7 @@
             q.remove();
             shouldThrow();
         } catch (NoSuchElementException success){
-        }   
+	}
     }
 
     /**
@@ -647,7 +647,7 @@
         }
         assertTrue(q.isEmpty());
     }
-        
+
     /**
      * contains(x) reports true when elements added but not yet removed
      */
@@ -669,8 +669,10 @@
         assertTrue(q.isEmpty());
         assertEquals(0, q.size());
         assertEquals(NOCAP, q.remainingCapacity());
-        q.add(new PDelay(1));
+        PDelay x = new PDelay(1);
+        q.add(x);
         assertFalse(q.isEmpty());
+        assertTrue(q.contains(x));
         q.clear();
         assertTrue(q.isEmpty());
     }
@@ -729,14 +731,14 @@
      */
     public void testToArray() {
         DelayQueue q = populatedQueue(SIZE);
-        Object[] o = q.toArray();
+	Object[] o = q.toArray();
         Arrays.sort(o);
-        try {
-        for(int i = 0; i < o.length; i++)
-            assertEquals(o[i], q.take());
-        } catch (InterruptedException e){
-            unexpectedException();
-        }    
+	try {
+	for(int i = 0; i < o.length; i++)
+	    assertEquals(o[i], q.take());
+	} catch (InterruptedException e){
+	    unexpectedException();
+	}
     }
 
     /**
@@ -744,15 +746,15 @@
      */
     public void testToArray2() {
         DelayQueue q = populatedQueue(SIZE);
-        PDelay[] ints = new PDelay[SIZE];
-        ints = (PDelay[])q.toArray(ints);
+	PDelay[] ints = new PDelay[SIZE];
+	ints = (PDelay[])q.toArray(ints);
         Arrays.sort(ints);
-        try {
-            for(int i = 0; i < ints.length; i++)
-                assertEquals(ints[i], q.take());
-        } catch (InterruptedException e){
-            unexpectedException();
-        }    
+	try {
+	    for(int i = 0; i < ints.length; i++)
+		assertEquals(ints[i], q.take());
+	} catch (InterruptedException e){
+	    unexpectedException();
+	}
     }
 
 
@@ -760,31 +762,31 @@
      * toArray(null) throws NPE
      */
     public void testToArray_BadArg() {
-        try {
+	try {
             DelayQueue q = populatedQueue(SIZE);
-            Object o[] = q.toArray(null);
-            shouldThrow();
-        } catch(NullPointerException success){}
+	    Object o[] = q.toArray(null);
+	    shouldThrow();
+	} catch(NullPointerException success){}
     }
 
     /**
      * toArray with incompatible array type throws CCE
      */
     public void testToArray1_BadArg() {
-        try {
+	try {
             DelayQueue q = populatedQueue(SIZE);
-            Object o[] = q.toArray(new String[10] );
-            shouldThrow();
-        } catch(ArrayStoreException  success){}
+	    Object o[] = q.toArray(new String[10] );
+	    shouldThrow();
+	} catch(ArrayStoreException  success){}
     }
-    
+
     /**
      * iterator iterates through all elements
      */
     public void testIterator() {
         DelayQueue q = populatedQueue(SIZE);
         int i = 0;
-        Iterator it = q.iterator();
+	Iterator it = q.iterator();
         while(it.hasNext()) {
             assertTrue(q.contains(it.next()));
             ++i;
@@ -819,7 +821,7 @@
         for (int i = 0; i < SIZE; ++i) {
             assertTrue(s.indexOf(String.valueOf(Integer.MIN_VALUE+i)) >= 0);
         }
-    }        
+    }
 
     /**
      * offer transfers elements across Executor tasks
@@ -875,7 +877,7 @@
                 NanoDelay e = (NanoDelay)(q.take());
                 long tt = e.getTriggerTime();
                 assertTrue(tt <= System.nanoTime());
-                if (i != 0) 
+                if (i != 0)
                     assertTrue(tt >= last);
                 last = tt;
             }
@@ -885,10 +887,41 @@
         }
     }
 
+    /**
+     * peek of a non-empty queue returns non-null even if not expired
+     */
+    public void testPeekDelayed() {
+        DelayQueue q = new DelayQueue();
+        q.add(new NanoDelay(Long.MAX_VALUE));
+        assert(q.peek() != null);
+    }
+
+
+    /**
+     * poll of a non-empty queue returns null if no expired elements.
+     */
+    public void testPollDelayed() {
+        DelayQueue q = new DelayQueue();
+        q.add(new NanoDelay(Long.MAX_VALUE));
+        assertNull(q.poll());
+    }
+
+    /**
+     * timed poll of a non-empty queue returns null if no expired elements.
+     */
+    public void testTimedPollDelayed() {
+        DelayQueue q = new DelayQueue();
+        q.add(new NanoDelay(LONG_DELAY_MS * 1000000L));
+        try {
+            assertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
+        } catch (Exception ex) {
+            unexpectedException();
+        }
+    }
 
     /**
      * drainTo(null) throws NPE
-     */ 
+     */
     public void testDrainToNull() {
         DelayQueue q = populatedQueue(SIZE);
         try {
@@ -900,7 +933,7 @@
 
     /**
      * drainTo(this) throws IAE
-     */ 
+     */
     public void testDrainToSelf() {
         DelayQueue q = populatedQueue(SIZE);
         try {
@@ -912,13 +945,30 @@
 
     /**
      * drainTo(c) empties queue into another collection c
-     */ 
+     */
     public void testDrainTo() {
-        DelayQueue q = populatedQueue(SIZE);
+        DelayQueue q = new DelayQueue();
+        PDelay[] elems = new PDelay[SIZE];
+        for (int i = 0; i < SIZE; ++i) {
+            elems[i] = new PDelay(i);
+            q.add(elems[i]);
+        }
         ArrayList l = new ArrayList();
         q.drainTo(l);
         assertEquals(q.size(), 0);
-        assertEquals(l.size(), SIZE);
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(l.get(i), elems[i]);
+        q.add(elems[0]);
+        q.add(elems[1]);
+        assertFalse(q.isEmpty());
+        assertTrue(q.contains(elems[0]));
+        assertTrue(q.contains(elems[1]));
+        l.clear();
+        q.drainTo(l);
+        assertEquals(q.size(), 0);
+        assertEquals(l.size(), 2);
+        for (int i = 0; i < 2; ++i)
+            assertEquals(l.get(i), elems[i]);
     }
 
     /**
diff --git a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ExecutorCompletionServiceTest.java b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ExecutorCompletionServiceTest.java
index 2e237e2..b1988cc 100644
--- a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ExecutorCompletionServiceTest.java
+++ b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ExecutorCompletionServiceTest.java
@@ -11,6 +11,7 @@
 import junit.framework.*;
 import java.util.*;
 import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
 import java.math.BigInteger;
 import java.security.*;
 
@@ -88,7 +89,7 @@
             Callable c = new StringTask();
             ecs.submit(c);
             Future f = ecs.take();
-            assert(f.isDone());
+            assertTrue(f.isDone());
         } catch (Exception ex) {
             unexpectedException();
         } finally {
@@ -128,7 +129,7 @@
             for (;;) {
                 Future f = ecs.poll();
                 if (f != null) {
-                    assert(f.isDone());
+                    assertTrue(f.isDone());
                     break;
                 }
             }
@@ -151,12 +152,11 @@
             ecs.submit(c);
             Future f = ecs.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
             if (f != null) 
-                assert(f.isDone());
+                assertTrue(f.isDone());
         } catch (Exception ex) {
             unexpectedException();
         } finally {
             joinPool(e);
         }
     }
-
 }
diff --git a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ExecutorsTest.java b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ExecutorsTest.java
index 40e23e4..e8fc7e5 100755
--- a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ExecutorsTest.java
+++ b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ExecutorsTest.java
@@ -16,7 +16,7 @@
 
 public class ExecutorsTest extends JSR166TestCase{
     public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());  
+        junit.textui.TestRunner.run (suite());
     }
     public static Test suite() {
         return new TestSuite(ExecutorsTest.class);
@@ -26,13 +26,13 @@
         private final ExecutorService exec;
         private final Callable<T> func;
         private final long msecs;
-        
+
         TimedCallable(ExecutorService exec, Callable<T> func, long msecs) {
             this.exec = exec;
             this.func = func;
             this.msecs = msecs;
         }
-        
+
         public T call() throws Exception {
             Future<T> ftask = exec.submit(func);
             try {
@@ -295,13 +295,13 @@
         List<Callable<BigInteger>> tasks = new ArrayList<Callable<BigInteger>>(N);
         try {
             long startTime = System.currentTimeMillis();
-            
+
             long i = 0;
             while (tasks.size() < N) {
                 tasks.add(new TimedCallable<BigInteger>(executor, new Fib(i), 1));
                 i += 10;
             }
-            
+
             int iters = 0;
             BigInteger sum = BigInteger.ZERO;
             for (Iterator<Callable<BigInteger>> it = tasks.iterator(); it.hasNext();) {
@@ -326,7 +326,7 @@
         }
     }
 
-    
+
     /**
      * ThreadPoolExecutor using defaultThreadFactory has
      * specified group, priority, daemon status, and name
@@ -335,31 +335,31 @@
         final ThreadGroup egroup = Thread.currentThread().getThreadGroup();
         Runnable r = new Runnable() {
                 public void run() {
-                    try {
-                        Thread current = Thread.currentThread();
-                        threadAssertTrue(!current.isDaemon());
-                        threadAssertTrue(current.getPriority() == Thread.NORM_PRIORITY);
-                        ThreadGroup g = current.getThreadGroup();
-                        SecurityManager s = System.getSecurityManager();
-                        if (s != null)
-                            threadAssertTrue(g == s.getThreadGroup());
-                        else
-                            threadAssertTrue(g == egroup);
-                        String name = current.getName();
-                        threadAssertTrue(name.endsWith("thread-1"));
-                    } catch (SecurityException ok) {
-                        // Also pass if not allowed to change setting
-                    }
+		    try {
+			Thread current = Thread.currentThread();
+			threadAssertTrue(!current.isDaemon());
+			threadAssertTrue(current.getPriority() <= Thread.NORM_PRIORITY);
+			ThreadGroup g = current.getThreadGroup();
+			SecurityManager s = System.getSecurityManager();
+			if (s != null)
+			    threadAssertTrue(g == s.getThreadGroup());
+			else
+			    threadAssertTrue(g == egroup);
+			String name = current.getName();
+			threadAssertTrue(name.endsWith("thread-1"));
+		    } catch (SecurityException ok) {
+			// Also pass if not allowed to change setting
+		    }
                 }
             };
         ExecutorService e = Executors.newSingleThreadExecutor(Executors.defaultThreadFactory());
-        
+
         e.execute(r);
         try {
             e.shutdown();
         } catch(SecurityException ok) {
         }
-        
+
         try {
             Thread.sleep(SHORT_DELAY_MS);
         } catch (Exception eX) {
@@ -390,27 +390,27 @@
         final AccessControlContext thisacc = AccessController.getContext();
         Runnable r = new Runnable() {
                 public void run() {
-                    try {
-                        Thread current = Thread.currentThread();
-                        threadAssertTrue(!current.isDaemon());
-                        threadAssertTrue(current.getPriority() == Thread.NORM_PRIORITY);
-                        ThreadGroup g = current.getThreadGroup();
-                        SecurityManager s = System.getSecurityManager();
-                        if (s != null)
-                            threadAssertTrue(g == s.getThreadGroup());
-                        else
-                            threadAssertTrue(g == egroup);
-                        String name = current.getName();
-                        threadAssertTrue(name.endsWith("thread-1"));
-                        threadAssertTrue(thisccl == current.getContextClassLoader());
-                        threadAssertTrue(thisacc.equals(AccessController.getContext()));
-                    } catch(SecurityException ok) {
-                        // Also pass if not allowed to change settings
-                    }
+		    try {
+			Thread current = Thread.currentThread();
+			threadAssertTrue(!current.isDaemon());
+			threadAssertTrue(current.getPriority() <= Thread.NORM_PRIORITY);
+			ThreadGroup g = current.getThreadGroup();
+			SecurityManager s = System.getSecurityManager();
+			if (s != null)
+			    threadAssertTrue(g == s.getThreadGroup());
+			else
+			    threadAssertTrue(g == egroup);
+			String name = current.getName();
+			threadAssertTrue(name.endsWith("thread-1"));
+			threadAssertTrue(thisccl == current.getContextClassLoader());
+			threadAssertTrue(thisacc.equals(AccessController.getContext()));
+		    } catch(SecurityException ok) {
+			// Also pass if not allowed to change settings
+		    }
                 }
             };
         ExecutorService e = Executors.newSingleThreadExecutor(Executors.privilegedThreadFactory());
-        
+
         Policy.setPolicy(savedPolicy);
         e.execute(r);
         try {
@@ -460,7 +460,7 @@
             Policy.setPolicy(savedPolicy);
             return;
         } catch(AccessControlException ok) {
-        } 
+        }
 
         try {
             Callable task = Executors.privilegedCallableUsingCurrentClassLoader(new NoOpCallable());
@@ -468,7 +468,7 @@
         } catch(AccessControlException success) {
         } catch(Exception ex) {
             unexpectedException();
-        } 
+        }
         finally {
             Policy.setPolicy(savedPolicy);
         }
@@ -489,13 +489,13 @@
         } catch (AccessControlException ok) {
             return;
         }
-            
+
         try {
             Callable task = Executors.privilegedCallableUsingCurrentClassLoader(new NoOpCallable());
             task.call();
         } catch(Exception ex) {
             unexpectedException();
-        } 
+        }
         finally {
             Policy.setPolicy(savedPolicy);
         }
@@ -520,7 +520,7 @@
             return; // program has too few permissions to set up test
         }
 
-        // Make sure that program doesn't have too many permissions 
+        // Make sure that program doesn't have too many permissions
         try {
             AccessController.doPrivileged(new PrivilegedAction() {
                     public Object run() {
@@ -538,7 +538,7 @@
         } catch(AccessControlException success) {
         } catch(Exception ex) {
             unexpectedException();
-        } 
+        }
     }
 
     /**
diff --git a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/JSR166TestCase.java b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/JSR166TestCase.java
index 70dafbc..c900616 100644
--- a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/JSR166TestCase.java
+++ b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/JSR166TestCase.java
@@ -2,8 +2,8 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
 package tests.api.java.util.concurrent;
@@ -19,13 +19,13 @@
  * utility methods and classes, as well as a simple framework for
  * helping to make sure that assertions failing in generated threads
  * cause the associated test that generated them to itself fail (which
- * JUnit doe not otherwise arrange).  The rules for creating such
+ * JUnit does not otherwise arrange).  The rules for creating such
  * tests are:
  *
  * <ol>
  *
  * <li> All assertions in code running in generated threads must use
- * the forms {@link #threadFail} , {@link #threadAssertTrue} {@link
+ * the forms {@link #threadFail}, {@link #threadAssertTrue}, {@link
  * #threadAssertEquals}, or {@link #threadAssertNull}, (not
  * <tt>fail</tt>, <tt>assertTrue</tt>, etc.) It is OK (but not
  * particularly recommended) for other code to use these forms too.
@@ -46,7 +46,7 @@
  * is always discriminable as larger than SHORT and smaller than
  * MEDIUM.  And so on. These constants are set to conservative values,
  * but even so, if there is ever any doubt, they can all be increased
- * in one spot to rerun tests on slower platforms</li>
+ * in one spot to rerun tests on slower platforms.</li>
  *
  * <li> All threads generated must be joined inside each test case
  * method (or <tt>fail</tt> to do so) before returning from the
@@ -65,7 +65,7 @@
  * "normal" behaviors differ significantly. And sometimes testcases
  * cover multiple methods when they cannot be tested in
  * isolation.</li>
- * 
+ *
  * <li> The documentation style for testcases is to provide as javadoc
  * a simple sentence or two describing the property that the testcase
  * method purports to test. The javadocs do not say anything about how
@@ -90,10 +90,10 @@
 public class JSR166TestCase extends TestCase {
     /**
      * Runs all JSR166 unit tests using junit.textui.TestRunner
-     */ 
+     */
     public static void main (String[] args) {
         int iters = 1;
-        if (args.length > 0) 
+        if (args.length > 0)
             iters = Integer.parseInt(args[0]);
         Test s = suite();
         for (int i = 0; i < iters; ++i) {
@@ -106,7 +106,7 @@
 
     /**
      * Collects all JSR166 unit tests as one suite
-     */ 
+     */
     public static Test suite ( ) {
         TestSuite suite = tests.TestSuiteFactory.createTestSuite("JSR166 Unit Tests");
         // BEGIN android-changed
@@ -114,18 +114,18 @@
         suite.addTest(AbstractQueueTest.suite());
         suite.addTest(AbstractQueuedSynchronizerTest.suite());
         suite.addTest(ArrayBlockingQueueTest.suite());
-        suite.addTest(AtomicBooleanTest.suite()); 
-        suite.addTest(AtomicIntegerArrayTest.suite()); 
-        suite.addTest(AtomicIntegerFieldUpdaterTest.suite()); 
-        suite.addTest(AtomicIntegerTest.suite()); 
-        suite.addTest(AtomicLongArrayTest.suite()); 
-        suite.addTest(AtomicLongFieldUpdaterTest.suite()); 
-        suite.addTest(AtomicLongTest.suite()); 
-        suite.addTest(AtomicMarkableReferenceTest.suite()); 
-        suite.addTest(AtomicReferenceArrayTest.suite()); 
-        suite.addTest(AtomicReferenceFieldUpdaterTest.suite()); 
-        suite.addTest(AtomicReferenceTest.suite()); 
-        suite.addTest(AtomicStampedReferenceTest.suite()); 
+        suite.addTest(AtomicBooleanTest.suite());
+        suite.addTest(AtomicIntegerArrayTest.suite());
+        suite.addTest(AtomicIntegerFieldUpdaterTest.suite());
+        suite.addTest(AtomicIntegerTest.suite());
+        suite.addTest(AtomicLongArrayTest.suite());
+        suite.addTest(AtomicLongFieldUpdaterTest.suite());
+        suite.addTest(AtomicLongTest.suite());
+        suite.addTest(AtomicMarkableReferenceTest.suite());
+        suite.addTest(AtomicReferenceArrayTest.suite());
+        suite.addTest(AtomicReferenceFieldUpdaterTest.suite());
+        suite.addTest(AtomicReferenceTest.suite());
+        suite.addTest(AtomicStampedReferenceTest.suite());
         suite.addTest(ConcurrentHashMapTest.suite());
         suite.addTest(ConcurrentLinkedQueueTest.suite());
         suite.addTest(CopyOnWriteArrayListTest.suite());
@@ -164,16 +164,16 @@
 
 
     /**
-     * Return the shortest timed delay. This could
+     * Returns the shortest timed delay. This could
      * be reimplemented to use for example a Property.
-     */ 
+     */
     protected long getShortDelay() {
         return 50;
     }
 
 
     /**
-     * Set delays as multiples of SHORT_DELAY.
+     * Sets delays as multiples of SHORT_DELAY.
      */
     protected  void setDelays() {
         SHORT_DELAY_MS = getShortDelay();
@@ -188,23 +188,23 @@
     volatile boolean threadFailed;
 
     /**
-     * Initialize test to indicate that no thread assertions have failed
+     * Initializes test to indicate that no thread assertions have failed
      */
-    public void setUp() { 
+    public void setUp() {
         setDelays();
-        threadFailed = false;  
+        threadFailed = false;
     }
 
     /**
-     * Trigger test case failure if any thread assertions have failed
+     * Triggers test case failure if any thread assertions have failed
      */
-    public void tearDown() { 
-        assertFalse(threadFailed);  
+    public void tearDown() {
+        assertFalse(threadFailed);
     }
 
     /**
      * Fail, also setting status to indicate current testcase should fail
-     */ 
+     */
     public void threadFail(String reason) {
         threadFailed = true;
         fail(reason);
@@ -213,7 +213,7 @@
     /**
      * If expression not true, set status to indicate current testcase
      * should fail
-     */ 
+     */
     public void threadAssertTrue(boolean b) {
         if (!b) {
             threadFailed = true;
@@ -224,7 +224,7 @@
     /**
      * If expression not false, set status to indicate current testcase
      * should fail
-     */ 
+     */
     public void threadAssertFalse(boolean b) {
         if (b) {
             threadFailed = true;
@@ -235,7 +235,7 @@
     /**
      * If argument not null, set status to indicate current testcase
      * should fail
-     */ 
+     */
     public void threadAssertNull(Object x) {
         if (x != null) {
             threadFailed = true;
@@ -246,7 +246,7 @@
     /**
      * If arguments not equal, set status to indicate current testcase
      * should fail
-     */ 
+     */
     public void threadAssertEquals(long x, long y) {
         if (x != y) {
             threadFailed = true;
@@ -257,7 +257,7 @@
     /**
      * If arguments not equal, set status to indicate current testcase
      * should fail
-     */ 
+     */
     public void threadAssertEquals(Object x, Object y) {
         if (x != y && (x == null || !x.equals(y))) {
             threadFailed = true;
@@ -267,10 +267,15 @@
 
     /**
      * threadFail with message "should throw exception"
-     */ 
+     */
     public void threadShouldThrow() {
-        threadFailed = true;
-        fail("should throw exception");
+       try {
+           threadFailed = true;
+           fail("should throw exception");
+       } catch (AssertionFailedError e) {
+           e.printStackTrace();
+           throw e;
+       }
     }
 
     /**
@@ -281,6 +286,14 @@
         fail("Unexpected exception");
     }
 
+    /**
+     * threadFail with message "Unexpected exception", with argument
+     */
+    public void threadUnexpectedException(Throwable ex) {
+        threadFailed = true;
+        ex.printStackTrace();
+        fail("Unexpected exception: " + ex);
+    }
 
     /**
      * Wait out termination of a thread pool or fail doing so
@@ -299,7 +312,7 @@
 
     /**
      * fail with message "should throw exception"
-     */ 
+     */
     public void shouldThrow() {
         fail("Should throw exception");
     }
@@ -334,6 +347,7 @@
     static final Integer m3  = new Integer(-3);
     static final Integer m4 = new Integer(-4);
     static final Integer m5 = new Integer(-5);
+    static final Integer m6 = new Integer(-6);
     static final Integer m10 = new Integer(-10);
 
 
@@ -389,7 +403,7 @@
                 Thread.sleep(SHORT_DELAY_MS);
             }
             catch(Exception e) {
-                threadUnexpectedException();
+                threadUnexpectedException(e);
             }
         }
     }
@@ -411,7 +425,7 @@
                 Thread.sleep(SMALL_DELAY_MS);
             }
             catch(Exception e) {
-                threadUnexpectedException();
+                threadUnexpectedException(e);
             }
         }
     }
@@ -432,7 +446,7 @@
                 Thread.sleep(SMALL_DELAY_MS);
             }
             catch(Exception e) {
-                threadUnexpectedException();
+                threadUnexpectedException(e);
             }
             return Boolean.TRUE;
         }
@@ -456,7 +470,7 @@
                 Thread.sleep(MEDIUM_DELAY_MS);
             }
             catch(Exception e) {
-                threadUnexpectedException();
+                threadUnexpectedException(e);
             }
         }
     }
@@ -498,7 +512,7 @@
     static class SimpleThreadFactory implements ThreadFactory{
         public Thread newThread(Runnable r){
             return new Thread(r);
-        }   
+        }
     }
 
     static class TrackedShortRunnable implements Runnable {
@@ -558,8 +572,8 @@
      * For use as RejectedExecutionHandler in constructors
      */
     static class NoOpREHandler implements RejectedExecutionHandler{
-        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor){} 
+        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor){}
     }
- 
-    
+
+
 }
diff --git a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/LinkedBlockingQueueTest.java b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/LinkedBlockingQueueTest.java
index 7496a4a..6648afb 100755
--- a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/LinkedBlockingQueueTest.java
+++ b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/LinkedBlockingQueueTest.java
@@ -16,7 +16,7 @@
 public class LinkedBlockingQueueTest extends JSR166TestCase {
 
     public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());        
+        junit.textui.TestRunner.run (suite());
     }
 
     public static Test suite() {
@@ -38,7 +38,7 @@
         assertEquals(n, q.size());
         return q;
     }
- 
+
     /**
      * A new queue has the indicated capacity, or Integer.MAX_VALUE if
      * none given
@@ -151,7 +151,7 @@
             LinkedBlockingQueue q = new LinkedBlockingQueue(1);
             q.offer(null);
             shouldThrow();
-        } catch (NullPointerException success) { }   
+        } catch (NullPointerException success) { }
     }
 
     /**
@@ -162,7 +162,7 @@
             LinkedBlockingQueue q = new LinkedBlockingQueue(1);
             q.add(null);
             shouldThrow();
-        } catch (NullPointerException success) { }   
+        } catch (NullPointerException success) { }
     }
 
     /**
@@ -186,7 +186,7 @@
             assertEquals(0, q.remainingCapacity());
             q.add(new Integer(SIZE));
         } catch (IllegalStateException success){
-        }   
+        }
     }
 
     /**
@@ -280,9 +280,9 @@
             LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE);
             q.put(null);
             shouldThrow();
-        } 
+        }
         catch (NullPointerException success){
-        }   
+        }
         catch (InterruptedException ie) {
             unexpectedException();
         }
@@ -323,11 +323,11 @@
                         threadShouldThrow();
                     } catch (InterruptedException ie){
                         threadAssertEquals(added, SIZE);
-                    }   
+                    }
                 }});
         t.start();
-        try { 
-           Thread.sleep(SHORT_DELAY_MS); 
+        try {
+           Thread.sleep(SHORT_DELAY_MS);
            t.interrupt();
            t.join();
         }
@@ -386,7 +386,7 @@
                     } catch (InterruptedException success){}
                 }
             });
-        
+
         try {
             t.start();
             Thread.sleep(SMALL_DELAY_MS);
@@ -408,7 +408,7 @@
             }
         } catch (InterruptedException e){
             unexpectedException();
-        }   
+        }
     }
 
     /**
@@ -421,7 +421,7 @@
                     try {
                         q.take();
                         threadShouldThrow();
-                    } catch (InterruptedException success){ }                
+                    } catch (InterruptedException success){ }
                 }
             });
         try {
@@ -448,11 +448,11 @@
                         q.take();
                         threadShouldThrow();
                     } catch (InterruptedException success){
-                    }   
+                    }
                 }});
         t.start();
-        try { 
-           Thread.sleep(SHORT_DELAY_MS); 
+        try {
+           Thread.sleep(SHORT_DELAY_MS);
            t.interrupt();
            t.join();
         }
@@ -485,7 +485,7 @@
             assertNull(q.poll(0, TimeUnit.MILLISECONDS));
         } catch (InterruptedException e){
             unexpectedException();
-        }   
+        }
     }
 
     /**
@@ -500,7 +500,7 @@
             assertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
         } catch (InterruptedException e){
             unexpectedException();
-        }   
+        }
     }
 
     /**
@@ -517,11 +517,11 @@
                         }
                         threadAssertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
                     } catch (InterruptedException success){
-                    }   
+                    }
                 }});
         t.start();
-        try { 
-           Thread.sleep(SHORT_DELAY_MS); 
+        try {
+           Thread.sleep(SHORT_DELAY_MS);
            t.interrupt();
            t.join();
         }
@@ -543,7 +543,7 @@
                         q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS);
                         q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS);
                         threadShouldThrow();
-                    } catch (InterruptedException success) { }                
+                    } catch (InterruptedException success) { }
                 }
             });
         try {
@@ -555,7 +555,7 @@
         } catch (Exception e){
             unexpectedException();
         }
-    }  
+    }
 
     /**
      * peek returns next element, or null if empty
@@ -599,7 +599,7 @@
             q.remove();
             shouldThrow();
         } catch (NoSuchElementException success){
-        }   
+        }
     }
 
     /**
@@ -616,7 +616,24 @@
         }
         assertTrue(q.isEmpty());
     }
-        
+
+    /**
+     * An add following remove(x) succeeds
+     */
+    public void testRemoveElementAndAdd() {
+        try {
+            LinkedBlockingQueue q = new LinkedBlockingQueue();
+            assertTrue(q.add(new Integer(1)));
+            assertTrue(q.add(new Integer(2)));
+            assertTrue(q.remove(new Integer(1)));
+            assertTrue(q.remove(new Integer(2)));
+            assertTrue(q.add(new Integer(3)));
+            assertTrue(q.take() != null);
+        } catch (Exception e){
+            unexpectedException();
+        }
+    }
+
     /**
      * contains(x) reports true when elements added but not yet removed
      */
@@ -640,6 +657,7 @@
         assertEquals(SIZE, q.remainingCapacity());
         q.add(one);
         assertFalse(q.isEmpty());
+        assertTrue(q.contains(one));
         q.clear();
         assertTrue(q.isEmpty());
     }
@@ -704,7 +722,7 @@
             assertEquals(o[i], q.take());
         } catch (InterruptedException e){
             unexpectedException();
-        }    
+        }
     }
 
     /**
@@ -719,7 +737,7 @@
                 assertEquals(ints[i], q.take());
         } catch (InterruptedException e){
             unexpectedException();
-        }    
+        }
     }
 
     /**
@@ -744,7 +762,7 @@
         } catch(ArrayStoreException  success){}
     }
 
-    
+
     /**
      * iterator iterates through all elements
      */
@@ -757,7 +775,7 @@
             }
         } catch (InterruptedException e){
             unexpectedException();
-        }    
+        }
     }
 
     /**
@@ -772,7 +790,7 @@
         Iterator it = q.iterator();
         it.next();
         it.remove();
-        
+
         it = q.iterator();
         assertEquals(it.next(), one);
         assertEquals(it.next(), three);
@@ -827,7 +845,7 @@
         for (int i = 0; i < SIZE; ++i) {
             assertTrue(s.indexOf(String.valueOf(i)) >= 0);
         }
-    }        
+    }
 
 
     /**
@@ -862,7 +880,7 @@
                 }
             }
         });
-        
+
         joinPool(executor);
     }
 
@@ -896,7 +914,7 @@
                 }
             }
         });
-        
+
         joinPool(executor);
     }
 
@@ -916,7 +934,7 @@
             ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
             LinkedBlockingQueue r = (LinkedBlockingQueue)in.readObject();
             assertEquals(q.size(), r.size());
-            while (!q.isEmpty()) 
+            while (!q.isEmpty())
                 assertEquals(q.remove(), r.remove());
         } catch(Exception e){
             unexpectedException();
@@ -925,7 +943,7 @@
 
     /**
      * drainTo(null) throws NPE
-     */ 
+     */
     public void testDrainToNull() {
         LinkedBlockingQueue q = populatedQueue(SIZE);
         try {
@@ -937,7 +955,7 @@
 
     /**
      * drainTo(this) throws IAE
-     */ 
+     */
     public void testDrainToSelf() {
         LinkedBlockingQueue q = populatedQueue(SIZE);
         try {
@@ -949,27 +967,38 @@
 
     /**
      * drainTo(c) empties queue into another collection c
-     */ 
+     */
     public void testDrainTo() {
         LinkedBlockingQueue q = populatedQueue(SIZE);
         ArrayList l = new ArrayList();
         q.drainTo(l);
         assertEquals(q.size(), 0);
         assertEquals(l.size(), SIZE);
-        for (int i = 0; i < SIZE; ++i) 
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(l.get(i), new Integer(i));
+        q.add(zero);
+        q.add(one);
+        assertFalse(q.isEmpty());
+        assertTrue(q.contains(zero));
+        assertTrue(q.contains(one));
+        l.clear();
+        q.drainTo(l);
+        assertEquals(q.size(), 0);
+        assertEquals(l.size(), 2);
+        for (int i = 0; i < 2; ++i)
             assertEquals(l.get(i), new Integer(i));
     }
 
     /**
      * drainTo empties full queue, unblocking a waiting put.
-     */ 
+     */
     public void testDrainToWithActivePut() {
         final LinkedBlockingQueue q = populatedQueue(SIZE);
         Thread t = new Thread(new Runnable() {
                 public void run() {
                     try {
                         q.put(new Integer(SIZE+1));
-                    } catch (InterruptedException ie){ 
+                    } catch (InterruptedException ie){
                         threadUnexpectedException();
                     }
                 }
@@ -979,7 +1008,7 @@
             ArrayList l = new ArrayList();
             q.drainTo(l);
             assertTrue(l.size() >= SIZE);
-            for (int i = 0; i < SIZE; ++i) 
+            for (int i = 0; i < SIZE; ++i)
                 assertEquals(l.get(i), new Integer(i));
             t.join();
             assertTrue(q.size() + l.size() >= SIZE);
@@ -990,7 +1019,7 @@
 
     /**
      * drainTo(null, n) throws NPE
-     */ 
+     */
     public void testDrainToNullN() {
         LinkedBlockingQueue q = populatedQueue(SIZE);
         try {
@@ -1002,7 +1031,7 @@
 
     /**
      * drainTo(this, n) throws IAE
-     */ 
+     */
     public void testDrainToSelfN() {
         LinkedBlockingQueue q = populatedQueue(SIZE);
         try {
@@ -1014,17 +1043,20 @@
 
     /**
      * drainTo(c, n) empties first max {n, size} elements of queue into c
-     */ 
+     */
     public void testDrainToN() {
+        LinkedBlockingQueue q = new LinkedBlockingQueue();
         for (int i = 0; i < SIZE + 2; ++i) {
-            LinkedBlockingQueue q = populatedQueue(SIZE);
+            for(int j = 0; j < SIZE; j++)
+                assertTrue(q.offer(new Integer(j)));
             ArrayList l = new ArrayList();
             q.drainTo(l, i);
             int k = (i < SIZE)? i : SIZE;
-            assertEquals(q.size(), SIZE-k);
             assertEquals(l.size(), k);
-            for (int j = 0; j < k; ++j) 
+            assertEquals(q.size(), SIZE-k);
+            for (int j = 0; j < k; ++j)
                 assertEquals(l.get(j), new Integer(j));
+            while (q.poll() != null) ;
         }
     }
 
diff --git a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/LockSupportTest.java b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/LockSupportTest.java
index 8d74a3a..b39db2e 100755
--- a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/LockSupportTest.java
+++ b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/LockSupportTest.java
@@ -15,7 +15,7 @@
 
 public class LockSupportTest extends JSR166TestCase{
     public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());        
+        junit.textui.TestRunner.run (suite());
     }
     public static Test suite() {
         return new TestSuite(LockSupportTest.class);
@@ -24,7 +24,7 @@
     /**
      * park is released by unpark occurring after park
      */
-    public void testPark() { 
+    public void testPark() {
         Thread t = new Thread(new Runnable() {
                 public void run() {
                     try {
@@ -48,7 +48,7 @@
     /**
      * park is released by unpark occurring before park
      */
-    public void testPark2() { 
+    public void testPark2() {
         Thread t = new Thread(new Runnable() {
                 public void run() {
                     try {
@@ -70,15 +70,14 @@
     }
 
     /**
-     * park is released by interrupt 
+     * park is released by interrupt
      */
-    public void testPark3() { 
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        LockSupport.park();
-                        threadAssertTrue(Thread.interrupted());
-                    } catch(Exception e){
+    public void testPark3() {
+	Thread t = new Thread(new Runnable() {
+		public void run() {
+		    try {
+			LockSupport.park();
+		    } catch(Exception e){
                         threadUnexpectedException();
                     }
                 }
@@ -97,7 +96,7 @@
     /**
      * park returns if interrupted before park
      */
-    public void testPark4() { 
+    public void testPark4() {
         final ReentrantLock lock = new ReentrantLock();
         lock.lock();
         Thread t = new Thread(new Runnable() {
@@ -124,7 +123,7 @@
     /**
      * parkNanos times out if not unparked
      */
-    public void testParkNanos() { 
+    public void testParkNanos() {
         Thread t = new Thread(new Runnable() {
                 public void run() {
                     try {
@@ -147,7 +146,7 @@
     /**
      * parkUntil times out if not unparked
      */
-    public void testParkUntil() { 
+    public void testParkUntil() {
         Thread t = new Thread(new Runnable() {
                 public void run() {
                     try {
diff --git a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/PriorityBlockingQueueTest.java b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/PriorityBlockingQueueTest.java
index b258963..3857e0f 100755
--- a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/PriorityBlockingQueueTest.java
+++ b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/PriorityBlockingQueueTest.java
@@ -628,9 +628,9 @@
         q.clear();
         assertTrue(q.isEmpty());
         assertEquals(0, q.size());
-        assertEquals(NOCAP, q.remainingCapacity());
-        q.add(new Integer(1));
+        q.add(one);
         assertFalse(q.isEmpty());
+        assertTrue(q.contains(one));
         q.clear();
         assertTrue(q.isEmpty());
     }
@@ -873,6 +873,17 @@
         assertEquals(l.size(), SIZE);
         for (int i = 0; i < SIZE; ++i) 
             assertEquals(l.get(i), new Integer(i));
+        q.add(zero);
+        q.add(one);
+        assertFalse(q.isEmpty());
+        assertTrue(q.contains(zero));
+        assertTrue(q.contains(one));
+        l.clear();
+        q.drainTo(l);
+        assertEquals(q.size(), 0);
+        assertEquals(l.size(), 2);
+        for (int i = 0; i < 2; ++i) 
+            assertEquals(l.get(i), new Integer(i));
     }
 
     /**
@@ -927,15 +938,18 @@
      * drainTo(c, n) empties first max {n, size} elements of queue into c
      */ 
     public void testDrainToN() {
+        PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE*2);
         for (int i = 0; i < SIZE + 2; ++i) {
-            PriorityBlockingQueue q = populatedQueue(SIZE);
+            for(int j = 0; j < SIZE; j++)
+                assertTrue(q.offer(new Integer(j)));
             ArrayList l = new ArrayList();
             q.drainTo(l, i);
             int k = (i < SIZE)? i : SIZE;
-            assertEquals(q.size(), SIZE-k);
             assertEquals(l.size(), k);
+            assertEquals(q.size(), SIZE-k);
             for (int j = 0; j < k; ++j) 
-                assertTrue(l.contains(new Integer(j)));
+                assertEquals(l.get(j), new Integer(j));
+            while (q.poll() != null) ;
         }
     }
 
diff --git a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ReentrantLockTest.java b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ReentrantLockTest.java
index fdc9f31..c50482d 100755
--- a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ReentrantLockTest.java
+++ b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ReentrantLockTest.java
@@ -16,7 +16,7 @@
 
 public class ReentrantLockTest extends JSR166TestCase {
     public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());        
+        junit.textui.TestRunner.run (suite());
     }
     public static Test suite() {
         return new TestSuite(ReentrantLockTest.class);
@@ -56,11 +56,11 @@
      */
     static class PublicReentrantLock extends ReentrantLock {
         PublicReentrantLock() { super(); }
-        public Collection<Thread> getQueuedThreads() { 
-            return super.getQueuedThreads(); 
+        public Collection<Thread> getQueuedThreads() {
+            return super.getQueuedThreads();
         }
-        public Collection<Thread> getWaitingThreads(Condition c) { 
-            return super.getWaitingThreads(c); 
+        public Collection<Thread> getWaitingThreads(Condition c) {
+            return super.getWaitingThreads(c);
         }
 
 
@@ -69,7 +69,7 @@
     /**
      * Constructor sets given fairness
      */
-    public void testConstructor() { 
+    public void testConstructor() {
         ReentrantLock rl = new ReentrantLock();
         assertFalse(rl.isFair());
         ReentrantLock r2 = new ReentrantLock(true);
@@ -79,7 +79,7 @@
     /**
      * locking an unlocked lock succeeds
      */
-    public void testLock() { 
+    public void testLock() {
         ReentrantLock rl = new ReentrantLock();
         rl.lock();
         assertTrue(rl.isLocked());
@@ -89,7 +89,7 @@
     /**
      * locking an unlocked fair lock succeeds
      */
-    public void testFairLock() { 
+    public void testFairLock() {
         ReentrantLock rl = new ReentrantLock(true);
         rl.lock();
         assertTrue(rl.isLocked());
@@ -99,7 +99,7 @@
     /**
      * Unlocking an unlocked lock throws IllegalMonitorStateException
      */
-    public void testUnlock_IllegalMonitorStateException() { 
+    public void testUnlock_IllegalMonitorStateException() {
         ReentrantLock rl = new ReentrantLock();
         try {
             rl.unlock();
@@ -111,7 +111,7 @@
     /**
      * tryLock on an unlocked lock succeeds
      */
-    public void testTryLock() { 
+    public void testTryLock() {
         ReentrantLock rl = new ReentrantLock();
         assertTrue(rl.tryLock());
         assertTrue(rl.isLocked());
@@ -122,7 +122,7 @@
     /**
      * hasQueuedThreads reports whether there are waiting threads
      */
-    public void testhasQueuedThreads() { 
+    public void testhasQueuedThreads() {
         final ReentrantLock lock = new ReentrantLock();
         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
@@ -146,12 +146,12 @@
         } catch(Exception e){
             unexpectedException();
         }
-    } 
+    }
 
     /**
      * getQueueLength reports number of waiting threads
      */
-    public void testGetQueueLength() { 
+    public void testGetQueueLength() {
         final ReentrantLock lock = new ReentrantLock();
         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
@@ -175,12 +175,12 @@
         } catch(Exception e){
             unexpectedException();
         }
-    } 
+    }
 
     /**
      * getQueueLength reports number of waiting threads
      */
-    public void testGetQueueLength_fair() { 
+    public void testGetQueueLength_fair() {
         final ReentrantLock lock = new ReentrantLock(true);
         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
@@ -204,12 +204,12 @@
         } catch(Exception e){
             unexpectedException();
         }
-    } 
+    }
 
     /**
      * hasQueuedThread(null) throws NPE
      */
-    public void testHasQueuedThreadNPE() { 
+    public void testHasQueuedThreadNPE() {
         final ReentrantLock sync = new ReentrantLock();
         try {
             sync.hasQueuedThread(null);
@@ -221,7 +221,7 @@
     /**
      * hasQueuedThread reports whether a thread is queued.
      */
-    public void testHasQueuedThread() { 
+    public void testHasQueuedThread() {
         final ReentrantLock sync = new ReentrantLock();
         Thread t1 = new Thread(new InterruptedLockRunnable(sync));
         Thread t2 = new Thread(new InterruptibleLockRunnable(sync));
@@ -250,13 +250,13 @@
         } catch(Exception e){
             unexpectedException();
         }
-    } 
+    }
 
 
     /**
      * getQueuedThreads includes waiting threads
      */
-    public void testGetQueuedThreads() { 
+    public void testGetQueuedThreads() {
         final PublicReentrantLock lock = new PublicReentrantLock();
         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
@@ -283,13 +283,13 @@
         } catch(Exception e){
             unexpectedException();
         }
-    } 
+    }
 
 
     /**
      * timed tryLock is interruptible.
      */
-    public void testInterruptedException2() { 
+    public void testInterruptedException2() {
         final ReentrantLock lock = new ReentrantLock();
         lock.lock();
         Thread t = new Thread(new Runnable() {
@@ -312,7 +312,7 @@
     /**
      * TryLock on a locked lock fails
      */
-    public void testTryLockWhenLocked() { 
+    public void testTryLockWhenLocked() {
         final ReentrantLock lock = new ReentrantLock();
         lock.lock();
         Thread t = new Thread(new Runnable() {
@@ -327,12 +327,12 @@
         } catch(Exception e){
             unexpectedException();
         }
-    } 
+    }
 
     /**
      * Timed tryLock on a locked lock times out
      */
-    public void testTryLock_Timeout() { 
+    public void testTryLock_Timeout() {
         final ReentrantLock lock = new ReentrantLock();
         lock.lock();
         Thread t = new Thread(new Runnable() {
@@ -351,8 +351,8 @@
         } catch(Exception e){
             unexpectedException();
         }
-    } 
-    
+    }
+
     /**
      * getHoldCount returns number of recursive holds
      */
@@ -367,8 +367,8 @@
             assertEquals(i-1,lock.getHoldCount());
         }
     }
-    
-   
+
+
     /**
      * isLocked is true when locked and false when not
      */
@@ -378,7 +378,7 @@
         assertTrue(lock.isLocked());
         lock.unlock();
         assertFalse(lock.isLocked());
-        Thread t = new Thread(new Runnable() { 
+        Thread t = new Thread(new Runnable() {
                 public void run() {
                     lock.lock();
                     try {
@@ -405,25 +405,27 @@
     /**
      * lockInterruptibly is interruptible.
      */
-    public void testLockInterruptibly1() { 
+    public void testLockInterruptibly1() {
         final ReentrantLock lock = new ReentrantLock();
         lock.lock();
         Thread t = new Thread(new InterruptedLockRunnable(lock));
         try {
             t.start();
+            Thread.sleep(SHORT_DELAY_MS);
             t.interrupt();
+            Thread.sleep(SHORT_DELAY_MS);
             lock.unlock();
             t.join();
         } catch(Exception e){
             unexpectedException();
         }
-    } 
+    }
 
     /**
      * lockInterruptibly succeeds when unlocked, else is interruptible
      */
     public void testLockInterruptibly2() {
-        final ReentrantLock lock = new ReentrantLock();        
+        final ReentrantLock lock = new ReentrantLock();
         try {
             lock.lockInterruptibly();
         } catch(Exception e) {
@@ -445,7 +447,7 @@
      * Calling await without holding lock throws IllegalMonitorStateException
      */
     public void testAwait_IllegalMonitor() {
-        final ReentrantLock lock = new ReentrantLock();        
+        final ReentrantLock lock = new ReentrantLock();
         final Condition c = lock.newCondition();
         try {
             c.await();
@@ -462,7 +464,7 @@
      * Calling signal without holding lock throws IllegalMonitorStateException
      */
     public void testSignal_IllegalMonitor() {
-        final ReentrantLock lock = new ReentrantLock();        
+        final ReentrantLock lock = new ReentrantLock();
         final Condition c = lock.newCondition();
         try {
             c.signal();
@@ -479,7 +481,7 @@
      * awaitNanos without a signal times out
      */
     public void testAwaitNanos_Timeout() {
-        final ReentrantLock lock = new ReentrantLock();        
+        final ReentrantLock lock = new ReentrantLock();
         final Condition c = lock.newCondition();
         try {
             lock.lock();
@@ -496,11 +498,11 @@
      *  timed await without a signal times out
      */
     public void testAwait_Timeout() {
-        final ReentrantLock lock = new ReentrantLock();        
+        final ReentrantLock lock = new ReentrantLock();
         final Condition c = lock.newCondition();
         try {
             lock.lock();
-            assertFalse(c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
+            c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
             lock.unlock();
         }
         catch (Exception ex) {
@@ -512,12 +514,12 @@
      * awaitUntil without a signal times out
      */
     public void testAwaitUntil_Timeout() {
-        final ReentrantLock lock = new ReentrantLock();        
+        final ReentrantLock lock = new ReentrantLock();
         final Condition c = lock.newCondition();
         try {
             lock.lock();
             java.util.Date d = new java.util.Date();
-            assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
+            c.awaitUntil(new java.util.Date(d.getTime() + 10));
             lock.unlock();
         }
         catch (Exception ex) {
@@ -529,9 +531,9 @@
      * await returns when signalled
      */
     public void testAwait() {
-        final ReentrantLock lock = new ReentrantLock();        
+        final ReentrantLock lock = new ReentrantLock();
         final Condition c = lock.newCondition();
-        Thread t = new Thread(new Runnable() { 
+        Thread t = new Thread(new Runnable() {
                 public void run() {
                     try {
                         lock.lock();
@@ -670,9 +672,9 @@
      * getWaitingThreads throws IAE if not owned
      */
     public void testGetWaitingThreadsIAE() {
-        final PublicReentrantLock lock = new PublicReentrantLock();        
+        final PublicReentrantLock lock = new PublicReentrantLock();
         final Condition c = (lock.newCondition());
-        final PublicReentrantLock lock2 = new PublicReentrantLock();        
+        final PublicReentrantLock lock2 = new PublicReentrantLock();
         try {
             lock2.getWaitingThreads(c);
             shouldThrow();
@@ -686,7 +688,7 @@
      * getWaitingThreads throws IMSE if not locked
      */
     public void testGetWaitingThreadsIMSE() {
-        final PublicReentrantLock lock = new PublicReentrantLock();        
+        final PublicReentrantLock lock = new PublicReentrantLock();
         final Condition c = (lock.newCondition());
         try {
             lock.getWaitingThreads(c);
@@ -703,9 +705,9 @@
      * hasWaiters returns true when a thread is waiting, else false
      */
     public void testHasWaiters() {
-        final ReentrantLock lock = new ReentrantLock();        
+        final ReentrantLock lock = new ReentrantLock();
         final Condition c = lock.newCondition();
-        Thread t = new Thread(new Runnable() { 
+        Thread t = new Thread(new Runnable() {
                 public void run() {
                     try {
                         lock.lock();
@@ -745,9 +747,9 @@
      * getWaitQueueLength returns number of waiting threads
      */
     public void testGetWaitQueueLength() {
-        final ReentrantLock lock = new ReentrantLock();        
+        final ReentrantLock lock = new ReentrantLock();
         final Condition c = lock.newCondition();
-        Thread t1 = new Thread(new Runnable() { 
+        Thread t1 = new Thread(new Runnable() {
                 public void run() {
                     try {
                         lock.lock();
@@ -762,7 +764,7 @@
                 }
             });
 
-        Thread t2 = new Thread(new Runnable() { 
+        Thread t2 = new Thread(new Runnable() {
                 public void run() {
                     try {
                         lock.lock();
@@ -806,9 +808,9 @@
      * getWaitingThreads returns only and all waiting threads
      */
     public void testGetWaitingThreads() {
-        final PublicReentrantLock lock = new PublicReentrantLock();        
+        final PublicReentrantLock lock = new PublicReentrantLock();
         final Condition c = lock.newCondition();
-        Thread t1 = new Thread(new Runnable() { 
+        Thread t1 = new Thread(new Runnable() {
                 public void run() {
                     try {
                         lock.lock();
@@ -822,7 +824,7 @@
                 }
             });
 
-        Thread t2 = new Thread(new Runnable() { 
+        Thread t2 = new Thread(new Runnable() {
                 public void run() {
                     try {
                         lock.lock();
@@ -865,34 +867,61 @@
         }
     }
 
+    /** A helper class for uninterruptible wait tests */
+    class UninterruptableThread extends Thread {
+        private ReentrantLock lock;
+        private Condition c;
 
+        public volatile boolean canAwake = false;
+        public volatile boolean interrupted = false;
+        public volatile boolean lockStarted = false;
+
+        public UninterruptableThread(ReentrantLock lock, Condition c) {
+            this.lock = lock;
+            this.c = c;
+        }
+
+        public synchronized void run() {
+            lock.lock();
+            lockStarted = true;
+
+            while (!canAwake) {
+                c.awaitUninterruptibly();
+            }
+
+            interrupted = isInterrupted();
+            lock.unlock();
+        }
+    }
 
     /**
      * awaitUninterruptibly doesn't abort on interrupt
      */
     public void testAwaitUninterruptibly() {
-        final ReentrantLock lock = new ReentrantLock();        
+        final ReentrantLock lock = new ReentrantLock();
         final Condition c = lock.newCondition();
-        Thread t = new Thread(new Runnable() { 
-                public void run() {
-                    lock.lock();
-                    c.awaitUninterruptibly();
-                    lock.unlock();
-                }
-            });
+        UninterruptableThread thread = new UninterruptableThread(lock, c);
 
         try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
+            thread.start();
+
+            while (!thread.lockStarted) {
+                Thread.sleep(100);
+            }
+
             lock.lock();
-            c.signal();
-            lock.unlock();
-            assert(t.isInterrupted());
-            t.join(SHORT_DELAY_MS);
-            assertFalse(t.isAlive());
-        }
-        catch (Exception ex) {
+            try {
+                thread.interrupt();
+                thread.canAwake = true;
+                c.signal();
+            } finally {
+                lock.unlock();
+            }
+
+            thread.join();
+            assertTrue(thread.interrupted);
+            assertFalse(thread.isAlive());
+        } catch (Exception ex) {
             unexpectedException();
         }
     }
@@ -901,9 +930,9 @@
      * await is interruptible
      */
     public void testAwait_Interrupt() {
-        final ReentrantLock lock = new ReentrantLock();        
+        final ReentrantLock lock = new ReentrantLock();
         final Condition c = lock.newCondition();
-        Thread t = new Thread(new Runnable() { 
+        Thread t = new Thread(new Runnable() {
                 public void run() {
                     try {
                         lock.lock();
@@ -932,9 +961,9 @@
      * awaitNanos is interruptible
      */
     public void testAwaitNanos_Interrupt() {
-        final ReentrantLock lock = new ReentrantLock();        
+        final ReentrantLock lock = new ReentrantLock();
         final Condition c = lock.newCondition();
-        Thread t = new Thread(new Runnable() { 
+        Thread t = new Thread(new Runnable() {
                 public void run() {
                     try {
                         lock.lock();
@@ -963,9 +992,9 @@
      * awaitUntil is interruptible
      */
     public void testAwaitUntil_Interrupt() {
-        final ReentrantLock lock = new ReentrantLock();        
+        final ReentrantLock lock = new ReentrantLock();
         final Condition c = lock.newCondition();
-        Thread t = new Thread(new Runnable() { 
+        Thread t = new Thread(new Runnable() {
                 public void run() {
                     try {
                         lock.lock();
@@ -995,9 +1024,9 @@
      * signalAll wakes up all threads
      */
     public void testSignalAll() {
-        final ReentrantLock lock = new ReentrantLock();        
+        final ReentrantLock lock = new ReentrantLock();
         final Condition c = lock.newCondition();
-        Thread t1 = new Thread(new Runnable() { 
+        Thread t1 = new Thread(new Runnable() {
                 public void run() {
                     try {
                         lock.lock();
@@ -1010,7 +1039,7 @@
                 }
             });
 
-        Thread t2 = new Thread(new Runnable() { 
+        Thread t2 = new Thread(new Runnable() {
                 public void run() {
                     try {
                         lock.lock();
@@ -1041,6 +1070,61 @@
     }
 
     /**
+     * await after multiple reentrant locking preserves lock count
+     */
+    public void testAwaitLockCount() {
+	final ReentrantLock lock = new ReentrantLock();
+        final Condition c = lock.newCondition();
+	Thread t1 = new Thread(new Runnable() {
+		public void run() {
+		    try {
+			lock.lock();
+                        threadAssertEquals(1, lock.getHoldCount());
+                        c.await();
+                        threadAssertEquals(1, lock.getHoldCount());
+                        lock.unlock();
+		    }
+		    catch(InterruptedException e) {
+                        threadUnexpectedException();
+                    }
+		}
+	    });
+
+	Thread t2 = new Thread(new Runnable() {
+		public void run() {
+		    try {
+			lock.lock();
+			lock.lock();
+                        threadAssertEquals(2, lock.getHoldCount());
+                        c.await();
+                        threadAssertEquals(2, lock.getHoldCount());
+                        lock.unlock();
+                        lock.unlock();
+		    }
+		    catch(InterruptedException e) {
+                        threadUnexpectedException();
+                    }
+		}
+	    });
+
+        try {
+            t1.start();
+            t2.start();
+            Thread.sleep(SHORT_DELAY_MS);
+            lock.lock();
+            c.signalAll();
+            lock.unlock();
+            t1.join(SHORT_DELAY_MS);
+            t2.join(SHORT_DELAY_MS);
+            assertFalse(t1.isAlive());
+            assertFalse(t2.isAlive());
+        }
+        catch (Exception ex) {
+            unexpectedException();
+        }
+    }
+
+    /**
      * A serialized lock deserializes as unlocked
      */
     public void testSerialization() {
diff --git a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ReentrantReadWriteLockTest.java b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ReentrantReadWriteLockTest.java
index 8925b42..e38165a 100644
--- a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ReentrantReadWriteLockTest.java
+++ b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ReentrantReadWriteLockTest.java
@@ -16,7 +16,7 @@
 
 public class ReentrantReadWriteLockTest extends JSR166TestCase {
     public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());        
+        junit.textui.TestRunner.run (suite());
     }
     public static Test suite() {
         return new TestSuite(ReentrantReadWriteLockTest.class);
@@ -56,18 +56,18 @@
      */
     static class PublicReentrantReadWriteLock extends ReentrantReadWriteLock {
         PublicReentrantReadWriteLock() { super(); }
-        public Collection<Thread> getQueuedThreads() { 
-            return super.getQueuedThreads(); 
+        public Collection<Thread> getQueuedThreads() {
+            return super.getQueuedThreads();
         }
-        public Collection<Thread> getWaitingThreads(Condition c) { 
-            return super.getWaitingThreads(c); 
+        public Collection<Thread> getWaitingThreads(Condition c) {
+            return super.getWaitingThreads(c);
         }
     }
 
     /**
      * Constructor sets given fairness, and is in unlocked state
      */
-    public void testConstructor() { 
+    public void testConstructor() {
         ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
         assertFalse(rl.isFair());
         assertFalse(rl.isWriteLocked());
@@ -81,7 +81,7 @@
     /**
      * write-locking and read-locking an unlocked lock succeed
      */
-    public void testLock() { 
+    public void testLock() {
         ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
         rl.writeLock().lock();
         assertTrue(rl.isWriteLocked());
@@ -105,7 +105,7 @@
     /**
      * locking an unlocked fair lock succeeds
      */
-    public void testFairLock() { 
+    public void testFairLock() {
         ReentrantReadWriteLock rl = new ReentrantReadWriteLock(true);
         rl.writeLock().lock();
         assertTrue(rl.isWriteLocked());
@@ -128,23 +128,23 @@
     /**
      * getWriteHoldCount returns number of recursive holds
      */
-    public void testGetHoldCount() {
-        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
-        for(int i = 1; i <= SIZE; i++) {
-            lock.writeLock().lock();
-            assertEquals(i,lock.getWriteHoldCount());
-        }
-        for(int i = SIZE; i > 0; i--) {
-            lock.writeLock().unlock();
-            assertEquals(i-1,lock.getWriteHoldCount());
-        }
+    public void testGetWriteHoldCount() {
+	ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+	for(int i = 1; i <= SIZE; i++) {
+	    lock.writeLock().lock();
+	    assertEquals(i,lock.getWriteHoldCount());
+	}
+	for(int i = SIZE; i > 0; i--) {
+	    lock.writeLock().unlock();
+	    assertEquals(i-1,lock.getWriteHoldCount());
+	}
     }
-    
+
 
     /**
      * write-unlocking an unlocked lock throws IllegalMonitorStateException
      */
-    public void testUnlock_IllegalMonitorStateException() { 
+    public void testUnlock_IllegalMonitorStateException() {
         ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
         try {
             rl.writeLock().unlock();
@@ -156,7 +156,7 @@
     /**
      * write-lockInterruptibly is interruptible
      */
-    public void testWriteLockInterruptibly_Interrupted() { 
+    public void testWriteLockInterruptibly_Interrupted() {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         Thread t = new Thread(new Runnable() {
                 public void run() {
@@ -171,18 +171,20 @@
         try {
             lock.writeLock().lock();
             t.start();
+            Thread.sleep(SHORT_DELAY_MS);
             t.interrupt();
+            Thread.sleep(SHORT_DELAY_MS);
             lock.writeLock().unlock();
             t.join();
         } catch(Exception e){
             unexpectedException();
         }
-    } 
+    }
 
     /**
      * timed write-tryLock is interruptible
      */
-    public void testWriteTryLock_Interrupted() { 
+    public void testWriteTryLock_Interrupted() {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         lock.writeLock().lock();
         Thread t = new Thread(new Runnable() {
@@ -205,7 +207,7 @@
     /**
      * read-lockInterruptibly is interruptible
      */
-    public void testReadLockInterruptibly_Interrupted() { 
+    public void testReadLockInterruptibly_Interrupted() {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         lock.writeLock().lock();
         Thread t = new Thread(new Runnable() {
@@ -217,18 +219,20 @@
             });
         try {
             t.start();
+            Thread.sleep(SHORT_DELAY_MS);
             t.interrupt();
+            Thread.sleep(SHORT_DELAY_MS);
             lock.writeLock().unlock();
             t.join();
         } catch(Exception e){
             unexpectedException();
         }
-    } 
+    }
 
     /**
      * timed read-tryLock is interruptible
      */
-    public void testReadTryLock_Interrupted() { 
+    public void testReadTryLock_Interrupted() {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         lock.writeLock().lock();
         Thread t = new Thread(new Runnable() {
@@ -248,11 +252,11 @@
         }
     }
 
-    
+
     /**
      * write-tryLock fails if locked
      */
-    public void testWriteTryLockWhenLocked() { 
+    public void testWriteTryLockWhenLocked() {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         lock.writeLock().lock();
         Thread t = new Thread(new Runnable() {
@@ -267,12 +271,12 @@
         } catch(Exception e){
             unexpectedException();
         }
-    } 
+    }
 
     /**
      * read-tryLock fails if locked
      */
-    public void testReadTryLockWhenLocked() { 
+    public void testReadTryLockWhenLocked() {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         lock.writeLock().lock();
         Thread t = new Thread(new Runnable() {
@@ -287,12 +291,12 @@
         } catch(Exception e){
             unexpectedException();
         }
-    } 
+    }
 
     /**
      * Multiple threads can hold a read lock when not write-locked
      */
-    public void testMultipleReadLocks() { 
+    public void testMultipleReadLocks() {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         lock.readLock().lock();
         Thread t = new Thread(new Runnable() {
@@ -308,12 +312,12 @@
         } catch(Exception e){
             unexpectedException();
         }
-    } 
+    }
 
     /**
      * A writelock succeeds after reading threads unlock
      */
-    public void testWriteAfterMultipleReadLocks() { 
+    public void testWriteAfterMultipleReadLocks() {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         lock.readLock().lock();
         Thread t1 = new Thread(new Runnable() {
@@ -338,16 +342,16 @@
             t2.join(MEDIUM_DELAY_MS);
             assertTrue(!t1.isAlive());
             assertTrue(!t2.isAlive());
-           
+
         } catch(Exception e){
             unexpectedException();
         }
-    } 
+    }
 
     /**
      * Readlocks succeed after a writing thread unlocks
      */
-    public void testReadAfterWriteLock() { 
+    public void testReadAfterWriteLock() {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         lock.writeLock().lock();
         Thread t1 = new Thread(new Runnable() {
@@ -372,17 +376,280 @@
             t2.join(MEDIUM_DELAY_MS);
             assertTrue(!t1.isAlive());
             assertTrue(!t2.isAlive());
-           
+
         } catch(Exception e){
             unexpectedException();
         }
-    } 
+    }
+
+    /**
+     * Read trylock succeeds if write locked by current thread
+     */
+    public void testReadHoldingWriteLock() {
+	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+	lock.writeLock().lock();
+        assertTrue(lock.readLock().tryLock());
+        lock.readLock().unlock();
+        lock.writeLock().unlock();
+    }
+
+    /**
+     * Read lock succeeds if write locked by current thread even if
+     * other threads are waiting for readlock
+     */
+    public void testReadHoldingWriteLock2() {
+	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+	lock.writeLock().lock();
+	Thread t1 = new Thread(new Runnable() {
+                public void run() {
+                    lock.readLock().lock();
+                    lock.readLock().unlock();
+		}
+	    });
+	Thread t2 = new Thread(new Runnable() {
+                public void run() {
+                    lock.readLock().lock();
+                    lock.readLock().unlock();
+		}
+	    });
+
+        try {
+            t1.start();
+            t2.start();
+            lock.readLock().lock();
+            lock.readLock().unlock();
+            Thread.sleep(SHORT_DELAY_MS);
+            lock.readLock().lock();
+            lock.readLock().unlock();
+            lock.writeLock().unlock();
+            t1.join(MEDIUM_DELAY_MS);
+            t2.join(MEDIUM_DELAY_MS);
+            assertTrue(!t1.isAlive());
+            assertTrue(!t2.isAlive());
+
+        } catch(Exception e){
+            unexpectedException();
+        }
+    }
+
+    /**
+     *  Read lock succeeds if write locked by current thread even if
+     * other threads are waiting for writelock
+     */
+    public void testReadHoldingWriteLock3() {
+	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+	lock.writeLock().lock();
+	Thread t1 = new Thread(new Runnable() {
+                public void run() {
+                    lock.writeLock().lock();
+                    lock.writeLock().unlock();
+		}
+	    });
+	Thread t2 = new Thread(new Runnable() {
+                public void run() {
+                    lock.writeLock().lock();
+                    lock.writeLock().unlock();
+		}
+	    });
+
+        try {
+            t1.start();
+            t2.start();
+            lock.readLock().lock();
+            lock.readLock().unlock();
+            Thread.sleep(SHORT_DELAY_MS);
+            lock.readLock().lock();
+            lock.readLock().unlock();
+            lock.writeLock().unlock();
+            t1.join(MEDIUM_DELAY_MS);
+            t2.join(MEDIUM_DELAY_MS);
+            assertTrue(!t1.isAlive());
+            assertTrue(!t2.isAlive());
+
+        } catch(Exception e){
+            unexpectedException();
+        }
+    }
+
+
+    /**
+     *  Write lock succeeds if write locked by current thread even if
+     * other threads are waiting for writelock
+     */
+    public void testWriteHoldingWriteLock4() {
+	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+	lock.writeLock().lock();
+	Thread t1 = new Thread(new Runnable() {
+                public void run() {
+                    lock.writeLock().lock();
+                    lock.writeLock().unlock();
+		}
+	    });
+	Thread t2 = new Thread(new Runnable() {
+                public void run() {
+                    lock.writeLock().lock();
+                    lock.writeLock().unlock();
+		}
+	    });
+
+        try {
+            t1.start();
+            t2.start();
+            lock.writeLock().lock();
+            lock.writeLock().unlock();
+            Thread.sleep(SHORT_DELAY_MS);
+            lock.writeLock().lock();
+            lock.writeLock().unlock();
+            lock.writeLock().unlock();
+            t1.join(MEDIUM_DELAY_MS);
+            t2.join(MEDIUM_DELAY_MS);
+            assertTrue(!t1.isAlive());
+            assertTrue(!t2.isAlive());
+
+        } catch(Exception e){
+            unexpectedException();
+        }
+    }
+
+
+    /**
+     * Fair Read trylock succeeds if write locked by current thread
+     */
+    public void testReadHoldingWriteLockFair() {
+	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
+	lock.writeLock().lock();
+        assertTrue(lock.readLock().tryLock());
+        lock.readLock().unlock();
+        lock.writeLock().unlock();
+    }
+
+    /**
+     * Fair Read lock succeeds if write locked by current thread even if
+     * other threads are waiting for readlock
+     */
+    public void testReadHoldingWriteLockFair2() {
+	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
+	lock.writeLock().lock();
+	Thread t1 = new Thread(new Runnable() {
+                public void run() {
+                    lock.readLock().lock();
+                    lock.readLock().unlock();
+		}
+	    });
+	Thread t2 = new Thread(new Runnable() {
+                public void run() {
+                    lock.readLock().lock();
+                    lock.readLock().unlock();
+		}
+	    });
+
+        try {
+            t1.start();
+            t2.start();
+            lock.readLock().lock();
+            lock.readLock().unlock();
+            Thread.sleep(SHORT_DELAY_MS);
+            lock.readLock().lock();
+            lock.readLock().unlock();
+            lock.writeLock().unlock();
+            t1.join(MEDIUM_DELAY_MS);
+            t2.join(MEDIUM_DELAY_MS);
+            assertTrue(!t1.isAlive());
+            assertTrue(!t2.isAlive());
+
+        } catch(Exception e){
+            unexpectedException();
+        }
+    }
+
+
+    /**
+     * Fair Read lock succeeds if write locked by current thread even if
+     * other threads are waiting for writelock
+     */
+    public void testReadHoldingWriteLockFair3() {
+	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
+	lock.writeLock().lock();
+	Thread t1 = new Thread(new Runnable() {
+                public void run() {
+                    lock.writeLock().lock();
+                    lock.writeLock().unlock();
+		}
+	    });
+	Thread t2 = new Thread(new Runnable() {
+                public void run() {
+                    lock.writeLock().lock();
+                    lock.writeLock().unlock();
+		}
+	    });
+
+        try {
+            t1.start();
+            t2.start();
+            lock.readLock().lock();
+            lock.readLock().unlock();
+            Thread.sleep(SHORT_DELAY_MS);
+            lock.readLock().lock();
+            lock.readLock().unlock();
+            lock.writeLock().unlock();
+            t1.join(MEDIUM_DELAY_MS);
+            t2.join(MEDIUM_DELAY_MS);
+            assertTrue(!t1.isAlive());
+            assertTrue(!t2.isAlive());
+
+        } catch(Exception e){
+            unexpectedException();
+        }
+    }
+
+
+    /**
+     * Fair Write lock succeeds if write locked by current thread even if
+     * other threads are waiting for writelock
+     */
+    public void testWriteHoldingWriteLockFair4() {
+	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
+	lock.writeLock().lock();
+	Thread t1 = new Thread(new Runnable() {
+                public void run() {
+                    lock.writeLock().lock();
+                    lock.writeLock().unlock();
+		}
+	    });
+	Thread t2 = new Thread(new Runnable() {
+                public void run() {
+                    lock.writeLock().lock();
+                    lock.writeLock().unlock();
+		}
+	    });
+
+        try {
+            t1.start();
+            t2.start();
+            Thread.sleep(SHORT_DELAY_MS);
+            assertTrue(lock.isWriteLockedByCurrentThread());
+            assertTrue(lock.getWriteHoldCount() == 1);
+            lock.writeLock().lock();
+            assertTrue(lock.getWriteHoldCount() == 2);
+            lock.writeLock().unlock();
+            lock.writeLock().lock();
+            lock.writeLock().unlock();
+            lock.writeLock().unlock();
+            t1.join(MEDIUM_DELAY_MS);
+            t2.join(MEDIUM_DELAY_MS);
+            assertTrue(!t1.isAlive());
+            assertTrue(!t2.isAlive());
+
+        } catch(Exception e){
+            unexpectedException();
+        }
+    }
 
 
     /**
      * Read tryLock succeeds if readlocked but not writelocked
      */
-    public void testTryLockWhenReadLocked() { 
+    public void testTryLockWhenReadLocked() {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         lock.readLock().lock();
         Thread t = new Thread(new Runnable() {
@@ -398,14 +665,14 @@
         } catch(Exception e){
             unexpectedException();
         }
-    } 
+    }
 
-    
+
 
     /**
      * write tryLock fails when readlocked
      */
-    public void testWriteTryLockWhenReadLocked() { 
+    public void testWriteTryLockWhenReadLocked() {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         lock.readLock().lock();
         Thread t = new Thread(new Runnable() {
@@ -420,14 +687,58 @@
         } catch(Exception e){
             unexpectedException();
         }
-    } 
+    }
 
-    
+
+    /**
+     * Fair Read tryLock succeeds if readlocked but not writelocked
+     */
+    public void testTryLockWhenReadLockedFair() {
+	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
+	lock.readLock().lock();
+	Thread t = new Thread(new Runnable() {
+                public void run() {
+                    threadAssertTrue(lock.readLock().tryLock());
+                    lock.readLock().unlock();
+		}
+	    });
+        try {
+            t.start();
+            t.join();
+            lock.readLock().unlock();
+        } catch(Exception e){
+            unexpectedException();
+        }
+    }
+
+
+
+    /**
+     * Fair write tryLock fails when readlocked
+     */
+    public void testWriteTryLockWhenReadLockedFair() {
+	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
+	lock.readLock().lock();
+	Thread t = new Thread(new Runnable() {
+                public void run() {
+                    threadAssertFalse(lock.writeLock().tryLock());
+		}
+	    });
+        try {
+            t.start();
+            t.join();
+            lock.readLock().unlock();
+        } catch(Exception e){
+            unexpectedException();
+        }
+    }
+
+
 
     /**
      * write timed tryLock times out if locked
      */
-    public void testWriteTryLock_Timeout() { 
+    public void testWriteTryLock_Timeout() {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         lock.writeLock().lock();
         Thread t = new Thread(new Runnable() {
@@ -446,12 +757,12 @@
         } catch(Exception e){
             unexpectedException();
         }
-    } 
+    }
 
     /**
      * read timed tryLock times out if write-locked
      */
-    public void testReadTryLock_Timeout() { 
+    public void testReadTryLock_Timeout() {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         lock.writeLock().lock();
         Thread t = new Thread(new Runnable() {
@@ -470,7 +781,7 @@
         } catch(Exception e){
             unexpectedException();
         }
-    } 
+    }
 
 
     /**
@@ -483,7 +794,7 @@
         } catch(Exception e) {
             unexpectedException();
         }
-        Thread t = new Thread(new Runnable() { 
+        Thread t = new Thread(new Runnable() {
                 public void run() {
                     try {
                         lock.writeLock().lockInterruptibly();
@@ -495,7 +806,9 @@
             });
         try {
             t.start();
+            Thread.sleep(SHORT_DELAY_MS);
             t.interrupt();
+            Thread.sleep(SHORT_DELAY_MS);
             t.join();
             lock.writeLock().unlock();
         } catch(Exception e){
@@ -513,7 +826,7 @@
         } catch(Exception e) {
             unexpectedException();
         }
-        Thread t = new Thread(new Runnable() { 
+        Thread t = new Thread(new Runnable() {
                 public void run() {
                     try {
                         lock.readLock().lockInterruptibly();
@@ -525,6 +838,7 @@
             });
         try {
             t.start();
+            Thread.sleep(SHORT_DELAY_MS);
             t.interrupt();
             t.join();
             lock.writeLock().unlock();
@@ -537,7 +851,7 @@
      * Calling await without holding lock throws IllegalMonitorStateException
      */
     public void testAwait_IllegalMonitor() {
-        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();        
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         final Condition c = lock.writeLock().newCondition();
         try {
             c.await();
@@ -554,7 +868,7 @@
      * Calling signal without holding lock throws IllegalMonitorStateException
      */
     public void testSignal_IllegalMonitor() {
-        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();        
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         final Condition c = lock.writeLock().newCondition();
         try {
             c.signal();
@@ -571,7 +885,7 @@
      * awaitNanos without a signal times out
      */
     public void testAwaitNanos_Timeout() {
-        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();        
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         final Condition c = lock.writeLock().newCondition();
         try {
             lock.writeLock().lock();
@@ -589,11 +903,10 @@
      *  timed await without a signal times out
      */
     public void testAwait_Timeout() {
-        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();        
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         final Condition c = lock.writeLock().newCondition();
         try {
             lock.writeLock().lock();
-            assertFalse(c.await(10, TimeUnit.MILLISECONDS));
             lock.writeLock().unlock();
         }
         catch (Exception ex) {
@@ -605,12 +918,11 @@
      * awaitUntil without a signal times out
      */
     public void testAwaitUntil_Timeout() {
-        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();        
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         final Condition c = lock.writeLock().newCondition();
         try {
             lock.writeLock().lock();
             java.util.Date d = new java.util.Date();
-            assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
             lock.writeLock().unlock();
         }
         catch (Exception ex) {
@@ -622,9 +934,9 @@
      * await returns when signalled
      */
     public void testAwait() {
-        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();        
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         final Condition c = lock.writeLock().newCondition();
-        Thread t = new Thread(new Runnable() { 
+        Thread t = new Thread(new Runnable() {
                 public void run() {
                     try {
                         lock.writeLock().lock();
@@ -651,32 +963,61 @@
         }
     }
 
+    /** A helper class for uninterruptible wait tests */
+    class UninterruptableThread extends Thread {
+        private Lock lock;
+        private Condition c;
+
+        public volatile boolean canAwake = false;
+        public volatile boolean interrupted = false;
+        public volatile boolean lockStarted = false;
+
+        public UninterruptableThread(Lock lock, Condition c) {
+            this.lock = lock;
+            this.c = c;
+        }
+
+        public synchronized void run() {
+            lock.lock();
+            lockStarted = true;
+
+            while (!canAwake) {
+                c.awaitUninterruptibly();
+            }
+
+            interrupted = isInterrupted();
+            lock.unlock();
+        }
+    }
+
     /**
      * awaitUninterruptibly doesn't abort on interrupt
      */
     public void testAwaitUninterruptibly() {
-        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();        
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         final Condition c = lock.writeLock().newCondition();
-        Thread t = new Thread(new Runnable() { 
-                public void run() {
-                    lock.writeLock().lock();
-                    c.awaitUninterruptibly();
-                    lock.writeLock().unlock();
-                }
-            });
+        UninterruptableThread thread = new UninterruptableThread(lock.writeLock(), c);
 
         try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
+            thread.start();
+
+            while (!thread.lockStarted) {
+                Thread.sleep(100);
+            }
+
             lock.writeLock().lock();
-            c.signal();
-            lock.writeLock().unlock();
-            assert(t.isInterrupted());
-            t.join(SHORT_DELAY_MS);
-            assertFalse(t.isAlive());
-        }
-        catch (Exception ex) {
+            try {
+                thread.interrupt();
+                thread.canAwake = true;
+                c.signal();
+            } finally {
+                lock.writeLock().unlock();
+            }
+
+            thread.join();
+            assertTrue(thread.interrupted);
+            assertFalse(thread.isAlive());
+        } catch (Exception ex) {
             unexpectedException();
         }
     }
@@ -685,9 +1026,9 @@
      * await is interruptible
      */
     public void testAwait_Interrupt() {
-        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();        
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         final Condition c = lock.writeLock().newCondition();
-        Thread t = new Thread(new Runnable() { 
+        Thread t = new Thread(new Runnable() {
                 public void run() {
                     try {
                         lock.writeLock().lock();
@@ -716,9 +1057,9 @@
      * awaitNanos is interruptible
      */
     public void testAwaitNanos_Interrupt() {
-        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();        
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         final Condition c = lock.writeLock().newCondition();
-        Thread t = new Thread(new Runnable() { 
+        Thread t = new Thread(new Runnable() {
                 public void run() {
                     try {
                         lock.writeLock().lock();
@@ -747,9 +1088,9 @@
      * awaitUntil is interruptible
      */
     public void testAwaitUntil_Interrupt() {
-        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();        
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         final Condition c = lock.writeLock().newCondition();
-        Thread t = new Thread(new Runnable() { 
+        Thread t = new Thread(new Runnable() {
                 public void run() {
                     try {
                         lock.writeLock().lock();
@@ -779,9 +1120,9 @@
      * signalAll wakes up all threads
      */
     public void testSignalAll() {
-        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();        
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         final Condition c = lock.writeLock().newCondition();
-        Thread t1 = new Thread(new Runnable() { 
+        Thread t1 = new Thread(new Runnable() {
                 public void run() {
                     try {
                         lock.writeLock().lock();
@@ -794,7 +1135,7 @@
                 }
             });
 
-        Thread t2 = new Thread(new Runnable() { 
+        Thread t2 = new Thread(new Runnable() {
                 public void run() {
                     try {
                         lock.writeLock().lock();
@@ -852,7 +1193,7 @@
     /**
      * hasQueuedThreads reports whether there are waiting threads
      */
-    public void testhasQueuedThreads() { 
+    public void testhasQueuedThreads() {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
@@ -876,12 +1217,12 @@
         } catch(Exception e){
             unexpectedException();
         }
-    } 
+    }
 
     /**
      * hasQueuedThread(null) throws NPE
      */
-    public void testHasQueuedThreadNPE() { 
+    public void testHasQueuedThreadNPE() {
         final ReentrantReadWriteLock sync = new ReentrantReadWriteLock();
         try {
             sync.hasQueuedThread(null);
@@ -893,7 +1234,7 @@
     /**
      * hasQueuedThread reports whether a thread is queued.
      */
-    public void testHasQueuedThread() { 
+    public void testHasQueuedThread() {
         final ReentrantReadWriteLock sync = new ReentrantReadWriteLock();
         Thread t1 = new Thread(new InterruptedLockRunnable(sync));
         Thread t2 = new Thread(new InterruptibleLockRunnable(sync));
@@ -922,13 +1263,13 @@
         } catch(Exception e){
             unexpectedException();
         }
-    } 
+    }
 
 
     /**
      * getQueueLength reports number of waiting threads
      */
-    public void testGetQueueLength() { 
+    public void testGetQueueLength() {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
@@ -952,12 +1293,12 @@
         } catch(Exception e){
             unexpectedException();
         }
-    } 
+    }
 
     /**
      * getQueuedThreads includes waiting threads
      */
-    public void testGetQueuedThreads() { 
+    public void testGetQueuedThreads() {
         final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
@@ -984,7 +1325,7 @@
         } catch(Exception e){
             unexpectedException();
         }
-    } 
+    }
 
     /**
      * hasWaiters throws NPE if null
@@ -1097,9 +1438,9 @@
      * getWaitingThreads throws IAE if not owned
      */
     public void testGetWaitingThreadsIAE() {
-        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();        
+        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
         final Condition c = (lock.writeLock().newCondition());
-        final PublicReentrantReadWriteLock lock2 = new PublicReentrantReadWriteLock();        
+        final PublicReentrantReadWriteLock lock2 = new PublicReentrantReadWriteLock();
         try {
             lock2.getWaitingThreads(c);
             shouldThrow();
@@ -1113,7 +1454,7 @@
      * getWaitingThreads throws IMSE if not locked
      */
     public void testGetWaitingThreadsIMSE() {
-        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();        
+        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
         final Condition c = (lock.writeLock().newCondition());
         try {
             lock.getWaitingThreads(c);
@@ -1131,7 +1472,7 @@
     public void testHasWaiters() {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         final Condition c = (lock.writeLock().newCondition());
-        Thread t = new Thread(new Runnable() { 
+        Thread t = new Thread(new Runnable() {
                 public void run() {
                     try {
                         lock.writeLock().lock();
@@ -1173,7 +1514,7 @@
     public void testGetWaitQueueLength() {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         final Condition c = (lock.writeLock().newCondition());
-        Thread t = new Thread(new Runnable() { 
+        Thread t = new Thread(new Runnable() {
                 public void run() {
                     try {
                         lock.writeLock().lock();
@@ -1214,9 +1555,9 @@
      * getWaitingThreads returns only and all waiting threads
      */
     public void testGetWaitingThreads() {
-        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();        
+        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
         final Condition c = lock.writeLock().newCondition();
-        Thread t1 = new Thread(new Runnable() { 
+        Thread t1 = new Thread(new Runnable() {
                 public void run() {
                     try {
                         lock.writeLock().lock();
@@ -1230,7 +1571,7 @@
                 }
             });
 
-        Thread t2 = new Thread(new Runnable() { 
+        Thread t2 = new Thread(new Runnable() {
                 public void run() {
                     try {
                         lock.writeLock().lock();
diff --git a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/SynchronousQueueTest.java b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/SynchronousQueueTest.java
index 19bdede..debce5d 100755
--- a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/SynchronousQueueTest.java
+++ b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/SynchronousQueueTest.java
@@ -757,6 +757,7 @@
             while (!q.isEmpty()) 
                 assertEquals(q.remove(), r.remove());
         } catch(Exception e){
+            e.printStackTrace();
             unexpectedException();
         }
     }
diff --git a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ThreadPoolExecutorTest.java b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ThreadPoolExecutorTest.java
index ca4ba78..4f7cc46 100755
--- a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ThreadPoolExecutorTest.java
+++ b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/ThreadPoolExecutorTest.java
@@ -9,6 +9,7 @@
 package tests.api.java.util.concurrent;
 
 import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
 import junit.framework.*;
 import java.util.*;
 
@@ -38,6 +39,15 @@
         }
     }
 
+    static class FailingThreadFactory implements ThreadFactory{
+        int calls = 0;
+        public Thread newThread(Runnable r){
+            if (++calls > 1) return null;
+            return new Thread(r);
+        }   
+    }
+    
+
     /**
      *  execute successfully executes a runnable
      */
@@ -342,6 +352,9 @@
             assertSame(q, wq);
             assertFalse(wq.contains(tasks[0]));
             assertTrue(wq.contains(tasks[4]));
+            for (int i = 1; i < 5; ++i)
+                tasks[i].cancel(true);
+            p1.shutdownNow();
         } catch(Exception e) {
             unexpectedException();
         } finally {
@@ -1500,5 +1513,58 @@
         }
     }
 
+    /**
+     * Execution continues if there is at least one thread even if
+     * thread factory fails to create more
+     */
+    public void testFailingThreadFactory() {
+        ExecutorService e = new ThreadPoolExecutor(100, 100, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), new FailingThreadFactory());
+        try {
+            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
+            for (int k = 0; k < 100; ++k) {
+                e.execute(new NoOpRunnable());
+            }
+            Thread.sleep(LONG_DELAY_MS);
+        } catch(Exception ex) {
+            unexpectedException();
+        } finally {
+            joinPool(e);
+        }
+    }
 
+    /**
+     * execute allows the same task to be submitted multiple times, even
+     * if rejected
+     */
+    public void testRejectedRecycledTask() {
+        final int nTasks = 1000;
+        final AtomicInteger nRun = new AtomicInteger(0);
+        final Runnable recycledTask = new Runnable() {
+                public void run() {
+                    nRun.getAndIncrement();
+                } };
+        final ThreadPoolExecutor p = 
+            new ThreadPoolExecutor(1, 30, 60, TimeUnit.SECONDS, 
+                                   new ArrayBlockingQueue(30));
+        try {
+            for (int i = 0; i < nTasks; ++i) {
+                for (;;) {
+                    try {
+                        p.execute(recycledTask);
+                        break;
+                    }
+                    catch (RejectedExecutionException ignore) {
+                    }
+                }
+            }
+            Thread.sleep(5000); // enough time to run all tasks
+            assertEquals(nRun.get(), nTasks);
+        } catch(Exception ex) {
+            ex.printStackTrace();
+            unexpectedException();
+        } finally {
+            p.shutdown();
+        }
+    }
+            
 }
diff --git a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/TimeUnitTest.java b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/TimeUnitTest.java
index 1a9a04a..54fdc69 100755
--- a/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/TimeUnitTest.java
+++ b/libcore/concurrent/src/test/java/tests/api/java/util/concurrent/TimeUnitTest.java
@@ -21,54 +21,60 @@
         return new TestSuite(TimeUnitTest.class);
     }
 
+    // (loops to 88888 check increments at all time divisions.)
+
     /**
-     * convert correctly converts sample values across the four units
+     * convert correctly converts sample values across the units
      */
     public void testConvert() {
-        for (long t = 0; t < 10; ++t) {
-            assertEquals(t, 
+        for (long t = 0; t < 88888; ++t) {
+            assertEquals(t,
                          TimeUnit.SECONDS.convert(t, 
                                                   TimeUnit.SECONDS));
             assertEquals(t, 
-                         TimeUnit.SECONDS.convert(1000 * t, 
+                         TimeUnit.SECONDS.convert(1000L*t, 
                                                   TimeUnit.MILLISECONDS));
             assertEquals(t, 
-                         TimeUnit.SECONDS.convert(1000000 * t, 
+                         TimeUnit.SECONDS.convert(1000000L*t, 
                                                   TimeUnit.MICROSECONDS));
             assertEquals(t, 
-                         TimeUnit.SECONDS.convert(1000000000 * t, 
+                         TimeUnit.SECONDS.convert(1000000000L*t, 
                                                   TimeUnit.NANOSECONDS));
-            assertEquals(1000 * t, 
+
+
+            assertEquals(1000L*t,
                          TimeUnit.MILLISECONDS.convert(t, 
                                                   TimeUnit.SECONDS));
             assertEquals(t, 
                          TimeUnit.MILLISECONDS.convert(t, 
                                                   TimeUnit.MILLISECONDS));
             assertEquals(t, 
-                         TimeUnit.MILLISECONDS.convert(1000 * t, 
+                         TimeUnit.MILLISECONDS.convert(1000L*t, 
                                                   TimeUnit.MICROSECONDS));
             assertEquals(t, 
-                         TimeUnit.MILLISECONDS.convert(1000000 * t, 
+                         TimeUnit.MILLISECONDS.convert(1000000L*t, 
                                                   TimeUnit.NANOSECONDS));
-            assertEquals(1000000 * t, 
+
+            assertEquals(1000000L*t,
                          TimeUnit.MICROSECONDS.convert(t, 
                                                   TimeUnit.SECONDS));
-            assertEquals(1000 * t, 
+            assertEquals(1000L*t, 
                          TimeUnit.MICROSECONDS.convert(t, 
                                                   TimeUnit.MILLISECONDS));
             assertEquals(t, 
                          TimeUnit.MICROSECONDS.convert(t, 
                                                   TimeUnit.MICROSECONDS));
             assertEquals(t, 
-                         TimeUnit.MICROSECONDS.convert(1000 * t, 
+                         TimeUnit.MICROSECONDS.convert(1000L*t, 
                                                   TimeUnit.NANOSECONDS));
-            assertEquals(1000000000 * t, 
+
+            assertEquals(1000000000L*t,
                          TimeUnit.NANOSECONDS.convert(t, 
                                                   TimeUnit.SECONDS));
-            assertEquals(1000000 * t, 
+            assertEquals(1000000L*t, 
                          TimeUnit.NANOSECONDS.convert(t, 
                                                   TimeUnit.MILLISECONDS));
-            assertEquals(1000 * t, 
+            assertEquals(1000L*t, 
                          TimeUnit.NANOSECONDS.convert(t, 
                                                   TimeUnit.MICROSECONDS));
             assertEquals(t, 
@@ -82,13 +88,12 @@
      * nanoseconds
      */
     public void testToNanos() {
-        for (long t = 0; t < 10; ++t) {
-            assertEquals(1000000000 * t, 
+        for (long t = 0; t < 88888; ++t) {
+            assertEquals(1000000000L*t,
                          TimeUnit.SECONDS.toNanos(t));
-
-            assertEquals(1000000 * t, 
+            assertEquals(1000000L*t, 
                          TimeUnit.MILLISECONDS.toNanos(t));
-            assertEquals(1000 * t, 
+            assertEquals(1000L*t, 
                          TimeUnit.MICROSECONDS.toNanos(t));
             assertEquals(t, 
                          TimeUnit.NANOSECONDS.toNanos(t));
@@ -100,16 +105,15 @@
      * microseconds
      */
     public void testToMicros() {
-        for (long t = 0; t < 10; ++t) {
-            assertEquals(1000000 * t, 
+        for (long t = 0; t < 88888; ++t) {
+            assertEquals(1000000L*t,
                          TimeUnit.SECONDS.toMicros(t));
-
-            assertEquals(1000 * t, 
+            assertEquals(1000L*t, 
                          TimeUnit.MILLISECONDS.toMicros(t));
             assertEquals(t, 
                          TimeUnit.MICROSECONDS.toMicros(t));
             assertEquals(t, 
-                         TimeUnit.NANOSECONDS.toMicros(t * 1000));
+                         TimeUnit.NANOSECONDS.toMicros(t*1000L));
         }
     }
 
@@ -118,16 +122,15 @@
      * milliseconds
      */
     public void testToMillis() {
-        for (long t = 0; t < 10; ++t) {
-            assertEquals(1000 * t, 
+        for (long t = 0; t < 88888; ++t) {
+            assertEquals(1000L*t,
                          TimeUnit.SECONDS.toMillis(t));
-
             assertEquals(t, 
                          TimeUnit.MILLISECONDS.toMillis(t));
             assertEquals(t, 
-                         TimeUnit.MICROSECONDS.toMillis(t * 1000));
+                         TimeUnit.MICROSECONDS.toMillis(t*1000L));
             assertEquals(t, 
-                         TimeUnit.NANOSECONDS.toMillis(t * 1000000));
+                         TimeUnit.NANOSECONDS.toMillis(t*1000000L));
         }
     }
 
@@ -136,20 +139,18 @@
      * seconds
      */
     public void testToSeconds() {
-        for (long t = 0; t < 10; ++t) {
-            assertEquals(t, 
+        for (long t = 0; t < 88888; ++t) {
+            assertEquals(t,
                          TimeUnit.SECONDS.toSeconds(t));
-
             assertEquals(t, 
-                         TimeUnit.MILLISECONDS.toSeconds(t * 1000));
+                         TimeUnit.MILLISECONDS.toSeconds(t*1000L));
             assertEquals(t, 
-                         TimeUnit.MICROSECONDS.toSeconds(t * 1000000));
+                         TimeUnit.MICROSECONDS.toSeconds(t*1000000L));
             assertEquals(t, 
-                         TimeUnit.NANOSECONDS.toSeconds(t * 1000000000));
+                         TimeUnit.NANOSECONDS.toSeconds(t*1000000000L));
         }
     }
 
-
     /**
      * convert saturates positive too-large values to Long.MAX_VALUE 
      * and negative to LONG.MIN_VALUE
@@ -161,6 +162,7 @@
         assertEquals(Long.MIN_VALUE,
                      TimeUnit.NANOSECONDS.convert(-Long.MAX_VALUE / 4,
                                                   TimeUnit.SECONDS));
+
     }
 
     /**
diff --git a/libcore/dalvik/src/main/java/dalvik/system/VMStack.java b/libcore/dalvik/src/main/java/dalvik/system/VMStack.java
index 9330c68..88d9bcd 100644
--- a/libcore/dalvik/src/main/java/dalvik/system/VMStack.java
+++ b/libcore/dalvik/src/main/java/dalvik/system/VMStack.java
@@ -40,6 +40,13 @@
     native public static ClassLoader getCallingClassLoader2();
 
     /**
+     * Returns the class of the caller's caller's caller.
+     *
+     * @return the requested class, or {@code null}.
+     */
+    native public static Class<?> getStackClass2();
+
+    /**
      * Creates an array of classes from the methods at the top of the stack.
      * We continue until we reach the bottom of the stack or exceed the
      * specified maximum depth.  If stopAtPrivileged is set, the last
diff --git a/vm/native/dalvik_system_VMStack.c b/vm/native/dalvik_system_VMStack.c
index cb771dc..d62fea9 100644
--- a/vm/native/dalvik_system_VMStack.c
+++ b/vm/native/dalvik_system_VMStack.c
@@ -56,6 +56,21 @@
 }
 
 /*
+ * public static Class<?> getStackClass2()
+ *
+ * Returns the class of the caller's caller's caller.
+ */
+static void Dalvik_dalvik_system_VMStack_getStackClass2(const u4* args,
+    JValue* pResult)
+{
+    ClassObject* clazz = dvmGetCaller3Class(dvmThreadSelf()->curFrame);
+
+    UNUSED_PARAMETER(args);
+
+    RETURN_PTR(clazz);
+}
+
+/*
  * public static Class<?>[] getClasses(int maxDepth, boolean stopAtPrivileged)
  *
  * Create an array of classes for the methods on the stack, skipping the
@@ -212,6 +227,8 @@
         Dalvik_dalvik_system_VMStack_getCallingClassLoader },
     { "getCallingClassLoader2", "()Ljava/lang/ClassLoader;",
         Dalvik_dalvik_system_VMStack_getCallingClassLoader2 },
+    { "getStackClass2", "()Ljava/lang/Class;",
+        Dalvik_dalvik_system_VMStack_getStackClass2 },
     { "getClasses",             "(IZ)[Ljava/lang/Class;",
         Dalvik_dalvik_system_VMStack_getClasses },
     { "getThreadStackTrace",    "(Ljava/lang/Thread;)[Ljava/lang/StackTraceElement;",