You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@commons.apache.org by gg...@apache.org on 2019/08/10 22:26:46 UTC

svn commit: r1048500 [24/39] - in /websites/production/commons/content/proper: commons-pool/ commons-pool/apidocs/ commons-pool/apidocs/org/apache/commons/pool2/ commons-pool/apidocs/org/apache/commons/pool2/class-use/ commons-pool/apidocs/org/apache/c...

Added: websites/production/commons/content/proper/commons-pool/jacoco/org.apache.commons.pool2.impl/LinkedBlockingDeque.java.html
==============================================================================
--- websites/production/commons/content/proper/commons-pool/jacoco/org.apache.commons.pool2.impl/LinkedBlockingDeque.java.html (added)
+++ websites/production/commons/content/proper/commons-pool/jacoco/org.apache.commons.pool2.impl/LinkedBlockingDeque.java.html Sat Aug 10 22:26:44 2019
@@ -0,0 +1,1424 @@
+<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>LinkedBlockingDeque.java</title><link rel="stylesheet" href="../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Apache Commons Pool</a> &gt; <a href="index.source.html" class="el_package">org.apache.commons.pool2.impl</a> &gt; <span class="el_so
 urce">LinkedBlockingDeque.java</span></div><h1>LinkedBlockingDeque.java</h1><pre class="source lang-java linenums">/*
+ * 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 &quot;License&quot;); 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 &quot;AS IS&quot; 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 org.apache.commons.pool2.impl;
+
+import java.io.Serializable;
+import java.util.AbstractQueue;
+import java.util.Collection;
+import java.util.Deque;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Condition;
+
+/**
+ * An optionally-bounded {@linkplain java.util.concurrent.BlockingDeque blocking
+ * deque} based on linked nodes.
+ *
+ * &lt;p&gt; The optional capacity bound constructor argument serves as a
+ * way to prevent excessive expansion. The capacity, if unspecified,
+ * is equal to {@link Integer#MAX_VALUE}.  Linked nodes are
+ * dynamically created upon each insertion unless this would bring the
+ * deque above capacity.
+ *
+ * &lt;p&gt;Most operations run in constant time (ignoring time spent
+ * blocking).  Exceptions include {@link #remove(Object) remove},
+ * {@link #removeFirstOccurrence removeFirstOccurrence}, {@link
+ * #removeLastOccurrence removeLastOccurrence}, {@link #contains
+ * contains}, {@link #iterator iterator.remove()}, and the bulk
+ * operations, all of which run in linear time.
+ *
+ * &lt;p&gt;This class and its iterator implement all of the
+ * &lt;em&gt;optional&lt;/em&gt; methods of the {@link Collection} and {@link
+ * Iterator} interfaces.
+ *
+ * &lt;p&gt;This class is a member of the
+ * &lt;a href=&quot;{@docRoot}/../technotes/guides/collections/index.html&quot;&gt;
+ * Java Collections Framework&lt;/a&gt;.
+ *
+ * @param &lt;E&gt; the type of elements held in this collection
+ *
+ * Note: This was copied from Apache Harmony and modified to suit the needs of
+ *       Commons Pool.
+ *
+ * @since 2.0
+ */
+class LinkedBlockingDeque&lt;E&gt; extends AbstractQueue&lt;E&gt;
+        implements Deque&lt;E&gt;, Serializable {
+
+    /*
+     * Implemented as a simple doubly-linked list protected by a
+     * single lock and using conditions to manage blocking.
+     *
+     * To implement weakly consistent iterators, it appears we need to
+     * keep all Nodes 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 jump to &quot;first&quot; (for next links)
+     * or &quot;last&quot; (for prev links).
+     */
+
+    /*
+     * We have &quot;diamond&quot; multiple interface/abstract class inheritance
+     * here, and that introduces ambiguities. Often we want the
+     * BlockingDeque javadoc combined with the AbstractQueue
+     * implementation, so a lot of method specs are duplicated here.
+     */
+
+    private static final long serialVersionUID = -387911632671998426L;
+
+    /**
+     * Doubly-linked list node class.
+     *
+     * @param &lt;E&gt; node item type
+     */
+    private static final class Node&lt;E&gt; {
+        /**
+         * The item, or null if this node has been removed.
+         */
+        E item;
+
+        /**
+         * One of:
+         * - the real predecessor Node
+         * - this Node, meaning the predecessor is tail
+         * - null, meaning there is no predecessor
+         */
+        Node&lt;E&gt; prev;
+
+        /**
+         * One of:
+         * - the real successor Node
+         * - this Node, meaning the successor is head
+         * - null, meaning there is no successor
+         */
+        Node&lt;E&gt; next;
+
+        /**
+         * Create a new list node.
+         *
+         * @param x The list item
+         * @param p Previous item
+         * @param n Next item
+         */
+<span class="fc" id="L125">        Node(final E x, final Node&lt;E&gt; p, final Node&lt;E&gt; n) {</span>
+<span class="fc" id="L126">            item = x;</span>
+<span class="fc" id="L127">            prev = p;</span>
+<span class="fc" id="L128">            next = n;</span>
+<span class="fc" id="L129">        }</span>
+    }
+
+    /**
+     * Pointer to first node.
+     * Invariant: (first == null &amp;&amp; last == null) ||
+     *            (first.prev == null &amp;&amp; first.item != null)
+     */
+    private transient Node&lt;E&gt; first; // @GuardedBy(&quot;lock&quot;)
+
+    /**
+     * Pointer to last node.
+     * Invariant: (first == null &amp;&amp; last == null) ||
+     *            (last.next == null &amp;&amp; last.item != null)
+     */
+    private transient Node&lt;E&gt; last; // @GuardedBy(&quot;lock&quot;)
+
+    /** Number of items in the deque */
+    private transient int count; // @GuardedBy(&quot;lock&quot;)
+
+    /** Maximum number of items in the deque */
+    private final int capacity;
+
+    /** Main lock guarding all access */
+    private final InterruptibleReentrantLock lock;
+
+    /** Condition for waiting takes */
+    private final Condition notEmpty;
+
+    /** Condition for waiting puts */
+    private final Condition notFull;
+
+    /**
+     * Creates a {@code LinkedBlockingDeque} with a capacity of
+     * {@link Integer#MAX_VALUE}.
+     */
+    public LinkedBlockingDeque() {
+<span class="fc" id="L166">        this(Integer.MAX_VALUE);</span>
+<span class="fc" id="L167">    }</span>
+
+    /**
+     * Creates a {@code LinkedBlockingDeque} with a capacity of
+     * {@link Integer#MAX_VALUE} and the given fairness policy.
+     * @param fairness true means threads waiting on the deque should be served
+     * as if waiting in a FIFO request queue
+     */
+    public LinkedBlockingDeque(final boolean fairness) {
+<span class="fc" id="L176">        this(Integer.MAX_VALUE, fairness);</span>
+<span class="fc" id="L177">    }</span>
+
+    /**
+     * Creates a {@code LinkedBlockingDeque} with the given (fixed) capacity.
+     *
+     * @param capacity the capacity of this deque
+     * @throws IllegalArgumentException if {@code capacity} is less than 1
+     */
+    public LinkedBlockingDeque(final int capacity) {
+<span class="fc" id="L186">        this(capacity, false);</span>
+<span class="fc" id="L187">    }</span>
+
+    /**
+     * Creates a {@code LinkedBlockingDeque} with the given (fixed) capacity
+     * and fairness policy.
+     *
+     * @param capacity the capacity of this deque
+     * @param fairness true means threads waiting on the deque should be served
+     * as if waiting in a FIFO request queue
+     * @throws IllegalArgumentException if {@code capacity} is less than 1
+     */
+<span class="fc" id="L198">    public LinkedBlockingDeque(final int capacity, final boolean fairness) {</span>
+<span class="pc bpc" id="L199" title="1 of 2 branches missed.">        if (capacity &lt;= 0) {</span>
+<span class="nc" id="L200">            throw new IllegalArgumentException();</span>
+        }
+<span class="fc" id="L202">        this.capacity = capacity;</span>
+<span class="fc" id="L203">        lock = new InterruptibleReentrantLock(fairness);</span>
+<span class="fc" id="L204">        notEmpty = lock.newCondition();</span>
+<span class="fc" id="L205">        notFull = lock.newCondition();</span>
+<span class="fc" id="L206">    }</span>
+
+    /**
+     * Creates a {@code LinkedBlockingDeque} with a capacity of
+     * {@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 the specified collection or any
+     *         of its elements are null
+     */
+    public LinkedBlockingDeque(final Collection&lt;? extends E&gt; c) {
+<span class="fc" id="L219">        this(Integer.MAX_VALUE);</span>
+<span class="fc" id="L220">        lock.lock(); // Never contended, but necessary for visibility</span>
+        try {
+<span class="fc bfc" id="L222" title="All 2 branches covered.">            for (final E e : c) {</span>
+<span class="fc bfc" id="L223" title="All 2 branches covered.">                if (e == null) {</span>
+<span class="fc" id="L224">                    throw new NullPointerException();</span>
+                }
+<span class="pc bpc" id="L226" title="1 of 2 branches missed.">                if (!linkLast(e)) {</span>
+<span class="nc" id="L227">                    throw new IllegalStateException(&quot;Deque full&quot;);</span>
+                }
+<span class="fc" id="L229">            }</span>
+        } finally {
+<span class="fc" id="L231">            lock.unlock();</span>
+        }
+<span class="fc" id="L233">    }</span>
+
+
+    // Basic linking and unlinking operations, called only while holding lock
+
+    /**
+     * Links provided element as first element, or returns false if full.
+     *
+     * @param e The element to link as the first element.
+     *
+     * @return {@code true} if successful, otherwise {@code false}
+     */
+    private boolean linkFirst(final E e) {
+        // assert lock.isHeldByCurrentThread();
+<span class="fc bfc" id="L247" title="All 2 branches covered.">        if (count &gt;= capacity) {</span>
+<span class="fc" id="L248">            return false;</span>
+        }
+<span class="fc" id="L250">        final Node&lt;E&gt; f = first;</span>
+<span class="fc" id="L251">        final Node&lt;E&gt; x = new Node&lt;&gt;(e, null, f);</span>
+<span class="fc" id="L252">        first = x;</span>
+<span class="fc bfc" id="L253" title="All 2 branches covered.">        if (last == null) {</span>
+<span class="fc" id="L254">            last = x;</span>
+        } else {
+<span class="fc" id="L256">            f.prev = x;</span>
+        }
+<span class="fc" id="L258">        ++count;</span>
+<span class="fc" id="L259">        notEmpty.signal();</span>
+<span class="fc" id="L260">        return true;</span>
+    }
+
+    /**
+     * Links provided element as last element, or returns false if full.
+     *
+     * @param e The element to link as the last element.
+     *
+     * @return {@code true} if successful, otherwise {@code false}
+     */
+    private boolean linkLast(final E e) {
+        // assert lock.isHeldByCurrentThread();
+<span class="fc bfc" id="L272" title="All 2 branches covered.">        if (count &gt;= capacity) {</span>
+<span class="fc" id="L273">            return false;</span>
+        }
+<span class="fc" id="L275">        final Node&lt;E&gt; l = last;</span>
+<span class="fc" id="L276">        final Node&lt;E&gt; x = new Node&lt;&gt;(e, l, null);</span>
+<span class="fc" id="L277">        last = x;</span>
+<span class="fc bfc" id="L278" title="All 2 branches covered.">        if (first == null) {</span>
+<span class="fc" id="L279">            first = x;</span>
+        } else {
+<span class="fc" id="L281">            l.next = x;</span>
+        }
+<span class="fc" id="L283">        ++count;</span>
+<span class="fc" id="L284">        notEmpty.signal();</span>
+<span class="fc" id="L285">        return true;</span>
+    }
+
+    /**
+     * Removes and returns the first element, or null if empty.
+     *
+     * @return The first element or {@code null} if empty
+     */
+    private E unlinkFirst() {
+        // assert lock.isHeldByCurrentThread();
+<span class="fc" id="L295">        final Node&lt;E&gt; f = first;</span>
+<span class="fc bfc" id="L296" title="All 2 branches covered.">        if (f == null) {</span>
+<span class="fc" id="L297">            return null;</span>
+        }
+<span class="fc" id="L299">        final Node&lt;E&gt; n = f.next;</span>
+<span class="fc" id="L300">        final E item = f.item;</span>
+<span class="fc" id="L301">        f.item = null;</span>
+<span class="fc" id="L302">        f.next = f; // help GC</span>
+<span class="fc" id="L303">        first = n;</span>
+<span class="fc bfc" id="L304" title="All 2 branches covered.">        if (n == null) {</span>
+<span class="fc" id="L305">            last = null;</span>
+        } else {
+<span class="fc" id="L307">            n.prev = null;</span>
+        }
+<span class="fc" id="L309">        --count;</span>
+<span class="fc" id="L310">        notFull.signal();</span>
+<span class="fc" id="L311">        return item;</span>
+    }
+
+    /**
+     * Removes and returns the last element, or null if empty.
+     *
+     * @return The first element or {@code null} if empty
+     */
+    private E unlinkLast() {
+        // assert lock.isHeldByCurrentThread();
+<span class="fc" id="L321">        final Node&lt;E&gt; l = last;</span>
+<span class="fc bfc" id="L322" title="All 2 branches covered.">        if (l == null) {</span>
+<span class="fc" id="L323">            return null;</span>
+        }
+<span class="fc" id="L325">        final Node&lt;E&gt; p = l.prev;</span>
+<span class="fc" id="L326">        final E item = l.item;</span>
+<span class="fc" id="L327">        l.item = null;</span>
+<span class="fc" id="L328">        l.prev = l; // help GC</span>
+<span class="fc" id="L329">        last = p;</span>
+<span class="fc bfc" id="L330" title="All 2 branches covered.">        if (p == null) {</span>
+<span class="fc" id="L331">            first = null;</span>
+        } else {
+<span class="fc" id="L333">            p.next = null;</span>
+        }
+<span class="fc" id="L335">        --count;</span>
+<span class="fc" id="L336">        notFull.signal();</span>
+<span class="fc" id="L337">        return item;</span>
+    }
+
+    /**
+     * Unlinks the provided node.
+     *
+     * @param x The node to unlink
+     */
+    private void unlink(final Node&lt;E&gt; x) {
+        // assert lock.isHeldByCurrentThread();
+<span class="fc" id="L347">        final Node&lt;E&gt; p = x.prev;</span>
+<span class="fc" id="L348">        final Node&lt;E&gt; n = x.next;</span>
+<span class="fc bfc" id="L349" title="All 2 branches covered.">        if (p == null) {</span>
+<span class="fc" id="L350">            unlinkFirst();</span>
+<span class="fc bfc" id="L351" title="All 2 branches covered.">        } else if (n == null) {</span>
+<span class="fc" id="L352">            unlinkLast();</span>
+        } else {
+<span class="fc" id="L354">            p.next = n;</span>
+<span class="fc" id="L355">            n.prev = p;</span>
+<span class="fc" id="L356">            x.item = null;</span>
+            // Don't mess with x's links.  They may still be in use by
+            // an iterator.
+<span class="fc" id="L359">        --count;</span>
+<span class="fc" id="L360">            notFull.signal();</span>
+        }
+<span class="fc" id="L362">    }</span>
+
+    // BlockingDeque methods
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void addFirst(final E e) {
+<span class="fc bfc" id="L371" title="All 2 branches covered.">        if (!offerFirst(e)) {</span>
+<span class="fc" id="L372">            throw new IllegalStateException(&quot;Deque full&quot;);</span>
+        }
+<span class="fc" id="L374">    }</span>
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void addLast(final E e) {
+<span class="fc bfc" id="L381" title="All 2 branches covered.">        if (!offerLast(e)) {</span>
+<span class="fc" id="L382">            throw new IllegalStateException(&quot;Deque full&quot;);</span>
+        }
+<span class="fc" id="L384">    }</span>
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean offerFirst(final E e) {
+<span class="fc bfc" id="L391" title="All 2 branches covered.">        if (e == null) {</span>
+<span class="fc" id="L392">            throw new NullPointerException();</span>
+        }
+<span class="fc" id="L394">        lock.lock();</span>
+        try {
+<span class="fc" id="L396">            return linkFirst(e);</span>
+        } finally {
+<span class="fc" id="L398">            lock.unlock();</span>
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean offerLast(final E e) {
+<span class="fc bfc" id="L407" title="All 2 branches covered.">        if (e == null) {</span>
+<span class="fc" id="L408">            throw new NullPointerException();</span>
+        }
+<span class="fc" id="L410">        lock.lock();</span>
+        try {
+<span class="fc" id="L412">            return linkLast(e);</span>
+        } finally {
+<span class="fc" id="L414">            lock.unlock();</span>
+        }
+    }
+
+    /**
+     * Links the provided element as the first in the queue, waiting until there
+     * is space to do so if the queue is full.
+     *
+     * @param e element to link
+     *
+     * @throws NullPointerException if e is null
+     * @throws InterruptedException if the thread is interrupted whilst waiting
+     *         for space
+     */
+    public void putFirst(final E e) throws InterruptedException {
+<span class="fc bfc" id="L429" title="All 2 branches covered.">        if (e == null) {</span>
+<span class="fc" id="L430">            throw new NullPointerException();</span>
+        }
+<span class="fc" id="L432">        lock.lock();</span>
+        try {
+<span class="pc bpc" id="L434" title="1 of 2 branches missed.">            while (!linkFirst(e)) {</span>
+<span class="nc" id="L435">                notFull.await();</span>
+            }
+        } finally {
+<span class="fc" id="L438">            lock.unlock();</span>
+        }
+<span class="fc" id="L440">    }</span>
+
+    /**
+     * Links the provided element as the last in the queue, waiting until there
+     * is space to do so if the queue is full.
+     *
+     * @param e element to link
+     *
+     * @throws NullPointerException if e is null
+     * @throws InterruptedException if the thread is interrupted whilst waiting
+     *         for space
+     */
+    public void putLast(final E e) throws InterruptedException {
+<span class="fc bfc" id="L453" title="All 2 branches covered.">        if (e == null) {</span>
+<span class="fc" id="L454">            throw new NullPointerException();</span>
+        }
+<span class="fc" id="L456">        lock.lock();</span>
+        try {
+<span class="pc bpc" id="L458" title="1 of 2 branches missed.">            while (!linkLast(e)) {</span>
+<span class="nc" id="L459">                notFull.await();</span>
+            }
+        } finally {
+<span class="fc" id="L462">            lock.unlock();</span>
+        }
+<span class="fc" id="L464">    }</span>
+
+    /**
+     * Links the provided element as the first in the queue, waiting up to the
+     * specified time to do so if the queue is full.
+     *
+     * @param e         element to link
+     * @param timeout   length of time to wait
+     * @param unit      units that timeout is expressed in
+     *
+     * @return {@code true} if successful, otherwise {@code false}
+     *
+     * @throws NullPointerException if e is null
+     * @throws InterruptedException if the thread is interrupted whilst waiting
+     *         for space
+     */
+    public boolean offerFirst(final E e, final long timeout, final TimeUnit unit)
+        throws InterruptedException {
+<span class="pc bpc" id="L482" title="1 of 2 branches missed.">        if (e == null) {</span>
+<span class="nc" id="L483">            throw new NullPointerException();</span>
+        }
+<span class="fc" id="L485">        long nanos = unit.toNanos(timeout);</span>
+<span class="fc" id="L486">        lock.lockInterruptibly();</span>
+        try {
+<span class="fc bfc" id="L488" title="All 2 branches covered.">            while (!linkFirst(e)) {</span>
+<span class="fc bfc" id="L489" title="All 2 branches covered.">                if (nanos &lt;= 0) {</span>
+<span class="fc" id="L490">                    return false;</span>
+                }
+<span class="fc" id="L492">                nanos = notFull.awaitNanos(nanos);</span>
+            }
+<span class="fc" id="L494">            return true;</span>
+        } finally {
+<span class="fc" id="L496">            lock.unlock();</span>
+        }
+    }
+
+    /**
+     * Links the provided element as the last in the queue, waiting up to the
+     * specified time to do so if the queue is full.
+     *
+     * @param e         element to link
+     * @param timeout   length of time to wait
+     * @param unit      units that timeout is expressed in
+     *
+     * @return {@code true} if successful, otherwise {@code false}
+     *
+     * @throws NullPointerException if e is null
+     * @throws InterruptedException if the thread is interrupted whist waiting
+     *         for space
+     */
+    public boolean offerLast(final E e, final long timeout, final TimeUnit unit)
+        throws InterruptedException {
+<span class="fc bfc" id="L516" title="All 2 branches covered.">        if (e == null) {</span>
+<span class="fc" id="L517">            throw new NullPointerException();</span>
+        }
+<span class="fc" id="L519">        long nanos = unit.toNanos(timeout);</span>
+<span class="fc" id="L520">        lock.lockInterruptibly();</span>
+        try {
+<span class="fc bfc" id="L522" title="All 2 branches covered.">            while (!linkLast(e)) {</span>
+<span class="fc bfc" id="L523" title="All 2 branches covered.">                if (nanos &lt;= 0) {</span>
+<span class="fc" id="L524">                    return false;</span>
+                }
+<span class="fc" id="L526">                nanos = notFull.awaitNanos(nanos);</span>
+            }
+<span class="fc" id="L528">            return true;</span>
+        } finally {
+<span class="fc" id="L530">            lock.unlock();</span>
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public E removeFirst() {
+<span class="fc" id="L539">        final E x = pollFirst();</span>
+<span class="fc bfc" id="L540" title="All 2 branches covered.">        if (x == null) {</span>
+<span class="fc" id="L541">            throw new NoSuchElementException();</span>
+        }
+<span class="fc" id="L543">        return x;</span>
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public E removeLast() {
+<span class="fc" id="L551">        final E x = pollLast();</span>
+<span class="fc bfc" id="L552" title="All 2 branches covered.">        if (x == null) {</span>
+<span class="fc" id="L553">            throw new NoSuchElementException();</span>
+        }
+<span class="fc" id="L555">        return x;</span>
+    }
+
+    @Override
+    public E pollFirst() {
+<span class="fc" id="L560">        lock.lock();</span>
+        try {
+<span class="fc" id="L562">            return unlinkFirst();</span>
+        } finally {
+<span class="fc" id="L564">            lock.unlock();</span>
+        }
+    }
+
+    @Override
+    public E pollLast() {
+<span class="fc" id="L570">        lock.lock();</span>
+        try {
+<span class="fc" id="L572">            return unlinkLast();</span>
+        } finally {
+<span class="fc" id="L574">            lock.unlock();</span>
+        }
+    }
+
+    /**
+     * Unlinks the first element in the queue, waiting until there is an element
+     * to unlink if the queue is empty.
+     *
+     * @return the unlinked element
+     * @throws InterruptedException if the current thread is interrupted
+     */
+    public E takeFirst() throws InterruptedException {
+<span class="fc" id="L586">        lock.lock();</span>
+        try {
+            E x;
+<span class="fc bfc" id="L589" title="All 2 branches covered.">            while ( (x = unlinkFirst()) == null) {</span>
+<span class="fc" id="L590">                notEmpty.await();</span>
+            }
+<span class="fc" id="L592">            return x;</span>
+        } finally {
+<span class="fc" id="L594">            lock.unlock();</span>
+        }
+    }
+
+    /**
+     * Unlinks the last element in the queue, waiting until there is an element
+     * to unlink if the queue is empty.
+     *
+     * @return the unlinked element
+     * @throws InterruptedException if the current thread is interrupted
+     */
+    public E takeLast() throws InterruptedException {
+<span class="fc" id="L606">        lock.lock();</span>
+        try {
+            E x;
+<span class="pc bpc" id="L609" title="1 of 2 branches missed.">            while ( (x = unlinkLast()) == null) {</span>
+<span class="nc" id="L610">                notEmpty.await();</span>
+            }
+<span class="fc" id="L612">            return x;</span>
+        } finally {
+<span class="fc" id="L614">            lock.unlock();</span>
+        }
+    }
+
+    /**
+     * Unlinks the first element in the queue, waiting up to the specified time
+     * to do so if the queue is empty.
+     *
+     * @param timeout   length of time to wait
+     * @param unit      units that timeout is expressed in
+     *
+     * @return the unlinked element
+     * @throws InterruptedException if the current thread is interrupted
+     */
+    public E pollFirst(final long timeout, final TimeUnit unit)
+        throws InterruptedException {
+<span class="fc" id="L630">        long nanos = unit.toNanos(timeout);</span>
+<span class="fc" id="L631">        lock.lockInterruptibly();</span>
+        try {
+            E x;
+<span class="fc bfc" id="L634" title="All 2 branches covered.">            while ( (x = unlinkFirst()) == null) {</span>
+<span class="fc bfc" id="L635" title="All 2 branches covered.">                if (nanos &lt;= 0) {</span>
+<span class="fc" id="L636">                    return null;</span>
+                }
+<span class="fc" id="L638">                nanos = notEmpty.awaitNanos(nanos);</span>
+            }
+<span class="fc" id="L640">            return x;</span>
+        } finally {
+<span class="fc" id="L642">            lock.unlock();</span>
+        }
+    }
+
+    /**
+     * Unlinks the last element in the queue, waiting up to the specified time
+     * to do so if the queue is empty.
+     *
+     * @param timeout   length of time to wait
+     * @param unit      units that timeout is expressed in
+     *
+     * @return the unlinked element
+     * @throws InterruptedException if the current thread is interrupted
+     */
+    public E pollLast(final long timeout, final TimeUnit unit)
+        throws InterruptedException {
+<span class="fc" id="L658">        long nanos = unit.toNanos(timeout);</span>
+<span class="fc" id="L659">        lock.lockInterruptibly();</span>
+        try {
+            E x;
+<span class="pc bpc" id="L662" title="1 of 2 branches missed.">            while ( (x = unlinkLast()) == null) {</span>
+<span class="fc bfc" id="L663" title="All 2 branches covered.">                if (nanos &lt;= 0) {</span>
+<span class="fc" id="L664">                    return null;</span>
+                }
+<span class="fc" id="L666">                nanos = notEmpty.awaitNanos(nanos);</span>
+            }
+<span class="nc" id="L668">            return x;</span>
+        } finally {
+<span class="fc" id="L670">            lock.unlock();</span>
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public E getFirst() {
+<span class="fc" id="L679">        final E x = peekFirst();</span>
+<span class="fc bfc" id="L680" title="All 2 branches covered.">        if (x == null) {</span>
+<span class="fc" id="L681">            throw new NoSuchElementException();</span>
+        }
+<span class="fc" id="L683">        return x;</span>
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public E getLast() {
+<span class="fc" id="L691">        final E x = peekLast();</span>
+<span class="fc bfc" id="L692" title="All 2 branches covered.">        if (x == null) {</span>
+<span class="fc" id="L693">            throw new NoSuchElementException();</span>
+        }
+<span class="fc" id="L695">        return x;</span>
+    }
+
+    @Override
+    public E peekFirst() {
+<span class="fc" id="L700">        lock.lock();</span>
+        try {
+<span class="fc bfc" id="L702" title="All 2 branches covered.">            return first == null ? null : first.item;</span>
+        } finally {
+<span class="fc" id="L704">            lock.unlock();</span>
+        }
+    }
+
+    @Override
+    public E peekLast() {
+<span class="fc" id="L710">        lock.lock();</span>
+        try {
+<span class="fc bfc" id="L712" title="All 2 branches covered.">            return last == null ? null : last.item;</span>
+        } finally {
+<span class="fc" id="L714">            lock.unlock();</span>
+        }
+    }
+
+    @Override
+    public boolean removeFirstOccurrence(final Object o) {
+<span class="pc bpc" id="L720" title="1 of 2 branches missed.">        if (o == null) {</span>
+<span class="nc" id="L721">            return false;</span>
+        }
+<span class="fc" id="L723">        lock.lock();</span>
+        try {
+<span class="fc bfc" id="L725" title="All 2 branches covered.">            for (Node&lt;E&gt; p = first; p != null; p = p.next) {</span>
+<span class="fc bfc" id="L726" title="All 2 branches covered.">                if (o.equals(p.item)) {</span>
+<span class="fc" id="L727">                    unlink(p);</span>
+<span class="fc" id="L728">                    return true;</span>
+                }
+            }
+<span class="fc" id="L731">            return false;</span>
+        } finally {
+<span class="fc" id="L733">            lock.unlock();</span>
+        }
+    }
+
+    @Override
+    public boolean removeLastOccurrence(final Object o) {
+<span class="fc bfc" id="L739" title="All 2 branches covered.">        if (o == null) {</span>
+<span class="fc" id="L740">            return false;</span>
+        }
+<span class="fc" id="L742">        lock.lock();</span>
+        try {
+<span class="pc bfc" id="L744" title="All 2 branches covered.">            for (Node&lt;E&gt; p = last; p != null; p = p.prev) {</span>
+<span class="pc bpc" id="L745" title="1 of 2 branches missed.">                if (o.equals(p.item)) {</span>
+<span class="fc" id="L746">                    unlink(p);</span>
+<span class="fc" id="L747">                    return true;</span>
+                }
+            }
+<span class="fc" id="L750">            return false;</span>
+        } finally {
+<span class="fc" id="L752">            lock.unlock();</span>
+        }
+    }
+
+    // BlockingQueue methods
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean add(final E e) {
+<span class="fc" id="L763">        addLast(e);</span>
+<span class="fc" id="L764">        return true;</span>
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean offer(final E e) {
+<span class="fc" id="L772">        return offerLast(e);</span>
+    }
+
+    /**
+     * Links the provided element as the last in the queue, waiting until there
+     * is space to do so if the queue is full.
+     *
+     * &lt;p&gt;This method is equivalent to {@link #putLast(Object)}.
+     *
+     * @param e element to link
+     *
+     * @throws NullPointerException if e is null
+     * @throws InterruptedException if the thread is interrupted whilst waiting
+     *         for space
+     */
+    public void put(final E e) throws InterruptedException {
+<span class="fc" id="L788">        putLast(e);</span>
+<span class="fc" id="L789">    }</span>
+
+    /**
+     * Links the provided element as the last in the queue, waiting up to the
+     * specified time to do so if the queue is full.
+     * &lt;p&gt;
+     * This method is equivalent to {@link #offerLast(Object, long, TimeUnit)}
+     *
+     * @param e         element to link
+     * @param timeout   length of time to wait
+     * @param unit      units that timeout is expressed in
+     *
+     * @return {@code true} if successful, otherwise {@code false}
+     *
+     * @throws NullPointerException if e is null
+     * @throws InterruptedException if the thread is interrupted whilst waiting
+     *         for space
+     */
+    public boolean offer(final E e, final long timeout, final TimeUnit unit)
+        throws InterruptedException {
+<span class="fc" id="L809">        return offerLast(e, timeout, unit);</span>
+    }
+
+    /**
+     * Retrieves and removes the head of the queue represented by this deque.
+     * This method differs from {@link #poll poll} only in that it throws an
+     * exception if this deque is empty.
+     *
+     * &lt;p&gt;This method is equivalent to {@link #removeFirst() removeFirst}.
+     *
+     * @return the head of the queue represented by this deque
+     * @throws NoSuchElementException if this deque is empty
+     */
+    @Override
+    public E remove() {
+<span class="fc" id="L824">        return removeFirst();</span>
+    }
+
+    @Override
+    public E poll() {
+<span class="fc" id="L829">        return pollFirst();</span>
+    }
+
+    /**
+     * Unlinks the first element in the queue, waiting until there is an element
+     * to unlink if the queue is empty.
+     *
+     * &lt;p&gt;This method is equivalent to {@link #takeFirst()}.
+     *
+     * @return the unlinked element
+     * @throws InterruptedException if the current thread is interrupted
+     */
+    public E take() throws InterruptedException {
+<span class="fc" id="L842">        return takeFirst();</span>
+    }
+
+    /**
+     * Unlinks the first element in the queue, waiting up to the specified time
+     * to do so if the queue is empty.
+     *
+     * &lt;p&gt;This method is equivalent to {@link #pollFirst(long, TimeUnit)}.
+     *
+     * @param timeout   length of time to wait
+     * @param unit      units that timeout is expressed in
+     *
+     * @return the unlinked element
+     * @throws InterruptedException if the current thread is interrupted
+     */
+    public E poll(final long timeout, final TimeUnit unit) throws InterruptedException {
+<span class="fc" id="L858">        return pollFirst(timeout, unit);</span>
+    }
+
+    /**
+     * Retrieves, but does not remove, the head of the queue represented by
+     * this deque.  This method differs from {@link #peek peek} only in that
+     * it throws an exception if this deque is empty.
+     *
+     * &lt;p&gt;This method is equivalent to {@link #getFirst() getFirst}.
+     *
+     * @return the head of the queue represented by this deque
+     * @throws NoSuchElementException if this deque is empty
+     */
+    @Override
+    public E element() {
+<span class="fc" id="L873">        return getFirst();</span>
+    }
+
+    @Override
+    public E peek() {
+<span class="fc" id="L878">        return peekFirst();</span>
+    }
+
+    /**
+     * Returns the number of additional elements that this deque can ideally
+     * (in the absence of memory or resource constraints) accept without
+     * blocking. This is always equal to the initial capacity of this deque
+     * less the current {@code size} of this deque.
+     *
+     * &lt;p&gt;Note that you &lt;em&gt;cannot&lt;/em&gt; always tell if an attempt to insert
+     * an element will succeed by inspecting {@code remainingCapacity}
+     * because it may be the case that another thread is about to
+     * insert or remove an element.
+     *
+     * @return The number of additional elements the queue is able to accept
+     */
+    public int remainingCapacity() {
+<span class="fc" id="L895">        lock.lock();</span>
+        try {
+<span class="fc" id="L897">            return capacity - count;</span>
+        } finally {
+<span class="fc" id="L899">            lock.unlock();</span>
+        }
+    }
+
+    /**
+     * Drains the queue to the specified collection.
+     *
+     * @param c The collection to add the elements to
+     *
+     * @return number of elements added to the collection
+     *
+     * @throws UnsupportedOperationException if the add operation is not
+     *         supported by the specified collection
+     * @throws ClassCastException if the class of the elements held by this
+     *         collection prevents them from being added to the specified
+     *         collection
+     * @throws NullPointerException if c is null
+     * @throws IllegalArgumentException if c is this instance
+     */
+    public int drainTo(final Collection&lt;? super E&gt; c) {
+<span class="fc" id="L919">        return drainTo(c, Integer.MAX_VALUE);</span>
+    }
+
+    /**
+     * Drains no more than the specified number of elements from the queue to the
+     * specified collection.
+     *
+     * @param c           collection to add the elements to
+     * @param maxElements maximum number of elements to remove from the queue
+     *
+     * @return number of elements added to the collection
+     * @throws UnsupportedOperationException if the add operation is not
+     *         supported by the specified collection
+     * @throws ClassCastException if the class of the elements held by this
+     *         collection prevents them from being added to the specified
+     *         collection
+     * @throws NullPointerException if c is null
+     * @throws IllegalArgumentException if c is this instance
+     */
+    public int drainTo(final Collection&lt;? super E&gt; c, final int maxElements) {
+<span class="pc bpc" id="L939" title="1 of 2 branches missed.">        if (c == null) {</span>
+<span class="nc" id="L940">            throw new NullPointerException();</span>
+        }
+<span class="pc bpc" id="L942" title="1 of 2 branches missed.">        if (c == this) {</span>
+<span class="nc" id="L943">            throw new IllegalArgumentException();</span>
+        }
+<span class="fc" id="L945">        lock.lock();</span>
+        try {
+<span class="fc" id="L947">            final int n = Math.min(maxElements, count);</span>
+<span class="fc bfc" id="L948" title="All 2 branches covered.">            for (int i = 0; i &lt; n; i++) {</span>
+<span class="fc" id="L949">                c.add(first.item);   // In this order, in case add() throws.</span>
+<span class="fc" id="L950">                unlinkFirst();</span>
+            }
+<span class="fc" id="L952">            return n;</span>
+        } finally {
+<span class="fc" id="L954">            lock.unlock();</span>
+        }
+    }
+
+    // Stack methods
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void push(final E e) {
+<span class="fc" id="L965">        addFirst(e);</span>
+<span class="fc" id="L966">    }</span>
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public E pop() {
+<span class="fc" id="L973">        return removeFirst();</span>
+    }
+
+    // Collection methods
+
+    /**
+     * Removes the first occurrence of the specified element from this deque.
+     * If the deque does not contain the element, it is unchanged.
+     * More formally, removes the first element {@code e} such that
+     * {@code o.equals(e)} (if such an element exists).
+     * Returns {@code true} if this deque contained the specified element
+     * (or equivalently, if this deque changed as a result of the call).
+     *
+     * &lt;p&gt;This method is equivalent to
+     * {@link #removeFirstOccurrence(Object) removeFirstOccurrence}.
+     *
+     * @param o element to be removed from this deque, if present
+     * @return {@code true} if this deque changed as a result of the call
+     */
+    @Override
+    public boolean remove(final Object o) {
+<span class="fc" id="L994">        return removeFirstOccurrence(o);</span>
+    }
+
+    /**
+     * Returns the number of elements in this deque.
+     *
+     * @return the number of elements in this deque
+     */
+    @Override
+    public int size() {
+<span class="fc" id="L1004">        lock.lock();</span>
+        try {
+<span class="fc" id="L1006">            return count;</span>
+        } finally {
+<span class="fc" id="L1008">            lock.unlock();</span>
+        }
+    }
+
+    /**
+     * Returns {@code true} if this deque contains the specified element.
+     * More formally, returns {@code true} if and only if this deque contains
+     * at least one element {@code e} such that {@code o.equals(e)}.
+     *
+     * @param o object to be checked for containment in this deque
+     * @return {@code true} if this deque contains the specified element
+     */
+    @Override
+    public boolean contains(final Object o) {
+<span class="fc bfc" id="L1022" title="All 2 branches covered.">        if (o == null) {</span>
+<span class="fc" id="L1023">            return false;</span>
+        }
+<span class="fc" id="L1025">        lock.lock();</span>
+        try {
+<span class="fc bfc" id="L1027" title="All 2 branches covered.">            for (Node&lt;E&gt; p = first; p != null; p = p.next) {</span>
+<span class="fc bfc" id="L1028" title="All 2 branches covered.">                if (o.equals(p.item)) {</span>
+<span class="fc" id="L1029">                    return true;</span>
+                }
+            }
+<span class="fc" id="L1032">            return false;</span>
+        } finally {
+<span class="fc" id="L1034">            lock.unlock();</span>
+        }
+    }
+
+    /*
+     * TODO: Add support for more efficient bulk operations.
+     *
+     * We don't want to acquire the lock for every iteration, but we
+     * also want other threads a chance to interact with the
+     * collection, especially when count is close to capacity.
+     */
+
+//     /**
+//      * Adds all of the elements in the specified collection to this
+//      * queue.  Attempts to addAll of a queue to itself result in
+//      * {@code IllegalArgumentException}. Further, 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 queue
+//      * @return {@code true} if this queue changed as a result of the call
+//      * @throws ClassCastException
+//      * @throws NullPointerException
+//      * @throws IllegalArgumentException
+//      * @throws IllegalStateException
+//      * @see #add(Object)
+//      */
+//     public boolean addAll(Collection&lt;? extends E&gt; c) {
+//         if (c == null)
+//             throw new NullPointerException();
+//         if (c == this)
+//             throw new IllegalArgumentException();
+//         final ReentrantLock lock = this.lock;
+//         lock.lock();
+//         try {
+//             boolean modified = false;
+//             for (E e : c)
+//                 if (linkLast(e))
+//                     modified = true;
+//             return modified;
+//         } finally {
+//             lock.unlock();
+//         }
+//     }
+
+    /**
+     * Returns an array containing all of the elements in this deque, in
+     * proper sequence (from first to last element).
+     *
+     * &lt;p&gt;The returned array will be &quot;safe&quot; in that no references to it are
+     * maintained by this deque.  (In other words, this method must allocate
+     * a new array).  The caller is thus free to modify the returned array.
+     *
+     * &lt;p&gt;This method acts as bridge between array-based and collection-based
+     * APIs.
+     *
+     * @return an array containing all of the elements in this deque
+     */
+    @Override
+    public Object[] toArray() {
+<span class="fc" id="L1094">        lock.lock();</span>
+        try {
+<span class="fc" id="L1096">            final Object[] a = new Object[count];</span>
+<span class="fc" id="L1097">            int k = 0;</span>
+<span class="fc bfc" id="L1098" title="All 2 branches covered.">            for (Node&lt;E&gt; p = first; p != null; p = p.next) {</span>
+<span class="fc" id="L1099">                a[k++] = p.item;</span>
+            }
+<span class="fc" id="L1101">            return a;</span>
+        } finally {
+<span class="fc" id="L1103">            lock.unlock();</span>
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @SuppressWarnings(&quot;unchecked&quot;)
+    @Override
+    public &lt;T&gt; T[] toArray(T[] a) {
+<span class="fc" id="L1113">        lock.lock();</span>
+        try {
+<span class="fc bfc" id="L1115" title="All 2 branches covered.">            if (a.length &lt; count) {</span>
+<span class="fc" id="L1116">                a = (T[])java.lang.reflect.Array.newInstance</span>
+<span class="fc" id="L1117">                    (a.getClass().getComponentType(), count);</span>
+            }
+<span class="fc" id="L1119">            int k = 0;</span>
+<span class="fc bfc" id="L1120" title="All 2 branches covered.">            for (Node&lt;E&gt; p = first; p != null; p = p.next) {</span>
+<span class="fc" id="L1121">                a[k++] = (T)p.item;</span>
+            }
+<span class="pc bpc" id="L1123" title="1 of 2 branches missed.">            if (a.length &gt; k) {</span>
+<span class="nc" id="L1124">                a[k] = null;</span>
+            }
+<span class="fc" id="L1126">            return a;</span>
+        } finally {
+<span class="fc" id="L1128">            lock.unlock();</span>
+        }
+    }
+
+    @Override
+    public String toString() {
+<span class="fc" id="L1134">        lock.lock();</span>
+        try {
+<span class="fc" id="L1136">            return super.toString();</span>
+        } finally {
+<span class="fc" id="L1138">            lock.unlock();</span>
+        }
+    }
+
+    /**
+     * Atomically removes all of the elements from this deque.
+     * The deque will be empty after this call returns.
+     */
+    @Override
+    public void clear() {
+<span class="fc" id="L1148">        lock.lock();</span>
+        try {
+<span class="fc bfc" id="L1150" title="All 2 branches covered.">            for (Node&lt;E&gt; f = first; f != null;) {</span>
+<span class="fc" id="L1151">                f.item = null;</span>
+<span class="fc" id="L1152">                final Node&lt;E&gt; n = f.next;</span>
+<span class="fc" id="L1153">                f.prev = null;</span>
+<span class="fc" id="L1154">                f.next = null;</span>
+<span class="fc" id="L1155">                f = n;</span>
+<span class="fc" id="L1156">            }</span>
+<span class="fc" id="L1157">            first = last = null;</span>
+<span class="fc" id="L1158">            count = 0;</span>
+<span class="fc" id="L1159">            notFull.signalAll();</span>
+        } finally {
+<span class="fc" id="L1161">            lock.unlock();</span>
+        }
+<span class="fc" id="L1163">    }</span>
+
+    /**
+     * Returns an iterator over the elements in this deque in proper sequence.
+     * The elements will be returned in order from first (head) to last (tail).
+     * The returned {@code Iterator} is a &quot;weakly consistent&quot; iterator that
+     * will never throw {@link java.util.ConcurrentModificationException
+     * 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 deque in proper sequence
+     */
+    @Override
+    public Iterator&lt;E&gt; iterator() {
+<span class="fc" id="L1179">        return new Itr();</span>
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Iterator&lt;E&gt; descendingIterator() {
+<span class="fc" id="L1187">        return new DescendingItr();</span>
+    }
+
+    /**
+     * Base class for Iterators for LinkedBlockingDeque
+     */
+    private abstract class AbstractItr implements Iterator&lt;E&gt; {
+        /**
+         * The next node to return in next()
+         */
+         Node&lt;E&gt; next;
+
+        /**
+         * nextItem holds on to item fields because once we claim that
+         * an element exists in hasNext(), we must return item read
+         * under lock (in advance()) even if it was in the process of
+         * being removed when hasNext() was called.
+         */
+        E nextItem;
+
+        /**
+         * Node returned by most recent call to next. Needed by remove.
+         * Reset to null if this element is deleted by a call to remove.
+         */
+        private Node&lt;E&gt; lastRet;
+
+        /**
+         * Obtain the first node to be returned by the iterator.
+         *
+         * @return first node
+         */
+        abstract Node&lt;E&gt; firstNode();
+
+        /**
+         * For a given node, obtain the next node to be returned by the
+         * iterator.
+         *
+         * @param n given node
+         *
+         * @return next node
+         */
+        abstract Node&lt;E&gt; nextNode(Node&lt;E&gt; n);
+
+        /**
+         * Create a new iterator. Sets the initial position.
+         */
+<span class="fc" id="L1233">        AbstractItr() {</span>
+            // set to initial position
+<span class="fc" id="L1235">            lock.lock();</span>
+            try {
+<span class="fc" id="L1237">                next = firstNode();</span>
+<span class="fc bfc" id="L1238" title="All 2 branches covered.">                nextItem = next == null ? null : next.item;</span>
+            } finally {
+<span class="fc" id="L1240">                lock.unlock();</span>
+            }
+<span class="fc" id="L1242">        }</span>
+
+        /**
+         * Returns the successor node of the given non-null, but
+         * possibly previously deleted, node.
+         *
+         * @param n node whose successor is sought
+         * @return successor node
+         */
+        private Node&lt;E&gt; succ(Node&lt;E&gt; n) {
+            // Chains of deleted nodes ending in null or self-links
+            // are possible if multiple interior nodes are removed.
+            for (;;) {
+<span class="fc" id="L1255">                final Node&lt;E&gt; s = nextNode(n);</span>
+<span class="fc bfc" id="L1256" title="All 2 branches covered.">                if (s == null) {</span>
+<span class="fc" id="L1257">                    return null;</span>
+<span class="fc bfc" id="L1258" title="All 2 branches covered.">                } else if (s.item != null) {</span>
+<span class="fc" id="L1259">                    return s;</span>
+<span class="fc bfc" id="L1260" title="All 2 branches covered.">                } else if (s == n) {</span>
+<span class="fc" id="L1261">                    return firstNode();</span>
+                } else {
+<span class="fc" id="L1263">                    n = s;</span>
+                }
+<span class="fc" id="L1265">            }</span>
+        }
+
+        /**
+         * Advances next.
+         */
+        void advance() {
+<span class="fc" id="L1272">            lock.lock();</span>
+            try {
+                // assert next != null;
+<span class="fc" id="L1275">                next = succ(next);</span>
+<span class="fc bfc" id="L1276" title="All 2 branches covered.">                nextItem = next == null ? null : next.item;</span>
+            } finally {
+<span class="fc" id="L1278">                lock.unlock();</span>
+            }
+<span class="fc" id="L1280">        }</span>
+
+        @Override
+        public boolean hasNext() {
+<span class="fc bfc" id="L1284" title="All 2 branches covered.">            return next != null;</span>
+        }
+
+        @Override
+        public E next() {
+<span class="fc bfc" id="L1289" title="All 2 branches covered.">            if (next == null) {</span>
+<span class="fc" id="L1290">                throw new NoSuchElementException();</span>
+            }
+<span class="fc" id="L1292">            lastRet = next;</span>
+<span class="fc" id="L1293">            final E x = nextItem;</span>
+<span class="fc" id="L1294">            advance();</span>
+<span class="fc" id="L1295">            return x;</span>
+        }
+
+        @Override
+        public void remove() {
+<span class="fc" id="L1300">            final Node&lt;E&gt; n = lastRet;</span>
+<span class="pc bpc" id="L1301" title="1 of 2 branches missed.">            if (n == null) {</span>
+<span class="nc" id="L1302">                throw new IllegalStateException();</span>
+            }
+<span class="fc" id="L1304">            lastRet = null;</span>
+<span class="fc" id="L1305">            lock.lock();</span>
+            try {
+<span class="pc bpc" id="L1307" title="1 of 2 branches missed.">                if (n.item != null) {</span>
+<span class="fc" id="L1308">                    unlink(n);</span>
+                }
+            } finally {
+<span class="fc" id="L1311">                lock.unlock();</span>
+            }
+<span class="fc" id="L1313">        }</span>
+    }
+
+    /** Forward iterator */
+<span class="fc" id="L1317">    private class Itr extends AbstractItr {</span>
+        @Override
+<span class="fc" id="L1319">        Node&lt;E&gt; firstNode() { return first; }</span>
+        @Override
+<span class="fc" id="L1321">        Node&lt;E&gt; nextNode(final Node&lt;E&gt; n) { return n.next; }</span>
+        }
+
+    /** Descending iterator */
+<span class="fc" id="L1325">    private class DescendingItr extends AbstractItr {</span>
+        @Override
+<span class="fc" id="L1327">        Node&lt;E&gt; firstNode() { return last; }</span>
+        @Override
+<span class="fc" id="L1329">        Node&lt;E&gt; nextNode(final Node&lt;E&gt; n) { return n.prev; }</span>
+    }
+
+    /**
+     * Saves the state of this deque to a stream (that is, serialize it).
+     *
+     * @serialData The capacity (int), followed by elements (each an
+     * {@code Object}) in the proper order, followed by a null
+     * @param s the stream
+     */
+    private void writeObject(final java.io.ObjectOutputStream s)
+        throws java.io.IOException {
+<span class="nc" id="L1341">        lock.lock();</span>
+        try {
+            // Write out capacity and any hidden stuff
+<span class="nc" id="L1344">            s.defaultWriteObject();</span>
+            // Write out all elements in the proper order.
+<span class="nc bnc" id="L1346" title="All 2 branches missed.">            for (Node&lt;E&gt; p = first; p != null; p = p.next) {</span>
+<span class="nc" id="L1347">                s.writeObject(p.item);</span>
+            }
+            // Use trailing null as sentinel
+<span class="nc" id="L1350">            s.writeObject(null);</span>
+        } finally {
+<span class="nc" id="L1352">            lock.unlock();</span>
+        }
+<span class="nc" id="L1354">    }</span>
+
+    /**
+     * Reconstitutes this deque from a stream (that is,
+     * deserialize it).
+     * @param s the stream
+     */
+    private void readObject(final java.io.ObjectInputStream s)
+        throws java.io.IOException, ClassNotFoundException {
+<span class="nc" id="L1363">        s.defaultReadObject();</span>
+<span class="nc" id="L1364">        count = 0;</span>
+<span class="nc" id="L1365">        first = null;</span>
+<span class="nc" id="L1366">        last = null;</span>
+        // Read in all elements and place in queue
+        for (;;) {
+            @SuppressWarnings(&quot;unchecked&quot;)
+            final
+<span class="nc" id="L1371">            E item = (E)s.readObject();</span>
+<span class="nc bnc" id="L1372" title="All 2 branches missed.">            if (item == null) {</span>
+<span class="nc" id="L1373">                break;</span>
+            }
+<span class="nc" id="L1375">            add(item);</span>
+<span class="nc" id="L1376">        }</span>
+<span class="nc" id="L1377">    }</span>
+
+    // Monitoring methods
+
+    /**
+     * Returns true if there are threads waiting to take instances from this deque. See disclaimer on accuracy in
+     * {@link java.util.concurrent.locks.ReentrantLock#hasWaiters(Condition)}.
+     *
+     * @return true if there is at least one thread waiting on this deque's notEmpty condition.
+     */
+    public boolean hasTakeWaiters() {
+<span class="fc" id="L1388">        lock.lock();</span>
+        try {
+<span class="fc" id="L1390">            return lock.hasWaiters(notEmpty);</span>
+        } finally {
+<span class="fc" id="L1392">            lock.unlock();</span>
+        }
+    }
+
+    /**
+     * Returns the length of the queue of threads waiting to take instances from this deque. See disclaimer on accuracy
+     * in {@link java.util.concurrent.locks.ReentrantLock#getWaitQueueLength(Condition)}.
+     *
+     * @return number of threads waiting on this deque's notEmpty condition.
+     */
+    public int getTakeQueueLength() {
+<span class="fc" id="L1403">        lock.lock();</span>
+        try {
+<span class="fc" id="L1405">           return lock.getWaitQueueLength(notEmpty);</span>
+        } finally {
+<span class="fc" id="L1407">            lock.unlock();</span>
+        }
+    }
+
+    /**
+     * Interrupts the threads currently waiting to take an object from the pool. See disclaimer on accuracy in
+     * {@link java.util.concurrent.locks.ReentrantLock#getWaitingThreads(Condition)}.
+     */
+    public void interuptTakeWaiters() {
+<span class="fc" id="L1416">        lock.lock();</span>
+        try {
+<span class="fc" id="L1418">           lock.interruptWaiters(notEmpty);</span>
+        } finally {
+<span class="fc" id="L1420">            lock.unlock();</span>
+        }
+<span class="fc" id="L1422">    }</span>
+}
+</pre><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.3.201901230119</span></div></body></html>
\ No newline at end of file

Added: websites/production/commons/content/proper/commons-pool/jacoco/org.apache.commons.pool2.impl/NoOpCallStack.html
==============================================================================
--- websites/production/commons/content/proper/commons-pool/jacoco/org.apache.commons.pool2.impl/NoOpCallStack.html (added)
+++ websites/production/commons/content/proper/commons-pool/jacoco/org.apache.commons.pool2.impl/NoOpCallStack.html Sat Aug 10 22:26:44 2019
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>NoOpCallStack</title><script type="text/javascript" src="../jacoco-resources/sort.js"></script></head><body onload="initialSort(['breadcrumb'])"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Apache Commons Pool</a> &gt; <a href="index.html" class="el_package">org.apache.commons.pool2.impl</a> &gt; <span class="el_class">NoOpCallStack</span></div><h1>NoOpCallStack</h1><table class="coverage" cellspacing="0" id="coveragetable"><
 thead><tr><td class="sortable" id="a" onclick="toggleSort(this)">Element</td><td class="down sortable bar" id="b" onclick="toggleSort(this)">Missed Instructions</td><td class="sortable ctr2" id="c" onclick="toggleSort(this)">Cov.</td><td class="sortable bar" id="d" onclick="toggleSort(this)">Missed Branches</td><td class="sortable ctr2" id="e" onclick="toggleSort(this)">Cov.</td><td class="sortable ctr1" id="f" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="g" onclick="toggleSort(this)">Cxty</td><td class="sortable ctr1" id="h" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="i" onclick="toggleSort(this)">Lines</td><td class="sortable ctr1" id="j" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="k" onclick="toggleSort(this)">Methods</td></tr></thead><tfoot><tr><td>Total</td><td class="bar">3 of 9</td><td class="ctr2">66%</td><td class="bar">0 of 0</td><td class="ctr2">n/a</td><td class="ctr1">2</td><td class="ctr2">4</td><td
  class="ctr1">2</td><td class="ctr2">4</td><td class="ctr1">2</td><td class="ctr2">4</td></tr></tfoot><tbody><tr><td id="a2"><a href="NoOpCallStack.java.html#L42" class="el_method">printStackTrace(PrintWriter)</a></td><td class="bar" id="b0"><img src="../jacoco-resources/redbar.gif" width="48" height="10" title="2" alt="2"/></td><td class="ctr2" id="c2">0%</td><td class="bar" id="d0"/><td class="ctr2" id="e0">n/a</td><td class="ctr1" id="f0">1</td><td class="ctr2" id="g0">1</td><td class="ctr1" id="h0">1</td><td class="ctr2" id="i0">1</td><td class="ctr1" id="j0">1</td><td class="ctr2" id="k0">1</td></tr><tr><td id="a1"><a href="NoOpCallStack.java.html#L48" class="el_method">fillInStackTrace()</a></td><td class="bar" id="b1"><img src="../jacoco-resources/redbar.gif" width="24" height="10" title="1" alt="1"/></td><td class="ctr2" id="c3">0%</td><td class="bar" id="d1"/><td class="ctr2" id="e1">n/a</td><td class="ctr1" id="f1">1</td><td class="ctr2" id="g1">1</td><td class="ctr1" id="
 h1">1</td><td class="ctr2" id="i1">1</td><td class="ctr1" id="j1">1</td><td class="ctr2" id="k1">1</td></tr><tr><td id="a3"><a href="NoOpCallStack.java.html#L32" class="el_method">static {...}</a></td><td class="bar" id="b2"><img src="../jacoco-resources/greenbar.gif" width="120" height="10" title="5" alt="5"/></td><td class="ctr2" id="c0">100%</td><td class="bar" id="d2"/><td class="ctr2" id="e2">n/a</td><td class="ctr1" id="f2">0</td><td class="ctr2" id="g2">1</td><td class="ctr1" id="h2">0</td><td class="ctr2" id="i2">1</td><td class="ctr1" id="j2">0</td><td class="ctr2" id="k2">1</td></tr><tr><td id="a0"><a href="NoOpCallStack.java.html#L53" class="el_method">clear()</a></td><td class="bar" id="b3"><img src="../jacoco-resources/greenbar.gif" width="24" height="10" title="1" alt="1"/></td><td class="ctr2" id="c1">100%</td><td class="bar" id="d3"/><td class="ctr2" id="e3">n/a</td><td class="ctr1" id="f3">0</td><td class="ctr2" id="g3">1</td><td class="ctr1" id="h3">0</td><td class
 ="ctr2" id="i3">1</td><td class="ctr1" id="j3">0</td><td class="ctr2" id="k3">1</td></tr></tbody></table><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.3.201901230119</span></div></body></html>
\ No newline at end of file

Added: websites/production/commons/content/proper/commons-pool/jacoco/org.apache.commons.pool2.impl/NoOpCallStack.java.html
==============================================================================
--- websites/production/commons/content/proper/commons-pool/jacoco/org.apache.commons.pool2.impl/NoOpCallStack.java.html (added)
+++ websites/production/commons/content/proper/commons-pool/jacoco/org.apache.commons.pool2.impl/NoOpCallStack.java.html Sat Aug 10 22:26:44 2019
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>NoOpCallStack.java</title><link rel="stylesheet" href="../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Apache Commons Pool</a> &gt; <a href="index.source.html" class="el_package">org.apache.commons.pool2.impl</a> &gt; <span class="el_source">
 NoOpCallStack.java</span></div><h1>NoOpCallStack.java</h1><pre class="source lang-java linenums">/*
+ * 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 &quot;License&quot;); 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 &quot;AS IS&quot; 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 org.apache.commons.pool2.impl;
+
+import java.io.PrintWriter;
+
+/**
+ * CallStack strategy using no-op implementations of all functionality. Can be used by default when abandoned object
+ * logging is disabled.
+ *
+ * @since 2.5
+ */
+public class NoOpCallStack implements CallStack {
+
+    /**
+     * Singleton instance.
+     */
+<span class="fc" id="L32">    public static final CallStack INSTANCE = new NoOpCallStack();</span>
+
+    /**
+     * Constructs the singleton instance.
+     */
+    private NoOpCallStack() {
+    }
+
+    @Override
+    public boolean printStackTrace(final PrintWriter writer) {
+<span class="nc" id="L42">        return false;</span>
+    }
+
+    @Override
+    public void fillInStackTrace() {
+        // no-op
+<span class="nc" id="L48">    }</span>
+
+    @Override
+    public void clear() {
+        // no-op
+<span class="fc" id="L53">    }</span>
+}
+</pre><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.3.201901230119</span></div></body></html>
\ No newline at end of file

Added: websites/production/commons/content/proper/commons-pool/jacoco/org.apache.commons.pool2.impl/PoolImplUtils.html
==============================================================================
--- websites/production/commons/content/proper/commons-pool/jacoco/org.apache.commons.pool2.impl/PoolImplUtils.html (added)
+++ websites/production/commons/content/proper/commons-pool/jacoco/org.apache.commons.pool2.impl/PoolImplUtils.html Sat Aug 10 22:26:44 2019
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>PoolImplUtils</title><script type="text/javascript" src="../jacoco-resources/sort.js"></script></head><body onload="initialSort(['breadcrumb'])"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Apache Commons Pool</a> &gt; <a href="index.html" class="el_package">org.apache.commons.pool2.impl</a> &gt; <span class="el_class">PoolImplUtils</span></div><h1>PoolImplUtils</h1><table class="coverage" cellspacing="0" id="coveragetable"><
 thead><tr><td class="sortable" id="a" onclick="toggleSort(this)">Element</td><td class="down sortable bar" id="b" onclick="toggleSort(this)">Missed Instructions</td><td class="sortable ctr2" id="c" onclick="toggleSort(this)">Cov.</td><td class="sortable bar" id="d" onclick="toggleSort(this)">Missed Branches</td><td class="sortable ctr2" id="e" onclick="toggleSort(this)">Cov.</td><td class="sortable ctr1" id="f" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="g" onclick="toggleSort(this)">Cxty</td><td class="sortable ctr1" id="h" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="i" onclick="toggleSort(this)">Lines</td><td class="sortable ctr1" id="j" onclick="toggleSort(this)">Missed</td><td class="sortable ctr2" id="k" onclick="toggleSort(this)">Methods</td></tr></thead><tfoot><tr><td>Total</td><td class="bar">13 of 160</td><td class="ctr2">91%</td><td class="bar">11 of 34</td><td class="ctr2">67%</td><td class="ctr1">12</td><td class="ctr2">22<
 /td><td class="ctr1">5</td><td class="ctr2">39</td><td class="ctr1">1</td><td class="ctr2">5</td></tr></tfoot><tbody><tr><td id="a1"><a href="PoolImplUtils.java.html#L78" class="el_method">getGenericType(Class, Class)</a></td><td class="bar" id="b0"><img src="../jacoco-resources/redbar.gif" width="9" height="10" title="4" alt="4"/><img src="../jacoco-resources/greenbar.gif" width="110" height="10" title="45" alt="45"/></td><td class="ctr2" id="c3">91%</td><td class="bar" id="d1"><img src="../jacoco-resources/redbar.gif" width="36" height="10" title="3" alt="3"/><img src="../jacoco-resources/greenbar.gif" width="84" height="10" title="7" alt="7"/></td><td class="ctr2" id="e1">70%</td><td class="ctr1" id="f1">3</td><td class="ctr2" id="g0">6</td><td class="ctr1" id="h0">2</td><td class="ctr2" id="i0">13</td><td class="ctr1" id="j1">0</td><td class="ctr2" id="k0">1</td></tr><tr><td id="a4"><a href="PoolImplUtils.java.html#L30" class="el_method">PoolImplUtils()</a></td><td class="bar" i
 d="b1"><img src="../jacoco-resources/redbar.gif" width="7" height="10" title="3" alt="3"/></td><td class="ctr2" id="c4">0%</td><td class="bar" id="d4"/><td class="ctr2" id="e4">n/a</td><td class="ctr1" id="f3">1</td><td class="ctr2" id="g4">1</td><td class="ctr1" id="h1">1</td><td class="ctr2" id="i4">1</td><td class="ctr1" id="j0">1</td><td class="ctr2" id="k1">1</td></tr><tr><td id="a0"><a href="PoolImplUtils.java.html#L42" class="el_method">getFactoryType(Class)</a></td><td class="bar" id="b2"><img src="../jacoco-resources/redbar.gif" width="4" height="10" title="2" alt="2"/><img src="../jacoco-resources/greenbar.gif" width="102" height="10" title="42" alt="42"/></td><td class="ctr2" id="c0">95%</td><td class="bar" id="d0"><img src="../jacoco-resources/redbar.gif" width="48" height="10" title="4" alt="4"/><img src="../jacoco-resources/greenbar.gif" width="72" height="10" title="6" alt="6"/></td><td class="ctr2" id="e3">60%</td><td class="ctr1" id="f0">4</td><td class="ctr2" id="g
 1">6</td><td class="ctr1" id="h2">1</td><td class="ctr2" id="i1">12</td><td class="ctr1" id="j2">0</td><td class="ctr2" id="k2">1</td></tr><tr><td id="a2"><a href="PoolImplUtils.java.html#L119" class="el_method">getParameterizedType(Class, Class)</a></td><td class="bar" id="b3"><img src="../jacoco-resources/redbar.gif" width="4" height="10" title="2" alt="2"/><img src="../jacoco-resources/greenbar.gif" width="85" height="10" title="35" alt="35"/></td><td class="ctr2" id="c1">94%</td><td class="bar" id="d2"><img src="../jacoco-resources/redbar.gif" width="36" height="10" title="3" alt="3"/><img src="../jacoco-resources/greenbar.gif" width="60" height="10" title="5" alt="5"/></td><td class="ctr2" id="e2">62%</td><td class="ctr1" id="f2">3</td><td class="ctr2" id="g2">5</td><td class="ctr1" id="h4">0</td><td class="ctr2" id="i3">6</td><td class="ctr1" id="j3">0</td><td class="ctr2" id="k3">1</td></tr><tr><td id="a3"><a href="PoolImplUtils.java.html#L145" class="el_method">getTypeParame
 ter(Class, Type)</a></td><td class="bar" id="b4"><img src="../jacoco-resources/redbar.gif" width="4" height="10" title="2" alt="2"/><img src="../jacoco-resources/greenbar.gif" width="61" height="10" title="25" alt="25"/></td><td class="ctr2" id="c2">92%</td><td class="bar" id="d3"><img src="../jacoco-resources/redbar.gif" width="12" height="10" title="1" alt="1"/><img src="../jacoco-resources/greenbar.gif" width="60" height="10" title="5" alt="5"/></td><td class="ctr2" id="e0">83%</td><td class="ctr1" id="f4">1</td><td class="ctr2" id="g3">4</td><td class="ctr1" id="h3">1</td><td class="ctr2" id="i2">7</td><td class="ctr1" id="j4">0</td><td class="ctr2" id="k4">1</td></tr></tbody></table><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.3.201901230119</span></div></body></html>
\ No newline at end of file

Added: websites/production/commons/content/proper/commons-pool/jacoco/org.apache.commons.pool2.impl/PoolImplUtils.java.html
==============================================================================
--- websites/production/commons/content/proper/commons-pool/jacoco/org.apache.commons.pool2.impl/PoolImplUtils.java.html (added)
+++ websites/production/commons/content/proper/commons-pool/jacoco/org.apache.commons.pool2.impl/PoolImplUtils.java.html Sat Aug 10 22:26:44 2019
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>PoolImplUtils.java</title><link rel="stylesheet" href="../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Apache Commons Pool</a> &gt; <a href="index.source.html" class="el_package">org.apache.commons.pool2.impl</a> &gt; <span class="el_source">
 PoolImplUtils.java</span></div><h1>PoolImplUtils.java</h1><pre class="source lang-java linenums">/*
+ * 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 &quot;License&quot;); 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 &quot;AS IS&quot; 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 org.apache.commons.pool2.impl;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+
+import org.apache.commons.pool2.PooledObjectFactory;
+
+/**
+ * Implementation specific utilities.
+ *
+ * @since 2.0
+ */
+<span class="nc" id="L30">class PoolImplUtils {</span>
+
+    /**
+     * Identifies the concrete type of object that an object factory creates.
+     *
+     * @param factoryClass
+     *            The factory to examine
+     *
+     * @return the type of object the factory creates
+     */
+    @SuppressWarnings(&quot;rawtypes&quot;)
+    static Class&lt;?&gt; getFactoryType(final Class&lt;? extends PooledObjectFactory&gt; factoryClass) {
+<span class="fc" id="L42">        final Class&lt;PooledObjectFactory&gt; type = PooledObjectFactory.class;</span>
+<span class="fc" id="L43">        final Object genericType = getGenericType(type, factoryClass);</span>
+<span class="fc bfc" id="L44" title="All 2 branches covered.">        if (genericType instanceof Integer) {</span>
+            // POOL-324 org.apache.commons.pool2.impl.GenericObjectPool.getFactoryType() throws
+            // java.lang.ClassCastException
+            //
+            // A bit hackish, but we must handle cases when getGenericType() does not return a concrete types.
+<span class="fc" id="L49">            final ParameterizedType pi = getParameterizedType(type, factoryClass);</span>
+<span class="pc bpc" id="L50" title="1 of 2 branches missed.">            if (pi != null) {</span>
+<span class="fc" id="L51">                final Type[] bounds = ((TypeVariable) pi.getActualTypeArguments()[(Integer) genericType]).getBounds();</span>
+<span class="pc bpc" id="L52" title="2 of 4 branches missed.">                if (bounds != null &amp;&amp; bounds.length &gt; 0) {</span>
+<span class="fc" id="L53">                    final Type bound0 = bounds[0];</span>
+<span class="pc bpc" id="L54" title="1 of 2 branches missed.">                    if (bound0 instanceof Class) {</span>
+<span class="fc" id="L55">                        return (Class&lt;?&gt;) bound0;</span>
+                    }
+                }
+            }
+            // last resort: Always return a Class
+<span class="nc" id="L60">            return Object.class;</span>
+        }
+<span class="fc" id="L62">        return (Class&lt;?&gt;) genericType;</span>
+    }
+
+    /**
+     * Obtains the concrete type used by an implementation of an interface that uses a generic type.
+     *
+     * @param type
+     *            The interface that defines a generic type
+     * @param clazz
+     *            The class that implements the interface with a concrete type
+     * @param &lt;T&gt;
+     *            The interface type
+     *
+     * @return concrete type used by the implementation
+     */
+    private static &lt;T&gt; Object getGenericType(final Class&lt;T&gt; type, final Class&lt;? extends T&gt; clazz) {
+<span class="pc bpc" id="L78" title="2 of 4 branches missed.">        if (type == null || clazz == null) {</span>
+            // Error will be logged further up the call stack
+<span class="nc" id="L80">            return null;</span>
+        }
+
+        // Look to see if this class implements the generic interface
+<span class="fc" id="L84">        final ParameterizedType pi = getParameterizedType(type, clazz);</span>
+<span class="fc bfc" id="L85" title="All 2 branches covered.">        if (pi != null) {</span>
+<span class="fc" id="L86">            return getTypeParameter(clazz, pi.getActualTypeArguments()[0]);</span>
+        }
+
+        // Interface not found on this class. Look at the superclass.
+        @SuppressWarnings(&quot;unchecked&quot;)
+<span class="fc" id="L91">        final Class&lt;? extends T&gt; superClass = (Class&lt;? extends T&gt;) clazz.getSuperclass();</span>
+
+<span class="fc" id="L93">        final Object result = getGenericType(type, superClass);</span>
+<span class="fc bfc" id="L94" title="All 2 branches covered.">        if (result instanceof Class&lt;?&gt;) {</span>
+            // Superclass implements interface and defines explicit type for generic
+<span class="fc" id="L96">            return result;</span>
+<span class="pc bpc" id="L97" title="1 of 2 branches missed.">        } else if (result instanceof Integer) {</span>
+            // Superclass implements interface and defines unknown type for generic
+            // Map that unknown type to the generic types defined in this class
+<span class="fc" id="L100">            final ParameterizedType superClassType = (ParameterizedType) clazz.getGenericSuperclass();</span>
+<span class="fc" id="L101">            return getTypeParameter(clazz, superClassType.getActualTypeArguments()[((Integer) result).intValue()]);</span>
+        } else {
+            // Error will be logged further up the call stack
+<span class="nc" id="L104">            return null;</span>
+        }
+    }
+
+    /**
+     * Gets the matching parameterized type or null.
+     * @param type
+     *            The interface that defines a generic type.
+     * @param clazz
+     *            The class that implements the interface with a concrete type.
+     * @param &lt;T&gt;
+     *            The interface type.
+     * @return the matching parameterized type or null.
+     */
+    private static &lt;T&gt; ParameterizedType getParameterizedType(final Class&lt;T&gt; type, final Class&lt;? extends T&gt; clazz) {
+<span class="pc bfc" id="L119" title="All 2 branches covered.">        for (final Type iface : clazz.getGenericInterfaces()) {</span>
+            // Only need to check interfaces that use generics
+<span class="pc bpc" id="L121" title="1 of 2 branches missed.">            if (iface instanceof ParameterizedType) {</span>
+<span class="fc" id="L122">                final ParameterizedType pi = (ParameterizedType) iface;</span>
+                // Look for the generic interface
+<span class="pc bpc" id="L124" title="2 of 4 branches missed.">                if (pi.getRawType() instanceof Class &amp;&amp; type.isAssignableFrom((Class&lt;?&gt;) pi.getRawType())) {</span>
+<span class="fc" id="L125">                    return pi;</span>
+                }
+            }
+        }
+<span class="fc" id="L129">        return null;</span>
+    }
+
+    /**
+     * For a generic parameter, return either the Class used or if the type is unknown, the index for the type in
+     * definition of the class
+     *
+     * @param clazz
+     *            defining class
+     * @param argType
+     *            the type argument of interest
+     *
+     * @return An instance of {@link Class} representing the type used by the type parameter or an instance of
+     *         {@link Integer} representing the index for the type in the definition of the defining class
+     */
+    private static Object getTypeParameter(final Class&lt;?&gt; clazz, final Type argType) {
+<span class="fc bfc" id="L145" title="All 2 branches covered.">        if (argType instanceof Class&lt;?&gt;) {</span>
+<span class="fc" id="L146">            return argType;</span>
+        }
+<span class="fc" id="L148">        final TypeVariable&lt;?&gt;[] tvs = clazz.getTypeParameters();</span>
+<span class="pc bpc" id="L149" title="1 of 2 branches missed.">        for (int i = 0; i &lt; tvs.length; i++) {</span>
+<span class="fc bfc" id="L150" title="All 2 branches covered.">            if (tvs[i].equals(argType)) {</span>
+<span class="fc" id="L151">                return Integer.valueOf(i);</span>
+            }
+        }
+<span class="nc" id="L154">        return null;</span>
+    }
+}
+</pre><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.3.201901230119</span></div></body></html>
\ No newline at end of file