/*******************************************************************************
 * Copyright (c) 2000, 2008 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package java.util;

public abstract class AbstractList extends AbstractCollection implements List {

	protected transient int modCount;
	
public void add(int index, Object element) {
	throw new UnsupportedOperationException();
}

public boolean add(Object o) {
	add(size(), o);
	return true;
}

public void addAll(int index, Collection c) {
	if (index < 0 || index > size()) throw new IndexOutOfBoundsException();
	Iterator iterator = c.iterator();
	while (iterator.hasNext()) {
		add(index++, iterator.next());
	}
}

public boolean equals(Object other) {
	if (this == other) return true;
	if (!(other instanceof List)) return false;
	List list = (List)other;
	if (size() != list.size()) return false;
	for (int i = 0; i < size(); i++) {
		Object e1 = get(i);
		Object e2 = get(i);
		if (e1 == null) {
			if (e2 != null) return false;
		} else {
			if (!e1.equals(e2)) return false;
		}
	}
	return true;
}

public abstract Object get(int index);

public int hashCode() {
	int hashCode = 1;
	Iterator iter = iterator();
	while (iter.hasNext()) {
		Object e = iter.next();
		hashCode = 31 * hashCode + (e == null ? 0 : e.hashCode());
	}
	return hashCode;
}

public int indexOf(Object o) {
	int size = size();
	for (int i = 0; i < size; i++) {
		Object e = get(i);
		if (o == null ? e == null : o.equals(e)) {
			return i;
		}
	}
	return -1;
}

public Iterator iterator() {
	return new Iterator() {
		int pos;
		public boolean hasNext() {
			return pos < size();
		}
		public Object next() throws NoSuchElementException {
			if (pos >= size()) throw new NoSuchElementException();
			return get(pos++);
		}
		public void remove() {
			AbstractList.this.remove(pos);
		}
	};
}

public int lastIndexOf(Object o) {
	int size = size();
	for (int i = size - 1; i >= 0; i--) {
		Object e = get(i);
		if (o == null ? e == null : o.equals(e)) {
			return i;
		}
	}
	return -1;
}

public ListIterator listIterator() {
	return listIterator(0);
}

public ListIterator listIterator(int index) {
	return new ListIterator() {
		int pos;

		public void add(Object o) {
			AbstractList.this.add(pos, o);
		}

		public boolean hasPrevious() {
			return pos > 0;
		}

		public int nextIndex() {
			return pos == size() ? -1 : pos + 1;
		}

		public Object previous() {
			if (pos == 0) throw new NoSuchElementException();
			return get(pos--);
		}

		public int previousIndex() {
			return pos == 0 ? -1 : pos - 1;
		}

		public void set(Object o) {
			AbstractList.this.set(pos, o);			
		}

		public boolean hasNext() {
			return pos < size();
		}

		public Object next() throws NoSuchElementException {
			if (pos >= size()) throw new NoSuchElementException();
			return get(pos++);
		}

		public void remove() {
			AbstractList.this.remove(pos);
		}
		
	};
}

public Object remove(int index) {
	throw new UnsupportedOperationException();
}

protected void removeRange(int fromIndex, int toIndex) {
	int count = toIndex - fromIndex;
	Iterator iter = listIterator(fromIndex);
	while (iter.hasNext() && count > 0) {
		iter.next();
		iter.remove();
		count--;
	}
}

public Object set(int index, Object element) {
	throw new UnsupportedOperationException();
}

public List subList(int fromIndex, int toIndex) {
	//TODO
	return null;
}

}
