public static UnifiedExpression CreateMethodDeclaration(XElement node) {
			Contract.Requires(node != null);
			Contract.Requires(node.Name() == "methodDeclaration");
			/*
			 * methodDeclaration 
			 * :   //constructor
			 *     modifiers (typeParameters)? IDENTIFIER formalParameters ('throws' qualifiedNameList)? 
				   '{' (explicitConstructorInvocation)? (blockStatement)* '}'
			 * |   modifiers (typeParameters)? (type | 'void') IDENTIFIER formalParameters
			 *     ('[' ']')* ('throws' qualifiedNameList)? (block | ';' ) 
			 */

			/* コード例
			 * public int[] getName(String className) [] throws Error {
			 *	   int[][] a = null;
			 *     return a;
			 * } 
			 */

			var name =
					UnifiedVariableIdentifier.Create(
							node.Element("IDENTIFIER").Value);
			var typeParameters = node.HasElement("typeParameters")
										? CreateTypeParameters(
												node.Element("typeParameters"))
										: null;
			var type = CreateType(node.Element("type"));
			//コンストラクタの場合はnullになるがどうせ使わない
			var dimension = node.ElementsByContent("[").Count();
			type = type.WrapArrayRepeatedly(dimension);

			var annotationsAndModifiers =
					CreateModifiers(node.Element("modifiers"));
			var parameters =
					CreateFormalParameters(node.Element("formalParameters"));
			var throws = node.HasElement("qualifiedNameList")
								? CreateQualifiedNameList(
										node.Element("qualifiedNameList"))
										.Select(UnifiedType.Create)
										.ToSet()
								: null;
			var body = node.HasElement("block")
							? CreateBlock(node.Element("block")) : null;

			if (!node.HasElement("type") && !node.HasElementByContent("void")) {
				//case constructor
				var invocationNode =
						node.Element("explicitConstructorInvocation");
				var invocations = invocationNode != null
										? Enumerable.Repeat(
												CreateExplicitConstructorInvocation
														(
																invocationNode),
												1)
										: Enumerable.Empty<UnifiedExpression>
												();
				var block =
						invocations.Concat(
								node.Elements("blockStatement")
										.SelectMany(CreateBlockStatement)
								)
								.ToBlock();

				return UnifiedConstructor.Create(
						block,
						annotationsAndModifiers.Item1,
						annotationsAndModifiers.Item2,
						parameters,
						typeParameters,
						throws);
			}
			return UnifiedFunctionDefinition.Create(
					annotationsAndModifiers.Item1,
					annotationsAndModifiers.Item2,
					type,
					typeParameters,
					name,
					parameters,
					throws,
					body);
		}
		private static UnifiedSynchronized CreateSynchronized(XElement node) {
			Contract.Requires(node != null);
			Contract.Requires(node.Name() == "statement");
			Contract.Requires(node.HasElementByContent("synchronized"));
			/* 
			 * 'synchronized' parExpression block 
			 */
			return UnifiedSynchronized.Create(
					CreateParExpression(node.Element("parExpression")),
					CreateBlock(node.Element("block")));
		}
		private static UnifiedExpression CreateThrow(XElement node) {
			Contract.Requires(node != null);
			Contract.Requires(node.Name() == "statement");
			Contract.Requires(node.HasElementByContent("throw"));
			/*
			 * 'throw' expression ';' 
			 */
			return UnifiedThrow.Create(
					CreateExpression(node.Element("expression")));
		}
		private static UnifiedExpression CreateReturn(XElement node) {
			Contract.Requires(node != null);
			Contract.Requires(node.Name() == "statement");
			Contract.Requires(node.HasElementByContent("return"));
			/*
			 * 'return' (expression)? ';'
			 */
			UnifiedExpression value = null;
			if (node.Elements().Count() == 3) {
				value = CreateExpression(node.Element("expression"));
			}
			return UnifiedReturn.Create(value);
		}
		private static UnifiedExpression CreateContinue(XElement node) {
			Contract.Requires(node != null);
			Contract.Requires(node.Name() == "statement");
			Contract.Requires(node.HasElementByContent("continue"));
			/*
			 * 'continue' (IDENTIFIER)? ';' 
			 */
			var identifierNode = node.Element("IDENTIFIER");
			if (identifierNode != null) {
				return UnifiedContinue.Create(
						UnifiedVariableIdentifier.Create(identifierNode.Value));
			}
			return UnifiedContinue.Create();
		}
		private static UnifiedSwitch CreateSwitch(XElement node) {
			Contract.Requires(node != null);
			Contract.Requires(node.Name() == "statement");
			Contract.Requires(node.HasElementByContent("switch"));
			/* 
			 * 'switch' parExpression '{' switchBlockStatementGroups '}' 
			 */
			return UnifiedSwitch.Create(
					CreateParExpression(node.Element("parExpression")),
					CreateSwitchBlockStatementGroups(
							node.Element("switchBlockStatementGroups"))
					);
		}
		public static UnifiedImport CreateImportDeclaration(XElement node) {
			Contract.Requires(node != null);
			Contract.Requires(node.Name() == "importDeclaration");
			/*
			 * importDeclaration  
			 * :   'import' ('static')? IDENTIFIER '.' '*' ';'
			 * |   'import' ('static')? IDENTIFIER ('.' IDENTIFIER)+ ('.' '*')? ';' 
			 */
			var idStrs = node.Elements("IDENTIFIER").Select(e => e.Value);
			if (node.HasElementByContent("*")) {
				idStrs = idStrs.Concat("*");
			}

			var name =
					idStrs.Select(UnifiedVariableIdentifier.Create).
							ToProperty(".");
			var modifiers = node.HasElementByContent("static")
									? UnifiedModifier.Create(
											node.NthElement(1).Value).
											ToSet()
									: null;

			return UnifiedImport.Create(name, null, null, modifiers);
		}
 public static UnifiedExpression CreateFor_stmt(XElement node)
 {
     Contract.Requires(node != null);
     Contract.Requires(node.Name() == "for_stmt");
     /*
      * for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]
      */
     var exprlist = CreateExprlist(node.Element("exprlist"));
     var testlist = CreateTestlist(node.Element("testlist"));
     var suite = CreateSuite(node.Element("suite"));
     var elseSuite = node.HasElementByContent("else")
                             ? CreateSuite(node.LastElement())
                             : null;
     return UnifiedForeach.Create(
             exprlist.SelectMany(
                     e => e.DescendantsAndSelf<UnifiedIdentifier>())
                     .Select(
                             e =>
                             UnifiedVariableDefinition.Create(
                                     name: e.DeepCopy()))
                     .ToVariableDefinitionList(),
             testlist.ToSmartTupleLiteral(),
             suite,
             elseSuite);
 }
 public static UnifiedExpression CreateWhile_stmt(XElement node)
 {
     Contract.Requires(node != null);
     Contract.Requires(node.Name() == "while_stmt");
     /*
      * while_stmt: 'while' test ':' suite ['else' ':' suite]
      */
     var test = CreateTest(node.Element("test"));
     var suite = CreateSuite(node.Element("suite"));
     var elseSuite = node.HasElementByContent("else")
                             ? CreateSuite(node.LastElement())
                             : null;
     return UnifiedWhile.Create(test, suite, elseSuite);
 }
 public static UnifiedExpression CreateSubscript(XElement node)
 {
     Contract.Requires(node != null);
     Contract.Requires(node.Name() == "subscript");
     /*
      * subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop]
      */
     if (node.HasElementByContent(".")) {
         return UnifiedVariableIdentifier.Create("...");
     }
     var colon = node.ElementByContent(":");
     if (colon == null) {
         return CreateTest(node.FirstElement());
     }
     var firstTestNode = colon.PreviousElementOrDefault();
     var firstTest = firstTestNode != null
                             ? CreateTest(firstTestNode)
                             : null;
     var secondTestNode = colon.NextElementOrDefault("test");
     var secondTest = secondTestNode != null
                              ? CreateTest(secondTestNode)
                              : null;
     var lastTestNode = node.Element("sliceop");
     var lastTest = lastTestNode != null
                            ? CreateSliceop(lastTestNode)
                            : null;
     return UnifiedSlice.Create(firstTest, secondTest, lastTest);
 }