import java.io.ByteArrayInputStream; 
import java.io.ByteArrayOutputStream; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.io.Serializable; 
import java.util.ArrayList; 
import java.util.HashSet; 
import java.util.List; 
import java.util.Random; 
import java.util.Set; 

/** 
 * Test serialization of {@link HashSet}. 
 * 
 */ 

public class JI9053219 {
	private static final Random RANDOM = new Random(); 

	public static class Superclass implements Serializable 
	{ 

		private final Long id; 

		public Superclass() 
		{ 
			this.id = RANDOM.nextLong(); 
		} 

		public int hashCode() 
		{ 
			return this.id.hashCode(); 
		} 

		/* 
	      private void readObject(java.io.ObjectInputStream in) 
	         throws IOException, ClassNotFoundException 
	      { 
	         in.defaultReadObject(); 
	      } 
		 */ 

	} 


	public static class Node extends Superclass implements Serializable 
	{ 

		private final String name; 
		private final Node parent; 
		private final Set<Node> children = new HashSet<>(); 

		public Node(String name, Node parent) 
		{ 
			this.name = name; 
			this.parent = parent; 
			if (parent != null) 
			{ 
				parent.children.add(this); 
			} 
		} 

	} 

	public static void main(String[] args) 
	{ 
		new JI9053219().test(); 
	} 

	@SuppressWarnings("unchecked") 
	private void test() 
	{ 

		Node a = new Node("a", null); 
		Node b = new Node("b", a); 

		List<Node> elements = new ArrayList<>(); 
		elements.add(b); 
		elements.add(a); 

		byte[] bytes = serialize((Serializable) elements); 

		List<Node> deserialized = (List<Node>) deSerialize(bytes); 
	} 

	/** 
	 * Serializes the given object into a byte array. 
	 * 
	 * @param serializable not null 
	 * @return a byte array, not null 
	 */ 
	private static byte[] serialize(Serializable serializable) 
	{ 
		try 
		{ 
			ByteArrayOutputStream out = new ByteArrayOutputStream(); 
			ObjectOutputStream objectOutputStream = new ObjectOutputStream(out); 
			objectOutputStream.writeObject(serializable); 
			return out.toByteArray(); 
		} 
		catch (Exception e) 
		{ 
			throw new RuntimeException(e); 
		} 
	} 

	/** 
	 * De-serializes the given byte array into an object. 
	 * 
	 * @param bytes the byte array to de-serializes, not null 
	 * @return the de-serialized object 
	 */ 
	private static Serializable deSerialize(byte[] bytes) 
	{ 
		try 
		{ 
			return (Serializable) new ObjectInputStream(new ByteArrayInputStream(bytes)).readObject(); 
		} 
		catch (Exception e) 
		{ 
			throw new RuntimeException(e); 
		} 
	} 
}
