import java.util.EmptyStackException;
import java.util.Iterator;
import java.lang.Iterable;
import java.util.NoSuchElementException;


class Stack<E> implements Iterable<E>{

	// you cannot create an array of a generic type
	private Object[] stack = null;	
	private int count = 0;

	Stack(int initialCapacity) {
		stack = new Object[initialCapacity];
	 }

	E push(E elm) {
		if (count == stack.length) {
			Object[] temp = new Object[2 * count];

			for(int i = 0; i < count; i++) {
				temp[i] = stack[i];
			}	
			stack = temp;

			System.out.println("expanded the stack");
		}

		stack[count] = elm;
		count++;

		return elm;
	}

	@SuppressWarnings("unchecked")
	E pop() {
		if (count == 0) {
			throw new EmptyStackException();
		}

		Object elm = stack[count - 1];
		stack[count - 1] = null;
		count--;
		return (E) elm;
	}

	boolean empty() {
		return (count == 0);
	}

	@SuppressWarnings("unchecked")
	E peek() {
		if (count == 0) {
			throw new EmptyStackException();
		}

		return (E) stack[count - 1];
	}
	
	@Override
	public String toString() {
		String s = "";
		for (int i = 0; i < count; i++) {
			s += stack[i].toString() + " ";
		}
		return s;
	}

	public Iterator<E> iterator() {
		return new StackIterator();
	}

	class StackIterator implements Iterator<E> {

		private int numReturned = 0;

		public boolean hasNext() {
			return (numReturned < count); 
		}

		@SuppressWarnings("unchecked")
		public E next() {
			return (E) stack[numReturned++];
		}

	}

}
