public class Garage implements Cloneable {

    private Vehicle[] spaces;

    public Garage(int size) {
	spaces = new Vehicle[size];
    }

    public Object clone() throws CloneNotSupportedException {
	Garage nObj = (Garage)super.clone();
	nObj.spaces = (Vehicle[])spaces.clone();
	for (int i = 0; i < spaces.length; i++)
	    nObj.spaces[i] = (Vehicle)spaces[i].clone();
	return nObj;
    }

    public void put(Vehicle v, int pos) throws SpaceOccupiedException {
	if (spaces[pos] != null)
	    throw new SpaceOccupiedException(String.valueOf(pos));

	spaces[pos] = v;
    }

    public Vehicle peek(int pos) {
	return spaces[pos];
    }

    public Vehicle remove(int pos) {
	Vehicle v = spaces[pos];
	spaces[pos] = null;
	return v;
    }

    public String toString() {
	return String.valueOf(spaces.length) + " door garage";
    }

    public void print(java.io.PrintStream out) {
	out.println("A " + toString() + ":");
	for (int i = 0; i < spaces.length; i++) {
	    out.print("\t");
	    if (spaces[i] != null)
		out.print(spaces[i].toString());
	    else
		out.print("nothing");
	    out.println(" behind door #" + (i + 1));
	}
    }

    public static void main(String[] args) {
	Garage g1 = new Garage(3);
	try {
	    g1.put(new Vehicle("Mark"), 0);
	    g1.put(new Vehicle("Esa"), 1);
	    g1.put(new Vehicle("Wayne"), 2);
	} catch (SpaceOccupiedException e) {
	    // can't happen
	    throw new InternalError(e.toString());
	}

	Garage g2;
	try {
	    g2 = (Garage)g1.clone();
	} catch (CloneNotSupportedException e) {
	    System.err.println("Clone failed: " + e);
	    return;
	}

	System.out.print("Original garage: ");
	g1.print(System.out);
	System.out.print("Cloned garage: ");
	g2.print(System.out);

	g1.remove(1);
	System.out.println();
	System.out.println("(after removing vehicle behind door #2)");
	System.out.println();

	System.out.print("Original garage: ");
	g1.print(System.out);
	System.out.print("Cloned garage: ");
	g2.print(System.out);
    }
}

class SpaceOccupiedException extends Exception {

    public SpaceOccupiedException() {
	super();
    }

    public SpaceOccupiedException(String message) {
	super(message);
    }
}
