INode InitStaticVariable(string initFieldName, string variableName, Expression initializer, TypeDeclaration typeDeclaration)
		{
			const string helperMethodName = "InitStaticVariableHelper";
			
			if (typeDeclaration != null) {
				if (!typeDeclaration.Children.OfType<MethodDeclaration>().Any(m => m.Name == helperMethodName)) {
					// add helper method
					var helperMethod = new MethodDeclaration {
						Name = helperMethodName,
						Modifier = Modifiers.Static,
						TypeReference = new TypeReference("System.Boolean", true),
						Parameters = {
							new ParameterDeclarationExpression(new TypeReference("Microsoft.VisualBasic.CompilerServices.StaticLocalInitFlag"), "flag")
						},
						Body = new BlockStatement()
					};
					BlockStatement trueBlock = new BlockStatement();
					BlockStatement elseIfBlock = new BlockStatement();
					BlockStatement falseBlock = new BlockStatement();
					helperMethod.Body.AddStatement(
						new IfElseStatement(ExpressionBuilder.Identifier("flag").Member("State").Operator(BinaryOperatorType.Equality, new PrimitiveExpression(0))) {
							TrueStatement = { trueBlock },
							ElseIfSections = {
								new ElseIfSection(ExpressionBuilder.Identifier("flag").Member("State").Operator(BinaryOperatorType.Equality, new PrimitiveExpression(2)), elseIfBlock)
							},
							FalseStatement = { falseBlock }
						});
					trueBlock.Assign(ExpressionBuilder.Identifier("flag").Member("State"), new PrimitiveExpression(2));
					trueBlock.Return(new PrimitiveExpression(true));
					elseIfBlock.Throw(new TypeReference("Microsoft.VisualBasic.CompilerServices.IncompleteInitialization").New());
					falseBlock.Return(new PrimitiveExpression(false));
					typeDeclaration.AddChild(helperMethod);
				}
			}
			
			BlockStatement tryBlock = new BlockStatement();
			BlockStatement ifTrueBlock = new BlockStatement();
			tryBlock.AddStatement(new IfElseStatement(ExpressionBuilder.Identifier(helperMethodName).Call(ExpressionBuilder.Identifier(initFieldName)), ifTrueBlock));
			ifTrueBlock.Assign(ExpressionBuilder.Identifier(variableName), initializer);
			
			BlockStatement finallyBlock = new BlockStatement();
			finallyBlock.Assign(ExpressionBuilder.Identifier(initFieldName).Member("State"), new PrimitiveExpression(1));
			
			BlockStatement lockBlock = new BlockStatement();
			lockBlock.AddStatement(new TryCatchStatement(tryBlock, null, finallyBlock));
			return new LockStatement(ExpressionBuilder.Identifier(initFieldName), lockBlock);
		}
		void ReplaceAllFunctionAssignments(BlockStatement block, string functionName, TypeReference typeReference)
		{
			ReturnStatementForFunctionAssignment visitor = new ReturnStatementForFunctionAssignment(functionName);
			block.AcceptVisitor(visitor, null);
			if (visitor.expressionsToReplace.Count == 1 && !visitor.hasExit && IsAssignmentTo(block.Children.Last(), functionName)) {
				Expression returnValue = GetAssignmentFromStatement(block.Children.Last()).Right;
				block.Children.RemoveAt(block.Children.Count - 1);
				block.Return(returnValue);
			} else {
				if (visitor.expressionsToReplace.Count > 0) {
					foreach (var expr in visitor.expressionsToReplace) {
						expr.Identifier = FunctionReturnValueName;
					}
					Expression init;
					init = ExpressionBuilder.CreateDefaultValueForType(typeReference);
					block.Children.Insert(0, new LocalVariableDeclaration(new VariableDeclaration(FunctionReturnValueName, init, typeReference)));
					block.Children[0].Parent = block;
					block.Return(new IdentifierExpression(FunctionReturnValueName));
				}
			}
		}