/*******************************************************************************
 * This file is part of TERMINAL RECALL
 * Copyright (c) 2012-2015 Chuck Ritola
 * Part of the jTRFP.org project
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl.html
 * 
 * Contributors:
 *     chuck - initial API and implementation
 ******************************************************************************/

package org.jtrfp.trcl.coll;

import java.util.Collection;
import java.util.Iterator;

/**
 * Debugging helper to catch if an unauthorized thread 
 * @author Chuck Ritola
 *
 * @param <E>
 */
public final class ThreadEnforcementCollection<E> implements Collection<E> {
    private final Collection<E> delegate;
    private final Thread threadToEnforce;
    
    public ThreadEnforcementCollection(Collection<E> delegate, Thread threadToEnforce){
	this.delegate       = delegate;
	this.threadToEnforce= threadToEnforce;
    }
    
    private void enforceThread(){
	assert Thread.currentThread().equals(threadToEnforce):"Wrong thread. Expected "+threadToEnforce.getName()+" got "+Thread.currentThread().getName();
    }

    /**
     * @return
     * @see java.util.Collection#size()
     */
    public int size() {
	enforceThread();
	return delegate.size();
    }

    /**
     * @return
     * @see java.util.Collection#isEmpty()
     */
    public boolean isEmpty() {
	enforceThread();
	return delegate.isEmpty();
    }

    /**
     * @param o
     * @return
     * @see java.util.Collection#contains(java.lang.Object)
     */
    public boolean contains(Object o) {
	enforceThread();
	return delegate.contains(o);
    }

    /**
     * @return
     * @see java.util.Collection#iterator()
     */
    public Iterator<E> iterator() {
	enforceThread();
	return delegate.iterator();
    }

    /**
     * @return
     * @see java.util.Collection#toArray()
     */
    public Object[] toArray() {
	enforceThread();
	return delegate.toArray();
    }

    /**
     * @param a
     * @return
     * @see java.util.Collection#toArray(T[])
     */
    public <T> T[] toArray(T[] a) {
	enforceThread();
	return delegate.toArray(a);
    }

    /**
     * @param e
     * @return
     * @see java.util.Collection#add(java.lang.Object)
     */
    public boolean add(E e) {
	enforceThread();
	return delegate.add(e);
    }

    /**
     * @param o
     * @return
     * @see java.util.Collection#remove(java.lang.Object)
     */
    public boolean remove(Object o) {
	enforceThread();
	return delegate.remove(o);
    }

    /**
     * @param c
     * @return
     * @see java.util.Collection#containsAll(java.util.Collection)
     */
    public boolean containsAll(Collection<?> c) {
	enforceThread();
	return delegate.containsAll(c);
    }

    /**
     * @param c
     * @return
     * @see java.util.Collection#addAll(java.util.Collection)
     */
    public boolean addAll(Collection<? extends E> c) {
	enforceThread();
	return delegate.addAll(c);
    }

    /**
     * @param c
     * @return
     * @see java.util.Collection#removeAll(java.util.Collection)
     */
    public boolean removeAll(Collection<?> c) {
	enforceThread();
	return delegate.removeAll(c);
    }

    /**
     * @param c
     * @return
     * @see java.util.Collection#retainAll(java.util.Collection)
     */
    public boolean retainAll(Collection<?> c) {
	enforceThread();
	return delegate.retainAll(c);
    }

    /**
     * 
     * @see java.util.Collection#clear()
     */
    public void clear() {
	enforceThread();
	delegate.clear();
    }

    /**
     * @param o
     * @return
     * @see java.util.Collection#equals(java.lang.Object)
     */
    public boolean equals(Object o) {
	enforceThread();
	return delegate.equals(o);
    }

    /**
     * @return
     * @see java.util.Collection#hashCode()
     */
    public int hashCode() {
	enforceThread();
	return delegate.hashCode();
    }
}//end ThreadEnforcementCollection

@@ -660,16 +660,51 @@
 rator;%0A%0A
+import org.jtrfp.trcl.tools.Util;%0A%0A
 /**%0A * D
@@ -874,16 +874,52 @@
 ction%3CE%3E
+, BulkRemovable%3CE%3E, Repopulatable%3CE%3E
  %7B%0A    p
@@ -4111,16 +4111,256 @@
 );%0A    %7D
+%0A%0A    @Override%0A    public void bulkRemove(Collection%3CE%3E items) %7B%0A%09enforceThread();%0A%09Util.bulkRemove(items, delegate);%0A    %7D%0A%0A    @Override%0A    public void repopulate(Collection%3CE%3E c) %7B%0A%09enforceThread();%0A%09Util.repopulate(delegate, c);%0A    %7D
 %0A%7D//end 

Add BulkRemovable/Repopulatable suppor to ThreadEnforcementCollection.