import java.io.PrintStream;

public class List
{
	private class Node
	{
		private String data = null;
		
		private Node previous = null;
		
		private Node next = null;
		
		public Node(String data)
		{
			this(data, null, null);
		}
		
		public Node(String data, Node previous)
		{
			this(data, previous, null);
		}
		
		public Node(String data, Node previous, Node next)
		{
			this.data = data;
			this.previous = previous;
			this.next = next;
		}
		
		public Node getPrevious()
		{
			return this.previous;
		}
		
		public Node getNext()
		{
			return this.next;
		}
		
		public Node setPrevious(Node previous)
		{
			return this.previous = previous;
		}
		
		public Node setNext(Node next)
		{
			return this.next = next;
		}
		
		public String getData()
		{
			return this.data;
		}
	}
	
	private Node first = null;
	
	private Node last = null;
	
	private int count = 0;
	
	public void append(String element)
	{
		if ( this.isEmpty() )
		{
			this.last = this.first = new Node(element);
		}
		else
		{
			this.last = this.last.setNext( new Node(element, this.last) );
		}
		
		++this.count;
	}
	
	public boolean isEmpty()
	{
		return this.first == null;
	}
	
	public void print(PrintStream out)
	{
		int counter = 0;
		Node current = this.first;
		while ( current != null )
		{
			out.printf("%d: [%s]%n", ++counter, current.getData() );
			current = current.getNext();
		}
	}
	
	public void insertAfter(Node referenceNode, String element)
	{
		if ( this.isEmpty() )
		{
			this.append(element);
		}
		else
		{
			Node newNode = new Node(element, referenceNode, referenceNode.getNext());
			
			if ( referenceNode.getNext() != null )
			{
				referenceNode.getNext().setPrevious(newNode);
			}
			
			referenceNode.setNext( newNode );
			
			if ( referenceNode == last )
			{
				this.last = referenceNode.getNext();
			}
			
			++this.count;
		}
	}
}

