private Tree buildTree(Object element, Tree parent)
	{
		Tree tree = null; 
		Class<? extends Object> elementClass = element.getClass(); 
		ArrayList<Tree> children = new ArrayList<Tree>();
		Object[] tokens = getTokens(element);	

		String modifiers;
		String kind;
		String type;

		switch( elementClass.getSimpleName() )
		{
		case "CompilationUnitContext": 
			tree = new Tree(element, parent, ShadowLabel.COMPILATION_UNIT);
			for( Object token : tokens )
			{
				String name = token.getClass().getSimpleName();
				if( name.equals("ClassOrInterfaceDeclarationContext") || name.equals("EnumDeclarationContext") )
				{
					for( Object detail :  getTokens(token) )
					{
						if( detail.getClass().getSimpleName().equals("UnqualifiedNameContext") )
						{
							children.add(new Tree(detail, tree, ShadowLabel.PACKAGE));
							break;
						}						
					}					

					children.add(buildTree(token, tree));
				}
			}
			break;		 
		case "ClassOrInterfaceDeclarationContext": 

			String typeParameters = "";
			for( Object token : tokens )
			{
				if( token.getClass().getSimpleName().equals("TypeParametersContext") )
					typeParameters = processType(token);
			}


			kind = getTokens(element)[0].toString();
			if( kind.contains("singleton"))
				tree = new Tree(element, parent, typeParameters, ShadowLabel.SINGLETON);
			else if( kind.contains("exception"))
				tree = new Tree(element, parent, typeParameters, ShadowLabel.EXCEPTION);
			else if( kind.contains("interface"))
				tree = new Tree(element, parent, typeParameters, ShadowLabel.INTERFACE);
			else // [Working]
				tree = new Tree(element, parent, typeParameters, ShadowLabel.CLASS);

			for( Object token : tokens )
			{
				String name = token.getClass().getSimpleName();
				if( name.equals("ClassOrInterfaceBodyContext") )
				{					
					for( Object declaration : getTokens(token) )
						if(this.contextClass.isInstance(declaration))
							bodyDeclaration(declaration, tree, children);		
				}
			}
			break;
		case "EnumDeclarationContext": 
			tree = new Tree(element, parent, ShadowLabel.ENUM);
			for( Object token : tokens )
			{
				String name = token.getClass().getSimpleName();
				if( name.equals("EnumBodyContext") )
				{
					for( Object declaration : getTokens(token) )
					{
						if( declaration.getClass().getSimpleName().equals("EnumConstantContext"))
							children.add(buildTree(declaration, tree));
						else 
							bodyDeclaration(declaration, tree, children);
					}					
				}
			}			
			break;
		case "EnumConstantContext":
			tree = new Tree(element, parent, ShadowLabel.CONSTANT);
			break;
		case "VariableDeclaratorContext":
			modifiers = getModifiers(getParent(element));
			type = getType(getParent(element));
			if( modifiers.contains("constant") )
				tree = new Tree(element, parent, type, ShadowLabel.CONSTANT);
			else
				tree = new Tree(element, parent, type, ShadowLabel.FIELD);
			break;
		case "CreateDeclarationContext":
		case "DestroyDeclarationContext":
		case "MethodDeclaratorContext":
			type = "";			
			if(elementClass.getSimpleName().equals("MethodDeclaratorContext"))
			{
				type = processType(tokens[1]) + " => " + processType(tokens[3]); 
				modifiers = getModifiers(getParent(element));
			}
			else if( elementClass.getSimpleName().equals("CreateDeclarationContext") )
			{
				type = processType(getTokens(tokens[0])[1]); 
				modifiers = getModifiers(element);
				element = tokens[0];
			}
			else
				modifiers = getModifiers(element);

			if( modifiers.contains("public"))
				tree = new Tree(element, parent, type, ShadowLabel.PUBLIC_METHOD);
			else if( modifiers.contains("protected"))
				tree = new Tree(element, parent, type, ShadowLabel.PROTECTED_METHOD);
			else
				tree = new Tree(element, parent, type, ShadowLabel.PRIVATE_METHOD);

			break;
		}

		tree.setChildren(children.toArray(new Tree[children.size()]));
		return tree;
	}