// the base list class, maintains a doubly linked list, only understands node as input
var List:=class Value
(
	var dynamic head;
	var dynamic tail;
	var dynamic size:=0;
	
	var addtotail:=method[toadd]
	{
		size:=size + 1;
		if (head==null)
		{
			head:=toadd;
			tail:=head;
		} else {			
			tail.setnext[toadd];
			toadd.setprev[tail];
			tail:=toadd
		};
	};
	
	var init :=method[]
	(		
		size:=0;
	);
	
	var addtohead:=method[toadd]
	{
		size:=size + 1;		
		if (head==null)
		{
			head:=toadd;
			tail:=head;
		} else {			
		  
			toadd.setnext[head];
			head.setprev[toadd];
			head:=toadd;				
		};
	};
	
	var gethead:=method[] 
	(
		if (head==null)
		(
			return null;
		) else (
			return head;
		);
	);
	
	var gettail:=method[] 
	(
		if (tail==null)
		(
			return null;
		) else (
			return tail;
		);
	);
	
	var removehead:=method[]
	(
		if (head!=null)
		(
			size:=size - 1;
			head:=head.getnext[];
		);
	);
	
	var remove:=method[index]
	{
		if (index==0)
		(
			removehead[];
		) else (
		var i:=0;
		var tempy:=head;				
		for i from 1 to index
		(
			if (tempy!=null)
			(				
				tempy:=tempy.getnext[];				
			);
			if (tempy==null)
			 (			    
				return null;
			);
		);
		
		var onen:=tempy.getprev[];
		var twon:=tempy.getnext[];
		if (tempy==head)
		(
			head:=twon;
		);
		if (onen!=null)
		(
			onen.setnext[twon];			
		);	
		if (twon!=null)
		(
			twon.setprev[onen];			
		);			
		size:=size - 1;	
		);
	};
	
	var put:=method[index,data]
	{
		if (size==0 && index==0)
		(
			head:=data;
			tail:=head;
		) else (
		var i:=0;
		var tempy:=head;		
		for i from 1 to index
		(
			if (tempy!=null)
			(
				tempy:=tempy.getnext[];
			);
			if (tempy==null)
			 (
				return null;
			);
		);
		if (index== -1)
		(							
			data.setnext[head];
			head.setprev[data];			
			head:=data;
		) else (		
			if (!(tempy.getnext[]==null))
			(
				data.setnext[tempy.getnext[]];
				(tempy.getnext[]).setprev[data];
			);
			tempy.setnext[data];
			data.setprev[tempy];
		);
		);
		size:=size + 1;
	};
	
	var getiterator:=method[]
	{
		return new iterator[this];
	};
	
	var clear:=method[]
	(
		head:=null;
		tail:=null;
	);
	
	var get:=method[toget]
	{
		var i:=0;
		var tempy:=head;		
		for i from 1 to toget
		(
			if (tempy!=null)
			(
				tempy:=tempy.getnext[];
			);
			if (tempy==null)
			 (
				return null;
			);
		);
		return tempy;
	};
	
	var getsize:=method[] return size;
);