content: package android.util;
  
  public final class Pools {
  
    /**
     * Interface for managing a pool of objects.
     *
     * @param <T> The pooled type.
     */
    public static interface Pool<T> {
  
      /**
       * @return An instance from the pool if such, null otherwise.
       */
      public T acquire();
  
      /**
       * Release an instance to the pool.
       *
       * @param instance The instance to release.
       * @return Whether the instance was put in the pool.
       * @throws IllegalStateException If the instance is already in the pool.
       */
      public boolean release(T instance);
    }
  
    private Pools() {
      /* do nothing - hiding constructor */
    }
  
    /**
     * Simple (non-synchronized) pool of objects.
     *
     * @param <T> The pooled type.
     */
    public static class SimplePool<T> implements Pool<T> {
      private final Object[] mPool;
  
      private int mPoolSize;
  
      /**
       * Creates a new instance.
       *
       * @param maxPoolSize The max pool size.
       * @throws IllegalArgumentException If the max pool size is less than zero.
       */
      public SimplePool(int maxPoolSize) {
        if (maxPoolSize <= 0) {
          throw new IllegalArgumentException("The max pool size must be > 0");
        }
        mPool = new Object[maxPoolSize];
      }
  
      @Override
      @SuppressWarnings("unchecked")
      public T acquire() {
        if (mPoolSize > 0) {
          final int lastPooledIndex = mPoolSize - 1;
          T instance = (T) mPool[lastPooledIndex];
          mPool[lastPooledIndex] = null;
          mPoolSize--;
          return instance;
        }
        return null;
      }
  
      @Override
      public boolean release(T instance) {
        if (isInPool(instance)) {
          throw new IllegalStateException("Already in the pool!");
        }
        if (mPoolSize < mPool.length) {
          mPool[mPoolSize] = instance;
          mPoolSize++;
          return true;
        }
        return false;
      }
  
      private boolean isInPool(T instance) {
        for (int i = 0; i < mPoolSize; i++) {
          if (mPool[i] == instance) {
            return true;
          }
        }
        return false;
      }
    }
  
    /**
     * Synchronized pool of objects.
     *
     * @param <T> The pooled type.
     */
    public static class SynchronizedPool<T> extends SimplePool<T> {
      private final Object mLock;
  
      /**
       * Creates a new instance.
       *
       * @param maxPoolSize The max pool size.
       * @param lock        an optional custom object to synchronize on
       * @throws IllegalArgumentException If the max pool size is less than zero.
       */
      public SynchronizedPool(int maxPoolSize, Object lock) {
        super(maxPoolSize);
        mLock = lock;
      }
  
      /**
       * @see #SynchronizedPool(int, Object)
       */
      public SynchronizedPool(int maxPoolSize) {
        this(maxPoolSize, new Object());
      }
  
      @Override
      public T acquire() {
        synchronized (mLock) {
          return super.acquire();
        }
      }
  
      @Override
      public boolean release(T element) {
        synchronized (mLock) {
          return super.release(element);
        }
      }
    }
  }