/*******************************************************************************
 * Copyright (c) 2005, 2016 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 *******************************************************************************/
package org.eclipse.dltk.ruby.internal.parsers.jruby;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.regex.Pattern;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.Platform;
import org.eclipse.dltk.ast.ASTNode;
import org.eclipse.dltk.ast.Modifiers;
import org.eclipse.dltk.ast.declarations.Argument;
import org.eclipse.dltk.ast.declarations.MethodDeclaration;
import org.eclipse.dltk.ast.declarations.ModuleDeclaration;
import org.eclipse.dltk.ast.declarations.TypeDeclaration;
import org.eclipse.dltk.ast.expressions.BigNumericLiteral;
import org.eclipse.dltk.ast.expressions.BooleanLiteral;
import org.eclipse.dltk.ast.expressions.CallArgumentsList;
import org.eclipse.dltk.ast.expressions.CallExpression;
import org.eclipse.dltk.ast.expressions.ExpressionConstants;
import org.eclipse.dltk.ast.expressions.FloatNumericLiteral;
import org.eclipse.dltk.ast.expressions.NilLiteral;
import org.eclipse.dltk.ast.expressions.NumericLiteral;
import org.eclipse.dltk.ast.expressions.StringLiteral;
import org.eclipse.dltk.ast.references.ConstantReference;
import org.eclipse.dltk.ast.references.SimpleReference;
import org.eclipse.dltk.ast.references.VariableReference;
import org.eclipse.dltk.ast.statements.Block;
import org.eclipse.dltk.compiler.util.Util;
import org.eclipse.dltk.ruby.ast.RubyAliasExpression;
import org.eclipse.dltk.ruby.ast.RubyArrayExpression;
import org.eclipse.dltk.ruby.ast.RubyAssignment;
import org.eclipse.dltk.ruby.ast.RubyBacktickStringLiteral;
import org.eclipse.dltk.ruby.ast.RubyBeginExpression;
import org.eclipse.dltk.ruby.ast.RubyBinaryExpression;
import org.eclipse.dltk.ruby.ast.RubyBlock;
import org.eclipse.dltk.ruby.ast.RubyBreakExpression;
import org.eclipse.dltk.ruby.ast.RubyCallArgumentsList;
import org.eclipse.dltk.ruby.ast.RubyCaseStatement;
import org.eclipse.dltk.ruby.ast.RubyClassDeclaration;
import org.eclipse.dltk.ruby.ast.RubyColonExpression;
import org.eclipse.dltk.ruby.ast.RubyConstantDeclaration;
import org.eclipse.dltk.ruby.ast.RubyDAssgnExpression;
import org.eclipse.dltk.ruby.ast.RubyDRegexpExpression;
import org.eclipse.dltk.ruby.ast.RubyDSymbolExpression;
import org.eclipse.dltk.ruby.ast.RubyDVarExpression;
import org.eclipse.dltk.ruby.ast.RubyDefinedExpression;
import org.eclipse.dltk.ruby.ast.RubyDotExpression;
import org.eclipse.dltk.ruby.ast.RubyDynamicBackquoteStringExpression;
import org.eclipse.dltk.ruby.ast.RubyDynamicStringExpression;
import org.eclipse.dltk.ruby.ast.RubyEnsureExpression;
import org.eclipse.dltk.ruby.ast.RubyEvaluatableStringExpression;
import org.eclipse.dltk.ruby.ast.RubyForStatement2;
import org.eclipse.dltk.ruby.ast.RubyHashExpression;
import org.eclipse.dltk.ruby.ast.RubyHashPairExpression;
import org.eclipse.dltk.ruby.ast.RubyIfStatement;
import org.eclipse.dltk.ruby.ast.RubyMatch2Expression;
import org.eclipse.dltk.ruby.ast.RubyMatch3Expression;
import org.eclipse.dltk.ruby.ast.RubyMatchExpression;
import org.eclipse.dltk.ruby.ast.RubyMethodArgument;
import org.eclipse.dltk.ruby.ast.RubyModuleDeclaration;
import org.eclipse.dltk.ruby.ast.RubyMultipleAssignmentStatement;
import org.eclipse.dltk.ruby.ast.RubyNextExpression;
import org.eclipse.dltk.ruby.ast.RubyNotExpression;
import org.eclipse.dltk.ruby.ast.RubyRedoExpression;
import org.eclipse.dltk.ruby.ast.RubyRegexpExpression;
import org.eclipse.dltk.ruby.ast.RubyRescueBodyStatement;
import org.eclipse.dltk.ruby.ast.RubyRescueStatement;
import org.eclipse.dltk.ruby.ast.RubyRetryExpression;
import org.eclipse.dltk.ruby.ast.RubyReturnStatement;
import org.eclipse.dltk.ruby.ast.RubySelfReference;
import org.eclipse.dltk.ruby.ast.RubySingletonClassDeclaration;
import org.eclipse.dltk.ruby.ast.RubySingletonMethodDeclaration;
import org.eclipse.dltk.ruby.ast.RubySuperExpression;
import org.eclipse.dltk.ruby.ast.RubySymbolReference;
import org.eclipse.dltk.ruby.ast.RubyUndefStatement;
import org.eclipse.dltk.ruby.ast.RubyUntilStatement;
import org.eclipse.dltk.ruby.ast.RubyVariableKind;
import org.eclipse.dltk.ruby.ast.RubyWhenStatement;
import org.eclipse.dltk.ruby.ast.RubyWhileStatement;
import org.eclipse.dltk.ruby.ast.RubyYieldExpression;
import org.eclipse.dltk.ruby.core.RubyPlugin;
import org.eclipse.dltk.ruby.core.utils.RubySyntaxUtils;
import org.eclipse.dltk.ruby.internal.parser.JRubySourceParser;
import org.eclipse.osgi.util.NLS;
import org.jruby.ast.AliasNode;
import org.jruby.ast.AndNode;
import org.jruby.ast.ArgsCatNode;
import org.jruby.ast.ArgsNode;
import org.jruby.ast.ArgsPushNode;
import org.jruby.ast.ArgumentNode;
import org.jruby.ast.ArrayNode;
import org.jruby.ast.AttrAssignNode;
import org.jruby.ast.BackRefNode;
import org.jruby.ast.BeginNode;
import org.jruby.ast.BignumNode;
import org.jruby.ast.BlockArgNode;
import org.jruby.ast.BlockNode;
import org.jruby.ast.BlockPassNode;
import org.jruby.ast.BreakNode;
import org.jruby.ast.CallNode;
import org.jruby.ast.CaseNode;
import org.jruby.ast.ClassNode;
import org.jruby.ast.ClassVarAsgnNode;
import org.jruby.ast.ClassVarDeclNode;
import org.jruby.ast.ClassVarNode;
import org.jruby.ast.Colon2Node;
import org.jruby.ast.Colon3Node;
import org.jruby.ast.ConstDeclNode;
import org.jruby.ast.ConstNode;
import org.jruby.ast.DAsgnNode;
import org.jruby.ast.DRegexpNode;
import org.jruby.ast.DStrNode;
import org.jruby.ast.DSymbolNode;
import org.jruby.ast.DVarNode;
import org.jruby.ast.DXStrNode;
import org.jruby.ast.DefinedNode;
import org.jruby.ast.DefnNode;
import org.jruby.ast.DefsNode;
import org.jruby.ast.DotNode;
import org.jruby.ast.EnsureNode;
import org.jruby.ast.EvStrNode;
import org.jruby.ast.FCallNode;
import org.jruby.ast.FalseNode;
import org.jruby.ast.FixnumNode;
import org.jruby.ast.FlipNode;
import org.jruby.ast.FloatNode;
import org.jruby.ast.ForNode;
import org.jruby.ast.GlobalAsgnNode;
import org.jruby.ast.GlobalVarNode;
import org.jruby.ast.HashNode;
import org.jruby.ast.IfNode;
import org.jruby.ast.InstAsgnNode;
import org.jruby.ast.InstVarNode;
import org.jruby.ast.IterNode;
import org.jruby.ast.ListNode;
import org.jruby.ast.LocalAsgnNode;
import org.jruby.ast.LocalVarNode;
import org.jruby.ast.Match2Node;
import org.jruby.ast.Match3Node;
import org.jruby.ast.MatchNode;
import org.jruby.ast.ModuleNode;
import org.jruby.ast.MultipleAsgnNode;
import org.jruby.ast.NewlineNode;
import org.jruby.ast.NextNode;
import org.jruby.ast.NilNode;
import org.jruby.ast.Node;
import org.jruby.ast.NotNode;
import org.jruby.ast.NthRefNode;
import org.jruby.ast.OpAsgnAndNode;
import org.jruby.ast.OpAsgnNode;
import org.jruby.ast.OpAsgnOrNode;
import org.jruby.ast.OpElementAsgnNode;
import org.jruby.ast.OptNNode;
import org.jruby.ast.OrNode;
import org.jruby.ast.PostExeNode;
import org.jruby.ast.RedoNode;
import org.jruby.ast.RegexpNode;
import org.jruby.ast.RescueBodyNode;
import org.jruby.ast.RescueNode;
import org.jruby.ast.RetryNode;
import org.jruby.ast.ReturnNode;
import org.jruby.ast.RootNode;
import org.jruby.ast.SClassNode;
import org.jruby.ast.SValueNode;
import org.jruby.ast.SelfNode;
import org.jruby.ast.SplatNode;
import org.jruby.ast.StrNode;
import org.jruby.ast.SuperNode;
import org.jruby.ast.SymbolNode;
import org.jruby.ast.ToAryNode;
import org.jruby.ast.TrueNode;
import org.jruby.ast.UndefNode;
import org.jruby.ast.UntilNode;
import org.jruby.ast.VAliasNode;
import org.jruby.ast.VCallNode;
import org.jruby.ast.WhenNode;
import org.jruby.ast.WhileNode;
import org.jruby.ast.XStrNode;
import org.jruby.ast.YieldNode;
import org.jruby.ast.ZArrayNode;
import org.jruby.ast.ZSuperNode;
import org.jruby.ast.visitor.NodeVisitor;
import org.jruby.evaluator.Instruction;
import org.jruby.lexer.yacc.ISourcePosition;
import org.jruby.lexer.yacc.SourcePosition;
import org.jruby.runtime.Arity;
import org.jruby.runtime.Visibility;

/**
 * RubyASTBuildVisitor performs transformation from JRuby's AST to DLTK AST.
 */
public class RubyASTBuildVisitor implements NodeVisitor {

	protected static final boolean TRACE_RECOVERING = Boolean
			.valueOf(
					Platform
							.getDebugOption("org.eclipse.dltk.ruby.core/parsing/traceRecoveryWhenInterpretingAST")) //$NON-NLS-1$
			.booleanValue();

	private ModuleDeclaration module;

	private final char[] content;

	protected static interface IState {
		public void add(ASTNode node);
	}

	protected static String getShortClassName(Object instance) {
		final String className = instance.getClass().getName();
		int dotIndex = className.lastIndexOf('.');
		int dollarIndex = className.lastIndexOf('$');
		if (dotIndex >= 0 || dollarIndex >= 0) {
			return className.substring(Math.max(dotIndex, dollarIndex) + 1);
		} else {
			return className;
		}
	}

	protected static class CollectingState implements IState {
		private final ArrayList<ASTNode> list;

		public CollectingState() {
			list = new ArrayList<ASTNode>();
		}

		public void add(ASTNode s) {
			list.add(s);
		}

		public ArrayList<ASTNode> getList() {
			return list;
		}

		public void reset() {
			list.clear();
		}

		@Override
		public String toString() {
			return getShortClassName(this) + '[' + list + ']';
		}

	}

	protected static class ArgumentsState implements IState {
		private final RubyCallArgumentsList list;

		public ArgumentsState(RubyCallArgumentsList list) {
			this.list = list;
		}

		public void add(ASTNode s) {
			list.addArgument(s, 0);
		}

		@Override
		public String toString() {
			return getShortClassName(this) + '[' + list + ']';
		}
	}

	protected static class TopLevelState implements IState {
		private final ModuleDeclaration module;

		public TopLevelState(ModuleDeclaration module) {
			this.module = module;
		}

		public void add(ASTNode statement) {
			module.getStatements().add(statement);
		}

		@Override
		public String toString() {
			return getShortClassName(this);
		}
	}

	protected static abstract class ClassLikeState implements IState {
		public int visibility;
		public final TypeDeclaration type;
		public final String fullName;

		public ClassLikeState(TypeDeclaration type, String parentName) {
			this.type = type;
			this.fullName = parentName.length() == 0 ? type.getName()
					: parentName + "::" + type.getName(); //$NON-NLS-1$
			visibility = Modifiers.AccPublic;
		}

		public void add(ASTNode statement) {
			type.getStatements().add(statement);
		}

		@Override
		public String toString() {
			return getShortClassName(this) + '[' + fullName + ']';
		}
	}

	protected static class ClassState extends ClassLikeState {

		public ClassState(TypeDeclaration type, String parentName) {
			super(type, parentName);
		}

	}

	protected static class ModuleState extends ClassLikeState {

		public ModuleState(TypeDeclaration type, String parentName) {
			super(type, parentName);
		}

	}

	protected static class MethodState implements IState {

		private final MethodDeclaration method;

		public MethodState(MethodDeclaration method) {
			this.method = method;
		}

		public void add(ASTNode statement) {
			method.getStatements().add(statement);
		}

		@Override
		public String toString() {
			return getShortClassName(this) + '[' + method.getName() + ']';
		}
	}

	protected static class BlockState implements IState {

		public final Block block;

		public BlockState(Block block) {
			this.block = block;
		}

		public void add(ASTNode statement) {
			block.getStatements().add(statement);
		}

		@Override
		public String toString() {
			return getShortClassName(this);
		}
	}

	private static class StateManager {
		private LinkedList<IState> states = new LinkedList<IState>();

		public IState peek() {
			return states.getLast();
		}

		public void pop() {
			states.removeLast();
		}

		public void push(IState state) {
			states.add(state);
		}

		public boolean isClassLikeState() {
			IState state = peek();
			if (state instanceof ClassLikeState) {
				return true;
			} else if (states.size() > 1) {
				ListIterator<IState> i = states.listIterator(states.size());
				while (i.hasPrevious()) {
					IState s = i.previous();
					if (s instanceof ClassLikeState) {
						return true;
					}
				}
			}
			return false;
		}

		public ClassLikeState getClassLikeState() {
			IState state = peek();
			if (state instanceof ClassLikeState) {
				return (ClassLikeState) state;
			} else if (states.size() > 1) {
				final ListIterator<IState> i = states.listIterator(states.size());
				while (i.hasPrevious()) {
					final IState s = i.previous();
					if (s instanceof ClassLikeState) {
						return (ClassLikeState) s;
					}
				}
			}
			return null;
		}

		public String getFullClassName() {
			final ClassLikeState classState = getClassLikeState();
			if (classState != null) {
				return classState.fullName;
			} else {
				return Util.EMPTY_STRING;
			}
		}

	}

	private StateManager states = new StateManager();

	protected ASTNode collectSingleNodeSafe(Node pathNode) {
		return collectSingleNodeSafe(pathNode, false);
	}

	/**
	 * Safe wrapper for <code>collectSingleStatement0</code>. It checks
	 * SILENT_MODE flag, and it is true, just performs
	 * <code>node.accept(this);</code> without throwing an exception.
	 * 
	 * @param node
	 * @param allowZero
	 * @return
	 */
	protected ASTNode collectSingleNodeSafe(Node node, boolean allowZero) {
		ASTNode res = null;
		try {
			res = collectSingleNode0(node, allowZero);
		} catch (Throwable t) {
			if (JRubySourceParser.isSilentState()) {
				node.accept(this);
			} else {
				throw new RuntimeException(t);
			}
		}
		return res;
	}

	/**
	 * Tries to convert single JRuby's node to single DLTK AST node. If
	 * conversion fails, and for ex., more than one or zero nodes were fetched
	 * as result, then RuntimeException will be thrown. Option
	 * <code>allowZero</code> allows to fetch no DLTK nodes and just return null
	 * without throwing an exception.
	 * 
	 * @param node
	 * @param allowZero
	 * @return
	 */
	protected ASTNode collectSingleNode0(Node node, boolean allowZero) {
		if (node == null)
			return null;
		CollectingState state = new CollectingState();
		states.push(state);
		node.accept(this);
		states.pop();

		ArrayList<ASTNode> list = state.getList();
		if (list.size() == 1)
			return list.iterator().next();

		if (node instanceof NewlineNode) {
			NewlineNode newlineNode = (NewlineNode) node;
			node = newlineNode.getNextNode();
		}
		if (list.size() > 1) {
			throw new RuntimeException(
					NLS.bind(
									Messages.RubyASTBuildVisitor_jrubyNodeHasntBeenConvertedIntoAnyDltkAstNode,
									node.getClass().getName()));
		}
		if (allowZero)
			return null;
		throw new RuntimeException(
				NLS.bind(
								Messages.RubyASTBuildVisitor_jrubyNodeHasntBeenConvertedIntoAnyDltkAstNode,
								node.getClass().getName()));
	}

	protected char[] getContent() {
		return content;
	}

	public RubyASTBuildVisitor(ModuleDeclaration module, char[] content) {
		this.module = module;
		this.content = content;
		states.push(new TopLevelState(this.module));
	}

	public Instruction visitAliasNode(AliasNode iVisited) { // done
		ISourcePosition pos = iVisited.getPosition();
		final int start = pos.getStartOffset();
		int end = pos.getEndOffset();
		while (end > start && Character.isWhitespace(content[end - 1])) {
			--end;
		}
		RubyAliasExpression expr = new RubyAliasExpression(start, end, iVisited
				.getOldName(), iVisited.getNewName());
		states.peek().add(expr);
		return null;
	}

	public Instruction visitAndNode(AndNode iVisited) { // done
		ASTNode left = collectSingleNodeSafe(iVisited.getFirstNode());
		ASTNode right = collectSingleNodeSafe(iVisited.getSecondNode());
		RubyBinaryExpression b = new RubyBinaryExpression(left,
				ExpressionConstants.E_BAND, right);
		states.peek().add(b);
		return null;
	}

	// should never get here
	public Instruction visitArgsNode(ArgsNode iVisited) {
		if (iVisited.getOptArgs() != null) {
			iVisited.getOptArgs().accept(this);
		}
		return null;
	}

	// should never get here
	public Instruction visitArgsCatNode(ArgsCatNode iVisited) {
		if (iVisited.getFirstNode() != null) {
			iVisited.getFirstNode().accept(this);
		}
		if (iVisited.getSecondNode() != null) {
			iVisited.getSecondNode().accept(this);
		}
		return null;
	}

	private List<ASTNode> processListNode(ListNode node) { // done
		CollectingState coll = new CollectingState();

		states.push(coll);
		Iterator<Node> iterator = node.childNodes().iterator();
		while (iterator.hasNext()) {
			iterator.next().accept(this);
		}
		states.pop();

		return coll.getList();
	}

	public Instruction visitArrayNode(ArrayNode iVisited) { // done
		List<ASTNode> exprs = processListNode(iVisited);

		ISourcePosition position = iVisited.getPosition();
		RubyArrayExpression arr = new RubyArrayExpression();
		arr.setEnd(position.getEndOffset());
		arr.setStart(position.getStartOffset());
		arr.setChilds(exprs);
		states.peek().add(arr);

		return null;
	}

	public Instruction visitBackRefNode(BackRefNode iVisited) { // done
		ISourcePosition pos = iVisited.getPosition();
		VariableReference ref = new VariableReference(pos.getStartOffset(), pos
				.getEndOffset(), "$" + iVisited.getType()); //$NON-NLS-1$
		states.peek().add(ref);
		return null;
	}

	public Instruction visitBeginNode(BeginNode iVisited) { // done
		ASTNode body = collectSingleNodeSafe(iVisited.getBodyNode());
		ISourcePosition pos = iVisited.getPosition();
		RubyBeginExpression e = new RubyBeginExpression(pos.getStartOffset(),
				pos.getEndOffset(), body);
		states.peek().add(e);
		return null;
	}

	// should never get here
	public Instruction visitBlockArgNode(BlockArgNode iVisited) {
		return null;
	}

	public Instruction visitBlockNode(BlockNode iVisited) { // done
		ISourcePosition pos = iVisited.getPosition();
		Block block = new Block(pos.getStartOffset(), pos.getEndOffset());
		states.push(new BlockState(block));
		Iterator<Node> iterator = iVisited.childNodes().iterator();
		while (iterator.hasNext()) {
			iterator.next().accept(this);
		}
		states.pop();
		states.peek().add(block);
		return null;
	}

	public Instruction visitBlockPassNode(BlockPassNode iVisited) {
		// ASTNode args = collectSingleNodeSafe(iVisited.getArgsNode());
		ASTNode body = collectSingleNodeSafe(iVisited.getBodyNode());
		ISourcePosition pos = iVisited.getPosition();
		RubyBlock e = new RubyBlock(pos.getStartOffset(), pos.getEndOffset(),
				body);
		// TODO: handle vars
		states.peek().add(e);
		return null;
	}

	public Instruction visitBreakNode(BreakNode iVisited) { // done
		ASTNode value = collectSingleNodeSafe(iVisited.getValueNode());
		ISourcePosition pos = iVisited.getPosition();
		RubyBreakExpression e = new RubyBreakExpression(pos.getStartOffset(),
				pos.getEndOffset(), value);
		states.peek().add(e);
		return null;
	}

	public Instruction visitConstDeclNode(ConstDeclNode iVisited) {
		Node pathNode = iVisited.getConstNode();
		ASTNode pathResult = null;
		if (pathNode != null)
			pathResult = collectSingleNodeSafe(pathNode);
		ASTNode value = collectSingleNodeSafe(iVisited.getValueNode());
		ISourcePosition position = iVisited.getPosition();
		int start = position.getStartOffset();
		int end = start;
		while (RubySyntaxUtils.isWhitespace(content[end])) {
			end++;
		}
		while (RubySyntaxUtils.isNameChar(content[end])) {
			end++;
		}
		SimpleReference name = new SimpleReference(start, end, iVisited
				.getName());
		RubyConstantDeclaration node = new RubyConstantDeclaration(position
				.getStartOffset(), position.getEndOffset(), pathResult, name,
				value);
		states.peek().add(node);
		return null;
	}

	public Instruction visitClassVarAsgnNode(ClassVarAsgnNode iVisited) {
		processVariableAssignment(iVisited, iVisited.getName(),
				RubyVariableKind.CLASS, iVisited.getValueNode());
		return null;
	}

	public Instruction visitClassVarDeclNode(ClassVarDeclNode iVisited) {
		processVariableAssignment(iVisited, iVisited.getName(),
				RubyVariableKind.CLASS, iVisited.getValueNode());
		return null;
	}

	public Instruction visitClassVarNode(ClassVarNode iVisited) {
		processVariableReference(iVisited, iVisited.getName(),
				RubyVariableKind.CLASS);
		return null;
	}

	private void fixCallOffsets(CallExpression callNode, String nameNode,
			int possibleDotPosition, int firstArgStart, int lastArgEnd) {
		int dotPosition = RubySyntaxUtils.skipWhitespaceForward(content,
				possibleDotPosition);
		if (dotPosition >= 0 && dotPosition < content.length
				&& content[dotPosition] == ']')
			dotPosition++;
		if (dotPosition >= 0 && dotPosition < content.length
				&& (content[dotPosition] == '.' || content[dotPosition] == ':')) {
			if (content[dotPosition] == ':')
				dotPosition++;
			fixFunctionCallOffsets(callNode, nameNode, dotPosition + 1,
					firstArgStart, lastArgEnd);
			return;
		}
		String methodName = nameNode;
		if (methodName == RubySyntaxUtils.ARRAY_GET_METHOD) {
			// TODO
		} else if (methodName == RubySyntaxUtils.ARRAY_PUT_METHOD) {
			// TODO
		} else {
			// WTF?
			if (TRACE_RECOVERING)
				RubyPlugin
						.log("Ruby AST: non-dot-call not recognized, non-dot found at " //$NON-NLS-1$
								+ dotPosition + ", function name " + methodName); //$NON-NLS-1$
		}

		// trim end whitespaces
		int sourceEnd = callNode.sourceEnd() - 1;
		while (sourceEnd >= 0 && Character.isWhitespace(content[sourceEnd]))
			sourceEnd--;
		if (sourceEnd >= 0)
			callNode.setEnd(sourceEnd + 1);

	}

	private void fixFunctionCallOffsets(CallExpression callNode,
			String methodName, int possibleNameStart, int firstArgStart,
			int lastArgEnd) {
		int nameStart = RubySyntaxUtils.skipWhitespaceForward(content,
				possibleNameStart);
		int nameEnd = nameStart + methodName.length();

		// Assert.isLegal(nameSequence.toString().equals(methodName)); //XXX
		callNode.getCallName().setStart(nameStart);
		callNode.getCallName().setEnd(nameEnd);

		if (firstArgStart < 0) {
			int lParenOffset = RubySyntaxUtils.skipWhitespaceForward(content,
					nameEnd);
			if (lParenOffset >= 0 && content[lParenOffset] == '(') {
				int rParenOffset = RubySyntaxUtils.skipWhitespaceForward(
						content, lParenOffset + 1);
				if (rParenOffset >= 0 && content[rParenOffset] == ')')
					callNode.setEnd(rParenOffset + 1);
				else {
					if (TRACE_RECOVERING)
						RubyPlugin
								.log("Ruby AST: function call, empty args, no closing paren; " //$NON-NLS-1$
										+ "opening paren at " //$NON-NLS-1$
										+ lParenOffset
										+ ", function name " + methodName); //$NON-NLS-1$
					callNode.setEnd(lParenOffset - 1); // don't include these
					// parens
				}
			}
		} else {
			if (nameEnd > firstArgStart) {
				if (callNode.getArgs().getChilds().isEmpty()) {
					callNode.setEnd(nameEnd);
				}
				if (TRACE_RECOVERING)
					RubyPlugin
							.log("DLTKASTBuildVisitor.fixFunctionCallOffsets(" //$NON-NLS-1$
									+ methodName + "): nameEnd > firstArgStart"); //$NON-NLS-1$
				return;
			}
			int lParenOffset = RubySyntaxUtils.skipWhitespaceForward(content,
					nameEnd, firstArgStart);
			if (lParenOffset >= 0 && content[lParenOffset] == '(') {
				if (lastArgEnd <= lParenOffset) {
					if (TRACE_RECOVERING)
						RubyPlugin
								.log("DLTKASTBuildVisitor.fixFunctionCallOffsets(" //$NON-NLS-1$
										+ methodName
										+ "): lastArgEnd <= lParenOffset"); //$NON-NLS-1$
					return;
				}
				int rParenOffset = RubySyntaxUtils.skipWhitespaceForward(
						content, lastArgEnd);
				if (rParenOffset >= 0 && content[rParenOffset] == ')')
					callNode.setEnd(rParenOffset + 1);
				else {
					if (TRACE_RECOVERING)
						RubyPlugin
								.log("Ruby AST: function call, non-empty args, no closing paren; " //$NON-NLS-1$
										+ "opening paren at " //$NON-NLS-1$
										+ lParenOffset + ", " //$NON-NLS-1$
										+ "last argument ending at " //$NON-NLS-1$
										+ lastArgEnd + ", function name " //$NON-NLS-1$
										+ methodName);
					callNode.setEnd(lastArgEnd); // probably no closing paren
				}
			}
		}

		if (lastArgEnd >= 0 && callNode.sourceEnd() < lastArgEnd)
			callNode.setEnd(lastArgEnd);
	}

	/**
	 * @fixme iteration not correctly defined
	 */
	public Instruction visitCallNode(CallNode iVisited) {
		String methodName = iVisited.getName();
		CollectingState collector = new CollectingState();

		Assert.isTrue(iVisited.getReceiverNode() != null);
		states.push(collector);
		iVisited.getReceiverNode().accept(this);
		states.pop();
		// TODO: uncomment when visitor is done
		if (collector.getList().size() > 1) {
			if (TRACE_RECOVERING)
				RubyPlugin.log("DLTKASTBuildVisitor.visitCallNode(" //$NON-NLS-1$
						+ methodName
						+ "): receiver " //$NON-NLS-1$
						+ iVisited.getReceiverNode().getClass().getName()
						+ " turned into multiple nodes"); //$NON-NLS-1$
		}
		ASTNode recv;
		if (collector.getList().size() < 1) {
			recv = new NumericLiteral(-1, -1, 0);
			recv.setStart(iVisited.getPosition().getStartOffset());
			recv.setEnd(iVisited.getPosition().getEndOffset() + 1);
		} else
			recv = collector.getList().get(0);

		collector.reset();

		int argsStart = -1, argsEnd = -1;
		RubyCallArgumentsList argList = new RubyCallArgumentsList();
		Node argsNode = iVisited.getArgsNode();
		if (argsNode != null) {
			argList.setStart(argsNode.getPosition().getStartOffset());
			argList.setEnd(argsNode.getPosition().getEndOffset());

			states.push(new ArgumentsState(argList));
			if (argsNode instanceof ListNode) {
				ListNode arrayNode = (ListNode) argsNode;
				List<Node> list = arrayNode.childNodes();
				for (Iterator<Node> iter = list.iterator(); iter.hasNext();) {
					Node node = iter.next();
					node.accept(this);
				}
			} else {
				if (TRACE_RECOVERING)
					RubyPlugin.log("DLTKASTBuildVisitor.visitCallNode(" //$NON-NLS-1$
							+ methodName + ") - unknown args node type: " //$NON-NLS-1$
							+ argsNode.getClass().getName());
				argsNode.accept(this);
			}
			states.pop();
			List<Node> children = argsNode.childNodes();
			if (children.size() > 0) {
				argsStart = children.get(0).getPosition()
						.getStartOffset();
				argsEnd = children.get(children.size() - 1)
						.getPosition().getEndOffset();
				// correction for nodes with incorrect positions
				List<ASTNode> argListExprs = argList.getChilds();
				if (!argListExprs.isEmpty())
					argsEnd = Math.max(argsEnd, argListExprs
							.get(argListExprs.size() - 1).sourceEnd());
			}
		}
		if (iVisited.getIterNode() != null) {
			ASTNode s = collectSingleNodeSafe(iVisited.getIterNode());
			argList.addNode(s);

		}

		argList.autosetOffsets();
		CallExpression c = new CallExpression(recv, methodName, argList);
		int receiverEnd = recv.sourceEnd();

		c.setStart(iVisited.getPosition().getStartOffset());
		c
				.setEnd(argsEnd >= 0 ? argsEnd : iVisited.getPosition()
						.getEndOffset()); // just in case, should
		// be overriden
		fixCallOffsets(c, methodName, receiverEnd, argsStart, argsEnd);

		this.states.peek().add(c);

		return null;
	}

	public Instruction visitCaseNode(CaseNode iVisited) { // done
		ISourcePosition pos = iVisited.getPosition();
		RubyCaseStatement statement = new RubyCaseStatement(pos
				.getStartOffset(), pos.getEndOffset());
		ASTNode caseTarget = collectSingleNodeSafe(iVisited.getCaseNode());
		statement.setTarget(caseTarget);
		Node caseBody = iVisited.getFirstWhenNode();
		ASTNode caseSt = collectSingleNodeSafe(caseBody);
		List whens = new ArrayList(1);
		while (caseBody instanceof WhenNode) {
			WhenNode whenNode = (WhenNode) caseBody;
			whens.add(caseSt);
			caseBody = whenNode.getNextCase();
			caseSt = collectSingleNodeSafe(caseBody);
		}
		statement.setWhens(whens);
		if (caseSt != null) {
			statement.setElseWhen(caseSt);
		}
		states.peek().add(statement);
		return null;
	}

	private static String colons2Name(Node cpathNode) {
		String name = ""; //$NON-NLS-1$
		while (cpathNode instanceof Colon2Node) {
			Colon2Node colon2Node = (Colon2Node) cpathNode;
			if (name.length() > 0)
				name = "::" + name; //$NON-NLS-1$
			name = colon2Node.getName() + name;
			cpathNode = colon2Node.getLeftNode();
		}
		if (cpathNode instanceof Colon3Node) {
			Colon3Node colon3Node = (Colon3Node) cpathNode;
			if (name.length() > 0)
				name = "::" + name; //$NON-NLS-1$
			name = "::" + colon3Node.getName() + name; //$NON-NLS-1$
		} else if (cpathNode instanceof ConstNode) {
			ConstNode constNode = (ConstNode) cpathNode;
			if (name.length() > 0)
				name = "::" + name; //$NON-NLS-1$
			name = constNode.getName() + name;
		}
		return name;
	}

	private ISourcePosition fixNamePosition(ISourcePosition pos) {
		int start = pos.getStartOffset();
		int end = pos.getEndOffset();

		while (end - 1 >= 0 && (end - 1) > start
				&& !RubySyntaxUtils.isNameChar(content[end - 1])) {
			end--;
		}
		if (end >= 0) {
			while (end < content.length
					&& RubySyntaxUtils.isNameChar(content[end]))
				end++;
		}
		return new SourcePosition(pos.getFile(), pos.getStartLine(), pos
				.getEndLine(), start, end);
	}

	private ISourcePosition fixBorders(ISourcePosition pos) {
		int start = pos.getStartOffset();
		int end = pos.getEndOffset();
		while (end - 1 >= 0 && !RubySyntaxUtils.isNameChar(content[end - 1])) {
			end--;
		}
		if (end >= 0) {
			while (end < content.length
					&& RubySyntaxUtils.isNameChar(content[end]))
				end++;
		}
		return new SourcePosition(pos.getFile(), pos.getStartLine(), pos
				.getEndLine(), start, end);
	}

	public Instruction visitClassNode(ClassNode iVisited) {
		Node cpathNode = iVisited.getCPath();
		Node superClassNode = iVisited.getSuperNode();
		ASTNode cpath = collectSingleNodeSafe(cpathNode);
		ASTNode supernode = collectSingleNodeSafe(superClassNode);
		ISourcePosition pos = iVisited.getCPath().getPosition();
		ISourcePosition cPos = iVisited.getPosition();
		cPos = fixNamePosition(cPos);
		pos = fixNamePosition(pos);

		RubyClassDeclaration type = new RubyClassDeclaration(supernode, cpath,
				null, cPos.getStartOffset(), cPos.getEndOffset());

		String name = colons2Name(cpathNode);
		type.setName(name);

		states.peek().add(type);
		final String enclosingTypeName = states.getFullClassName();
		type.setEnclosingTypeName(enclosingTypeName);
		states.push(new ClassState(type, enclosingTypeName));
		// body
		Node bodyNode = iVisited.getBodyNode();
		if (bodyNode != null) {
			pos = bodyNode.getPosition();
			int end = -1;
			while (bodyNode instanceof NewlineNode)
				bodyNode = ((NewlineNode) bodyNode).getNextNode();
			if (bodyNode instanceof BlockNode) {
				BlockNode blockNode = (BlockNode) bodyNode;
				// XXX !!!!
				end = blockNode.getLast().getPosition().getEndOffset() + 1;
			}
			pos = fixBorders(pos);
			Block bl = new Block(pos.getStartOffset(), (end == -1) ? pos
					.getEndOffset() + 1 : end);
			type.setBody(bl);

			if (bodyNode instanceof BlockNode) {
				for (Iterator<Node> iterator = bodyNode.childNodes().iterator(); iterator
						.hasNext();) {
					Node n = iterator.next();
					n.accept(this);
				}
			} else
				bodyNode.accept(this);
		}

		states.pop();
		return null;
	}

	public Instruction visitColon2Node(Colon2Node iVisited) {

		CollectingState collector = new CollectingState();
		states.push(collector);
		if (iVisited.getLeftNode() != null) {
			iVisited.getLeftNode().accept(this);
		}
		states.pop();

		int start = iVisited.getPosition().getStartOffset();
		int end = iVisited.getPosition().getEndOffset();
		ASTNode left = null;
		if (collector.list.size() == 1) {

			left = collector.list.get(0);

		}

		String right = iVisited.getName();

		if (left != null) {
			RubyColonExpression colon = new RubyColonExpression(right, left);
			colon.setStart(start);
			colon.setEnd(end);
			states.peek().add(colon);
		} else {
			ConstantReference ref = new ConstantReference(start, end, right);
			states.peek().add(ref);
		}

		return null;
	}

	public Instruction visitColon3Node(Colon3Node iVisited) {
		ISourcePosition position = iVisited.getPosition();
		RubyColonExpression colon = new RubyColonExpression(iVisited.getName(),
				null);
		colon.setStart(position.getStartOffset());
		colon.setEnd(position.getEndOffset());
		states.peek().add(colon);
		return null;
	}

	public Instruction visitConstNode(ConstNode iVisited) {
		String name = iVisited.getName();
		ISourcePosition pos = iVisited.getPosition();
		pos = fixBorders(pos);
		this.states.peek().add(
				new ConstantReference(pos.getStartOffset(), pos.getEndOffset(),
						name));
		return null;
	}

	public Instruction visitDAsgnNode(DAsgnNode iVisited) {
		ISourcePosition pos = iVisited.getPosition();
		ASTNode valueNode = this.collectSingleNodeSafe(iVisited.getValueNode(),
				true);
		RubyDAssgnExpression e = new RubyDAssgnExpression(pos.getStartOffset(),
				pos.getEndOffset(), iVisited.getName(), valueNode);

		states.peek().add(e);

		return null;
	}

	public Instruction visitDRegxNode(DRegexpNode iVisited) { // done
		ISourcePosition pos = iVisited.getPosition();
		List<ASTNode> list = processListNode(iVisited);
		RubyDRegexpExpression ex = new RubyDRegexpExpression(pos
				.getStartOffset(), pos.getEndOffset());
		ex.setChilds(list);
		states.peek().add(ex);
		return null;
	}

	public Instruction visitDStrNode(DStrNode iVisited) { // done
		ISourcePosition pos = iVisited.getPosition();
		List<ASTNode> list = processListNode(iVisited);
		RubyDynamicStringExpression ex = new RubyDynamicStringExpression(pos
				.getStartOffset(), pos.getEndOffset());
		ex.setChilds(list);
		states.peek().add(ex);
		return null;
	}

	/**
	 * @see NodeVisitor#visitDSymbolNode(DSymbolNode)
	 */
	public Instruction visitDSymbolNode(DSymbolNode iVisited) { // done
		ISourcePosition pos = iVisited.getPosition();
		List<ASTNode> list = processListNode(iVisited);
		RubyDSymbolExpression ex = new RubyDSymbolExpression(pos
				.getStartOffset(), pos.getEndOffset());
		ex.setChilds(list);
		states.peek().add(ex);
		return null;
	}

	public Instruction visitDVarNode(DVarNode iVisited) { // done (?)
		String name = iVisited.getName();
		ISourcePosition pos = iVisited.getPosition();
		RubyDVarExpression e = new RubyDVarExpression(pos.getStartOffset(), pos
				.getEndOffset(), name);
		states.peek().add(e);
		return null;
	}

	public Instruction visitDXStrNode(DXStrNode iVisited) { // done
		ISourcePosition pos = iVisited.getPosition();
		List<ASTNode> list = processListNode(iVisited);
		RubyDynamicBackquoteStringExpression ex = new RubyDynamicBackquoteStringExpression(
				pos.getStartOffset(), pos.getEndOffset());
		ex.setChilds(list);
		states.peek().add(ex);
		return null;
	}

	public Instruction visitDefinedNode(DefinedNode iVisited) { // done
		ISourcePosition pos = iVisited.getPosition();
		ASTNode value = collectSingleNodeSafe(iVisited.getExpressionNode());
		RubyDefinedExpression e = new RubyDefinedExpression(pos
				.getStartOffset(), pos.getEndOffset(), value);
		states.peek().add(e);
		return null;
	}

	private List<Argument> processMethodArguments(ArgsNode args) {
		List<Argument> arguments = new ArrayList<Argument>();
		Arity arity = args.getArity();
		int endPos = args.getPosition().getStartOffset() - 1;
		if (arity.getValue() != 0) { // BIG XXX, PLEASE CHECK IT
			ListNode argsList = args.getArgs();
			if (argsList != null) {
				Iterator<Node> i = argsList.childNodes().iterator();
				while (i.hasNext()) {
					Node nde = i.next();
					if (nde instanceof ArgumentNode) {
						ArgumentNode a = (ArgumentNode) nde;
						Argument aa = new RubyMethodArgument();
						ISourcePosition argPos = fixNamePosition(a
								.getPosition());

						if (argPos.getEndOffset() > endPos)
							endPos = argPos.getEndOffset();

						aa.set(new SimpleReference(argPos.getStartOffset(),
								argPos.getEndOffset(), a.getName()), null);
						aa.setModifier(RubyMethodArgument.SIMPLE);
						arguments.add(aa);
					}
				}
			}
			ListNode optArgs = args.getOptArgs();
			if (optArgs != null) {
				Iterator<?> iterator = optArgs.childNodes().iterator();
				while (iterator.hasNext()) {
					Object obj = iterator.next();
					if (obj instanceof LocalAsgnNode) {
						LocalAsgnNode a = (LocalAsgnNode) obj;
						Argument aa = new RubyMethodArgument();
						ISourcePosition argPos = a.getPosition();

						if (argPos.getEndOffset() > endPos)
							endPos = argPos.getEndOffset();

						CollectingState coll = new CollectingState();
						states.push(coll);
						a.getValueNode().accept(this);
						states.pop();
						ASTNode defaultVal = null;
						int nameStart = argPos.getStartOffset();
						int nameEnd = argPos.getEndOffset();

						if (coll.list.size() == 1) {
							Object object = coll.list.get(0);
							defaultVal = (ASTNode) object;
							if (defaultVal.sourceStart() > nameStart
									&& defaultVal.sourceStart() < nameEnd) {
								nameEnd = defaultVal.sourceStart();
							}
						}

						aa.set(new SimpleReference(nameStart, nameEnd, a
								.getName()), defaultVal);
						aa.setModifier(RubyMethodArgument.SIMPLE);
						arguments.add(aa);
					} else {
						System.err
								.println(Messages.RubyASTBuildVisitor_unknownArgumentType);
					}
				}
			}
		}
		if (args.getRestArg() >= 0) {

			// restore vararg name and position
			int vaStart = 0, vaEnd = 0;
			IState s = states.peek();
			if (s instanceof MethodState) {
				int bodyStart = args.getPosition().getEndOffset();
				if (endPos >= 0 && endPos < bodyStart) { // this assumes that
					// sourceStart is always set and always less than
					// contents.length()
					while (endPos < bodyStart && content[endPos] != '*')
						endPos++;
					endPos++;
					if (endPos < content.length) {
						vaStart = endPos - 1;
						while (RubySyntaxUtils
								.isIdentifierCharacter(content[endPos]))
							endPos++;
						vaEnd = endPos;
					}

				}
			}

			Argument aa = new RubyMethodArgument();
			aa.set(new SimpleReference(vaStart + 1, vaEnd, String.copyValueOf(
					content, vaStart, vaEnd - vaStart)), null);
			aa.setModifier(RubyMethodArgument.VARARG);
			arguments.add(aa);
		}
		BlockArgNode blockArgNode = args.getBlockArgNode();
		if (blockArgNode != null) {
			ISourcePosition position = fixNamePosition(blockArgNode
					.getPosition());
			String baName = String.copyValueOf(content, position
					.getStartOffset() - 1, position.getEndOffset()
					- (position.getStartOffset() - 1));
			Argument aa = new RubyMethodArgument();
			aa.set(new SimpleReference(position.getStartOffset(), position
					.getEndOffset(), baName), null); // XXX:
			aa.setModifier(RubyMethodArgument.BLOCK);
			arguments.add(aa);
		}
		return arguments;
	}

	private void setMethodVisibility(MethodDeclaration method,
			Visibility visibility) {
		if (visibility.isPrivate())
			ASTUtils.setVisibility(method, Modifiers.AccPrivate);

		if (visibility.isPublic())
			ASTUtils.setVisibility(method, Modifiers.AccPublic);

		if (visibility.isProtected())
			ASTUtils.setVisibility(method, Modifiers.AccProtected);
	}

	// method
	public Instruction visitDefnNode(DefnNode iVisited) {
		// Collection comments = iVisited.getComments();
		// System.out.println(comments);
		ArgumentNode nameNode = iVisited.getNameNode();

		ISourcePosition pos = fixNamePosition(nameNode.getPosition());
		ISourcePosition cPos = fixNamePosition(iVisited.getPosition());
		MethodDeclaration method = new MethodDeclaration(iVisited.getName(),
				pos.getStartOffset(), pos.getEndOffset(),
				cPos.getStartOffset(), cPos.getEndOffset());

		setMethodVisibility(method, iVisited.getVisibility());
		if (states.isClassLikeState()) {
			ClassLikeState classState = states.getClassLikeState();
			ASTUtils.setVisibility(method, classState.visibility);
		}

		final ClassLikeState classState = states.getClassLikeState();
		if (classState != null) {
			method.setDeclaringTypeName(classState.fullName);
		}
		states.peek().add(method);
		states.push(new MethodState(method));
		Node bodyNode = iVisited.getBodyNode();
		if (bodyNode != null) {
			ISourcePosition bodyPos = bodyNode.getPosition();
			method.getBody().setStart(bodyPos.getStartOffset());
			method.getBody().setEnd(bodyPos.getEndOffset());
			if (bodyNode instanceof BlockNode) {
				for (Iterator<Node> iterator = bodyNode.childNodes().iterator(); iterator
						.hasNext();) {
					Node n = iterator.next();
					n.accept(this);
				}
			} else
				bodyNode.accept(this);
		}
		ArgsNode args = iVisited.getArgsNode();
		if (args != null) {
			List<Argument> arguments = processMethodArguments(args);
			method.acceptArguments(arguments);
		}
		states.pop();
		return null;
	}

	private ISourcePosition restoreMethodNamePosition(DefsNode node, int recvEnd) {
		ISourcePosition recvPos = node.getReceiverNode().getPosition();
		int pos = recvEnd;
		if (pos >= 0) {
			while (pos < content.length && content[pos] != '.'
					&& content[pos] != ':')
				pos++;
			if (content[pos] == ':')
				pos++;
		}
		if (pos >= content.length || pos < 0)
			return recvPos;
		int nameStart = RubySyntaxUtils.skipWhitespaceForward(content, pos + 1);
		int nameEnd = nameStart;
		while (RubySyntaxUtils.isIdentifierCharacter(content[nameEnd]))
			nameEnd++;
		return new SourcePosition(recvPos.getFile(), recvPos.getStartLine(),
				recvPos.getEndLine(), nameStart, nameEnd);
	}

	// singleton method
	public Instruction visitDefsNode(DefsNode iVisited) {
		ASTNode receiverExpression = null;
		Node receiverNode = iVisited.getReceiverNode();
		CollectingState collectingState = new CollectingState();

		states.push(collectingState);
		receiverNode.accept(this);
		states.pop();
		if (collectingState.list.size() == 1) {
			Object obj = collectingState.list.get(0);
			receiverExpression = (ASTNode) obj;
		}

		ISourcePosition cPos = iVisited.getPosition();
		// if (receiverExpression == null)
		// System.out.println();
		ISourcePosition namePos = restoreMethodNamePosition(iVisited,
				receiverExpression.sourceEnd());
		String name = iVisited.getName();
		// if (receiverNode instanceof SelfNode) {
		// name = "self." + name;
		// } else if (receiverNode instanceof ConstNode) {
		// name = ((ConstNode) receiverNode).getName() + "." + name;
		// }
		RubySingletonMethodDeclaration method = new RubySingletonMethodDeclaration(
				name, namePos.getStartOffset(), namePos.getEndOffset(), cPos
						.getStartOffset(), cPos.getEndOffset(),
				receiverExpression);
		method.setModifier(Modifiers.AccStatic);
		ASTUtils.setVisibility(method, Modifiers.AccPublic);
		// if (states.peek() instanceof ClassLikeState) {
		if (states.isClassLikeState()) {
			ClassLikeState classState = states.getClassLikeState();
			ASTUtils.setVisibility(method, classState.visibility);
		}
		states.peek().add(method);
		states.push(new MethodState(method));
		ArgsNode args = iVisited.getArgsNode();
		if (args != null) {
			List list = processMethodArguments(args);
			method.acceptArguments(list);
		}
		Node bodyNode = iVisited.getBodyNode();
		if (bodyNode != null) {
			if (bodyNode instanceof BlockNode) {
				for (Iterator iterator = bodyNode.childNodes().iterator(); iterator
						.hasNext();) {
					Node n = (Node) iterator.next();
					n.accept(this);
				}
			} else
				bodyNode.accept(this);
		}
		states.pop();
		return null;
	}

	public Instruction visitDotNode(DotNode iVisited) { // done
		ASTNode begin = collectSingleNodeSafe(iVisited.getBeginNode());
		ASTNode end = collectSingleNodeSafe(iVisited.getEndNode());
		ISourcePosition pos = iVisited.getPosition();
		RubyDotExpression e = new RubyDotExpression(pos.getStartOffset(), pos
				.getEndOffset(), begin, end);
		states.peek().add(e);
		return null;
	}

	public Instruction visitEnsureNode(EnsureNode iVisited) { // done
		ASTNode body = collectSingleNodeSafe(iVisited.getBodyNode());
		ASTNode ensure = collectSingleNodeSafe(iVisited.getEnsureNode());
		ISourcePosition pos = iVisited.getPosition();
		RubyEnsureExpression e = new RubyEnsureExpression(pos.getStartOffset(),
				pos.getEndOffset(), ensure, body);
		states.peek().add(e);
		return null;
	}

	public Instruction visitEvStrNode(EvStrNode iVisited) { // done
		ISourcePosition pos = iVisited.getPosition();
		ASTNode body = collectSingleNodeSafe(iVisited.getBody());
		RubyEvaluatableStringExpression e = new RubyEvaluatableStringExpression(
				pos.getStartOffset(), pos.getEndOffset(), body);
		states.peek().add(e);
		return null;
	}

	public Instruction visitFCallNode(FCallNode iVisited) {

		String methodName = iVisited.getName();

		if (states.isClassLikeState()) {
			if (methodName.equals("private")) //$NON-NLS-1$
				handleVisibilitySetter(iVisited, Modifiers.AccPrivate);
			else if (methodName.equals("protected")) //$NON-NLS-1$
				handleVisibilitySetter(iVisited, Modifiers.AccProtected);
			else if (methodName.equals("public")) //$NON-NLS-1$
				handleVisibilitySetter(iVisited, Modifiers.AccPublic);
		}

		RubyCallArgumentsList argList = new RubyCallArgumentsList();
		Node argsNode = iVisited.getArgsNode();
		if (argsNode != null) {
			argList.setStart(argsNode.getPosition().getStartOffset());
			argList.setEnd(argsNode.getPosition().getEndOffset());

			states.push(new ArgumentsState(argList));
			if (argsNode instanceof ListNode) {
				ListNode arrayNode = (ListNode) argsNode;
				List list = arrayNode.childNodes();
				for (Iterator iter = list.iterator(); iter.hasNext();) {
					Node node = (Node) iter.next();
					node.accept(this);
				}
			} else {
				if (TRACE_RECOVERING)
					RubyPlugin.log("DLTKASTBuildVisitor.visitFCallNode(" //$NON-NLS-1$
							+ methodName + ") - unknown args node type: " //$NON-NLS-1$
							+ argsNode.getClass().getName());
				argsNode.accept(this);
			}
			states.pop();
		}

		if (iVisited.getIterNode() != null) {
			ASTNode s = collectSingleNodeSafe(iVisited.getIterNode());
			argList.addNode(s);
		}

		argList.autosetOffsets();
		CallExpression c = new CallExpression(null, methodName, argList);

		int funcNameStart = iVisited.getPosition().getStartOffset();
		c.setStart(funcNameStart);
		c.setEnd(funcNameStart + methodName.length());
		fixFunctionCallOffsets(c, methodName, funcNameStart, argList
				.sourceStart(), argList.sourceEnd());

		states.peek().add(c);

		return null;
	}

	private void handleVisibilitySetter(FCallNode node, int newVisibility) {
		if (states.isClassLikeState()) {
			ClassLikeState classState = states.getClassLikeState();
			Node argsNode = node.getArgsNode();
			if (argsNode instanceof ArrayNode) {
				ArrayNode argsArrayNode = (ArrayNode) argsNode;
				List args = argsArrayNode.childNodes();
				for (Iterator iter = args.iterator(); iter.hasNext();) {
					Node arg = (Node) iter.next();
					if (arg instanceof SymbolNode) {
						SymbolNode symbolNode = (SymbolNode) arg;
						String xmethodName = symbolNode.getName();
						List statements = classState.type.getStatements();
						for (Iterator statIter = statements.iterator(); statIter
								.hasNext();) {
							ASTNode statement = (ASTNode) statIter.next();
							if (statement instanceof MethodDeclaration) {
								MethodDeclaration methodDeclaration = (MethodDeclaration) statement;
								if (methodDeclaration.getName().equals(
										xmethodName))
									ASTUtils.setVisibility(methodDeclaration,
											newVisibility);
							}
						}
					}
				}
			}
		}
	}

	public Instruction visitFalseNode(FalseNode iVisited) { // done
		ISourcePosition position = iVisited.getPosition();
		states.peek().add(
				new BooleanLiteral(position.getStartOffset(), position
						.getEndOffset(), false));
		return null;
	}

	public Instruction visitFlipNode(FlipNode iVisited) {

		return null;
	}

	public Instruction visitForNode(ForNode iVisited) { // done
		ASTNode varNode = collectSingleNodeSafe(iVisited.getVarNode());
		ASTNode listSt = collectSingleNodeSafe(iVisited.getIterNode());
		ASTNode listNode;
		if (!(listSt instanceof org.eclipse.dltk.ast.ASTListNode)) {
			org.eclipse.dltk.ast.ASTListNode list = new org.eclipse.dltk.ast.ASTListNode();
			list.addNode(listSt);
			listNode = list;
		} else
			listNode = listSt;
		ASTNode bodyNode = collectSingleNodeSafe(iVisited.getBodyNode());
		ISourcePosition pos = iVisited.getPosition();
		RubyForStatement2 statement = new RubyForStatement2(pos
				.getStartOffset(), pos.getEndOffset(), varNode,
				(org.eclipse.dltk.ast.ASTListNode) listNode, bodyNode);
		states.peek().add(statement);
		return null;
	}

	public Instruction visitGlobalAsgnNode(GlobalAsgnNode iVisited) {
		processVariableAssignment(iVisited, iVisited.getName(),
				RubyVariableKind.GLOBAL, iVisited.getValueNode());
		return null;
	}

	public Instruction visitGlobalVarNode(GlobalVarNode iVisited) {
		processVariableReference(iVisited, iVisited.getName(),
				RubyVariableKind.GLOBAL);
		return null;
	}

	public Instruction visitHashNode(HashNode iVisited) { // done
		ListNode listNode = iVisited.getListNode();
		List<ASTNode> exprs = processListNode(listNode);

		ISourcePosition position = iVisited.getPosition();
		RubyHashExpression arr = new RubyHashExpression();
		arr.setStart(position.getStartOffset());
		arr.setEnd(position.getEndOffset());

		if (arr.sourceEnd() == arr.sourceStart() && listNode != null) {
			arr.setStart(listNode.getPosition().getStartOffset());
			arr.setEnd(listNode.getPosition().getEndOffset());
		}

		List<ASTNode> hashPairs = new ArrayList<ASTNode>();

		if (exprs.size() % 2 == 0) {
			Iterator<ASTNode> i = exprs.iterator();
			while (i.hasNext()) {
				ASTNode key = i.next();
				ASTNode value = i.next();
				RubyHashPairExpression e = new RubyHashPairExpression(key
						.sourceStart(), value.sourceEnd(), key, value);
				hashPairs.add(e);
			}
		} else {
			if (!JRubySourceParser.isSilentState()) {
				throw new RuntimeException(
						Messages.RubyASTBuildVisitor_unpairedHash);
			}
		}

		arr.setChilds(hashPairs);
		states.peek().add(arr);
		return null;
	}

	public Instruction visitInstAsgnNode(InstAsgnNode iVisited) {
		processVariableAssignment(iVisited, iVisited.getName(),
				RubyVariableKind.INSTANCE, iVisited.getValueNode());
		return null;
	}

	public Instruction visitInstVarNode(InstVarNode iVisited) {
		processVariableReference(iVisited, iVisited.getName(),
				RubyVariableKind.INSTANCE);
		return null;
	}

	public Instruction visitIfNode(IfNode iVisited) { // done
		ASTNode condition = collectSingleNodeSafe(iVisited.getCondition());
		ASTNode thenPart = collectSingleNodeSafe(iVisited.getThenBody());
		ASTNode elsePart = collectSingleNodeSafe(iVisited.getElseBody());
		RubyIfStatement res = new RubyIfStatement(condition, thenPart, elsePart);
		res.setStart(iVisited.getPosition().getStartOffset());
		res.setEnd(iVisited.getPosition().getEndOffset() + 1);
		states.peek().add(res);
		return null;
	}

	public Instruction visitIterNode(IterNode iVisited) { // done
		ASTNode bodyNode = collectSingleNodeSafe(iVisited.getBodyNode());
		ASTNode varNode = collectSingleNodeSafe(iVisited.getVarNode());
		ISourcePosition pos = iVisited.getPosition();
		RubyBlock block = new RubyBlock(pos.getStartOffset(), pos
				.getEndOffset(), bodyNode);
		block.addVar(varNode);
		states.peek().add(block);
		return null;
	}

	public Instruction visitLocalAsgnNode(LocalAsgnNode iVisited) {
		processVariableAssignment(iVisited, iVisited.getName(),
				RubyVariableKind.LOCAL, iVisited.getValueNode());
		return null;
	}

	private void processVariableAssignment(Node iVisited, String name,
			RubyVariableKind varKind, Node valueNode) {
		ISourcePosition pos = iVisited.getPosition();
		ASTNode left = new VariableReference(pos.getStartOffset(), pos
				.getStartOffset()
				+ name.length(), name, varKind);
		ASTNode right = collectSingleNodeSafe(valueNode);
		RubyAssignment assgn = new RubyAssignment(left, right);
		copyOffsets(assgn, iVisited);
		states.peek().add(assgn);
	}

	public Instruction visitLocalVarNode(LocalVarNode iVisited) {
		processVariableReference(iVisited, iVisited.getName(),
				RubyVariableKind.LOCAL);
		return null;
	}

	private void processVariableReference(Node iVisited, String varName,
			RubyVariableKind varKind) {
		final ISourcePosition pos = iVisited.getPosition();
		final int start = pos.getStartOffset();
		int end = pos.getEndOffset();
		if (end - start > varName.length()) {
			end = start + varName.length();
		}
		VariableReference node = new VariableReference(start, end, varName,
				varKind);
		states.peek().add(node);
	}

	private void copyOffsets(ASTNode target, Node source) {
		ISourcePosition pos = source.getPosition();
		target.setStart(pos.getStartOffset());
		target.setEnd(pos.getEndOffset());
	}

	public Instruction visitMultipleAsgnNode(MultipleAsgnNode iVisited) { // done
		ISourcePosition pos = iVisited.getPosition();
		RubyMultipleAssignmentStatement s = new RubyMultipleAssignmentStatement(
				pos.getStartOffset(), pos.getEndOffset());
		ListNode headNode = iVisited.getHeadNode();
		if (headNode != null) {
			for (Iterator<Node> iterator = headNode.childNodes().iterator(); iterator
					.hasNext();) {
				Node n = iterator.next();
				if (n instanceof LocalAsgnNode
						&& ((LocalAsgnNode) n).getValueNode() == null) {
					String name = ((LocalAsgnNode) n).getName();
					ISourcePosition nPos = n.getPosition();
					s.addLhs(new VariableReference(nPos.getStartOffset(), nPos
							.getEndOffset(), name, RubyVariableKind.LOCAL));
				} else {
					ASTNode ss = collectSingleNodeSafe(n);
					s.addLhs(ss);
				}
			}
		}
		Node argsNode = iVisited.getArgsNode();
		if (argsNode != null) {
			s.setLeftAsterix(collectSingleNodeSafe(argsNode), argsNode
					.getPosition().getStartOffset());
		}
		Node valueNode = iVisited.getValueNode();
		if (valueNode instanceof ArgsCatNode) {
			ArgsCatNode argsCatNode = (ArgsCatNode) valueNode;
			Node firstNode = argsCatNode.getFirstNode();
			if (firstNode instanceof ListNode) {
				ListNode list = (ListNode) firstNode;
				for (Iterator<Node> iterator = list.childNodes().iterator(); iterator
						.hasNext();) {
					Node nd = iterator.next();
					s.addRhs(collectSingleNodeSafe(nd));
				}
			} else if (firstNode != null)
				s.addRhs(collectSingleNodeSafe(firstNode));
			Node secondNode = argsCatNode.getSecondNode();
			if (secondNode != null)
				s.setRightAsterix(collectSingleNodeSafe(secondNode));
		} else if (valueNode instanceof ListNode) {
			ListNode list = (ListNode) valueNode;
			for (Iterator<Node> iterator = list.childNodes().iterator(); iterator
					.hasNext();) {
				Node nd = iterator.next();
				s.addRhs(collectSingleNodeSafe(nd));
			}
		} else if (valueNode != null) {
			s.addRhs(collectSingleNodeSafe(valueNode));
		}
		states.peek().add(s);
		return null;
	}

	public Instruction visitMatch2Node(Match2Node iVisited) {// done
		ISourcePosition pos = iVisited.getPosition();
		ASTNode receiverNode = collectSingleNodeSafe(iVisited.getReceiverNode());
		ASTNode valueNode = collectSingleNodeSafe(iVisited.getValueNode());
		RubyMatch2Expression e = new RubyMatch2Expression(pos.getStartOffset(),
				pos.getEndOffset(), receiverNode, valueNode);
		states.peek().add(e);
		return null;
	}

	public Instruction visitMatch3Node(Match3Node iVisited) {// done
		ISourcePosition pos = iVisited.getPosition();
		ASTNode receiverNode = collectSingleNodeSafe(iVisited.getReceiverNode());
		ASTNode valueNode = collectSingleNodeSafe(iVisited.getValueNode());
		RubyMatch3Expression e = new RubyMatch3Expression(pos.getStartOffset(),
				pos.getEndOffset(), receiverNode, valueNode);
		states.peek().add(e);
		return null;
	}

	public Instruction visitMatchNode(MatchNode iVisited) { // done
		ISourcePosition pos = iVisited.getPosition();
		ASTNode regexp = collectSingleNodeSafe(iVisited.getRegexpNode());
		RubyMatchExpression e = new RubyMatchExpression(pos.getStartOffset(),
				pos.getEndOffset(), regexp);
		states.peek().add(e);
		return null;
	}

	public Instruction visitModuleNode(ModuleNode iVisited) {
		String name = ""; //$NON-NLS-1$
		Node cpathNode = iVisited.getCPath();
		if (cpathNode instanceof Colon2Node || cpathNode instanceof ConstNode) {
			name = colons2Name(cpathNode);
		}
		ASTNode cpath = collectSingleNodeSafe(cpathNode);
		ISourcePosition pos = iVisited.getCPath().getPosition();
		ISourcePosition cPos = iVisited.getPosition();
		cPos = fixNamePosition(cPos);
		pos = fixNamePosition(pos);
		RubyModuleDeclaration type = new RubyModuleDeclaration(cpath, null,
				cPos.getStartOffset(), cPos.getEndOffset());
		type.setModifier(Modifiers.AccModule);
		states.peek().add(type);
		final String enclosingTypeName = states.getFullClassName();
		type.setEnclosingTypeName(enclosingTypeName);
		states.push(new ModuleState(type, enclosingTypeName));
		// body
		Node bodyNode = iVisited.getBodyNode();
		if (bodyNode != null) {
			pos = bodyNode.getPosition();
			int end = -1;
			while (bodyNode instanceof NewlineNode)
				bodyNode = ((NewlineNode) bodyNode).getNextNode();
			if (bodyNode instanceof BlockNode) {
				BlockNode blockNode = (BlockNode) bodyNode;
				// XXX!!!!
				end = blockNode.getLast().getPosition().getEndOffset();
			} else {
				if (TRACE_RECOVERING)
					RubyPlugin.log("DLTKASTBuildVisitor.visitModuleNode(" //$NON-NLS-1$
							+ name + "): unknown body type " //$NON-NLS-1$
							+ bodyNode.getClass().getName());
			}
			pos = fixBorders(pos);
			Block bl = new Block(pos.getStartOffset(), (end == -1) ? pos
					.getEndOffset() : end);
			type.setBody(bl);
			bodyNode.accept(this);
		}
		states.pop();
		return null;
	}

	public Instruction visitNewlineNode(NewlineNode iVisited) { // done
		iVisited.getNextNode().accept(this);
		return null;
	}

	public Instruction visitNextNode(NextNode iVisited) { // done
		ISourcePosition position = iVisited.getPosition();
		RubyCallArgumentsList args = new RubyCallArgumentsList();
		Node valueNode = iVisited.getValueNode();
		if (valueNode != null) {
			ASTNode s = collectSingleNodeSafe(valueNode);
			args.addArgument(s, 0);
		}
		states.peek().add(
				new RubyNextExpression(position.getStartOffset(), position
						.getEndOffset(), args));
		return null;
	}

	public Instruction visitNilNode(NilNode iVisited) { // done
		ISourcePosition pos = iVisited.getPosition();
		states.peek().add(
				new NilLiteral(pos.getStartOffset(), pos.getEndOffset()));
		return null;
	}

	public Instruction visitNotNode(NotNode iVisited) { // done
		ISourcePosition pos = iVisited.getPosition();
		ASTNode expr = collectSingleNodeSafe(iVisited.getConditionNode());
		RubyNotExpression e = new RubyNotExpression(pos.getStartOffset(), pos
				.getEndOffset(), expr);
		states.peek().add(e);
		return null;
	}

	public Instruction visitNthRefNode(NthRefNode iVisited) { // done
		ISourcePosition pos = iVisited.getPosition();
		states.peek().add(
				new VariableReference(pos.getStartOffset(), pos.getEndOffset(),
						"$" + iVisited.getMatchNumber(), //$NON-NLS-1$
						RubyVariableKind.GLOBAL));

		return null;
	}

	public Instruction visitOpElementAsgnNode(OpElementAsgnNode iVisited) {

		return null;
	}

	public Instruction visitOpAsgnNode(OpAsgnNode iVisited) {

		return null;
	}

	public Instruction visitOpAsgnAndNode(OpAsgnAndNode iVisited) {

		return null;
	}

	public Instruction visitOpAsgnOrNode(OpAsgnOrNode iVisited) {

		return null;
	}

	public Instruction visitOptNNode(OptNNode iVisited) {
		// System.out.println("DLTKASTBuildVisitor.visitOptNNode()");
		iVisited.getBodyNode().accept(this);
		return null;
	}

	public Instruction visitOrNode(OrNode iVisited) { // done
		ASTNode leftSt = collectSingleNodeSafe(iVisited.getFirstNode());
		ASTNode rightSt = collectSingleNodeSafe(iVisited.getSecondNode());

		RubyBinaryExpression b = new RubyBinaryExpression(leftSt,
				ExpressionConstants.E_BOR, rightSt);
		states.peek().add(b);
		return null;
	}

	public Instruction visitPostExeNode(PostExeNode iVisited) {

		return null;
	}

	public Instruction visitRedoNode(RedoNode iVisited) {
		ISourcePosition position = iVisited.getPosition();
		states.peek().add(
				new RubyRedoExpression(position.getStartOffset(), position
						.getEndOffset()));
		return null;
	}

	public Instruction visitRescueBodyNode(RescueBodyNode iVisited) { // done
		ASTNode bodyNode = collectSingleNodeSafe(iVisited.getBodyNode());
		ASTNode exceptionNodes = collectSingleNodeSafe(iVisited
				.getExceptionNodes()); // in fact it would be an expression
		// list
		// TODO: exception nodes contains only names of exceptions, not their
		// names itself
		// so we need to parse them by hands
		RubyRescueBodyStatement optRescueNode = (RubyRescueBodyStatement) collectSingleNodeSafe(iVisited
				.getOptRescueNode());

		ISourcePosition pos = iVisited.getPosition();

		RubyRescueBodyStatement rescueStatement = new RubyRescueBodyStatement(
				pos.getStartOffset(), pos.getEndOffset(), bodyNode,
				exceptionNodes, optRescueNode);

		states.peek().add(rescueStatement);

		return null;
	}

	public Instruction visitRescueNode(RescueNode iVisited) { // done
		ASTNode bodyNode = collectSingleNodeSafe(iVisited.getBodyNode());
		ASTNode elseNode = collectSingleNodeSafe(iVisited.getElseNode());

		RubyRescueBodyStatement rescueNode = (RubyRescueBodyStatement) collectSingleNodeSafe(iVisited
				.getRescueNode());

		ISourcePosition pos = iVisited.getPosition();

		RubyRescueStatement rescueStatement = new RubyRescueStatement(pos
				.getStartOffset(), pos.getEndOffset(), bodyNode, elseNode,
				rescueNode);

		states.peek().add(rescueStatement);

		return null;
	}

	public Instruction visitRetryNode(RetryNode iVisited) { // done
		ISourcePosition position = iVisited.getPosition();
		states.peek().add(
				new RubyRetryExpression(position.getStartOffset(), position
						.getEndOffset()));
		return null;
	}

	public Instruction visitReturnNode(ReturnNode iVisited) {
		ISourcePosition position = iVisited.getPosition();
		ASTNode value = null;
		if (iVisited.getValueNode() != null) {
			value = collectSingleNodeSafe(iVisited.getValueNode());
		}
		RubyCallArgumentsList list = new RubyCallArgumentsList();
		if (value != null)
			list.addArgument(value, 0);
		states.peek().add(
				new RubyReturnStatement(list, position.getStartOffset(),
						position.getEndOffset()));
		return null;
	}

	public Instruction visitSClassNode(SClassNode iVisited) {
		String name = ""; //$NON-NLS-1$
		Node receiver = iVisited.getReceiverNode();
		if (receiver instanceof ConstNode) {
			name = "<< " + ((ConstNode) iVisited.getReceiverNode()).getName(); //$NON-NLS-1$
		} else if (receiver instanceof SelfNode) {
			name = "<< self"; //$NON-NLS-1$
		} else {
			int startOffset = receiver.getPosition().getStartOffset();
			int endOffset = receiver.getPosition().getEndOffset();
			name = "<< " //$NON-NLS-1$
					+ String.copyValueOf(content, startOffset,
							endOffset - startOffset).trim();
		}
		ISourcePosition pos = iVisited.getReceiverNode().getPosition();
		ISourcePosition cPos = iVisited.getPosition();
		RubySingletonClassDeclaration type = new RubySingletonClassDeclaration(
				name, pos.getStartOffset(), pos.getEndOffset(), cPos
						.getStartOffset(), cPos.getEndOffset());
		states.peek().add(type);

		CollectingState coll = new CollectingState();
		states.push(coll);
		receiver.accept(this);
		states.pop();
		if (coll.list.size() == 1 && coll.list.get(0) instanceof ASTNode) {
			Object obj = coll.list.get(0);
			type.setReceiver((ASTNode) obj);
			if (obj instanceof SimpleReference) {
				SimpleReference reference = (SimpleReference) obj;
				type.setName("<< " + reference.getName()); //$NON-NLS-1$
			}
		}
		states.push(new ClassState(type, states.getFullClassName()));
		Node bodyNode = iVisited.getBodyNode();
		if (bodyNode != null) {
			pos = bodyNode.getPosition();
			Block bl = new Block(pos.getStartOffset(), pos.getEndOffset() + 1);
			type.setBody(bl);
			bodyNode.accept(this);
		}
		states.pop();
		return null;
	}

	public Instruction visitSelfNode(SelfNode iVisited) {
		ISourcePosition position = fixNamePosition(iVisited.getPosition());
		states.peek().add(
				new RubySelfReference(position.getStartOffset(), position
						.getEndOffset()));
		return null;
	}

	public Instruction visitSplatNode(SplatNode iVisited) {
		Iterator<Node> iterator = iVisited.childNodes().iterator();
		while (iterator.hasNext()) {
			iterator.next().accept(this);
		}

		return null;
	}

	public Instruction visitStrNode(StrNode iVisited) {
		String value = iVisited.getValue().toString();
		ISourcePosition position = iVisited.getPosition();
		int start = position.getStartOffset();
		int end = position.getEndOffset();
		if (value.length() == 0 && !isEmptyString(start, end)) {
			// FIXME why do we need this code? only for the __FILE__?
			value = String.copyValueOf(content, start, end - start);
		} else {
			value = '"' + value + '"';
		}
		states.peek().add(new StringLiteral(start, end, value));
		return null;
	}

	private boolean isEmptyString(int start, int end) {
		if (end - start == 2) {
			if (content[start] == '\'' && content[start + 1] == '\''
					|| content[start] == '"' && content[start + 1] == '"') {
				return true;
			}
		} else if (end - start == 3) {
			if (content[start] == '%') {
				final char starter = content[start + 1];
				if (!RubySyntaxUtils.isValidPercentStringStarter(starter)) {
					final char terminator = RubySyntaxUtils
							.getPercentStringTerminator(starter);
					if (terminator != 0 && content[start + 2] == terminator) {
						return true;
					}
				}
			}
		} else if (end - start == 4) {
			if (content[start] == '%') {
				if (RubySyntaxUtils
						.isValidPercentStringStarter(content[start + 1])) {
					final char terminator = RubySyntaxUtils
							.getPercentStringTerminator(content[start + 2]);
					if (terminator != 0 && content[start + 3] == terminator) {
						return true;
					}
				}
			}
		}
		return false;
	}

	public Instruction visitSValueNode(SValueNode iVisited) {
		Iterator<Node> iterator = iVisited.childNodes().iterator();
		while (iterator.hasNext()) {
			iterator.next().accept(this);
		}
		return null;
	}

	private CallArgumentsList processCallArguments(Node argsNode) {
		RubyCallArgumentsList argList = new RubyCallArgumentsList();
		states.push(new ArgumentsState(argList));

		if (argsNode instanceof ListNode) {
			ListNode arrayNode = (ListNode) argsNode;
			List<Node> list = arrayNode.childNodes();
			for (Iterator<Node> iter = list.iterator(); iter.hasNext();) {
				Node node = iter.next();
				node.accept(this);
			}
		} else if (argsNode instanceof ArgsCatNode) {
			ArgsCatNode argsCatNode = (ArgsCatNode) argsNode;
			CallArgumentsList first = processCallArguments(argsCatNode
					.getFirstNode());
			CallArgumentsList second = processCallArguments(argsCatNode
					.getSecondNode());
			for (Iterator<ASTNode> iterator = first.getChilds().iterator(); iterator
					.hasNext();) {
				ASTNode e = iterator.next();
				argList.addNode(e);
			}
			for (Iterator<ASTNode> iterator = second.getChilds().iterator(); iterator
					.hasNext();) {
				ASTNode e = iterator.next();
				argList.addNode(e);
			}
		} else if (argsNode != null) {
			argsNode.accept(this);
		}

		states.pop();

		return argList;
	}

	public Instruction visitSuperNode(SuperNode iVisited) { // done
		Node argsNode = iVisited.getArgsNode();
		CallArgumentsList callArguments = processCallArguments(argsNode);

		Node iterNode = iVisited.getIterNode();
		ASTNode block = collectSingleNodeSafe(iterNode);

		ISourcePosition pos = iVisited.getPosition();

		RubySuperExpression expr = new RubySuperExpression(
				pos.getStartOffset(), pos.getEndOffset(), callArguments, block);

		states.peek().add(expr);

		return null;
	}

	public Instruction visitToAryNode(ToAryNode iVisited) {
		Iterator<Node> iterator = iVisited.childNodes().iterator();
		while (iterator.hasNext()) {
			iterator.next().accept(this);
		}
		return null;
	}

	public Instruction visitTrueNode(TrueNode iVisited) { // done
		ISourcePosition position = iVisited.getPosition();
		states.peek().add(
				new BooleanLiteral(position.getStartOffset(), position
						.getEndOffset(), true));
		return null;
	}

	public Instruction visitUndefNode(UndefNode iVisited) { // done
		ISourcePosition pos = iVisited.getPosition();
		RubyUndefStatement s = new RubyUndefStatement(pos.getStartOffset(), pos
				.getEndOffset());
		states.peek().add(s);
		return null;
	}

	public Instruction visitUntilNode(UntilNode iVisited) { // done
		ASTNode condition = collectSingleNodeSafe(iVisited.getConditionNode());
		ASTNode body = collectSingleNodeSafe(iVisited.getBodyNode());
		ISourcePosition pos = iVisited.getPosition();
		RubyUntilStatement st = new RubyUntilStatement(condition, body);
		st.setStart(pos.getStartOffset());
		st.setEnd(pos.getEndOffset());
		states.peek().add(st);
		return null;
	}

	public Instruction visitVAliasNode(VAliasNode iVisited) {

		return null;
	}

	public Instruction visitVCallNode(VCallNode iVisited) {
		String methodName = iVisited.getName();

		if (states.isClassLikeState()) {
			ClassLikeState classState = states.getClassLikeState();
			if (methodName.equals("private")) //$NON-NLS-1$
				classState.visibility = Modifiers.AccPrivate;
			else if (methodName.equals("protected")) //$NON-NLS-1$
				classState.visibility = Modifiers.AccProtected;
			else if (methodName.equals("public")) //$NON-NLS-1$
				classState.visibility = Modifiers.AccPublic;
		}

		ISourcePosition pos = iVisited.getPosition();
		int funcNameStart = pos.getStartOffset();
		// Assert.isTrue(funcNameStart + methodName.length() == funcNameEnd);
		CallExpression c = new CallExpression(null, methodName,
				CallArgumentsList.EMPTY);
		c.setStart(funcNameStart);
		c.setEnd(funcNameStart + methodName.length());
		c.getCallName().setStart(funcNameStart);
		c.getCallName().setEnd(funcNameStart + methodName.length());
		this.states.peek().add(c);

		return null;
	}

	public Instruction visitWhenNode(WhenNode iVisited) { // done
		ISourcePosition position = iVisited.getPosition();
		RubyWhenStatement statement = new RubyWhenStatement(position
				.getStartOffset(), position.getEndOffset());
		ASTNode bodyStatement = collectSingleNodeSafe(iVisited.getBodyNode());
		ASTNode expressionsStatement = collectSingleNodeSafe(iVisited
				.getExpressionNodes());

		statement.setBody(bodyStatement);
		if (expressionsStatement instanceof org.eclipse.dltk.ast.ASTListNode) {
			org.eclipse.dltk.ast.ASTListNode list = (org.eclipse.dltk.ast.ASTListNode) expressionsStatement;
			statement.setExpressions(list.getChilds());
		} else {
			List<ASTNode> list = new ArrayList<ASTNode>(1);
			list.add(expressionsStatement);
			statement.setExpressions(list);
		}

		states.peek().add(statement);
		return null;
	}

	public Instruction visitWhileNode(WhileNode iVisited) { // done
		ASTNode condition = collectSingleNodeSafe(iVisited.getConditionNode());
		ASTNode body = collectSingleNodeSafe(iVisited.getBodyNode());
		ISourcePosition pos = iVisited.getPosition();
		RubyWhileStatement st = new RubyWhileStatement(condition, body);
		st.setStart(pos.getStartOffset());
		st.setEnd(pos.getEndOffset());
		states.peek().add(st);
		return null;
	}

	public Instruction visitXStrNode(XStrNode iVisited) { // done
		ISourcePosition pos = iVisited.getPosition();
		String value = iVisited.getValue().toString();
		RubyBacktickStringLiteral s = new RubyBacktickStringLiteral(pos
				.getStartOffset(), pos.getEndOffset(), value);
		states.peek().add(s);
		return null;
	}

	public Instruction visitYieldNode(YieldNode iVisited) {
		ISourcePosition position = iVisited.getPosition();
		RubyCallArgumentsList args = new RubyCallArgumentsList();
		Node valueNode = iVisited.getArgsNode();
		if (valueNode != null) {
			ASTNode s = collectSingleNodeSafe(valueNode);
			args.addArgument(s, 0);
		}
		states.peek().add(
				new RubyYieldExpression(position.getStartOffset(), position
						.getEndOffset(), args));
		return null;
	}

	public Instruction visitZArrayNode(ZArrayNode iVisited) { // done
		ISourcePosition pos = iVisited.getPosition();
		RubyArrayExpression arr = new RubyArrayExpression();
		arr.setStart(pos.getStartOffset());
		arr.setEnd(pos.getEndOffset());
		states.peek().add(arr);
		return null;
	}

	public Instruction visitZSuperNode(ZSuperNode iVisited) { // done

		CallArgumentsList callArguments = new CallArgumentsList(); // no
		// arguments

		Node iterNode = iVisited.getIterNode();
		ASTNode block = collectSingleNodeSafe(iterNode);

		ISourcePosition pos = iVisited.getPosition();

		RubySuperExpression expr = new RubySuperExpression(
				pos.getStartOffset(), pos.getEndOffset(), callArguments, block);

		states.peek().add(expr);

		return null;
	}

	/**
	 * @see NodeVisitor#visitBignumNode(BignumNode)
	 */
	public Instruction visitBignumNode(BignumNode iVisited) {// done
		ISourcePosition pos = iVisited.getPosition();
		BigInteger value = iVisited.getValue();
		BigNumericLiteral literal = new BigNumericLiteral(pos.getStartOffset(),
				pos.getEndOffset(), value);
		states.peek().add(literal);
		return null;
	}

	/**
	 * @see NodeVisitor#visitFixnumNode(FixnumNode)
	 */
	public Instruction visitFixnumNode(FixnumNode iVisited) {
		ISourcePosition pos = iVisited.getPosition();
		NumericLiteral node = new NumericLiteral(pos.getStartOffset(), pos
				.getEndOffset(), iVisited.getValue());
		states.peek().add(node);
		return null;
	}

	/**
	 * @see NodeVisitor#visitFloatNode(FloatNode)
	 */
	public Instruction visitFloatNode(FloatNode iVisited) { // done
		ISourcePosition pos = iVisited.getPosition();
		double value = iVisited.getValue();
		FloatNumericLiteral num = new FloatNumericLiteral(pos.getStartOffset(),
				pos.getEndOffset(), value);
		states.peek().add(num);
		return null;
	}

	/**
	 * @see NodeVisitor#visitRegexpNode(RegexpNode)
	 */
	public Instruction visitRegexpNode(RegexpNode iVisited) { // done
		Pattern pattern = iVisited.getPattern();
		ISourcePosition position = iVisited.getPosition();
		String value = iVisited.getValue().toString();
		RubyRegexpExpression e = new RubyRegexpExpression(position
				.getStartOffset(), position.getEndOffset(), value);
		e.setPattern(pattern);
		states.peek().add(e);
		return null;
	}

	/**
	 * @see NodeVisitor#visitSymbolNode(SymbolNode)
	 */
	public Instruction visitSymbolNode(SymbolNode iVisited) { // done
		final String symName = iVisited.getName();
		final ISourcePosition position = iVisited.getPosition();
		final int start = position.getStartOffset();
		int nameLen = symName.length();
		if (content[start] == ':') {
			++nameLen;
		}
		int end = position.getEndOffset();
		if (end - start > nameLen) {
			end = start + nameLen;
		}
		RubySymbolReference sr = new RubySymbolReference(start, end, symName);
		states.peek().add(sr);

		return null;
	}

	public Instruction visitArgsPushNode(ArgsPushNode arg0) {
		// TODO Auto-generated method stub
		return null;
	}

	public Instruction visitAttrAssignNode(AttrAssignNode arg0) { // done
		ASTNode receiver = collectSingleNodeSafe(arg0.getReceiverNode());
		CallArgumentsList list = processCallArguments(arg0.getArgsNode());
		CallExpression expr = new CallExpression(receiver, arg0.getName(), list);
		copyOffsets(expr, arg0);
		int possNameStart = arg0.getPosition().getStartOffset();
		if (receiver != null)
			possNameStart = receiver.sourceEnd() + 1;
		fixFunctionCallOffsets(expr, arg0.getName(), possNameStart, list
				.sourceStart(), list.sourceEnd());
		states.peek().add(expr);
		return null;
	}

	public Instruction visitRootNode(RootNode arg0) { // done
		Node bodyNode = arg0.getBodyNode();
		if (bodyNode instanceof BlockNode) {
			BlockNode blockNode = (BlockNode) bodyNode;
			Iterator<Node> iterator = blockNode.childNodes().iterator();
			while (iterator.hasNext()) {
				iterator.next().accept(this);
			}
		} else if (bodyNode != null)
			bodyNode.accept(this);
		return null;
	}
}