gt:           data[ i - correction ] = o;
context: /*!
  * This program is free software; you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
  * Foundation.
  *
  * You should have received a copy of the GNU Lesser General Public License along with this
  * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
  * or from the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  * See the GNU Lesser General Public License for more details.
  *
  * Copyright (c) 2002-2013 Pentaho Corporation..  All rights reserved.
  */
  
  package org.pentaho.reporting.libraries.designtime.swing;
  
  import java.lang.ref.WeakReference;
  import java.lang.reflect.Array;
  import java.util.ArrayList;
  import java.util.EventListener;
  import java.util.concurrent.locks.ReadWriteLock;
  import java.util.concurrent.locks.ReentrantReadWriteLock;
  
  /**
   * An event listener list that stores the listeners as weak references. This list behaves like the {@link
   * javax.swing.event.EventListenerList}, but does not create the risk of memory leaks when maintaining listener lists
   * for global objects.
   * <p/>
   * The list is fully synchronized and safe to be used in multi-threading environments.
   *
   * @author Thomas Morgner
   */
  public class WeakEventListenerList {
    private static final Object[] EMPTY_ARRAY = new Object[ 0 ];
    private final ReadWriteLock lock = new ReentrantReadWriteLock();
    private Object[] data;
    private int size;
    private final int increment;
    private int count;
  
    /**
     * Creates a new listener list with a increment of 10.
     */
    public WeakEventListenerList() {
      data = EMPTY_ARRAY;
      increment = 10;
    }
  
    /**
     * Adds a new listener of the given type to this list.
     *
     * @param t   the type of the listener.
     * @param l   the listener.
     * @param <T> the type of the listener, must be a subclass of {@code java.util.EventListener}.
     */
    public <T extends EventListener> void add( final Class<T> t, final T l ) {
      lock.writeLock().lock();
      try {
        ensureCapacity( size + 2 );
        data[ size ] = t;
        data[ size + 1 ] = new WeakReference( l );
        size += 2;
      } finally {
        lock.writeLock().unlock();
      }
    }
  
    /**
     * Removes an existing listener of the given type from this eventlistener list.
     *
     * @param t   the type of the listener.
     * @param l   the listener.
     * @param <T> the type of the listener, must be a subclass of {@code java.util.EventListener}.
     */
    public <T extends EventListener> void remove( final Class<T> t, final T l ) {
      lock.writeLock().lock();
      try {
        final int position = findInternal( t, l );
        if ( position < 0 ) {
          return;
        }
  
        final int shiftElements = size - position - 2;
        if ( shiftElements == 0 ) {
          data[ position ] = null;
          data[ position + 1 ] = null;
          size -= 2;
          return;
        }
  
        size -= 2;
        System.arraycopy( data, position + 2, data, position, shiftElements );
  
        data[ size ] = null;
        data[ size + 1 ] = null;
      } finally {
        lock.writeLock().unlock();
      }
    }
  
    /**
     * Tries to find the given listener <code>l</code>, which has to be stored under the given type.
     *
     * @param t   the type of the listener.
     * @param l   the listener.
     * @param <T> the type of the listener, must be a subclass of {@code java.util.EventListener}.
     * @return the index of the listener, or -1 if the listener is not an element of this collection.
     */
    private <T extends EventListener> int findInternal( final Class<T> t, final T l ) {
      for ( int i = 0; i < size; i += 2 ) {
        final WeakReference l2 = (WeakReference) data[ i + 1 ];
        if ( l2 == null ) {
          continue;
        }
        final Object o = l2.get();
        if ( o == null ) {
          data[ i ] = null;
          data[ i + 1 ] = null;
          count += 1;
        } else if ( o == l ) {
          if ( data[ i ] == t ) {
            return i;
          }
        }
      }
      return -1;
    }
  
    /**
     * Returns the number of listeners of any type stored in this eventlistener list.
     *
     * @return the overall size of this list.
     */
    public int getSize() {
      lock.readLock().lock();
      try {
        return size / 2;
      } finally {
        lock.readLock().unlock();
      }
    }
  
    /**
     * Counts the number of listeners of a given type that are contained in this list.
     *
     * @param t the type of the listener.
     * @return the number of listeners.
     */
    public int getListenerCount( final Class<?> t ) {
      lock.readLock().lock();
      try {
        int retval = 0;
        for ( int i = 0; i < size; i += 2 ) {
          if ( data[ i ] != t ) {
            continue;
          }
  
          final WeakReference l2 = (WeakReference) data[ i + 1 ];
          final Object o = l2.get();
          if ( o == null ) {
            data[ i ] = null;
            data[ i + 1 ] = null;
            count += 1;
          } else {
            retval += 1;
          }
        }
        return retval;
      } finally {
        lock.readLock().unlock();
      }
    }
  
    /**
     * Returns all listeners of the given type that are stored in this list.
     *
     * @param t   the type of the listener to be retrieved.
     * @param <T> a implementation or derived interface of EventListener.
     * @return the array containing all listeners.
     */
    public <T extends EventListener> T[] getListeners( final Class<T> t ) {
      final ArrayList list = new ArrayList();
      lock.readLock().lock();
      try {
        for ( int i = 0; i < size; i += 2 ) {
          if ( data[ i ] != t ) {
            continue;
          }
  
          final WeakReference l2 = (WeakReference) data[ i + 1 ];
          final Object o = l2.get();
          if ( o == null ) {
            data[ i ] = null;
            data[ i + 1 ] = null;
            count += 1;
          } else {
            list.add( o );
          }
        }
      } finally {
        lock.readLock().unlock();
      }
  
      pack();
  
      final T[] result = (T[]) Array.newInstance( t, list.size() );
      return (T[]) list.toArray( result );
    }
  
    /**
     * Removes any null-entries from this list.
     */
    private void pack() {
      if ( count < 5 ) {
        lock.writeLock().lock();
        try {
          int correction = 0;
          for ( int i = 0; i < size; i += 2 ) {
            final Object o = data[ i ];
            if ( o == null ) {
              correction += 2;
              continue;
            }
  