changeset 10597:79041ab43660

Truffle-DSL: API-change: Renamed truffle.api.codegen to truffle.api.dsl for all projects and packages.
author Christian Humer <christian.humer@gmail.com>
date Mon, 01 Jul 2013 20:58:32 +0200
parents f43eb2f1bbbc
children 5b9abb0cc9d8
files graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/AssumptionsTest.java graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/BinaryNodeTest.java graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/ExecuteEvaluatedTest.java graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/GuardsTest.java graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/NodeContainerTest.java graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/PolymorphicTest.java graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/TestHelper.java graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/TypeSystemTest.java graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/package-info.java graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/CreateCast.java graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/GeneratedBy.java graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/Generic.java graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeAssumptions.java graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeChild.java graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeChildren.java graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeContainer.java graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeFactory.java graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeId.java graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/PolymorphicLimit.java graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/ShortCircuit.java graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/Specialization.java graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/SpecializationListener.java graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/TypeCast.java graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/TypeCheck.java graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/TypeSystem.java graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/TypeSystemReference.java graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/AssumptionsTest.java graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/BinaryNodeTest.java graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ExecuteEvaluatedTest.java graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/GuardsTest.java graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NodeContainerTest.java graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest.java graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TestHelper.java graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TypeSystemTest.java graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/package-info.java graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/CreateCast.java graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/GeneratedBy.java graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/Generic.java graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/NodeAssumptions.java graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/NodeChild.java graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/NodeChildren.java graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/NodeContainer.java graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/NodeFactory.java graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/NodeId.java graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/PolymorphicLimit.java graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/ShortCircuit.java graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/Specialization.java graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/SpecializationListener.java graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/TypeCast.java graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/TypeCheck.java graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/TypeSystem.java graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/TypeSystemReference.java graal/com.oracle.truffle.codegen.processor/src/META-INF/services/javax.annotation.processing.Processor graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/AbstractParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/AnnotationProcessor.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/CompileErrorException.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Log.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ProcessorContext.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/TruffleProcessor.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/TruffleTypes.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Utils.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/api/ExtensionContext.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/api/ExtensionProcessor.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/api/element/WritableAnnotationMirror.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/api/element/WritableElement.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/api/element/WritableElementFactory.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/api/element/WritableExecutableElement.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/api/element/WritableVariableElement.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeAnnotationMirror.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeAnnotationValue.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeCompilationUnit.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeElement.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeElementScanner.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeExecutableElement.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeImport.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeNames.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTree.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTreeBuilder.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTreeKind.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTreeVariable.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTypeElement.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTypeMirror.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeVariableElement.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/GeneratedElement.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/codewriter/AbstractCodeWriter.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/codewriter/FixWarningsVisitor.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/codewriter/GenerateOverrideVisitor.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/codewriter/OrganizedImports.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/compiler/AbstractCompiler.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/compiler/Compiler.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/compiler/CompilerFactory.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/compiler/JDTCompiler.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/compiler/JavaCCompiler.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/CreateCastData.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/CreateCastParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ExecutableTypeData.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ExecutableTypeMethodParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/GenericParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeChildData.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeFieldData.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeMethodParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ShortCircuitData.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ShortCircuitParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationData.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationGuardData.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationListenerData.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationListenerParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationMethodParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationThrowsData.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ActualParameter.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ClassElementFactory.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/CodeElementFactory.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/CompilationUnitFactory.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/JavaName.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/MessageContainer.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/MethodSpec.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ParameterSpec.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/Template.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethod.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/GuardData.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/GuardParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeCastData.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeCastParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeCheckData.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeCheckParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeData.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemCodeGenerator.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemData.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemMethodParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemParser.java graal/com.oracle.truffle.dsl.processor/src/META-INF/services/javax.annotation.processing.Processor graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/AbstractParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/AnnotationProcessor.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/CompileErrorException.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/Log.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ProcessorContext.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleProcessor.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleTypes.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/Utils.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/ExtensionContext.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/ExtensionProcessor.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/element/WritableAnnotationMirror.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/element/WritableElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/element/WritableElementFactory.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/element/WritableExecutableElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/element/WritableVariableElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeAnnotationMirror.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeAnnotationValue.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeCompilationUnit.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeElementScanner.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeExecutableElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeImport.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeNames.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTree.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTreeBuilder.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTreeKind.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTreeVariable.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTypeElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTypeMirror.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeVariableElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/GeneratedElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/codewriter/AbstractCodeWriter.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/codewriter/FixWarningsVisitor.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/codewriter/GenerateOverrideVisitor.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/codewriter/OrganizedImports.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/AbstractCompiler.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/Compiler.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/CompilerFactory.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/JDTCompiler.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/JavaCCompiler.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/CreateCastData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/CreateCastParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ExecutableTypeData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ExecutableTypeMethodParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/GenericParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeChildData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeFieldData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeMethodParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ShortCircuitData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ShortCircuitParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationGuardData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationListenerData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationListenerParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationMethodParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationThrowsData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ActualParameter.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ClassElementFactory.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/CodeElementFactory.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/CompilationUnitFactory.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/JavaName.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MessageContainer.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MethodSpec.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ParameterSpec.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/Template.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethod.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethodParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeCastData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeCastParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeCheckData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeCheckParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemCodeGenerator.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemMethodParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemParser.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLTypes.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ArithmeticNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/BigIntegerLiteralNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/BinaryNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/IfNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/IntegerLiteralNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/LessThanNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/LogicalAndNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/PrintNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ReadLocalNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/StringLiteralNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/TernaryNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/TimeNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/WriteLocalNode.java mx/projects
diffstat 234 files changed, 16869 insertions(+), 16867 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/AssumptionsTest.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.codegen.test;
-
-import org.junit.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.codegen.*;
-import com.oracle.truffle.api.codegen.test.AssumptionsTestFactory.DerivedAssumptionNodeFactory;
-import com.oracle.truffle.api.codegen.test.AssumptionsTestFactory.DerivedAssumptionRedeclaredNodeFactory;
-import com.oracle.truffle.api.codegen.test.AssumptionsTestFactory.MultipleAssumptionsNodeFactory;
-import com.oracle.truffle.api.codegen.test.AssumptionsTestFactory.SingleAssumptionNodeFactory;
-import com.oracle.truffle.api.codegen.test.TypeSystemTest.TestRootNode;
-import com.oracle.truffle.api.codegen.test.TypeSystemTest.ValueNode;
-
-public class AssumptionsTest {
-
-    @Test
-    public void testSingleAssumption() {
-        Assumption assumption = Truffle.getRuntime().createAssumption();
-        TestRootNode<?> root = TestHelper.createRoot(SingleAssumptionNodeFactory.getInstance(), assumption);
-
-        Assert.assertEquals(42, TestHelper.executeWith(root));
-        assumption.invalidate();
-        Assert.assertEquals("42", TestHelper.executeWith(root));
-    }
-
-    @NodeAssumptions("assumption")
-    abstract static class SingleAssumptionNode extends ValueNode {
-
-        @Specialization(order = 0, assumptions = "assumption")
-        int doInt() {
-            return 42;
-        }
-
-        @Specialization
-        Object doObject() {
-            return "42";
-        }
-    }
-
-    @Test
-    public void testMultipleAssumption() {
-        Assumption assumption1 = Truffle.getRuntime().createAssumption();
-        Assumption assumption2 = Truffle.getRuntime().createAssumption();
-        TestRootNode<?> root = TestHelper.createRoot(MultipleAssumptionsNodeFactory.getInstance(), assumption1, assumption2);
-
-        Assert.assertEquals(42, TestHelper.executeWith(root));
-        assumption2.invalidate();
-        Assert.assertEquals("42", TestHelper.executeWith(root));
-        assumption1.invalidate();
-        Assert.assertEquals("43", TestHelper.executeWith(root));
-    }
-
-    @NodeAssumptions({"assumption1", "assumption2"})
-    abstract static class MultipleAssumptionsNode extends ValueNode {
-
-        @Specialization(assumptions = {"assumption1", "assumption2"})
-        int doInt() {
-            return 42;
-        }
-
-        @Specialization(assumptions = "assumption1")
-        Object doObject() {
-            return "42";
-        }
-
-        @Generic
-        Object doGeneric() {
-            return "43";
-        }
-    }
-
-    @Test
-    public void testDerivedAssumption() {
-        Assumption additionalAssumption = Truffle.getRuntime().createAssumption();
-        Assumption assumption = Truffle.getRuntime().createAssumption();
-        TestRootNode<?> root = TestHelper.createRoot(DerivedAssumptionNodeFactory.getInstance(), assumption, additionalAssumption);
-
-        Assert.assertEquals(42, TestHelper.executeWith(root));
-        assumption.invalidate();
-        Assert.assertEquals(43, TestHelper.executeWith(root));
-        additionalAssumption.invalidate();
-        Assert.assertEquals("42", TestHelper.executeWith(root));
-    }
-
-    @NodeAssumptions({"additionalAssumption"})
-    abstract static class DerivedAssumptionNode extends SingleAssumptionNode {
-
-        @Specialization(order = 1, assumptions = "additionalAssumption")
-        int doIntDerived() {
-            return 43;
-        }
-    }
-
-    @Test
-    public void testDerivedAssumptionRedeclared() {
-        Assumption additionalAssumption = Truffle.getRuntime().createAssumption();
-        Assumption assumption = Truffle.getRuntime().createAssumption();
-        TestRootNode<?> root = TestHelper.createRoot(DerivedAssumptionRedeclaredNodeFactory.getInstance(), additionalAssumption, assumption);
-
-        Assert.assertEquals(42, TestHelper.executeWith(root));
-        assumption.invalidate();
-        Assert.assertEquals(43, TestHelper.executeWith(root));
-        additionalAssumption.invalidate();
-        Assert.assertEquals("42", TestHelper.executeWith(root));
-    }
-
-    @NodeAssumptions({"additionalAssumption", "assumption"})
-    abstract static class DerivedAssumptionRedeclaredNode extends SingleAssumptionNode {
-
-        @Specialization(order = 1, assumptions = "additionalAssumption")
-        int doIntDerived() {
-            return 43;
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/BinaryNodeTest.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.codegen.test;
-
-import static com.oracle.truffle.api.codegen.test.TestHelper.*;
-import static org.junit.Assert.*;
-
-import org.junit.*;
-
-import com.oracle.truffle.api.codegen.*;
-import com.oracle.truffle.api.codegen.test.BinaryNodeTestFactory.AddNodeFactory;
-import com.oracle.truffle.api.codegen.test.TypeSystemTest.TestRootNode;
-import com.oracle.truffle.api.codegen.test.TypeSystemTest.ValueNode;
-
-public class BinaryNodeTest {
-
-    @Test
-    public void testAdd() {
-        TestRootNode<AddNode> node = createRoot(AddNodeFactory.getInstance());
-        assertEquals(42, executeWith(node, 19, 23));
-        assertEquals(42d, executeWith(node, 19d, 23d));
-        assertEquals(42d, executeWith(node, "19", "23"));
-        assertEquals(42, executeWith(node, 19, 23));
-    }
-
-    @Test(expected = RuntimeException.class)
-    public void testAddUnsupported() {
-        TestRootNode<AddNode> node = createRoot(AddNodeFactory.getInstance());
-        executeWith(node, new Object(), new Object());
-    }
-
-    @NodeChildren({@NodeChild("left"), @NodeChild("right")})
-    abstract static class BinaryNode extends ValueNode {
-    }
-
-    abstract static class AddNode extends BinaryNode {
-
-        @Specialization
-        int add(int left, int right) {
-            return left + right;
-        }
-
-        @Generic
-        Object add(Object left, Object right) {
-            return convertDouble(left) + convertDouble(right);
-        }
-
-        static double convertDouble(Object value) {
-            if (value instanceof Number) {
-                return ((Number) value).doubleValue();
-            } else if (value instanceof String) {
-                return Double.parseDouble((String) value);
-            }
-            throw new RuntimeException("Invalid datatype");
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/ExecuteEvaluatedTest.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.codegen.test;
-
-import org.junit.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.codegen.*;
-import com.oracle.truffle.api.codegen.test.ExecuteEvaluatedTestFactory.DoubleEvaluatedNodeFactory;
-import com.oracle.truffle.api.codegen.test.ExecuteEvaluatedTestFactory.EvaluatedNodeFactory;
-import com.oracle.truffle.api.codegen.test.ExecuteEvaluatedTestFactory.UseDoubleEvaluatedNodeFactory;
-import com.oracle.truffle.api.codegen.test.ExecuteEvaluatedTestFactory.UseEvaluatedNodeFactory;
-import com.oracle.truffle.api.codegen.test.TypeSystemTest.ArgumentNode;
-import com.oracle.truffle.api.codegen.test.TypeSystemTest.TestArguments;
-import com.oracle.truffle.api.codegen.test.TypeSystemTest.ValueNode;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-
-public class ExecuteEvaluatedTest {
-
-    @Test
-    public void testSingleEvaluated() {
-        ArgumentNode arg0 = new ArgumentNode(0);
-        CallTarget callTarget = TestHelper.createCallTarget(UseEvaluatedNodeFactory.create(arg0, EvaluatedNodeFactory.create(null)));
-
-        Assert.assertEquals(43, callTarget.call(new TestArguments(42)));
-        Assert.assertEquals(1, arg0.getInvocationCount());
-    }
-
-    @NodeChild("exp")
-    abstract static class EvaluatedNode extends ValueNode {
-
-        @Specialization
-        int doExecuteWith(int exp) {
-            return exp + 1;
-        }
-
-        public abstract Object executeEvaluated(VirtualFrame frame, Object targetValue);
-
-        public abstract int executeIntEvaluated(VirtualFrame frame, Object targetValue) throws UnexpectedResultException;
-    }
-
-    @NodeChildren({@NodeChild("exp0"), @NodeChild(value = "exp1", type = EvaluatedNode.class, executeWith = "exp0")})
-    abstract static class UseEvaluatedNode extends ValueNode {
-
-        @Specialization
-        int call(int exp0, int exp1) {
-            Assert.assertEquals(exp0 + 1, exp1);
-            return exp1;
-        }
-    }
-
-    @Test
-    public void testDoubleEvaluated() {
-        ArgumentNode arg0 = new ArgumentNode(0);
-        ArgumentNode arg1 = new ArgumentNode(1);
-        CallTarget callTarget = TestHelper.createCallTarget(UseDoubleEvaluatedNodeFactory.create(arg0, arg1, DoubleEvaluatedNodeFactory.create(null, null)));
-
-        Assert.assertEquals(85, callTarget.call(new TestArguments(42, 43)));
-        Assert.assertEquals(1, arg0.getInvocationCount());
-        Assert.assertEquals(1, arg1.getInvocationCount());
-    }
-
-    @NodeChildren({@NodeChild("exp0"), @NodeChild("exp1")})
-    abstract static class DoubleEvaluatedNode extends ValueNode {
-
-        @Specialization
-        int doExecuteWith(int exp0, int exp1) {
-            return exp0 + exp1;
-        }
-
-        public abstract Object executeEvaluated(VirtualFrame frame, Object exp0, Object exp1);
-
-        public abstract int executeIntEvaluated(VirtualFrame frame, Object exp0, Object exp1) throws UnexpectedResultException;
-    }
-
-    @NodeChildren({@NodeChild("exp0"), @NodeChild("exp1"), @NodeChild(value = "exp2", type = DoubleEvaluatedNode.class, executeWith = {"exp0", "exp1"})})
-    abstract static class UseDoubleEvaluatedNode extends ValueNode {
-
-        @Specialization
-        int call(int exp0, int exp1, int exp2) {
-            Assert.assertEquals(exp0 + exp1, exp2);
-            return exp2;
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/GuardsTest.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.codegen.test;
-
-import static com.oracle.truffle.api.codegen.test.TestHelper.*;
-
-import org.junit.*;
-import static org.junit.Assert.*;
-
-import com.oracle.truffle.api.codegen.*;
-import com.oracle.truffle.api.codegen.test.GuardsTestFactory.GlobalFlagGuardFactory;
-import com.oracle.truffle.api.codegen.test.GuardsTestFactory.InvocationGuardFactory;
-import com.oracle.truffle.api.codegen.test.TypeSystemTest.TestRootNode;
-import com.oracle.truffle.api.codegen.test.TypeSystemTest.ValueNode;
-
-@SuppressWarnings("unused")
-public class GuardsTest {
-
-    private static final Object NULL = new Object();
-
-    @Test
-    public void testGuardInvocations() {
-        TestRootNode<InvocationGuard> root = createRoot(InvocationGuardFactory.getInstance());
-
-        assertEquals(Integer.MAX_VALUE, executeWith(root, Integer.MAX_VALUE - 1, 1));
-        assertEquals(1, InvocationGuard.specializedInvocations);
-        assertEquals(0, InvocationGuard.genericInvocations);
-
-        assertEquals(42, executeWith(root, Integer.MAX_VALUE, 1));
-        assertEquals(1, InvocationGuard.specializedInvocations);
-        assertEquals(1, InvocationGuard.genericInvocations);
-    }
-
-    @NodeChildren({@NodeChild("value0"), @NodeChild("value1")})
-    public abstract static class InvocationGuard extends ValueNode {
-
-        static int specializedInvocations = 0;
-        static int genericInvocations = 0;
-
-        boolean guard(int value0, int value1) {
-            return value0 != Integer.MAX_VALUE;
-        }
-
-        @Specialization(guards = "guard")
-        int doSpecialized(int value0, int value1) {
-            specializedInvocations++;
-            return value0 + value1;
-        }
-
-        @Generic
-        int doGeneric(Object value0, Object value1) {
-            genericInvocations++;
-            return 42; // the generic answer to all questions
-        }
-    }
-
-    @Test
-    public void testGuardGlobal() {
-        TestRootNode<GlobalFlagGuard> root = createRoot(GlobalFlagGuardFactory.getInstance());
-
-        assertEquals(42, executeWith(root, NULL));
-
-        GlobalFlagGuard.globalFlag = true;
-        assertEquals(41, executeWith(root, NULL));
-
-        GlobalFlagGuard.globalFlag = false;
-        assertEquals(42, executeWith(root, NULL));
-    }
-
-    @NodeChild("expression")
-    public abstract static class GlobalFlagGuard extends ValueNode {
-
-        static boolean globalFlag = false;
-
-        static boolean globalFlagGuard() {
-            return globalFlag;
-        }
-
-        @Specialization(guards = "globalFlagGuard")
-        int doSpecialized(Object value0) {
-            return 41;
-        }
-
-        @Generic
-        int doGeneric(Object value0) {
-            return 42; // the generic answer to all questions
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/NodeContainerTest.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,186 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.codegen.test;
-
-import static com.oracle.truffle.api.codegen.test.TestHelper.*;
-import static org.junit.Assert.*;
-
-import org.junit.*;
-
-import com.oracle.truffle.api.codegen.*;
-import com.oracle.truffle.api.codegen.test.NodeContainerTestFactory.StrFactory.StrAccessContextFactory;
-import com.oracle.truffle.api.codegen.test.NodeContainerTestFactory.StrFactory.StrConcatFactory;
-import com.oracle.truffle.api.codegen.test.NodeContainerTestFactory.StrFactory.StrLengthFactory;
-import com.oracle.truffle.api.codegen.test.NodeContainerTestFactory.StrFactory.StrSubstrFactory;
-import com.oracle.truffle.api.codegen.test.TypeSystemTest.TestRootNode;
-import com.oracle.truffle.api.codegen.test.TypeSystemTest.ValueNode;
-
-public class NodeContainerTest {
-
-    @Test
-    public void testConcat() {
-        TestRootNode<BuiltinNode> node = createRoot(StrConcatFactory.getInstance(), new Context());
-        Str str1 = new Str("42");
-        Str str2 = new Str(" is the number.");
-        assertEquals(str1.concat(str2), executeWith(node, str1, str2));
-    }
-
-    @Test(expected = UnsupportedOperationException.class)
-    public void testConcatUnsupported() {
-        TestRootNode<BuiltinNode> node = createRoot(StrConcatFactory.getInstance(), new Context());
-        executeWith(node, 42, new Str(" is the number."));
-    }
-
-    @Test
-    public void testSubstrSpecialized() {
-        TestRootNode<BuiltinNode> node = createRoot(StrSubstrFactory.getInstance(), new Context());
-        Str str = new Str("test 42");
-
-        assertEquals(str.substr(5, 7), executeWith(node, str, 5, 7));
-    }
-
-    @Test
-    public void testSubstrGeneric() {
-        TestRootNode<BuiltinNode> node = createRoot(StrSubstrFactory.getInstance(), new Context());
-        Str str = new Str("test 42");
-
-        assertEquals(Str.substr(str, "5", "7"), executeWith(node, str, "5", "7"));
-    }
-
-    @Test(expected = UnsupportedOperationException.class)
-    public void testSubstrUnsupported() {
-        TestRootNode<BuiltinNode> node = createRoot(StrSubstrFactory.getInstance(), new Context());
-        executeWith(node, new Object(), "5", "7");
-    }
-
-    @Test
-    public void testLength() {
-        TestRootNode<BuiltinNode> node = createRoot(StrLengthFactory.getInstance(), new Context());
-        Str testStr = new Str("test 42");
-        assertEquals(testStr.length(), executeWith(node, testStr));
-    }
-
-    @Test(expected = UnsupportedOperationException.class)
-    public void testLengthUnsupported() {
-        TestRootNode<BuiltinNode> node = createRoot(StrLengthFactory.getInstance(), new Context());
-        executeWith(node, new Object());
-    }
-
-    @Test
-    public void testAccessContext() {
-        Context context = new Context();
-        TestRootNode<BuiltinNode> node = createRoot(StrAccessContextFactory.getInstance(), context);
-        // accessible by node
-        assertSame(context, node.getNode().getContext());
-        // accessible by execution
-        assertSame(context, executeWith(node));
-    }
-
-    @NodeContainer(BuiltinNode.class)
-    static class Str {
-
-        private final String internal;
-
-        public Str(String internal) {
-            this.internal = internal;
-        }
-
-        @Specialization
-        Str concat(Str s1) {
-            return new Str(internal + s1.internal);
-        }
-
-        @Specialization
-        Str substr(int beginIndex, int endIndex) {
-            return new Str(internal.substring(beginIndex, endIndex));
-        }
-
-        @Generic
-        static Str substr(Object thisValue, Object beginIndex, Object endIndex) {
-            if (!(thisValue instanceof Str)) {
-                throw new UnsupportedOperationException();
-            }
-            return ((Str) thisValue).substr(convertInt(beginIndex), convertInt(endIndex));
-        }
-
-        @Specialization
-        int length() {
-            return internal.length();
-        }
-
-        @Specialization
-        static Object accessContext(Context context) {
-            return context;
-        }
-
-        static int convertInt(Object value) {
-            if (value instanceof Number) {
-                return ((Number) value).intValue();
-            } else if (value instanceof String) {
-                return Integer.parseInt((String) value);
-            }
-            throw new RuntimeException("Invalid datatype");
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (obj instanceof Str) {
-                return internal.equals(((Str) obj).internal);
-            }
-            return super.equals(obj);
-        }
-
-        @Override
-        public String toString() {
-            return internal;
-        }
-
-        @Override
-        public int hashCode() {
-            return internal.hashCode();
-        }
-    }
-
-    @NodeChild(value = "children", type = ValueNode[].class)
-    abstract static class BuiltinNode extends ValueNode {
-
-        protected final Context context;
-
-        public BuiltinNode(BuiltinNode node) {
-            this(node.context);
-        }
-
-        public BuiltinNode(Context context) {
-            this.context = context;
-        }
-
-        public Context getContext() {
-            return context;
-        }
-    }
-
-    static class Context {
-
-    }
-
-}
--- a/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/PolymorphicTest.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,123 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.codegen.test;
-
-import static com.oracle.truffle.api.codegen.test.TestHelper.*;
-import static org.junit.Assert.*;
-
-import org.junit.*;
-
-import com.oracle.truffle.api.codegen.*;
-import com.oracle.truffle.api.codegen.test.BinaryNodeTest.BinaryNode;
-import com.oracle.truffle.api.codegen.test.PolymorphicTestFactory.Node1Factory;
-import com.oracle.truffle.api.codegen.test.TypeSystemTest.TestRootNode;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.api.nodes.NodeInfo.Kind;
-
-public class PolymorphicTest {
-
-    @Test
-    public void testJustSpecialize() {
-        TestRootNode<Node1> node = TestHelper.createRoot(Node1Factory.getInstance());
-        assertEquals("(int,int)", executeWith(node, 42, 42));
-        assertEquals("(boolean,boolean)", executeWith(node, false, false));
-        assertEquals("(int,boolean)", executeWith(node, 42, false));
-        assertEquals("(boolean,int)", executeWith(node, false, 42));
-        assertEquals(Kind.SPECIALIZED, node.getNode().getClass().getAnnotation(NodeInfo.class).kind());
-    }
-
-    @Test
-    public void testPolymorphic2() {
-        TestRootNode<Node1> node = TestHelper.createRoot(Node1Factory.getInstance());
-        assertEquals("(int,boolean)", executeWith(node, 42, false));
-        assertEquals("(int,int)", executeWith(node, 42, 42));
-        assertEquals(Kind.POLYMORPHIC, node.getNode().getClass().getAnnotation(NodeInfo.class).kind());
-    }
-
-    @Test
-    public void testPolymorphic3() {
-        TestRootNode<Node1> node = TestHelper.createRoot(Node1Factory.getInstance());
-        assertEquals("(int,boolean)", executeWith(node, 42, false));
-        assertEquals("(boolean,boolean)", executeWith(node, true, false));
-        assertEquals("(int,int)", executeWith(node, 42, 42));
-        assertEquals(Kind.POLYMORPHIC, node.getNode().getClass().getAnnotation(NodeInfo.class).kind());
-    }
-
-    @Test
-    public void testGenericLimitReached() {
-        TestRootNode<Node1> node = TestHelper.createRoot(Node1Factory.getInstance());
-        assertEquals("(boolean,int)", executeWith(node, false, 42));
-        assertEquals("(int,boolean)", executeWith(node, 42, false));
-        assertEquals("(boolean,boolean)", executeWith(node, true, false));
-        assertEquals("(int,int)", executeWith(node, 42, 42));
-        assertEquals(Kind.GENERIC, node.getNode().getClass().getAnnotation(NodeInfo.class).kind());
-    }
-
-    @Test
-    public void testGenericInitial() {
-        TestRootNode<Node1> node = TestHelper.createRoot(Node1Factory.getInstance());
-        assertEquals("(generic,generic)", executeWith(node, "", ""));
-        assertEquals(Kind.GENERIC, node.getNode().getClass().getAnnotation(NodeInfo.class).kind());
-    }
-
-    @Test
-    public void testGenericPolymorphic() {
-        TestRootNode<Node1> node = TestHelper.createRoot(Node1Factory.getInstance());
-        assertEquals("(boolean,int)", executeWith(node, false, 42));
-        assertEquals("(int,boolean)", executeWith(node, 42, false));
-        assertEquals("(generic,generic)", executeWith(node, "", ""));
-        assertEquals(Kind.GENERIC, node.getNode().getClass().getAnnotation(NodeInfo.class).kind());
-    }
-
-    @SuppressWarnings("unused")
-    @PolymorphicLimit(3)
-    abstract static class Node1 extends BinaryNode {
-
-        @Specialization(order = 1)
-        String add(int left, int right) {
-            return "(int,int)";
-        }
-
-        @Specialization(order = 2)
-        String add(boolean left, boolean right) {
-            return "(boolean,boolean)";
-        }
-
-        @Specialization(order = 3)
-        String add(int left, boolean right) {
-            return "(int,boolean)";
-        }
-
-        @Specialization(order = 4)
-        String add(boolean left, int right) {
-            return "(boolean,int)";
-        }
-
-        @Generic
-        String add(Object left, Object right) {
-            return "(generic,generic)";
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/TestHelper.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.codegen.test;
-
-import java.util.*;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.codegen.*;
-import com.oracle.truffle.api.codegen.test.NodeContainerTest.*;
-import com.oracle.truffle.api.codegen.test.TypeSystemTest.*;
-
-/**
- * Utility class to provide some test helper functions.
- */
-class TestHelper {
-
-    private static ArgumentNode[] arguments(int count) {
-        ArgumentNode[] nodes = new ArgumentNode[count];
-        for (int i = 0; i < nodes.length; i++) {
-            nodes[i] = new ArgumentNode(i);
-        }
-        return nodes;
-    }
-
-    static <E extends ValueNode> E createNode(NodeFactory<E> factory, Object... constants) {
-        ArgumentNode[] argumentNodes = arguments(factory.getExecutionSignature().size());
-
-        List<Object> argumentList = new ArrayList<>();
-        argumentList.addAll(Arrays.asList(constants));
-        if (ChildrenNode.class.isAssignableFrom(factory.getNodeClass()) || BuiltinNode.class.isAssignableFrom(factory.getNodeClass())) {
-            argumentList.add(argumentNodes);
-        } else {
-            argumentList.addAll(Arrays.asList(argumentNodes));
-        }
-        return factory.createNode(argumentList.toArray(new Object[argumentList.size()]));
-    }
-
-    static <E extends ValueNode> TestRootNode<E> createRoot(NodeFactory<E> factory, Object... constants) {
-        return new TestRootNode<>(createNode(factory, constants));
-    }
-
-    static CallTarget createCallTarget(ValueNode node) {
-        return createCallTarget(new TestRootNode<>(node));
-    }
-
-    static CallTarget createCallTarget(TestRootNode<? extends ValueNode> node) {
-        return Truffle.getRuntime().createCallTarget(node);
-    }
-
-    static <E> Object executeWith(TestRootNode<? extends ValueNode> node, Object... values) {
-        return createCallTarget(node).call(new TestArguments(values));
-    }
-
-}
--- a/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/TypeSystemTest.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
-/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.codegen.test;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.codegen.*;
-import com.oracle.truffle.api.codegen.test.NodeContainerTest.Str;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-
-public class TypeSystemTest {
-
-    @TypeSystem({int.class, boolean.class, String.class, Str.class, CallTarget.class, Object[].class})
-    static class SimpleTypes {
-    }
-
-    @TypeSystemReference(SimpleTypes.class)
-    public abstract static class ValueNode extends Node {
-
-        public int executeInt(VirtualFrame frame) throws UnexpectedResultException {
-            return SimpleTypesGen.SIMPLETYPES.expectInteger(execute(frame));
-        }
-
-        public Str executeStr(VirtualFrame frame) throws UnexpectedResultException {
-            return SimpleTypesGen.SIMPLETYPES.expectStr(execute(frame));
-        }
-
-        public String executeString(VirtualFrame frame) throws UnexpectedResultException {
-            return SimpleTypesGen.SIMPLETYPES.expectString(execute(frame));
-        }
-
-        public boolean executeBoolean(VirtualFrame frame) throws UnexpectedResultException {
-            return SimpleTypesGen.SIMPLETYPES.expectBoolean(execute(frame));
-        }
-
-        public Object[] executeIntArray(VirtualFrame frame) throws UnexpectedResultException {
-            return SimpleTypesGen.SIMPLETYPES.expectObjectArray(execute(frame));
-        }
-
-        public abstract Object execute(VirtualFrame frame);
-
-        @Override
-        public ValueNode copy() {
-            return (ValueNode) super.copy();
-        }
-    }
-
-    @NodeChild(value = "children", type = ValueNode[].class)
-    public abstract static class ChildrenNode extends ValueNode {
-
-    }
-
-    @TypeSystemReference(SimpleTypes.class)
-    public static class TestRootNode<E extends ValueNode> extends RootNode {
-
-        @Child private E node;
-
-        public TestRootNode(E node) {
-            this.node = adoptChild(node);
-        }
-
-        @Override
-        public Object execute(VirtualFrame frame) {
-            return node.execute(frame);
-        }
-
-        public E getNode() {
-            return node;
-        }
-    }
-
-    public static class TestArguments extends Arguments {
-
-        private final Object[] values;
-
-        public TestArguments(Object... values) {
-            this.values = values;
-        }
-
-        public Object[] getValues() {
-            return values;
-        }
-
-        public Object get(int index) {
-            return values[index];
-        }
-
-    }
-
-    public static class ArgumentNode extends ValueNode {
-
-        private int invocationCount;
-        final int index;
-
-        public ArgumentNode(int index) {
-            this.index = index;
-        }
-
-        public int getInvocationCount() {
-            return invocationCount;
-        }
-
-        @Override
-        public Object execute(VirtualFrame frame) {
-            invocationCount++;
-            return frame.getArguments(TestArguments.class).get(index);
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/package-info.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-/**
- * <p>This package contains basic tests of the Truffle-Source-Code-Generation (short Codegen) API and serves at the same
- * time as an introduction to the Codegen API for language implementors. Every test gives an example on how to use the construct explained in the class description.</p>
- *
- * <p>
- * This API relies heavily on the concepts described in com.oracle.truffle.api.test. We assume that the
- * reader is already familiarized with those concepts.
- * </p>
- *
- * <p>
- * TODO general description
- * </p>
- *
- * <p>
- * This introduction to Codegen contains items in the following recommended order:
- *
- * Prerequisites:
- * 
- *
- * <ul>
- * <li>What do I need to get started? {@link com.oracle.truffle.api.codegen.test.TypeSystemTest}</li>
- * <li>How would you generate function nodes for runtime objects? {@link com.oracle.truffle.api.codegen.test.NodeContainerTest}</li>
- * </ul>
- * </p>
- *
- */
-package com.oracle.truffle.api.codegen.test;
-
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/CreateCast.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.codegen;
-
-import java.lang.annotation.*;
-
-import com.oracle.truffle.api.nodes.*;
-
-/**
- * Specifies a factory method that creates a {@link Node} which is used to cast this child.
- */
-@Retention(RetentionPolicy.CLASS)
-@Target({ElementType.METHOD})
-public @interface CreateCast {
-
-    String[] value();
-
-}
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/GeneratedBy.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.codegen;
-
-import java.lang.annotation.*;
-
-/**
- * Marks a type to be generated by another class or a method.
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ElementType.TYPE})
-public @interface GeneratedBy {
-
-    Class<?> value();
-
-    String methodName() default "";
-
-}
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/Generic.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.codegen;
-
-import java.lang.annotation.*;
-
-/**
- *
- */
-@Retention(RetentionPolicy.CLASS)
-@Target({ElementType.METHOD})
-public @interface Generic {
-
-}
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeAssumptions.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.codegen;
-
-import java.lang.annotation.*;
-
-/**
- * Declares one or multiple assumptions for use inside a source code generation enabled node.
- * Declared assumptions must be passed to the {@link NodeFactory#createNode(Object...)} method as
- * parameters.
- */
-@Retention(RetentionPolicy.CLASS)
-@Target({ElementType.TYPE})
-public @interface NodeAssumptions {
-
-    String[] value();
-
-}
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeChild.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.codegen;
-
-import java.lang.annotation.*;
-
-import com.oracle.truffle.api.nodes.*;
-
-/**
- * A {@link NodeChild} element defines an executable child for the enclosing {@link Node}. A
- * {@link Node} contains multiple {@link NodeChildren} specified in linear execution order.
- */
-@Retention(RetentionPolicy.CLASS)
-@Target({ElementType.TYPE})
-public @interface NodeChild {
-
-    String value() default "";
-
-    Class<?> type() default Node.class;
-
-    /**
-     * The {@link #executeWith()} property allows a node to pass the result of one child's
-     * executable as an input to another child's executable. These referenced children must be
-     * defined before the current node in the execution order. The current node {@link #type()}
-     * attribute must be set to a {@link Node} which supports the evaluated execution with the
-     * number of {@link #executeWith()} arguments that are defined. For example if this child is
-     * executed with one argument, the {@link #type()} attribute must define a node which publicly
-     * declares a method with the signature <code>Object execute*(VirtualFrame, Object)</code>.
-     */
-    String[] executeWith() default {};
-}
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeChildren.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.codegen;
-
-import java.lang.annotation.*;
-
-@Retention(RetentionPolicy.CLASS)
-@Target({ElementType.TYPE})
-public @interface NodeChildren {
-
-    NodeChild[] value() default {};
-
-}
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeContainer.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.codegen;
-
-import java.lang.annotation.*;
-
-import com.oracle.truffle.api.nodes.*;
-
-/**
- * A node container can be used to enable Truffle-DSL in classes which do not extend {@link Node}.
- * Compared to normal {@link Node} implementation the nodes are not identified by a class but by
- * their method name. There are cases were method signatures are matching exactly but should be in
- * the same {@link Node}. In this case use {@link NodeId} to disambiguate such cases.
- */
-@Retention(RetentionPolicy.CLASS)
-@Target({ElementType.TYPE})
-public @interface NodeContainer {
-
-    /** The node class to use as base class for {@link Node} definitions grouped by method names. */
-    Class<? extends Node> value();
-
-}
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeFactory.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.codegen;
-
-import java.util.*;
-
-import com.oracle.truffle.api.nodes.*;
-
-/**
- * Enables the dynamic creation of generated nodes. It provides an convenient way to instantiate
- * generated node classes without using reflection.
- */
-public interface NodeFactory<T> {
-
-    /**
-     * Instantiates the node using the arguments array. The arguments length and types must suffice
-     * one of the returned signatures in {@link #getNodeSignatures()}. If the arguments array does
-     * not suffice one of the node signatures an {@link IllegalArgumentException} is thrown.
-     * 
-     * @param arguments the argument values
-     * @return the instantiated node
-     * @throws IllegalArgumentException
-     */
-    T createNode(Object... arguments);
-
-    /**
-     * Instantiates a new generic variant of the node. This is an optional method and throws an
-     * {@link UnsupportedOperationException} if not supported.
-     * 
-     * @param thisNode the current node
-     * @return the specialized node
-     */
-    T createNodeGeneric(T thisNode);
-
-    /**
-     * Returns the node class that will get created by {@link #createNode(Object...)}. The node
-     * class does not match exactly to the instantiated object but they are guaranteed to be
-     * assignable.
-     */
-    Class<T> getNodeClass();
-
-    /**
-     * Returns a list of signatures that can be used to invoke {@link #createNode(Object...)}.
-     */
-    List<List<Class<?>>> getNodeSignatures();
-
-    /**
-     * Returns a list of children that will be executed by the created node. This is useful for base
-     * nodes that can execute a variable amount of nodes.
-     */
-    List<Class<? extends Node>> getExecutionSignature();
-
-}
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeId.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.codegen;
-
-import java.lang.annotation.*;
-
-@Retention(RetentionPolicy.CLASS)
-@Target({ElementType.METHOD, ElementType.TYPE})
-public @interface NodeId {
-
-    String value();
-
-}
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/PolymorphicLimit.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.codegen;
-
-import java.lang.annotation.*;
-
-@Retention(RetentionPolicy.CLASS)
-@Target({ElementType.TYPE})
-public @interface PolymorphicLimit {
-
-    /** Specifies the maximum polymorphic cache depth until it falls back to the generic case. */
-    int value();
-
-}
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/ShortCircuit.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.codegen;
-
-import java.lang.annotation.*;
-
-@Retention(RetentionPolicy.CLASS)
-@Target({ElementType.METHOD})
-public @interface ShortCircuit {
-
-    String value();
-
-}
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/Specialization.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.codegen;
-
-import java.lang.annotation.*;
-
-@Retention(RetentionPolicy.CLASS)
-@Target({ElementType.METHOD})
-public @interface Specialization {
-
-    int DEFAULT_ORDER = -1;
-
-    int order() default DEFAULT_ORDER;
-
-    Class<? extends Throwable>[] rewriteOn() default {};
-
-    String[] guards() default {};
-
-    /**
-     * Defines the assumptions to check for this specialization. When the specialization method is
-     * invoked it is guaranteed that the assigned assumptions still hold. To declare assumptions use
-     * the {@link NodeAssumptions} annotation at class level.
-     */
-    String[] assumptions() default {};
-
-}
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/SpecializationListener.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.codegen;
-
-import java.lang.annotation.*;
-
-@Retention(RetentionPolicy.CLASS)
-@Target({ElementType.METHOD})
-public @interface SpecializationListener {
-}
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/TypeCast.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.codegen;
-
-import java.lang.annotation.*;
-
-@Retention(RetentionPolicy.CLASS)
-@Target({ElementType.METHOD})
-public @interface TypeCast {
-
-}
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/TypeCheck.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.codegen;
-
-import java.lang.annotation.*;
-
-/**
- * <p>
- * Provides a way to define a custom type check for a defined type. The name of the annotated method
- * must fit to the pattern is${typeName} (eg. isInteger), where ${typeName} must be a valid type
- * defined in the parent {@link TypeSystem}. The annotated method must have exactly one argument
- * where the type of the argument is the generic type {@link Object} or a more specific one from the
- * {@link TypeSystem}. You can define multiple overloaded {@link TypeCheck} methods for the same
- * type. This can be used to reduce the boxing overhead in type conversions.
- * </p>
- * 
- * <p>
- * By default the system generates type checks for all types in the parent {@link TypeSystem} which
- * look like the follows:
- * 
- * <pre>
- * {@literal @}TypeCheck
- * boolean is${typeName}(Object value) {
- *         return value instanceof ${typeName};
- * }
- * </pre>
- * 
- * </p>
- * 
- * <b>Example:</b>
- * <p>
- * A type check for BigInteger with one overloaded optimized variant to reduce boxing.
- * </p>
- * 
- * <pre>
- * 
- * 
- * {@literal @}TypeSystem(types = {int.class, BigInteger.class, String.class}, nodeBaseClass = TypedNode.class)
- * public abstract class Types {
- * 
- *     {@literal @}TypeCheck
- *     public boolean isBigInteger(Object value) {
- *         return value instanceof Integer || value instanceof BigInteger;
- *     }
- * 
- *     {@literal @}TypeCheck
- *     public boolean isBigInteger(int value) {
- *         return true;
- *     }
- * 
- * }
- * </pre>
- * 
- * 
- */
-@Retention(RetentionPolicy.CLASS)
-@Target({ElementType.METHOD})
-public @interface TypeCheck {
-
-}
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/TypeSystem.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.codegen;
-
-import java.lang.annotation.*;
-
-import com.oracle.truffle.api.nodes.*;
-
-/**
- * <p>
- * Each {@link Node} has one {@link TypeSystem} at its root to define the types that can be used
- * throughout the system. Multiple {@link TypeSystem}s are allowed, but they cannot be mixed inside
- * a single {@link Node} hierarchy. A {@link TypeSystem} defines a list of types as its child
- * elements, in which every type precedes its super types.The latter condition ensures that the most
- * concrete type is found first when searching the list sequentially for the type of a given generic
- * value.
- * </p>
- * 
- * <p>
- * Each {@link #value()} is represented as a java type. A type can specify two annotations:
- * {@link TypeCheck} and {@link TypeCast}. The {@link TypeCheck} checks whether a given generic
- * value matches to the current type. The {@link TypeCast} casts a generic type value to the current
- * type. If the {@link TypeCheck} and {@link TypeCast} annotations are not declared in the
- * {@link TypeSystem} the a default implementation is provided. The default implementation of
- * {@link TypeCheck} returns <code>true</code> only on an exact type match and {@link TypeCast} is
- * only a cast to this type. Specified methods with {@link TypeCheck} and {@link TypeCast} may be
- * used to extend the definition of a type in the language. In our example, the
- * <code>isInteger</code> and <code>asInteger</code> methods are defined in a way so that they
- * accept also {@link Integer} values, implicitly converting them to {@link Double} . This example
- * points out how we express implicit type conversions.
- * </p>
- * 
- * <p>
- * <b>Example:</b> The {@link TypeSystem} contains the types {@link Boolean}, {@link Integer}, and
- * {@link Double}. The type {@link Object} is always used implicitly as the generic type represent
- * all values.
- * 
- * <pre>
- * 
- * {@literal @}TypeSystem(types = {boolean.class, int.class, double.class})
- * public abstract class ExampleTypeSystem {
- * 
- *     {@literal @}TypeCheck
- *     public boolean isInteger(Object value) {
- *         return value instanceof Integer || value instanceof Double;
- *     }
- * 
- *     {@literal @}TypeCast
- *     public double asInteger(Object value) {
- *         return ((Number)value).doubleValue();
- *     }
- * }
- * </pre>
- * 
- * </p>
- * 
- * @see TypeCast
- * @see TypeCheck
- */
-@Retention(RetentionPolicy.CLASS)
-@Target({ElementType.TYPE})
-public @interface TypeSystem {
-
-    /**
-     * The list of types as child elements of the {@link TypeSystem}. Each precedes its super type.
-     */
-    Class[] value();
-
-}
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/TypeSystemReference.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.codegen;
-
-import java.lang.annotation.*;
-
-import com.oracle.truffle.api.nodes.*;
-
-/**
- * References a {@link TypeSystem} on a node. Must be applied on a {@link Node} class. At least one
- * {@link TypeSystem} must be referenced in a {@link Node}'s type hierarchy.
- * 
- * @see TypeSystem
- * @see Node
- */
-@Retention(RetentionPolicy.CLASS)
-@Target({ElementType.TYPE})
-public @interface TypeSystemReference {
-
-    /** The {@link TypeSystem} java type. */
-    Class<?> value();
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/AssumptionsTest.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.dsl.test;
+
+import org.junit.*;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.dsl.test.AssumptionsTestFactory.DerivedAssumptionNodeFactory;
+import com.oracle.truffle.api.dsl.test.AssumptionsTestFactory.DerivedAssumptionRedeclaredNodeFactory;
+import com.oracle.truffle.api.dsl.test.AssumptionsTestFactory.MultipleAssumptionsNodeFactory;
+import com.oracle.truffle.api.dsl.test.AssumptionsTestFactory.SingleAssumptionNodeFactory;
+import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode;
+import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode;
+
+public class AssumptionsTest {
+
+    @Test
+    public void testSingleAssumption() {
+        Assumption assumption = Truffle.getRuntime().createAssumption();
+        TestRootNode<?> root = TestHelper.createRoot(SingleAssumptionNodeFactory.getInstance(), assumption);
+
+        Assert.assertEquals(42, TestHelper.executeWith(root));
+        assumption.invalidate();
+        Assert.assertEquals("42", TestHelper.executeWith(root));
+    }
+
+    @NodeAssumptions("assumption")
+    abstract static class SingleAssumptionNode extends ValueNode {
+
+        @Specialization(order = 0, assumptions = "assumption")
+        int doInt() {
+            return 42;
+        }
+
+        @Specialization
+        Object doObject() {
+            return "42";
+        }
+    }
+
+    @Test
+    public void testMultipleAssumption() {
+        Assumption assumption1 = Truffle.getRuntime().createAssumption();
+        Assumption assumption2 = Truffle.getRuntime().createAssumption();
+        TestRootNode<?> root = TestHelper.createRoot(MultipleAssumptionsNodeFactory.getInstance(), assumption1, assumption2);
+
+        Assert.assertEquals(42, TestHelper.executeWith(root));
+        assumption2.invalidate();
+        Assert.assertEquals("42", TestHelper.executeWith(root));
+        assumption1.invalidate();
+        Assert.assertEquals("43", TestHelper.executeWith(root));
+    }
+
+    @NodeAssumptions({"assumption1", "assumption2"})
+    abstract static class MultipleAssumptionsNode extends ValueNode {
+
+        @Specialization(assumptions = {"assumption1", "assumption2"})
+        int doInt() {
+            return 42;
+        }
+
+        @Specialization(assumptions = "assumption1")
+        Object doObject() {
+            return "42";
+        }
+
+        @Generic
+        Object doGeneric() {
+            return "43";
+        }
+    }
+
+    @Test
+    public void testDerivedAssumption() {
+        Assumption additionalAssumption = Truffle.getRuntime().createAssumption();
+        Assumption assumption = Truffle.getRuntime().createAssumption();
+        TestRootNode<?> root = TestHelper.createRoot(DerivedAssumptionNodeFactory.getInstance(), assumption, additionalAssumption);
+
+        Assert.assertEquals(42, TestHelper.executeWith(root));
+        assumption.invalidate();
+        Assert.assertEquals(43, TestHelper.executeWith(root));
+        additionalAssumption.invalidate();
+        Assert.assertEquals("42", TestHelper.executeWith(root));
+    }
+
+    @NodeAssumptions({"additionalAssumption"})
+    abstract static class DerivedAssumptionNode extends SingleAssumptionNode {
+
+        @Specialization(order = 1, assumptions = "additionalAssumption")
+        int doIntDerived() {
+            return 43;
+        }
+    }
+
+    @Test
+    public void testDerivedAssumptionRedeclared() {
+        Assumption additionalAssumption = Truffle.getRuntime().createAssumption();
+        Assumption assumption = Truffle.getRuntime().createAssumption();
+        TestRootNode<?> root = TestHelper.createRoot(DerivedAssumptionRedeclaredNodeFactory.getInstance(), additionalAssumption, assumption);
+
+        Assert.assertEquals(42, TestHelper.executeWith(root));
+        assumption.invalidate();
+        Assert.assertEquals(43, TestHelper.executeWith(root));
+        additionalAssumption.invalidate();
+        Assert.assertEquals("42", TestHelper.executeWith(root));
+    }
+
+    @NodeAssumptions({"additionalAssumption", "assumption"})
+    abstract static class DerivedAssumptionRedeclaredNode extends SingleAssumptionNode {
+
+        @Specialization(order = 1, assumptions = "additionalAssumption")
+        int doIntDerived() {
+            return 43;
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/BinaryNodeTest.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.dsl.test;
+
+import static com.oracle.truffle.api.dsl.test.TestHelper.*;
+import static org.junit.Assert.*;
+
+import org.junit.*;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.dsl.test.BinaryNodeTestFactory.AddNodeFactory;
+import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode;
+import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode;
+
+public class BinaryNodeTest {
+
+    @Test
+    public void testAdd() {
+        TestRootNode<AddNode> node = createRoot(AddNodeFactory.getInstance());
+        assertEquals(42, executeWith(node, 19, 23));
+        assertEquals(42d, executeWith(node, 19d, 23d));
+        assertEquals(42d, executeWith(node, "19", "23"));
+        assertEquals(42, executeWith(node, 19, 23));
+    }
+
+    @Test(expected = RuntimeException.class)
+    public void testAddUnsupported() {
+        TestRootNode<AddNode> node = createRoot(AddNodeFactory.getInstance());
+        executeWith(node, new Object(), new Object());
+    }
+
+    @NodeChildren({@NodeChild("left"), @NodeChild("right")})
+    abstract static class BinaryNode extends ValueNode {
+    }
+
+    abstract static class AddNode extends BinaryNode {
+
+        @Specialization
+        int add(int left, int right) {
+            return left + right;
+        }
+
+        @Generic
+        Object add(Object left, Object right) {
+            return convertDouble(left) + convertDouble(right);
+        }
+
+        static double convertDouble(Object value) {
+            if (value instanceof Number) {
+                return ((Number) value).doubleValue();
+            } else if (value instanceof String) {
+                return Double.parseDouble((String) value);
+            }
+            throw new RuntimeException("Invalid datatype");
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ExecuteEvaluatedTest.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.dsl.test;
+
+import org.junit.*;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.DoubleEvaluatedNodeFactory;
+import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.EvaluatedNodeFactory;
+import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.UseDoubleEvaluatedNodeFactory;
+import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.UseEvaluatedNodeFactory;
+import com.oracle.truffle.api.dsl.test.TypeSystemTest.ArgumentNode;
+import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestArguments;
+import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+
+public class ExecuteEvaluatedTest {
+
+    @Test
+    public void testSingleEvaluated() {
+        ArgumentNode arg0 = new ArgumentNode(0);
+        CallTarget callTarget = TestHelper.createCallTarget(UseEvaluatedNodeFactory.create(arg0, EvaluatedNodeFactory.create(null)));
+
+        Assert.assertEquals(43, callTarget.call(new TestArguments(42)));
+        Assert.assertEquals(1, arg0.getInvocationCount());
+    }
+
+    @NodeChild("exp")
+    abstract static class EvaluatedNode extends ValueNode {
+
+        @Specialization
+        int doExecuteWith(int exp) {
+            return exp + 1;
+        }
+
+        public abstract Object executeEvaluated(VirtualFrame frame, Object targetValue);
+
+        public abstract int executeIntEvaluated(VirtualFrame frame, Object targetValue) throws UnexpectedResultException;
+    }
+
+    @NodeChildren({@NodeChild("exp0"), @NodeChild(value = "exp1", type = EvaluatedNode.class, executeWith = "exp0")})
+    abstract static class UseEvaluatedNode extends ValueNode {
+
+        @Specialization
+        int call(int exp0, int exp1) {
+            Assert.assertEquals(exp0 + 1, exp1);
+            return exp1;
+        }
+    }
+
+    @Test
+    public void testDoubleEvaluated() {
+        ArgumentNode arg0 = new ArgumentNode(0);
+        ArgumentNode arg1 = new ArgumentNode(1);
+        CallTarget callTarget = TestHelper.createCallTarget(UseDoubleEvaluatedNodeFactory.create(arg0, arg1, DoubleEvaluatedNodeFactory.create(null, null)));
+
+        Assert.assertEquals(85, callTarget.call(new TestArguments(42, 43)));
+        Assert.assertEquals(1, arg0.getInvocationCount());
+        Assert.assertEquals(1, arg1.getInvocationCount());
+    }
+
+    @NodeChildren({@NodeChild("exp0"), @NodeChild("exp1")})
+    abstract static class DoubleEvaluatedNode extends ValueNode {
+
+        @Specialization
+        int doExecuteWith(int exp0, int exp1) {
+            return exp0 + exp1;
+        }
+
+        public abstract Object executeEvaluated(VirtualFrame frame, Object exp0, Object exp1);
+
+        public abstract int executeIntEvaluated(VirtualFrame frame, Object exp0, Object exp1) throws UnexpectedResultException;
+    }
+
+    @NodeChildren({@NodeChild("exp0"), @NodeChild("exp1"), @NodeChild(value = "exp2", type = DoubleEvaluatedNode.class, executeWith = {"exp0", "exp1"})})
+    abstract static class UseDoubleEvaluatedNode extends ValueNode {
+
+        @Specialization
+        int call(int exp0, int exp1, int exp2) {
+            Assert.assertEquals(exp0 + exp1, exp2);
+            return exp2;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/GuardsTest.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.dsl.test;
+
+import static com.oracle.truffle.api.dsl.test.TestHelper.*;
+import static org.junit.Assert.*;
+
+import org.junit.*;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.dsl.test.GuardsTestFactory.GlobalFlagGuardFactory;
+import com.oracle.truffle.api.dsl.test.GuardsTestFactory.InvocationGuardFactory;
+import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode;
+import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode;
+
+@SuppressWarnings("unused")
+public class GuardsTest {
+
+    private static final Object NULL = new Object();
+
+    @Test
+    public void testGuardInvocations() {
+        TestRootNode<InvocationGuard> root = createRoot(InvocationGuardFactory.getInstance());
+
+        assertEquals(Integer.MAX_VALUE, executeWith(root, Integer.MAX_VALUE - 1, 1));
+        assertEquals(1, InvocationGuard.specializedInvocations);
+        assertEquals(0, InvocationGuard.genericInvocations);
+
+        assertEquals(42, executeWith(root, Integer.MAX_VALUE, 1));
+        assertEquals(1, InvocationGuard.specializedInvocations);
+        assertEquals(1, InvocationGuard.genericInvocations);
+    }
+
+    @NodeChildren({@NodeChild("value0"), @NodeChild("value1")})
+    public abstract static class InvocationGuard extends ValueNode {
+
+        static int specializedInvocations = 0;
+        static int genericInvocations = 0;
+
+        boolean guard(int value0, int value1) {
+            return value0 != Integer.MAX_VALUE;
+        }
+
+        @Specialization(guards = "guard")
+        int doSpecialized(int value0, int value1) {
+            specializedInvocations++;
+            return value0 + value1;
+        }
+
+        @Generic
+        int doGeneric(Object value0, Object value1) {
+            genericInvocations++;
+            return 42; // the generic answer to all questions
+        }
+    }
+
+    @Test
+    public void testGuardGlobal() {
+        TestRootNode<GlobalFlagGuard> root = createRoot(GlobalFlagGuardFactory.getInstance());
+
+        assertEquals(42, executeWith(root, NULL));
+
+        GlobalFlagGuard.globalFlag = true;
+        assertEquals(41, executeWith(root, NULL));
+
+        GlobalFlagGuard.globalFlag = false;
+        assertEquals(42, executeWith(root, NULL));
+    }
+
+    @NodeChild("expression")
+    public abstract static class GlobalFlagGuard extends ValueNode {
+
+        static boolean globalFlag = false;
+
+        static boolean globalFlagGuard() {
+            return globalFlag;
+        }
+
+        @Specialization(guards = "globalFlagGuard")
+        int doSpecialized(Object value0) {
+            return 41;
+        }
+
+        @Generic
+        int doGeneric(Object value0) {
+            return 42; // the generic answer to all questions
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NodeContainerTest.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.dsl.test;
+
+import static com.oracle.truffle.api.dsl.test.TestHelper.*;
+import static org.junit.Assert.*;
+
+import org.junit.*;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.dsl.test.NodeContainerTestFactory.StrFactory.StrAccessContextFactory;
+import com.oracle.truffle.api.dsl.test.NodeContainerTestFactory.StrFactory.StrConcatFactory;
+import com.oracle.truffle.api.dsl.test.NodeContainerTestFactory.StrFactory.StrLengthFactory;
+import com.oracle.truffle.api.dsl.test.NodeContainerTestFactory.StrFactory.StrSubstrFactory;
+import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode;
+import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode;
+
+public class NodeContainerTest {
+
+    @Test
+    public void testConcat() {
+        TestRootNode<BuiltinNode> node = createRoot(StrConcatFactory.getInstance(), new Context());
+        Str str1 = new Str("42");
+        Str str2 = new Str(" is the number.");
+        assertEquals(str1.concat(str2), executeWith(node, str1, str2));
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testConcatUnsupported() {
+        TestRootNode<BuiltinNode> node = createRoot(StrConcatFactory.getInstance(), new Context());
+        executeWith(node, 42, new Str(" is the number."));
+    }
+
+    @Test
+    public void testSubstrSpecialized() {
+        TestRootNode<BuiltinNode> node = createRoot(StrSubstrFactory.getInstance(), new Context());
+        Str str = new Str("test 42");
+
+        assertEquals(str.substr(5, 7), executeWith(node, str, 5, 7));
+    }
+
+    @Test
+    public void testSubstrGeneric() {
+        TestRootNode<BuiltinNode> node = createRoot(StrSubstrFactory.getInstance(), new Context());
+        Str str = new Str("test 42");
+
+        assertEquals(Str.substr(str, "5", "7"), executeWith(node, str, "5", "7"));
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testSubstrUnsupported() {
+        TestRootNode<BuiltinNode> node = createRoot(StrSubstrFactory.getInstance(), new Context());
+        executeWith(node, new Object(), "5", "7");
+    }
+
+    @Test
+    public void testLength() {
+        TestRootNode<BuiltinNode> node = createRoot(StrLengthFactory.getInstance(), new Context());
+        Str testStr = new Str("test 42");
+        assertEquals(testStr.length(), executeWith(node, testStr));
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testLengthUnsupported() {
+        TestRootNode<BuiltinNode> node = createRoot(StrLengthFactory.getInstance(), new Context());
+        executeWith(node, new Object());
+    }
+
+    @Test
+    public void testAccessContext() {
+        Context context = new Context();
+        TestRootNode<BuiltinNode> node = createRoot(StrAccessContextFactory.getInstance(), context);
+        // accessible by node
+        assertSame(context, node.getNode().getContext());
+        // accessible by execution
+        assertSame(context, executeWith(node));
+    }
+
+    @NodeContainer(BuiltinNode.class)
+    static class Str {
+
+        private final String internal;
+
+        public Str(String internal) {
+            this.internal = internal;
+        }
+
+        @Specialization
+        Str concat(Str s1) {
+            return new Str(internal + s1.internal);
+        }
+
+        @Specialization
+        Str substr(int beginIndex, int endIndex) {
+            return new Str(internal.substring(beginIndex, endIndex));
+        }
+
+        @Generic
+        static Str substr(Object thisValue, Object beginIndex, Object endIndex) {
+            if (!(thisValue instanceof Str)) {
+                throw new UnsupportedOperationException();
+            }
+            return ((Str) thisValue).substr(convertInt(beginIndex), convertInt(endIndex));
+        }
+
+        @Specialization
+        int length() {
+            return internal.length();
+        }
+
+        @Specialization
+        static Object accessContext(Context context) {
+            return context;
+        }
+
+        static int convertInt(Object value) {
+            if (value instanceof Number) {
+                return ((Number) value).intValue();
+            } else if (value instanceof String) {
+                return Integer.parseInt((String) value);
+            }
+            throw new RuntimeException("Invalid datatype");
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof Str) {
+                return internal.equals(((Str) obj).internal);
+            }
+            return super.equals(obj);
+        }
+
+        @Override
+        public String toString() {
+            return internal;
+        }
+
+        @Override
+        public int hashCode() {
+            return internal.hashCode();
+        }
+    }
+
+    @NodeChild(value = "children", type = ValueNode[].class)
+    abstract static class BuiltinNode extends ValueNode {
+
+        protected final Context context;
+
+        public BuiltinNode(BuiltinNode node) {
+            this(node.context);
+        }
+
+        public BuiltinNode(Context context) {
+            this.context = context;
+        }
+
+        public Context getContext() {
+            return context;
+        }
+    }
+
+    static class Context {
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.dsl.test;
+
+import static com.oracle.truffle.api.dsl.test.TestHelper.*;
+import static org.junit.Assert.*;
+
+import org.junit.*;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.dsl.test.BinaryNodeTest.BinaryNode;
+import com.oracle.truffle.api.dsl.test.PolymorphicTestFactory.Node1Factory;
+import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.api.nodes.NodeInfo.Kind;
+
+public class PolymorphicTest {
+
+    @Test
+    public void testJustSpecialize() {
+        TestRootNode<Node1> node = TestHelper.createRoot(Node1Factory.getInstance());
+        assertEquals("(int,int)", executeWith(node, 42, 42));
+        assertEquals("(boolean,boolean)", executeWith(node, false, false));
+        assertEquals("(int,boolean)", executeWith(node, 42, false));
+        assertEquals("(boolean,int)", executeWith(node, false, 42));
+        assertEquals(Kind.SPECIALIZED, node.getNode().getClass().getAnnotation(NodeInfo.class).kind());
+    }
+
+    @Test
+    public void testPolymorphic2() {
+        TestRootNode<Node1> node = TestHelper.createRoot(Node1Factory.getInstance());
+        assertEquals("(int,boolean)", executeWith(node, 42, false));
+        assertEquals("(int,int)", executeWith(node, 42, 42));
+        assertEquals(Kind.POLYMORPHIC, node.getNode().getClass().getAnnotation(NodeInfo.class).kind());
+    }
+
+    @Test
+    public void testPolymorphic3() {
+        TestRootNode<Node1> node = TestHelper.createRoot(Node1Factory.getInstance());
+        assertEquals("(int,boolean)", executeWith(node, 42, false));
+        assertEquals("(boolean,boolean)", executeWith(node, true, false));
+        assertEquals("(int,int)", executeWith(node, 42, 42));
+        assertEquals(Kind.POLYMORPHIC, node.getNode().getClass().getAnnotation(NodeInfo.class).kind());
+    }
+
+    @Test
+    public void testGenericLimitReached() {
+        TestRootNode<Node1> node = TestHelper.createRoot(Node1Factory.getInstance());
+        assertEquals("(boolean,int)", executeWith(node, false, 42));
+        assertEquals("(int,boolean)", executeWith(node, 42, false));
+        assertEquals("(boolean,boolean)", executeWith(node, true, false));
+        assertEquals("(int,int)", executeWith(node, 42, 42));
+        assertEquals(Kind.GENERIC, node.getNode().getClass().getAnnotation(NodeInfo.class).kind());
+    }
+
+    @Test
+    public void testGenericInitial() {
+        TestRootNode<Node1> node = TestHelper.createRoot(Node1Factory.getInstance());
+        assertEquals("(generic,generic)", executeWith(node, "", ""));
+        assertEquals(Kind.GENERIC, node.getNode().getClass().getAnnotation(NodeInfo.class).kind());
+    }
+
+    @Test
+    public void testGenericPolymorphic() {
+        TestRootNode<Node1> node = TestHelper.createRoot(Node1Factory.getInstance());
+        assertEquals("(boolean,int)", executeWith(node, false, 42));
+        assertEquals("(int,boolean)", executeWith(node, 42, false));
+        assertEquals("(generic,generic)", executeWith(node, "", ""));
+        assertEquals(Kind.GENERIC, node.getNode().getClass().getAnnotation(NodeInfo.class).kind());
+    }
+
+    @SuppressWarnings("unused")
+    @PolymorphicLimit(3)
+    abstract static class Node1 extends BinaryNode {
+
+        @Specialization(order = 1)
+        String add(int left, int right) {
+            return "(int,int)";
+        }
+
+        @Specialization(order = 2)
+        String add(boolean left, boolean right) {
+            return "(boolean,boolean)";
+        }
+
+        @Specialization(order = 3)
+        String add(int left, boolean right) {
+            return "(int,boolean)";
+        }
+
+        @Specialization(order = 4)
+        String add(boolean left, int right) {
+            return "(boolean,int)";
+        }
+
+        @Generic
+        String add(Object left, Object right) {
+            return "(generic,generic)";
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TestHelper.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.dsl.test;
+
+import java.util.*;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.dsl.test.NodeContainerTest.BuiltinNode;
+import com.oracle.truffle.api.dsl.test.TypeSystemTest.ArgumentNode;
+import com.oracle.truffle.api.dsl.test.TypeSystemTest.ChildrenNode;
+import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestArguments;
+import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode;
+import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode;
+
+/**
+ * Utility class to provide some test helper functions.
+ */
+class TestHelper {
+
+    private static ArgumentNode[] arguments(int count) {
+        ArgumentNode[] nodes = new ArgumentNode[count];
+        for (int i = 0; i < nodes.length; i++) {
+            nodes[i] = new ArgumentNode(i);
+        }
+        return nodes;
+    }
+
+    static <E extends ValueNode> E createNode(NodeFactory<E> factory, Object... constants) {
+        ArgumentNode[] argumentNodes = arguments(factory.getExecutionSignature().size());
+
+        List<Object> argumentList = new ArrayList<>();
+        argumentList.addAll(Arrays.asList(constants));
+        if (ChildrenNode.class.isAssignableFrom(factory.getNodeClass()) || BuiltinNode.class.isAssignableFrom(factory.getNodeClass())) {
+            argumentList.add(argumentNodes);
+        } else {
+            argumentList.addAll(Arrays.asList(argumentNodes));
+        }
+        return factory.createNode(argumentList.toArray(new Object[argumentList.size()]));
+    }
+
+    static <E extends ValueNode> TestRootNode<E> createRoot(NodeFactory<E> factory, Object... constants) {
+        return new TestRootNode<>(createNode(factory, constants));
+    }
+
+    static CallTarget createCallTarget(ValueNode node) {
+        return createCallTarget(new TestRootNode<>(node));
+    }
+
+    static CallTarget createCallTarget(TestRootNode<? extends ValueNode> node) {
+        return Truffle.getRuntime().createCallTarget(node);
+    }
+
+    static <E> Object executeWith(TestRootNode<? extends ValueNode> node, Object... values) {
+        return createCallTarget(node).call(new TestArguments(values));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TypeSystemTest.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.dsl.test;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.dsl.test.NodeContainerTest.Str;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+
+public class TypeSystemTest {
+
+    @TypeSystem({int.class, boolean.class, String.class, Str.class, CallTarget.class, Object[].class})
+    static class SimpleTypes {
+    }
+
+    @TypeSystemReference(SimpleTypes.class)
+    public abstract static class ValueNode extends Node {
+
+        public int executeInt(VirtualFrame frame) throws UnexpectedResultException {
+            return SimpleTypesGen.SIMPLETYPES.expectInteger(execute(frame));
+        }
+
+        public Str executeStr(VirtualFrame frame) throws UnexpectedResultException {
+            return SimpleTypesGen.SIMPLETYPES.expectStr(execute(frame));
+        }
+
+        public String executeString(VirtualFrame frame) throws UnexpectedResultException {
+            return SimpleTypesGen.SIMPLETYPES.expectString(execute(frame));
+        }
+
+        public boolean executeBoolean(VirtualFrame frame) throws UnexpectedResultException {
+            return SimpleTypesGen.SIMPLETYPES.expectBoolean(execute(frame));
+        }
+
+        public Object[] executeIntArray(VirtualFrame frame) throws UnexpectedResultException {
+            return SimpleTypesGen.SIMPLETYPES.expectObjectArray(execute(frame));
+        }
+
+        public abstract Object execute(VirtualFrame frame);
+
+        @Override
+        public ValueNode copy() {
+            return (ValueNode) super.copy();
+        }
+    }
+
+    @NodeChild(value = "children", type = ValueNode[].class)
+    public abstract static class ChildrenNode extends ValueNode {
+
+    }
+
+    @TypeSystemReference(SimpleTypes.class)
+    public static class TestRootNode<E extends ValueNode> extends RootNode {
+
+        @Child private E node;
+
+        public TestRootNode(E node) {
+            this.node = adoptChild(node);
+        }
+
+        @Override
+        public Object execute(VirtualFrame frame) {
+            return node.execute(frame);
+        }
+
+        public E getNode() {
+            return node;
+        }
+    }
+
+    public static class TestArguments extends Arguments {
+
+        private final Object[] values;
+
+        public TestArguments(Object... values) {
+            this.values = values;
+        }
+
+        public Object[] getValues() {
+            return values;
+        }
+
+        public Object get(int index) {
+            return values[index];
+        }
+
+    }
+
+    public static class ArgumentNode extends ValueNode {
+
+        private int invocationCount;
+        final int index;
+
+        public ArgumentNode(int index) {
+            this.index = index;
+        }
+
+        public int getInvocationCount() {
+            return invocationCount;
+        }
+
+        @Override
+        public Object execute(VirtualFrame frame) {
+            invocationCount++;
+            return frame.getArguments(TestArguments.class).get(index);
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/package-info.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/**
+ * <p>This package contains basic tests of the Truffle-Source-Code-Generation (short Codegen) API and serves at the same
+ * time as an introduction to the Codegen API for language implementors. Every test gives an example on how to use the construct explained in the class description.</p>
+ *
+ * <p>
+ * This API relies heavily on the concepts described in com.oracle.truffle.api.test. We assume that the
+ * reader is already familiarized with those concepts.
+ * </p>
+ *
+ * <p>
+ * TODO general description
+ * </p>
+ *
+ * <p>
+ * This introduction to Codegen contains items in the following recommended order:
+ *
+ * Prerequisites:
+ * 
+ *
+ * <ul>
+ * <li>What do I need to get started? {@link com.oracle.truffle.api.dsl.test.TypeSystemTest}</li>
+ * <li>How would you generate function nodes for runtime objects? {@link com.oracle.truffle.api.dsl.test.NodeContainerTest}</li>
+ * </ul>
+ * </p>
+ *
+ */
+package com.oracle.truffle.api.dsl.test;
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/CreateCast.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.dsl;
+
+import java.lang.annotation.*;
+
+import com.oracle.truffle.api.nodes.*;
+
+/**
+ * Specifies a factory method that creates a {@link Node} which is used to cast this child.
+ */
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.METHOD})
+public @interface CreateCast {
+
+    String[] value();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/GeneratedBy.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.dsl;
+
+import java.lang.annotation.*;
+
+/**
+ * Marks a type to be generated by another class or a method.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE})
+public @interface GeneratedBy {
+
+    Class<?> value();
+
+    String methodName() default "";
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/Generic.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.dsl;
+
+import java.lang.annotation.*;
+
+/**
+ *
+ */
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.METHOD})
+public @interface Generic {
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/NodeAssumptions.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.dsl;
+
+import java.lang.annotation.*;
+
+/**
+ * Declares one or multiple assumptions for use inside a source code generation enabled node.
+ * Declared assumptions must be passed to the {@link NodeFactory#createNode(Object...)} method as
+ * parameters.
+ */
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.TYPE})
+public @interface NodeAssumptions {
+
+    String[] value();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/NodeChild.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.dsl;
+
+import java.lang.annotation.*;
+
+import com.oracle.truffle.api.nodes.*;
+
+/**
+ * A {@link NodeChild} element defines an executable child for the enclosing {@link Node}. A
+ * {@link Node} contains multiple {@link NodeChildren} specified in linear execution order.
+ */
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.TYPE})
+public @interface NodeChild {
+
+    String value() default "";
+
+    Class<?> type() default Node.class;
+
+    /**
+     * The {@link #executeWith()} property allows a node to pass the result of one child's
+     * executable as an input to another child's executable. These referenced children must be
+     * defined before the current node in the execution order. The current node {@link #type()}
+     * attribute must be set to a {@link Node} which supports the evaluated execution with the
+     * number of {@link #executeWith()} arguments that are defined. For example if this child is
+     * executed with one argument, the {@link #type()} attribute must define a node which publicly
+     * declares a method with the signature <code>Object execute*(VirtualFrame, Object)</code>.
+     */
+    String[] executeWith() default {};
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/NodeChildren.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.dsl;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.TYPE})
+public @interface NodeChildren {
+
+    NodeChild[] value() default {};
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/NodeContainer.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.dsl;
+
+import java.lang.annotation.*;
+
+import com.oracle.truffle.api.nodes.*;
+
+/**
+ * A node container can be used to enable Truffle-DSL in classes which do not extend {@link Node}.
+ * Compared to normal {@link Node} implementation the nodes are not identified by a class but by
+ * their method name. There are cases were method signatures are matching exactly but should be in
+ * the same {@link Node}. In this case use {@link NodeId} to disambiguate such cases.
+ */
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.TYPE})
+public @interface NodeContainer {
+
+    /** The node class to use as base class for {@link Node} definitions grouped by method names. */
+    Class<? extends Node> value();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/NodeFactory.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.dsl;
+
+import java.util.*;
+
+import com.oracle.truffle.api.nodes.*;
+
+/**
+ * Enables the dynamic creation of generated nodes. It provides an convenient way to instantiate
+ * generated node classes without using reflection.
+ */
+public interface NodeFactory<T> {
+
+    /**
+     * Instantiates the node using the arguments array. The arguments length and types must suffice
+     * one of the returned signatures in {@link #getNodeSignatures()}. If the arguments array does
+     * not suffice one of the node signatures an {@link IllegalArgumentException} is thrown.
+     * 
+     * @param arguments the argument values
+     * @return the instantiated node
+     * @throws IllegalArgumentException
+     */
+    T createNode(Object... arguments);
+
+    /**
+     * Instantiates a new generic variant of the node. This is an optional method and throws an
+     * {@link UnsupportedOperationException} if not supported.
+     * 
+     * @param thisNode the current node
+     * @return the specialized node
+     */
+    T createNodeGeneric(T thisNode);
+
+    /**
+     * Returns the node class that will get created by {@link #createNode(Object...)}. The node
+     * class does not match exactly to the instantiated object but they are guaranteed to be
+     * assignable.
+     */
+    Class<T> getNodeClass();
+
+    /**
+     * Returns a list of signatures that can be used to invoke {@link #createNode(Object...)}.
+     */
+    List<List<Class<?>>> getNodeSignatures();
+
+    /**
+     * Returns a list of children that will be executed by the created node. This is useful for base
+     * nodes that can execute a variable amount of nodes.
+     */
+    List<Class<? extends Node>> getExecutionSignature();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/NodeId.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.dsl;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.METHOD, ElementType.TYPE})
+public @interface NodeId {
+
+    String value();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/PolymorphicLimit.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.dsl;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.TYPE})
+public @interface PolymorphicLimit {
+
+    /** Specifies the maximum polymorphic cache depth until it falls back to the generic case. */
+    int value();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/ShortCircuit.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.dsl;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.METHOD})
+public @interface ShortCircuit {
+
+    String value();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/Specialization.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.dsl;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.METHOD})
+public @interface Specialization {
+
+    int DEFAULT_ORDER = -1;
+
+    int order() default DEFAULT_ORDER;
+
+    Class<? extends Throwable>[] rewriteOn() default {};
+
+    String[] guards() default {};
+
+    /**
+     * Defines the assumptions to check for this specialization. When the specialization method is
+     * invoked it is guaranteed that the assigned assumptions still hold. To declare assumptions use
+     * the {@link NodeAssumptions} annotation at class level.
+     */
+    String[] assumptions() default {};
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/SpecializationListener.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.dsl;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.METHOD})
+public @interface SpecializationListener {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/TypeCast.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.dsl;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.METHOD})
+public @interface TypeCast {
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/TypeCheck.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.dsl;
+
+import java.lang.annotation.*;
+
+/**
+ * <p>
+ * Provides a way to define a custom type check for a defined type. The name of the annotated method
+ * must fit to the pattern is${typeName} (eg. isInteger), where ${typeName} must be a valid type
+ * defined in the parent {@link TypeSystem}. The annotated method must have exactly one argument
+ * where the type of the argument is the generic type {@link Object} or a more specific one from the
+ * {@link TypeSystem}. You can define multiple overloaded {@link TypeCheck} methods for the same
+ * type. This can be used to reduce the boxing overhead in type conversions.
+ * </p>
+ * 
+ * <p>
+ * By default the system generates type checks for all types in the parent {@link TypeSystem} which
+ * look like the follows:
+ * 
+ * <pre>
+ * {@literal @}TypeCheck
+ * boolean is${typeName}(Object value) {
+ *         return value instanceof ${typeName};
+ * }
+ * </pre>
+ * 
+ * </p>
+ * 
+ * <b>Example:</b>
+ * <p>
+ * A type check for BigInteger with one overloaded optimized variant to reduce boxing.
+ * </p>
+ * 
+ * <pre>
+ * 
+ * 
+ * {@literal @}TypeSystem(types = {int.class, BigInteger.class, String.class}, nodeBaseClass = TypedNode.class)
+ * public abstract class Types {
+ * 
+ *     {@literal @}TypeCheck
+ *     public boolean isBigInteger(Object value) {
+ *         return value instanceof Integer || value instanceof BigInteger;
+ *     }
+ * 
+ *     {@literal @}TypeCheck
+ *     public boolean isBigInteger(int value) {
+ *         return true;
+ *     }
+ * 
+ * }
+ * </pre>
+ * 
+ * 
+ */
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.METHOD})
+public @interface TypeCheck {
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/TypeSystem.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.dsl;
+
+import java.lang.annotation.*;
+
+import com.oracle.truffle.api.nodes.*;
+
+/**
+ * <p>
+ * Each {@link Node} has one {@link TypeSystem} at its root to define the types that can be used
+ * throughout the system. Multiple {@link TypeSystem}s are allowed, but they cannot be mixed inside
+ * a single {@link Node} hierarchy. A {@link TypeSystem} defines a list of types as its child
+ * elements, in which every type precedes its super types.The latter condition ensures that the most
+ * concrete type is found first when searching the list sequentially for the type of a given generic
+ * value.
+ * </p>
+ * 
+ * <p>
+ * Each {@link #value()} is represented as a java type. A type can specify two annotations:
+ * {@link TypeCheck} and {@link TypeCast}. The {@link TypeCheck} checks whether a given generic
+ * value matches to the current type. The {@link TypeCast} casts a generic type value to the current
+ * type. If the {@link TypeCheck} and {@link TypeCast} annotations are not declared in the
+ * {@link TypeSystem} the a default implementation is provided. The default implementation of
+ * {@link TypeCheck} returns <code>true</code> only on an exact type match and {@link TypeCast} is
+ * only a cast to this type. Specified methods with {@link TypeCheck} and {@link TypeCast} may be
+ * used to extend the definition of a type in the language. In our example, the
+ * <code>isInteger</code> and <code>asInteger</code> methods are defined in a way so that they
+ * accept also {@link Integer} values, implicitly converting them to {@link Double} . This example
+ * points out how we express implicit type conversions.
+ * </p>
+ * 
+ * <p>
+ * <b>Example:</b> The {@link TypeSystem} contains the types {@link Boolean}, {@link Integer}, and
+ * {@link Double}. The type {@link Object} is always used implicitly as the generic type represent
+ * all values.
+ * 
+ * <pre>
+ * 
+ * {@literal @}TypeSystem(types = {boolean.class, int.class, double.class})
+ * public abstract class ExampleTypeSystem {
+ * 
+ *     {@literal @}TypeCheck
+ *     public boolean isInteger(Object value) {
+ *         return value instanceof Integer || value instanceof Double;
+ *     }
+ * 
+ *     {@literal @}TypeCast
+ *     public double asInteger(Object value) {
+ *         return ((Number)value).doubleValue();
+ *     }
+ * }
+ * </pre>
+ * 
+ * </p>
+ * 
+ * @see TypeCast
+ * @see TypeCheck
+ */
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.TYPE})
+public @interface TypeSystem {
+
+    /**
+     * The list of types as child elements of the {@link TypeSystem}. Each precedes its super type.
+     */
+    Class[] value();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/TypeSystemReference.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.dsl;
+
+import java.lang.annotation.*;
+
+import com.oracle.truffle.api.nodes.*;
+
+/**
+ * References a {@link TypeSystem} on a node. Must be applied on a {@link Node} class. At least one
+ * {@link TypeSystem} must be referenced in a {@link Node}'s type hierarchy.
+ * 
+ * @see TypeSystem
+ * @see Node
+ */
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.TYPE})
+public @interface TypeSystemReference {
+
+    /** The {@link TypeSystem} java type. */
+    Class<?> value();
+
+}
--- a/graal/com.oracle.truffle.codegen.processor/src/META-INF/services/javax.annotation.processing.Processor	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-com.oracle.truffle.codegen.processor.TruffleProcessor
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/AbstractParser.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor;
-
-import java.lang.annotation.*;
-import java.util.*;
-
-import javax.annotation.processing.*;
-import javax.lang.model.element.*;
-import javax.tools.Diagnostic.Kind;
-
-import com.oracle.truffle.codegen.processor.template.*;
-
-/**
- * THIS IS NOT PUBLIC API.
- */
-public abstract class AbstractParser<M extends Template> {
-
-    protected final ProcessorContext context;
-    protected final ProcessingEnvironment processingEnv;
-    protected RoundEnvironment roundEnv;
-
-    protected final Log log;
-
-    public AbstractParser(ProcessorContext c) {
-        this.context = c;
-        this.processingEnv = c.getEnvironment();
-        this.log = c.getLog();
-    }
-
-    public final M parse(RoundEnvironment env, Element element) {
-        this.roundEnv = env;
-        M model = null;
-        try {
-            AnnotationMirror mirror = null;
-            if (getAnnotationType() != null) {
-                mirror = Utils.findAnnotationMirror(processingEnv, element.getAnnotationMirrors(), getAnnotationType());
-            }
-
-            if (!context.getTruffleTypes().verify(context, element, mirror)) {
-                return null;
-            }
-            model = parse(element, mirror);
-            if (model == null) {
-                return null;
-            }
-
-            model.emitMessages((TypeElement) element, log);
-            return filterErrorElements(model);
-        } catch (CompileErrorException e) {
-            log.message(Kind.WARNING, element, null, null, "The truffle processor could not parse class due to error: %s", e.getMessage());
-            return null;
-        } finally {
-            this.roundEnv = null;
-        }
-    }
-
-    protected M filterErrorElements(M model) {
-        return model.hasErrors() ? null : model;
-    }
-
-    protected abstract M parse(Element element, AnnotationMirror mirror);
-
-    public abstract Class<? extends Annotation> getAnnotationType();
-
-    public boolean isDelegateToRootDeclaredType() {
-        return false;
-    }
-
-    public List<Class<? extends Annotation>> getAllAnnotationTypes() {
-        List<Class<? extends Annotation>> list = new ArrayList<>();
-        if (getAnnotationType() != null) {
-            list.add(getAnnotationType());
-        }
-        list.addAll(getTypeDelegatedAnnotationTypes());
-        return list;
-    }
-
-    public List<Class<? extends Annotation>> getTypeDelegatedAnnotationTypes() {
-        return Collections.emptyList();
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/AnnotationProcessor.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,132 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor;
-
-import java.io.*;
-import java.util.*;
-
-import javax.annotation.processing.*;
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-import javax.tools.*;
-
-import com.oracle.truffle.codegen.processor.ast.*;
-import com.oracle.truffle.codegen.processor.codewriter.*;
-import com.oracle.truffle.codegen.processor.compiler.*;
-import com.oracle.truffle.codegen.processor.template.*;
-
-/**
- * THIS IS NOT PUBLIC API.
- */
-class AnnotationProcessor<M extends Template> {
-
-    private final AbstractParser<M> parser;
-    private final CompilationUnitFactory<M> factory;
-    private final ProcessorContext context;
-
-    private final Set<String> processedElements = new HashSet<>();
-
-    public AnnotationProcessor(ProcessorContext context, AbstractParser<M> parser, CompilationUnitFactory<M> factory) {
-        this.context = context;
-        this.parser = parser;
-        this.factory = factory;
-    }
-
-    public AbstractParser<M> getParser() {
-        return parser;
-    }
-
-    public ProcessorContext getContext() {
-        return context;
-    }
-
-    @SuppressWarnings({"unchecked"})
-    public void process(RoundEnvironment env, Element element, boolean callback) {
-
-        // since it is not guaranteed to be called only once by the compiler
-        // we check for already processed elements to avoid errors when writing files.
-        if (!callback && element instanceof TypeElement) {
-            String qualifiedName = Utils.getQualifiedName((TypeElement) element);
-            if (processedElements.contains(qualifiedName)) {
-                return;
-            }
-            processedElements.add(qualifiedName);
-        }
-
-        TypeElement type = (TypeElement) element;
-
-        M model = (M) context.getTemplate(type.asType(), false);
-        boolean firstRun = !context.containsTemplate(type);
-
-        if (firstRun || !callback) {
-            context.registerTemplate(type, null);
-            model = parser.parse(env, element);
-            context.registerTemplate(type, model);
-
-            if (model != null) {
-                CodeCompilationUnit unit = factory.process(null, model);
-                unit.setGeneratorAnnotationMirror(model.getTemplateTypeAnnotation());
-                unit.setGeneratorElement(model.getTemplateType());
-
-                DeclaredType overrideType = (DeclaredType) context.getType(Override.class);
-                DeclaredType unusedType = (DeclaredType) context.getType(SuppressWarnings.class);
-                unit.accept(new GenerateOverrideVisitor(overrideType), null);
-                unit.accept(new FixWarningsVisitor(context, unusedType, overrideType), null);
-
-                if (!callback) {
-                    unit.accept(new CodeWriter(context.getEnvironment(), element), null);
-                }
-            }
-        }
-    }
-
-    private static class CodeWriter extends AbstractCodeWriter {
-
-        private final Element orignalElement;
-        private final ProcessingEnvironment env;
-
-        public CodeWriter(ProcessingEnvironment env, Element originalElement) {
-            this.env = env;
-            this.orignalElement = originalElement;
-        }
-
-        @Override
-        protected Writer createWriter(CodeTypeElement clazz) throws IOException {
-            JavaFileObject jfo = env.getFiler().createSourceFile(clazz.getQualifiedName(), orignalElement);
-            return jfo.openWriter();
-        }
-
-        @Override
-        protected void writeHeader() {
-            if (env == null) {
-                return;
-            }
-            String comment = CompilerFactory.getCompiler(orignalElement).getHeaderComment(env, orignalElement);
-            if (comment != null) {
-                writeLn(comment);
-            }
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/CompileErrorException.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor;
-
-public class CompileErrorException extends RuntimeException {
-
-    private static final long serialVersionUID = 1L;
-
-    public CompileErrorException(String message) {
-        super(message);
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Log.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor;
-
-import javax.annotation.processing.*;
-import javax.lang.model.element.*;
-import javax.tools.Diagnostic.Kind;
-
-import com.oracle.truffle.codegen.processor.ast.*;
-
-/**
- * THIS IS NOT PUBLIC API.
- */
-public class Log {
-
-    public static final boolean DEBUG = false;
-
-    private final ProcessingEnvironment processingEnv;
-
-    public Log(ProcessingEnvironment env) {
-        this.processingEnv = env;
-    }
-
-    public void message(Kind kind, Element element, AnnotationMirror mirror, AnnotationValue value, String format, Object... args) {
-        AnnotationMirror usedMirror = mirror;
-        Element usedElement = element;
-        AnnotationValue usedValue = value;
-        String message = String.format(format, args);
-
-        if (element instanceof GeneratedElement) {
-            usedMirror = ((GeneratedElement) element).getGeneratorAnnotationMirror();
-            usedElement = ((GeneratedElement) element).getGeneratorElement();
-            usedValue = null;
-            if (usedElement != null) {
-                message = String.format("Element %s: %s", element, message);
-            }
-        }
-        processingEnv.getMessager().printMessage(kind, message, usedElement, usedMirror, usedValue);
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ProcessorContext.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,212 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor;
-
-import static com.oracle.truffle.codegen.processor.Utils.*;
-
-import java.util.*;
-
-import javax.annotation.processing.*;
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-import javax.lang.model.util.*;
-
-import com.oracle.truffle.codegen.processor.ast.*;
-import com.oracle.truffle.codegen.processor.ast.CodeTypeMirror.ArrayCodeTypeMirror;
-import com.oracle.truffle.codegen.processor.template.*;
-
-/**
- * THIS IS NOT PUBLIC API.
- */
-public class ProcessorContext {
-
-    private final ProcessingEnvironment environment;
-
-    private final Map<String, Template> models = new HashMap<>();
-    private final Map<String, Map<String, TypeMirror>> generatedClasses = new HashMap<>();
-
-    private final ProcessCallback callback;
-    private final Log log;
-    private final TruffleTypes truffleTypes;
-
-    public ProcessorContext(ProcessingEnvironment env, ProcessCallback callback) {
-        this.environment = env;
-        this.callback = callback;
-        this.log = new Log(environment);
-        this.truffleTypes = new TruffleTypes(this);
-    }
-
-    public TruffleTypes getTruffleTypes() {
-        return truffleTypes;
-    }
-
-    public Log getLog() {
-        return log;
-    }
-
-    public ProcessingEnvironment getEnvironment() {
-        return environment;
-    }
-
-    public boolean containsTemplate(TypeElement element) {
-        return models.containsKey(Utils.getQualifiedName(element));
-    }
-
-    public void registerTemplate(TypeElement element, Template model) {
-        models.put(Utils.getQualifiedName(element), model);
-    }
-
-    public void registerType(TypeElement templateType, TypeMirror generatedTypeMirror) {
-        String templateQualifiedName = getQualifiedName(templateType);
-        Map<String, TypeMirror> simpleNameToType = generatedClasses.get(templateQualifiedName);
-        if (simpleNameToType == null) {
-            simpleNameToType = new HashMap<>();
-            generatedClasses.put(templateQualifiedName, simpleNameToType);
-        }
-        String generatedSimpleName = getSimpleName(generatedTypeMirror);
-        simpleNameToType.put(generatedSimpleName, generatedTypeMirror);
-    }
-
-    public Template getTemplate(TypeMirror templateTypeMirror, boolean invokeCallback) {
-        String qualifiedName = Utils.getQualifiedName(templateTypeMirror);
-        Template model = models.get(qualifiedName);
-        if (model == null && invokeCallback) {
-            callback.callback(Utils.fromTypeMirror(templateTypeMirror));
-            model = models.get(qualifiedName);
-        }
-        return model;
-    }
-
-    public TypeMirror resolveNotYetCompiledType(TypeMirror mirror, Template templateHint) {
-        TypeMirror resolvedType = null;
-        if (mirror.getKind() == TypeKind.ARRAY) {
-            TypeMirror originalComponentType = ((ArrayType) mirror).getComponentType();
-            TypeMirror resolvedComponent = resolveNotYetCompiledType(originalComponentType, templateHint);
-            if (resolvedComponent != originalComponentType) {
-                return new ArrayCodeTypeMirror(resolvedComponent);
-            }
-        }
-
-        if (mirror.getKind() == TypeKind.ERROR) {
-            Element element = ((ErrorType) mirror).asElement();
-            ElementKind kind = element.getKind();
-            if (kind == ElementKind.CLASS || kind == ElementKind.PARAMETER || kind == ElementKind.ENUM) {
-                String simpleName = element.getSimpleName().toString();
-                resolvedType = findGeneratedClassBySimpleName(simpleName, templateHint);
-            }
-        } else {
-            resolvedType = mirror;
-        }
-
-        return resolvedType;
-    }
-
-    public TypeMirror findGeneratedClassBySimpleName(String simpleName, Template templateHint) {
-        if (templateHint == null) {
-            // search all
-            for (String qualifiedTemplateName : generatedClasses.keySet()) {
-                Map<String, TypeMirror> mirrors = generatedClasses.get(qualifiedTemplateName);
-                if (mirrors.get(simpleName) != null) {
-                    return mirrors.get(simpleName);
-                }
-            }
-            return null;
-        } else {
-            String templateQualifiedName = getQualifiedName(templateHint.getTemplateType());
-            Map<String, TypeMirror> simpleNameToType = generatedClasses.get(templateQualifiedName);
-            if (simpleNameToType == null) {
-                return null;
-            }
-            return simpleNameToType.get(simpleName);
-        }
-    }
-
-    public TypeMirror getType(String className) {
-        TypeElement element = environment.getElementUtils().getTypeElement(className);
-        if (element != null) {
-            return element.asType();
-        }
-        return null;
-    }
-
-    public TypeMirror getType(Class<?> element) {
-        TypeMirror mirror;
-        if (element.isPrimitive()) {
-            if (element == boolean.class) {
-                mirror = environment.getTypeUtils().getPrimitiveType(TypeKind.BOOLEAN);
-            } else if (element == byte.class) {
-                mirror = environment.getTypeUtils().getPrimitiveType(TypeKind.BYTE);
-            } else if (element == short.class) {
-                mirror = environment.getTypeUtils().getPrimitiveType(TypeKind.SHORT);
-            } else if (element == char.class) {
-                mirror = environment.getTypeUtils().getPrimitiveType(TypeKind.CHAR);
-            } else if (element == int.class) {
-                mirror = environment.getTypeUtils().getPrimitiveType(TypeKind.INT);
-            } else if (element == long.class) {
-                mirror = environment.getTypeUtils().getPrimitiveType(TypeKind.LONG);
-            } else if (element == float.class) {
-                mirror = environment.getTypeUtils().getPrimitiveType(TypeKind.FLOAT);
-            } else if (element == double.class) {
-                mirror = environment.getTypeUtils().getPrimitiveType(TypeKind.DOUBLE);
-            } else if (element == void.class) {
-                mirror = environment.getTypeUtils().getNoType(TypeKind.VOID);
-            } else {
-                assert false;
-                return null;
-            }
-        } else {
-            TypeElement typeElement = environment.getElementUtils().getTypeElement(element.getCanonicalName());
-            mirror = typeElement.asType();
-        }
-        return mirror;
-    }
-
-    public interface ProcessCallback {
-
-        void callback(TypeElement template);
-
-    }
-
-    public TypeMirror reloadTypeElement(TypeElement type) {
-        return getType(type.getQualifiedName().toString());
-    }
-
-    public TypeMirror reloadType(TypeMirror type) {
-        if (type instanceof CodeTypeMirror) {
-            return type;
-        } else if (type.getKind().isPrimitive()) {
-            return type;
-        }
-        Types types = getEnvironment().getTypeUtils();
-
-        switch (type.getKind()) {
-            case ARRAY:
-                return types.getArrayType(reloadType(((ArrayType) type).getComponentType()));
-            case WILDCARD:
-                return types.getWildcardType(((WildcardType) type).getExtendsBound(), ((WildcardType) type).getSuperBound());
-            case DECLARED:
-                return reloadTypeElement((TypeElement) (((DeclaredType) type).asElement()));
-        }
-        return type;
-    }
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/TruffleProcessor.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,150 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor;
-
-import java.lang.annotation.*;
-import java.util.*;
-
-import javax.annotation.processing.*;
-import javax.lang.model.*;
-import javax.lang.model.element.*;
-import javax.tools.Diagnostic.*;
-
-import com.oracle.truffle.codegen.processor.ProcessorContext.ProcessCallback;
-import com.oracle.truffle.codegen.processor.node.*;
-import com.oracle.truffle.codegen.processor.typesystem.*;
-
-/**
- * THIS IS NOT PUBLIC API.
- */
-// @SupportedAnnotationTypes({"com.oracle.truffle.codegen.Operation",
-// "com.oracle.truffle.codegen.TypeLattice"})
-@SupportedSourceVersion(SourceVersion.RELEASE_7)
-public class TruffleProcessor extends AbstractProcessor implements ProcessCallback {
-
-    private ProcessorContext context;
-    private List<AnnotationProcessor<?>> generators;
-
-    private RoundEnvironment round;
-
-    @Override
-    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
-        if (!roundEnv.processingOver()) {
-            processImpl(roundEnv);
-        }
-        return false;
-    }
-
-    private void processImpl(RoundEnvironment env) {
-        this.round = env;
-        // TODO run verifications that other annotations are not processed out of scope of the
-        // operation or typelattice.
-        try {
-            for (AnnotationProcessor generator : getGenerators()) {
-                AbstractParser<?> parser = generator.getParser();
-                if (parser.getAnnotationType() != null) {
-                    for (Element e : env.getElementsAnnotatedWith(parser.getAnnotationType())) {
-                        processElement(env, generator, e, false);
-                    }
-                }
-
-                for (Class<? extends Annotation> annotationType : parser.getTypeDelegatedAnnotationTypes()) {
-                    for (Element e : env.getElementsAnnotatedWith(annotationType)) {
-                        TypeElement processedType;
-                        if (parser.isDelegateToRootDeclaredType()) {
-                            processedType = Utils.findRootEnclosingType(e);
-                        } else {
-                            processedType = Utils.findNearestEnclosingType(e);
-                        }
-                        processElement(env, generator, processedType, false);
-                    }
-                }
-
-            }
-        } finally {
-            this.round = null;
-        }
-    }
-
-    private static void processElement(RoundEnvironment env, AnnotationProcessor generator, Element e, boolean callback) {
-        try {
-            generator.process(env, e, callback);
-        } catch (Throwable e1) {
-            handleThrowable(generator, e1, e);
-        }
-    }
-
-    private static void handleThrowable(AnnotationProcessor generator, Throwable t, Element e) {
-        String message = "Uncaught error in " + generator.getClass().getSimpleName() + " while processing " + e;
-        generator.getContext().getLog().message(Kind.ERROR, e, null, null, message + ": " + Utils.printException(t));
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public void callback(TypeElement template) {
-        for (AnnotationProcessor generator : generators) {
-            Class annotationType = generator.getParser().getAnnotationType();
-            if (annotationType != null) {
-                Annotation annotation = template.getAnnotation(annotationType);
-                if (annotation != null) {
-                    processElement(round, generator, template, true);
-                }
-            }
-        }
-    }
-
-    @Override
-    public Set<String> getSupportedAnnotationTypes() {
-        Set<String> annotations = new HashSet<>();
-        List<Class<? extends Annotation>> annotationsTypes = new ArrayList<>();
-        annotationsTypes.addAll(NodeParser.ANNOTATIONS);
-        annotationsTypes.addAll(TypeSystemParser.ANNOTATIONS);
-        for (Class<? extends Annotation> type : annotationsTypes) {
-            annotations.add(type.getCanonicalName());
-        }
-        return annotations;
-    }
-
-    private List<AnnotationProcessor<?>> getGenerators() {
-        if (generators == null && processingEnv != null) {
-            generators = new ArrayList<>();
-            generators.add(new AnnotationProcessor<>(getContext(), new TypeSystemParser(getContext()), new TypeSystemCodeGenerator(getContext())));
-            generators.add(new AnnotationProcessor<>(getContext(), new NodeParser(getContext()), new NodeCodeGenerator(getContext())));
-        }
-        return generators;
-    }
-
-    private ProcessorContext getContext() {
-        if (context == null) {
-            context = new ProcessorContext(processingEnv, this);
-        }
-        return context;
-    }
-
-    @Override
-    public synchronized void init(ProcessingEnvironment env) {
-        this.processingEnv = env;
-        super.init(env);
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/TruffleTypes.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor;
-
-import java.util.*;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-import javax.tools.Diagnostic.Kind;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.api.nodes.Node.Child;
-import com.oracle.truffle.api.nodes.Node.Children;
-
-/**
- * THIS IS NOT PUBLIC API.
- */
-public final class TruffleTypes {
-
-    private final TypeMirror node;
-    private final TypeMirror nodeArray;
-    private final TypeMirror unexpectedValueException;
-    private final TypeMirror frame;
-    private final TypeMirror assumption;
-    private final TypeMirror invalidAssumption;
-    private final DeclaredType childAnnotation;
-    private final DeclaredType childrenAnnotation;
-    private final DeclaredType nodeInfoAnnotation;
-    private final DeclaredType nodeInfoKind;
-    private final TypeMirror compilerDirectives;
-    private final TypeMirror compilerAsserts;
-
-    private final List<String> errors = new ArrayList<>();
-
-    public TruffleTypes(ProcessorContext context) {
-        node = getRequired(context, Node.class);
-        nodeArray = context.getEnvironment().getTypeUtils().getArrayType(node);
-        unexpectedValueException = getRequired(context, UnexpectedResultException.class);
-        frame = getRequired(context, VirtualFrame.class);
-        childAnnotation = getRequired(context, Child.class);
-        childrenAnnotation = getRequired(context, Children.class);
-        compilerDirectives = getRequired(context, CompilerDirectives.class);
-        compilerAsserts = getRequired(context, CompilerAsserts.class);
-        assumption = getRequired(context, Assumption.class);
-        invalidAssumption = getRequired(context, InvalidAssumptionException.class);
-        nodeInfoAnnotation = getRequired(context, NodeInfo.class);
-        nodeInfoKind = getRequired(context, NodeInfo.Kind.class);
-    }
-
-    public DeclaredType getNodeInfoAnnotation() {
-        return nodeInfoAnnotation;
-    }
-
-    public boolean verify(ProcessorContext context, Element element, AnnotationMirror mirror) {
-        if (errors.isEmpty()) {
-            return true;
-        }
-
-        for (String error : errors) {
-            context.getLog().message(Kind.ERROR, element, mirror, null, error);
-        }
-
-        return false;
-    }
-
-    public DeclaredType getNodeInfoKind() {
-        return nodeInfoKind;
-    }
-
-    private DeclaredType getRequired(ProcessorContext context, Class clazz) {
-        TypeMirror type = context.getType(clazz);
-        if (type == null) {
-            errors.add(String.format("Could not find required type: %s", clazz.getSimpleName()));
-        }
-        return (DeclaredType) type;
-    }
-
-    public TypeMirror getInvalidAssumption() {
-        return invalidAssumption;
-    }
-
-    public TypeMirror getAssumption() {
-        return assumption;
-    }
-
-    public TypeMirror getCompilerDirectives() {
-        return compilerDirectives;
-    }
-
-    public TypeMirror getNode() {
-        return node;
-    }
-
-    public TypeMirror getNodeArray() {
-        return nodeArray;
-    }
-
-    public TypeMirror getFrame() {
-        return frame;
-    }
-
-    public TypeMirror getUnexpectedValueException() {
-        return unexpectedValueException;
-    }
-
-    public DeclaredType getChildAnnotation() {
-        return childAnnotation;
-    }
-
-    public DeclaredType getChildrenAnnotation() {
-        return childrenAnnotation;
-    }
-
-    public TypeMirror getCompilerAsserts() {
-        return compilerAsserts;
-    }
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Utils.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,930 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor;
-
-import java.io.*;
-import java.lang.annotation.*;
-import java.util.*;
-
-import javax.annotation.processing.*;
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-import javax.lang.model.util.*;
-
-import com.oracle.truffle.codegen.processor.ast.*;
-import com.oracle.truffle.codegen.processor.ast.CodeTypeMirror.DeclaredCodeTypeMirror;
-import com.oracle.truffle.codegen.processor.compiler.*;
-
-/**
- * THIS IS NOT PUBLIC API.
- */
-public class Utils {
-
-    public static ExecutableElement findExecutableElement(DeclaredType type, String name) {
-        List<? extends ExecutableElement> elements = ElementFilter.methodsIn(type.asElement().getEnclosedElements());
-        for (ExecutableElement executableElement : elements) {
-            if (executableElement.getSimpleName().toString().equals(name)) {
-                return executableElement;
-            }
-        }
-        return null;
-    }
-
-    public static VariableElement findVariableElement(DeclaredType type, String name) {
-        List<? extends VariableElement> elements = ElementFilter.fieldsIn(type.asElement().getEnclosedElements());
-        for (VariableElement variableElement : elements) {
-            if (variableElement.getSimpleName().toString().equals(name)) {
-                return variableElement;
-            }
-        }
-        return null;
-    }
-
-    public static String getMethodBody(ProcessingEnvironment env, ExecutableElement method) {
-        if (method instanceof CodeExecutableElement) {
-            return ((CodeExecutableElement) method).getBody();
-        } else {
-            return CompilerFactory.getCompiler(method).getMethodBody(env, method);
-        }
-    }
-
-    public static TypeMirror boxType(ProcessorContext context, TypeMirror primitiveType) {
-        TypeMirror boxedType = primitiveType;
-        if (boxedType.getKind().isPrimitive()) {
-            boxedType = context.getEnvironment().getTypeUtils().boxedClass((PrimitiveType) boxedType).asType();
-        }
-        return boxedType;
-    }
-
-    public static List<TypeMirror> asTypeMirrors(List<? extends Element> elements) {
-        List<TypeMirror> types = new ArrayList<>(elements.size());
-        for (Element element : elements) {
-            types.add(element.asType());
-        }
-        return types;
-    }
-
-    public static DeclaredType getDeclaredType(TypeElement typeElem, TypeMirror... typeArgs) {
-        return new DeclaredCodeTypeMirror(typeElem, Arrays.asList(typeArgs));
-    }
-
-    public static List<AnnotationMirror> collectAnnotations(ProcessorContext context, AnnotationMirror markerAnnotation, String elementName, Element element,
-                    Class<? extends Annotation> annotationClass) {
-        List<AnnotationMirror> result = new ArrayList<>();
-        if (markerAnnotation != null) {
-            result.addAll(Utils.getAnnotationValueList(AnnotationMirror.class, markerAnnotation, elementName));
-        }
-        AnnotationMirror explicit = Utils.findAnnotationMirror(context.getEnvironment(), element, annotationClass);
-        if (explicit != null) {
-            result.add(explicit);
-        }
-        return result;
-    }
-
-    public static TypeMirror getCommonSuperType(ProcessorContext context, TypeMirror[] types) {
-        if (types.length == 0) {
-            return context.getType(Object.class);
-        }
-        TypeMirror prev = types[0];
-        for (int i = 1; i < types.length; i++) {
-            prev = getCommonSuperType(context, prev, types[i]);
-        }
-        return prev;
-    }
-
-    public static TypeMirror getCommonSuperType(ProcessorContext context, TypeMirror type1, TypeMirror type2) {
-        if (typeEquals(type1, type2)) {
-            return type1;
-        }
-        TypeElement element1 = fromTypeMirror(type1);
-        TypeElement element2 = fromTypeMirror(type2);
-        if (element1 == null || element2 == null) {
-            return context.getType(Object.class);
-        }
-
-        List<TypeElement> element1Types = getDirectSuperTypes(element1);
-        element1Types.add(0, element1);
-        List<TypeElement> element2Types = getDirectSuperTypes(element2);
-        element2Types.add(0, element2);
-
-        for (TypeElement superType1 : element1Types) {
-            for (TypeElement superType2 : element2Types) {
-                if (typeEquals(superType1.asType(), superType2.asType())) {
-                    return superType2.asType();
-                }
-            }
-        }
-        return context.getType(Object.class);
-    }
-
-    public static String getReadableSignature(ExecutableElement method) {
-        // TODO toString does not guarantee a good signature
-        return method.toString();
-    }
-
-    public static boolean hasError(TypeMirror mirror) {
-        switch (mirror.getKind()) {
-            case BOOLEAN:
-            case BYTE:
-            case CHAR:
-            case DOUBLE:
-            case FLOAT:
-            case INT:
-            case SHORT:
-            case LONG:
-            case DECLARED:
-            case VOID:
-            case TYPEVAR:
-                return false;
-            case ARRAY:
-                return hasError(((ArrayType) mirror).getComponentType());
-            case ERROR:
-                return true;
-            default:
-                throw new RuntimeException("Unknown type specified " + mirror.getKind() + " mirror: " + mirror);
-        }
-    }
-
-    public static boolean isAssignable(ProcessorContext context, TypeMirror from, TypeMirror to) {
-        if (!(from instanceof CodeTypeMirror) && !(to instanceof CodeTypeMirror)) {
-            return context.getEnvironment().getTypeUtils().isAssignable(context.reloadType(from), context.reloadType(to));
-        } else {
-            return isAssignableImpl(context, from, to);
-        }
-    }
-
-    private static boolean isAssignableImpl(ProcessorContext context, TypeMirror from, TypeMirror to) {
-        // JLS 5.1.1 identity conversion
-        if (Utils.typeEquals(from, to)) {
-            return true;
-        }
-
-        // JLS 5.1.2 widening primitives
-        if (Utils.isPrimitive(from) && Utils.isPrimitive(to)) {
-            TypeKind fromKind = from.getKind();
-            TypeKind toKind = to.getKind();
-            switch (fromKind) {
-                case BYTE:
-                    switch (toKind) {
-                        case SHORT:
-                        case INT:
-                        case LONG:
-                        case FLOAT:
-                        case DOUBLE:
-                            return true;
-                    }
-                    break;
-                case SHORT:
-                    switch (toKind) {
-                        case INT:
-                        case LONG:
-                        case FLOAT:
-                        case DOUBLE:
-                            return true;
-                    }
-                    break;
-                case CHAR:
-                    switch (toKind) {
-                        case INT:
-                        case LONG:
-                        case FLOAT:
-                        case DOUBLE:
-                            return true;
-                    }
-                    break;
-                case INT:
-                    switch (toKind) {
-                        case LONG:
-                        case FLOAT:
-                        case DOUBLE:
-                            return true;
-                    }
-                    break;
-                case LONG:
-                    switch (toKind) {
-                        case FLOAT:
-                        case DOUBLE:
-                            return true;
-                    }
-                    break;
-                case FLOAT:
-                    switch (toKind) {
-                        case DOUBLE:
-                            return true;
-                    }
-                    break;
-
-            }
-            return false;
-        } else if (Utils.isPrimitive(from) || Utils.isPrimitive(to)) {
-            return false;
-        }
-
-        if (from instanceof ArrayType && to instanceof ArrayType) {
-            return isAssignable(context, ((ArrayType) from).getComponentType(), ((ArrayType) to).getComponentType());
-        }
-
-        TypeElement fromType = Utils.fromTypeMirror(from);
-        TypeElement toType = Utils.fromTypeMirror(to);
-        if (fromType == null || toType == null) {
-            return false;
-        }
-        // JLS 5.1.6 narrowing reference conversion
-
-        List<TypeElement> superTypes = Utils.getSuperTypes(fromType);
-        for (TypeElement superType : superTypes) {
-            if (Utils.typeEquals(superType.asType(), to)) {
-                return true;
-            }
-        }
-
-        // TODO more spec
-        return false;
-    }
-
-    public static Set<Modifier> modifiers(Modifier... modifier) {
-        return new LinkedHashSet<>(Arrays.asList(modifier));
-    }
-
-    public static String getTypeId(TypeMirror mirror) {
-        switch (mirror.getKind()) {
-            case BOOLEAN:
-                return "Boolean";
-            case BYTE:
-                return "Byte";
-            case CHAR:
-                return "Char";
-            case DOUBLE:
-                return "Double";
-            case FLOAT:
-                return "Float";
-            case SHORT:
-                return "Short";
-            case INT:
-                return "Int";
-            case LONG:
-                return "Long";
-            case DECLARED:
-                return ((DeclaredType) mirror).asElement().getSimpleName().toString();
-            case ARRAY:
-                return getTypeId(((ArrayType) mirror).getComponentType()) + "Array";
-            case VOID:
-                return "Void";
-            case WILDCARD:
-                StringBuilder b = new StringBuilder();
-                WildcardType type = (WildcardType) mirror;
-                if (type.getExtendsBound() != null) {
-                    b.append("Extends").append(getTypeId(type.getExtendsBound()));
-                } else if (type.getSuperBound() != null) {
-                    b.append("Super").append(getTypeId(type.getExtendsBound()));
-                }
-                return b.toString();
-            case TYPEVAR:
-                return "Any";
-            case ERROR:
-                throw new CompileErrorException("Type error " + mirror);
-            default:
-                throw new RuntimeException("Unknown type specified " + mirror.getKind() + " mirror: " + mirror);
-        }
-    }
-
-    public static String getSimpleName(TypeElement element) {
-        return getSimpleName(element.asType());
-    }
-
-    public static String getSimpleName(TypeMirror mirror) {
-        switch (mirror.getKind()) {
-            case BOOLEAN:
-                return "boolean";
-            case BYTE:
-                return "byte";
-            case CHAR:
-                return "char";
-            case DOUBLE:
-                return "double";
-            case FLOAT:
-                return "float";
-            case SHORT:
-                return "short";
-            case INT:
-                return "int";
-            case LONG:
-                return "long";
-            case DECLARED:
-                return getDeclaredName((DeclaredType) mirror);
-            case ARRAY:
-                return getSimpleName(((ArrayType) mirror).getComponentType()) + "[]";
-            case VOID:
-                return "void";
-            case WILDCARD:
-                return getWildcardName((WildcardType) mirror);
-            case TYPEVAR:
-                return "?";
-            case ERROR:
-                throw new CompileErrorException("Type error " + mirror);
-            default:
-                throw new RuntimeException("Unknown type specified " + mirror.getKind() + " mirror: " + mirror);
-        }
-    }
-
-    private static String getWildcardName(WildcardType type) {
-        StringBuilder b = new StringBuilder();
-        if (type.getExtendsBound() != null) {
-            b.append("? extends ").append(getSimpleName(type.getExtendsBound()));
-        } else if (type.getSuperBound() != null) {
-            b.append("? super ").append(getSimpleName(type.getExtendsBound()));
-        }
-        return b.toString();
-    }
-
-    private static String getDeclaredName(DeclaredType element) {
-        String simpleName = element.asElement().getSimpleName().toString();
-
-        if (element.getTypeArguments().size() == 0) {
-            return simpleName;
-        }
-
-        StringBuilder b = new StringBuilder(simpleName);
-        b.append("<");
-        if (element.getTypeArguments().size() > 0) {
-            for (int i = 0; i < element.getTypeArguments().size(); i++) {
-                b.append(getSimpleName(element.getTypeArguments().get(i)));
-                if (i < element.getTypeArguments().size() - 1) {
-                    b.append(", ");
-                }
-            }
-        }
-        b.append(">");
-        return b.toString();
-    }
-
-    public static String getQualifiedName(TypeElement element) {
-        return element.getQualifiedName().toString();
-    }
-
-    public static String getQualifiedName(TypeMirror mirror) {
-        switch (mirror.getKind()) {
-            case BOOLEAN:
-                return "boolean";
-            case BYTE:
-                return "byte";
-            case CHAR:
-                return "char";
-            case DOUBLE:
-                return "double";
-            case SHORT:
-                return "short";
-            case FLOAT:
-                return "float";
-            case INT:
-                return "int";
-            case LONG:
-                return "long";
-            case DECLARED:
-                return getQualifiedName(fromTypeMirror(mirror));
-            case ARRAY:
-                return getQualifiedName(((ArrayType) mirror).getComponentType());
-            case VOID:
-                return "void";
-            case TYPEVAR:
-                return getSimpleName(mirror);
-            case ERROR:
-                throw new CompileErrorException("Type error " + mirror);
-            case NONE:
-                return "$none";
-            default:
-                throw new RuntimeException("Unknown type specified " + mirror + " mirror: " + mirror);
-        }
-    }
-
-    public static boolean isVoid(TypeMirror mirror) {
-        return mirror.getKind() == TypeKind.VOID;
-    }
-
-    public static boolean isPrimitive(TypeMirror mirror) {
-        return mirror.getKind().isPrimitive();
-    }
-
-    public static boolean isPrimitiveOrVoid(TypeMirror mirror) {
-        return isPrimitive(mirror) || isVoid(mirror);
-    }
-
-    public static List<String> getQualifiedSuperTypeNames(TypeElement element) {
-        List<TypeElement> types = getSuperTypes(element);
-        List<String> qualifiedNames = new ArrayList<>();
-        for (TypeElement type : types) {
-            qualifiedNames.add(getQualifiedName(type));
-        }
-        return qualifiedNames;
-    }
-
-    public static List<TypeElement> getDeclaredTypes(TypeElement element) {
-        return ElementFilter.typesIn(element.getEnclosedElements());
-    }
-
-    public static VariableElement findDeclaredField(TypeMirror type, String singletonName) {
-        List<VariableElement> elements = ElementFilter.fieldsIn(fromTypeMirror(type).getEnclosedElements());
-        for (VariableElement var : elements) {
-            if (var.getSimpleName().toString().equals(singletonName)) {
-                return var;
-            }
-        }
-        return null;
-    }
-
-    public static TypeElement findRootEnclosingType(Element element) {
-        List<Element> elements = getElementHierarchy(element);
-
-        for (int i = elements.size() - 1; i >= 0; i--) {
-            if (elements.get(i).getKind().isClass()) {
-                return (TypeElement) elements.get(i);
-            }
-        }
-
-        return null;
-    }
-
-    public static List<Element> getElementHierarchy(Element e) {
-        List<Element> elements = new ArrayList<>();
-        elements.add(e);
-
-        Element enclosing = e.getEnclosingElement();
-        while (enclosing != null && enclosing.getKind() != ElementKind.PACKAGE) {
-            elements.add(enclosing);
-            enclosing = enclosing.getEnclosingElement();
-        }
-        if (enclosing != null) {
-            elements.add(enclosing);
-        }
-        return elements;
-    }
-
-    public static TypeElement findNearestEnclosingType(Element element) {
-        List<Element> elements = getElementHierarchy(element);
-        for (Element e : elements) {
-            if (e.getKind().isClass()) {
-                return (TypeElement) e;
-            }
-        }
-        return null;
-    }
-
-    public static List<TypeElement> getDirectSuperTypes(TypeElement element) {
-        List<TypeElement> types = new ArrayList<>();
-        if (element.getSuperclass() != null) {
-            TypeElement superElement = fromTypeMirror(element.getSuperclass());
-            if (superElement != null) {
-                types.add(superElement);
-                types.addAll(getDirectSuperTypes(superElement));
-            }
-        }
-
-        return types;
-    }
-
-    public static List<TypeElement> getSuperTypes(TypeElement element) {
-        List<TypeElement> types = new ArrayList<>();
-        List<TypeElement> superTypes = null;
-        List<TypeElement> superInterfaces = null;
-        if (element.getSuperclass() != null) {
-            TypeElement superElement = fromTypeMirror(element.getSuperclass());
-            if (superElement != null) {
-                types.add(superElement);
-                superTypes = getSuperTypes(superElement);
-            }
-        }
-        for (TypeMirror interfaceMirror : element.getInterfaces()) {
-            TypeElement interfaceElement = fromTypeMirror(interfaceMirror);
-            if (interfaceElement != null) {
-                types.add(interfaceElement);
-                superInterfaces = getSuperTypes(interfaceElement);
-            }
-        }
-
-        if (superTypes != null) {
-            types.addAll(superTypes);
-        }
-
-        if (superInterfaces != null) {
-            types.addAll(superInterfaces);
-        }
-
-        return types;
-    }
-
-    public static String getPackageName(TypeElement element) {
-        return findPackageElement(element).getQualifiedName().toString();
-    }
-
-    public static String getPackageName(TypeMirror mirror) {
-        switch (mirror.getKind()) {
-            case BOOLEAN:
-            case BYTE:
-            case CHAR:
-            case DOUBLE:
-            case FLOAT:
-            case SHORT:
-            case INT:
-            case LONG:
-            case VOID:
-            case TYPEVAR:
-                return null;
-            case DECLARED:
-                PackageElement pack = findPackageElement(fromTypeMirror(mirror));
-                if (pack == null) {
-                    throw new IllegalArgumentException("No package element found for declared type " + getSimpleName(mirror));
-                }
-                return pack.getQualifiedName().toString();
-            case ARRAY:
-                return getSimpleName(((ArrayType) mirror).getComponentType());
-            default:
-                throw new RuntimeException("Unknown type specified " + mirror.getKind());
-        }
-    }
-
-    public static String createConstantName(String simpleName) {
-        // TODO use camel case to produce underscores.
-        return simpleName.toString().toUpperCase();
-    }
-
-    public static TypeElement fromTypeMirror(TypeMirror mirror) {
-        switch (mirror.getKind()) {
-            case DECLARED:
-                return (TypeElement) ((DeclaredType) mirror).asElement();
-            case ARRAY:
-                return fromTypeMirror(((ArrayType) mirror).getComponentType());
-            default:
-                return null;
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    public static <T> List<T> getAnnotationValueList(Class<T> expectedListType, AnnotationMirror mirror, String name) {
-        List<? extends AnnotationValue> values = getAnnotationValue(List.class, mirror, name);
-        List<T> result = new ArrayList<>();
-
-        if (values != null) {
-            for (AnnotationValue value : values) {
-                T annotationValue = resolveAnnotationValue(expectedListType, value);
-                if (annotationValue != null) {
-                    result.add(annotationValue);
-                }
-            }
-        }
-        return result;
-    }
-
-    public static <T> T getAnnotationValue(Class<T> expectedType, AnnotationMirror mirror, String name) {
-        return resolveAnnotationValue(expectedType, getAnnotationValue(mirror, name));
-    }
-
-    @SuppressWarnings({"unchecked"})
-    private static <T> T resolveAnnotationValue(Class<T> expectedType, AnnotationValue value) {
-        if (value == null) {
-            return null;
-        }
-
-        Object unboxedValue = value.accept(new AnnotationValueVisitorImpl(), null);
-        if (unboxedValue != null) {
-            if (expectedType == TypeMirror.class && unboxedValue instanceof String) {
-                return null;
-            }
-            if (!expectedType.isAssignableFrom(unboxedValue.getClass())) {
-                throw new ClassCastException(unboxedValue.getClass().getName() + " not assignable from " + expectedType.getName());
-            }
-        }
-        return (T) unboxedValue;
-    }
-
-    public static AnnotationValue getAnnotationValue(AnnotationMirror mirror, String name) {
-        ExecutableElement valueMethod = null;
-        for (ExecutableElement method : ElementFilter.methodsIn(mirror.getAnnotationType().asElement().getEnclosedElements())) {
-            if (method.getSimpleName().toString().equals(name)) {
-                valueMethod = method;
-                break;
-            }
-        }
-
-        if (valueMethod == null) {
-            return null;
-        }
-
-        AnnotationValue value = mirror.getElementValues().get(valueMethod);
-        if (value == null) {
-            value = valueMethod.getDefaultValue();
-        }
-
-        return value;
-    }
-
-    private static class AnnotationValueVisitorImpl extends AbstractAnnotationValueVisitor7<Object, Void> {
-
-        @Override
-        public Object visitBoolean(boolean b, Void p) {
-            return Boolean.valueOf(b);
-        }
-
-        @Override
-        public Object visitByte(byte b, Void p) {
-            return Byte.valueOf(b);
-        }
-
-        @Override
-        public Object visitChar(char c, Void p) {
-            return c;
-        }
-
-        @Override
-        public Object visitDouble(double d, Void p) {
-            return d;
-        }
-
-        @Override
-        public Object visitFloat(float f, Void p) {
-            return f;
-        }
-
-        @Override
-        public Object visitInt(int i, Void p) {
-            return i;
-        }
-
-        @Override
-        public Object visitLong(long i, Void p) {
-            return i;
-        }
-
-        @Override
-        public Object visitShort(short s, Void p) {
-            return s;
-        }
-
-        @Override
-        public Object visitString(String s, Void p) {
-            return s;
-        }
-
-        @Override
-        public Object visitType(TypeMirror t, Void p) {
-            return t;
-        }
-
-        @Override
-        public Object visitEnumConstant(VariableElement c, Void p) {
-            return c;
-        }
-
-        @Override
-        public Object visitAnnotation(AnnotationMirror a, Void p) {
-            return a;
-        }
-
-        @Override
-        public Object visitArray(List<? extends AnnotationValue> vals, Void p) {
-            return vals;
-        }
-
-    }
-
-    public static boolean getAnnotationValueBoolean(AnnotationMirror mirror, String name) {
-        return (Boolean) getAnnotationValue(mirror, name).getValue();
-    }
-
-    public static String printException(Throwable e) {
-        StringWriter string = new StringWriter();
-        PrintWriter writer = new PrintWriter(string);
-        e.printStackTrace(writer);
-        writer.flush();
-        return e.getMessage() + "\r\n" + string.toString();
-    }
-
-    public static AnnotationMirror findAnnotationMirror(ProcessingEnvironment processingEnv, Element element, Class<?> annotationClass) {
-        return findAnnotationMirror(processingEnv, element.getAnnotationMirrors(), annotationClass);
-    }
-
-    public static AnnotationMirror findAnnotationMirror(ProcessingEnvironment processingEnv, List<? extends AnnotationMirror> mirrors, Class<?> annotationClass) {
-        TypeElement expectedAnnotationType = processingEnv.getElementUtils().getTypeElement(annotationClass.getCanonicalName());
-        for (AnnotationMirror mirror : mirrors) {
-            DeclaredType annotationType = mirror.getAnnotationType();
-            TypeElement actualAnnotationType = (TypeElement) annotationType.asElement();
-            if (actualAnnotationType.equals(expectedAnnotationType)) {
-                return mirror;
-            }
-        }
-        return null;
-    }
-
-    private static PackageElement findPackageElement(Element type) {
-        List<Element> hierarchy = getElementHierarchy(type);
-        for (Element element : hierarchy) {
-            if (element.getKind() == ElementKind.PACKAGE) {
-                return (PackageElement) element;
-            }
-        }
-        return null;
-    }
-
-    public static String firstLetterUpperCase(String name) {
-        if (name == null || name.isEmpty()) {
-            return name;
-        }
-        return Character.toUpperCase(name.charAt(0)) + name.substring(1, name.length());
-    }
-
-    public static String firstLetterLowerCase(String name) {
-        if (name == null || name.isEmpty()) {
-            return name;
-        }
-        return Character.toLowerCase(name.charAt(0)) + name.substring(1, name.length());
-    }
-
-    private static ExecutableElement getDeclaredMethod(TypeElement element, String name, TypeMirror[] params) {
-        List<ExecutableElement> methods = ElementFilter.methodsIn(element.getEnclosedElements());
-        method: for (ExecutableElement method : methods) {
-            if (!method.getSimpleName().toString().equals(name)) {
-                continue;
-            }
-            if (method.getParameters().size() != params.length) {
-                continue;
-            }
-            for (int i = 0; i < params.length; i++) {
-                TypeMirror param1 = params[i];
-                TypeMirror param2 = method.getParameters().get(i).asType();
-                if (param1.getKind() != TypeKind.TYPEVAR && param2.getKind() != TypeKind.TYPEVAR) {
-                    if (!getQualifiedName(param1).equals(getQualifiedName(param2))) {
-                        continue method;
-                    }
-                }
-            }
-            return method;
-        }
-        return null;
-    }
-
-    private static boolean isDeclaredMethod(TypeElement element, String name, TypeMirror[] params) {
-        return getDeclaredMethod(element, name, params) != null;
-    }
-
-    public static boolean isDeclaredMethodInSuperType(TypeElement element, String name, TypeMirror[] params) {
-        List<TypeElement> superElements = getSuperTypes(element);
-
-        for (TypeElement typeElement : superElements) {
-            if (isDeclaredMethod(typeElement, name, params)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private static ExecutableElement getDeclaredMethodInSuperType(TypeElement element, String name, TypeMirror[] params) {
-        List<TypeElement> superElements = getSuperTypes(element);
-
-        for (TypeElement typeElement : superElements) {
-            ExecutableElement declared = getDeclaredMethod(typeElement, name, params);
-            if (declared != null) {
-                return declared;
-            }
-        }
-        return null;
-    }
-
-    public static ExecutableElement getDeclaredMethodRecursive(TypeElement element, String name, TypeMirror[] params) {
-        ExecutableElement declared = getDeclaredMethod(element, name, params);
-        if (declared != null) {
-            return declared;
-        }
-        return getDeclaredMethodInSuperType(element, name, params);
-    }
-
-    public static boolean typeEquals(TypeMirror type1, TypeMirror type2) {
-        if (type1 == null && type2 == null) {
-            return true;
-        } else if (type1 == null || type2 == null) {
-            return false;
-        }
-        String qualified1 = getQualifiedName(type1);
-        String qualified2 = getQualifiedName(type2);
-
-        if (type1.getKind() == TypeKind.ARRAY || type2.getKind() == TypeKind.ARRAY) {
-            if (type1.getKind() == TypeKind.ARRAY && type2.getKind() == TypeKind.ARRAY) {
-                return typeEquals(((ArrayType) type1).getComponentType(), ((ArrayType) type2).getComponentType());
-            } else {
-                return false;
-            }
-        }
-        return qualified1.equals(qualified2);
-    }
-
-    public static int compareByTypeHierarchy(TypeMirror t1, TypeMirror t2) {
-        if (typeEquals(t1, t2)) {
-            return 0;
-        }
-        Set<String> t1SuperSet = new HashSet<>(getQualifiedSuperTypeNames(fromTypeMirror(t1)));
-        if (t1SuperSet.contains(getQualifiedName(t2))) {
-            return -1;
-        }
-
-        Set<String> t2SuperSet = new HashSet<>(getQualifiedSuperTypeNames(fromTypeMirror(t2)));
-        if (t2SuperSet.contains(getQualifiedName(t1))) {
-            return 1;
-        }
-        return 0;
-    }
-
-    public static boolean canThrowType(List<? extends TypeMirror> thrownTypes, TypeMirror exceptionType) {
-        if (Utils.containsType(thrownTypes, exceptionType)) {
-            return true;
-        }
-
-        if (isRuntimeException(exceptionType)) {
-            return true;
-        }
-
-        // search for any super types
-        TypeElement exceptionTypeElement = fromTypeMirror(exceptionType);
-        List<TypeElement> superTypes = getSuperTypes(exceptionTypeElement);
-        for (TypeElement typeElement : superTypes) {
-            if (Utils.containsType(thrownTypes, typeElement.asType())) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    public static Modifier getVisibility(Set<Modifier> modifier) {
-        for (Modifier mod : modifier) {
-            if (mod == Modifier.PUBLIC || mod == Modifier.PRIVATE || mod == Modifier.PROTECTED) {
-                return mod;
-            }
-        }
-        return null;
-    }
-
-    private static boolean isRuntimeException(TypeMirror type) {
-        Set<String> typeSuperSet = new HashSet<>(getQualifiedSuperTypeNames(fromTypeMirror(type)));
-        String typeName = getQualifiedName(type);
-        if (!typeSuperSet.contains(Throwable.class.getCanonicalName()) && !typeName.equals(Throwable.class.getCanonicalName())) {
-            throw new IllegalArgumentException("Given type does not extend Throwable.");
-        }
-        return typeSuperSet.contains(RuntimeException.class.getCanonicalName()) || typeName.equals(RuntimeException.class.getCanonicalName());
-    }
-
-    private static boolean containsType(Collection<? extends TypeMirror> collection, TypeMirror type) {
-        for (TypeMirror otherTypeMirror : collection) {
-            if (typeEquals(otherTypeMirror, type)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public static boolean isTopLevelClass(TypeMirror importType) {
-        TypeElement type = fromTypeMirror(importType);
-        if (type != null && type.getEnclosingElement() != null) {
-            return !type.getEnclosingElement().getKind().isClass();
-        }
-        return true;
-    }
-
-    public static boolean isObject(TypeMirror actualType) {
-        return getQualifiedName(actualType).equals("java.lang.Object");
-    }
-
-    public static boolean isFieldAccessible(Element element, VariableElement variable) {
-        TypeElement type = Utils.findNearestEnclosingType(element);
-        TypeElement varType = Utils.findNearestEnclosingType(variable);
-
-        while (type != null) {
-            if (typeEquals(type.asType(), varType.asType())) {
-                return true;
-            }
-            if (type.getSuperclass() != null) {
-                type = Utils.fromTypeMirror(type.getSuperclass());
-            } else {
-                type = null;
-            }
-        }
-        return false;
-    }
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/api/ExtensionContext.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.api;
-
-import javax.annotation.processing.*;
-
-import com.oracle.truffle.codegen.processor.api.element.*;
-
-public interface ExtensionContext {
-
-    ProcessingEnvironment getProcessingEnvironment();
-
-    RoundEnvironment getRoundEnvironment();
-
-    WritableElementFactory getElementFactory();
-
-    void addGeneratedElement(WritableElement element);
-
-    void removeGeneratedElement(WritableElement element);
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/api/ExtensionProcessor.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.api;
-
-import javax.lang.model.element.*;
-
-public interface ExtensionProcessor {
-
-    void process(ExtensionContext context, AnnotationMirror mirror, Element element);
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/api/element/WritableAnnotationMirror.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.api.element;
-
-import javax.lang.model.element.*;
-
-public interface WritableAnnotationMirror extends AnnotationMirror {
-
-    void setElementValue(ExecutableElement valueName, AnnotationValue value);
-
-    AnnotationValue getElementValue(ExecutableElement valueName);
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/api/element/WritableElement.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.api.element;
-
-import javax.lang.model.element.*;
-
-public interface WritableElement extends Element {
-
-    void addAnnotationMirror(AnnotationMirror annotationMirror);
-
-    void removeAnnotationMirror(AnnotationMirror annotationMirror);
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/api/element/WritableElementFactory.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.api.element;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-
-public interface WritableElementFactory {
-
-    WritableExecutableElement cloneExecutableElement(ExecutableElement method);
-
-    WritableVariableElement cloneVariableElement(VariableElement parameter);
-
-    WritableAnnotationMirror cloneAnnotationMirror(AnnotationMirror mirror);
-
-    WritableVariableElement createParameter(TypeMirror type, String simpleName);
-
-    WritableExecutableElement createExecutableElement(TypeMirror returnType, String methodName);
-
-    WritableAnnotationMirror createAnnotationMirror(DeclaredType annotationClass);
-
-    Name createName(String name);
-
-    AnnotationValue createAnnotationValue(Object value);
-
-    TypeMirror createTypeMirror(Class<?> javaClass);
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/api/element/WritableExecutableElement.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.api.element;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-
-public interface WritableExecutableElement extends ExecutableElement, WritableElement {
-
-    void setReturnType(TypeMirror type);
-
-    void setDefaultValue(AnnotationValue defaultValue);
-
-    void addParameter(VariableElement parameter);
-
-    void removeParameter(VariableElement parameter);
-
-    void addThrownType(TypeMirror thrownType);
-
-    void removeThrownType(TypeMirror thrownType);
-
-    void setSimpleName(Name name);
-
-    void setVarArgs(boolean varargs);
-
-    void setBody(String body);
-
-    String getBody();
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/api/element/WritableVariableElement.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.api.element;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-
-public interface WritableVariableElement extends VariableElement, WritableElement {
-
-    void setSimpleName(Name name);
-
-    void setType(TypeMirror type);
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeAnnotationMirror.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.ast;
-
-import java.util.*;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.api.element.*;
-
-public class CodeAnnotationMirror implements WritableAnnotationMirror {
-
-    private final DeclaredType annotationType;
-    private final Map<ExecutableElement, AnnotationValue> values = new LinkedHashMap<>();
-
-    public CodeAnnotationMirror(DeclaredType annotationType) {
-        this.annotationType = annotationType;
-    }
-
-    @Override
-    public DeclaredType getAnnotationType() {
-        return annotationType;
-    }
-
-    @Override
-    public Map<? extends ExecutableElement, ? extends AnnotationValue> getElementValues() {
-        return values;
-    }
-
-    @Override
-    public AnnotationValue getElementValue(ExecutableElement method) {
-        return values.get(method);
-    }
-
-    @Override
-    public void setElementValue(ExecutableElement method, AnnotationValue value) {
-        values.put(method, value);
-    }
-
-    public ExecutableElement findExecutableElement(String name) {
-        return Utils.findExecutableElement(annotationType, name);
-    }
-
-    public static CodeAnnotationMirror clone(AnnotationMirror mirror) {
-        CodeAnnotationMirror copy = new CodeAnnotationMirror(mirror.getAnnotationType());
-        for (ExecutableElement key : mirror.getElementValues().keySet()) {
-            copy.setElementValue(key, mirror.getElementValues().get(key));
-        }
-        return copy;
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeAnnotationValue.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.ast;
-
-import java.util.*;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-
-public class CodeAnnotationValue implements AnnotationValue {
-
-    private final Object value;
-
-    public CodeAnnotationValue(Object value) {
-        Objects.requireNonNull(value);
-        if ((value instanceof AnnotationMirror) || (value instanceof List<?>) || (value instanceof Boolean) || (value instanceof Byte) || (value instanceof Character) || (value instanceof Double) ||
-                        (value instanceof VariableElement) || (value instanceof Float) || (value instanceof Integer) || (value instanceof Long) || (value instanceof Short) ||
-                        (value instanceof String) || (value instanceof TypeMirror)) {
-            this.value = value;
-        } else {
-            throw new IllegalArgumentException("Invalid annotation value type " + value.getClass().getName());
-        }
-    }
-
-    @Override
-    public Object getValue() {
-        return value;
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public <R, P> R accept(AnnotationValueVisitor<R, P> v, P p) {
-        if (value instanceof AnnotationMirror) {
-            return v.visitAnnotation((AnnotationMirror) value, p);
-        } else if (value instanceof List<?>) {
-            return v.visitArray((List<? extends AnnotationValue>) value, p);
-        } else if (value instanceof Boolean) {
-            return v.visitBoolean((boolean) value, p);
-        } else if (value instanceof Byte) {
-            return v.visitByte((byte) value, p);
-        } else if (value instanceof Character) {
-            return v.visitChar((char) value, p);
-        } else if (value instanceof Double) {
-            return v.visitDouble((double) value, p);
-        } else if (value instanceof VariableElement) {
-            return v.visitEnumConstant((VariableElement) value, p);
-        } else if (value instanceof Float) {
-            return v.visitFloat((float) value, p);
-        } else if (value instanceof Integer) {
-            return v.visitInt((int) value, p);
-        } else if (value instanceof Long) {
-            return v.visitLong((long) value, p);
-        } else if (value instanceof Short) {
-            return v.visitShort((short) value, p);
-        } else if (value instanceof String) {
-            return v.visitString((String) value, p);
-        } else if (value instanceof TypeMirror) {
-            return v.visitType((TypeMirror) value, p);
-        } else {
-            return v.visitUnknown(this, p);
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeCompilationUnit.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.ast;
-
-import java.util.*;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-
-public class CodeCompilationUnit extends CodeElement<TypeElement> {
-
-    public CodeCompilationUnit() {
-        super(Collections.<Modifier> emptySet());
-    }
-
-    @Override
-    public TypeMirror asType() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public ElementKind getKind() {
-        return ElementKind.OTHER;
-    }
-
-    @Override
-    public Name getSimpleName() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public <R, P> R accept(ElementVisitor<R, P> v, P p) {
-        for (Element type : getEnclosedElements()) {
-            if (type.getKind().isClass()) {
-                type.accept(v, p);
-            } else {
-                throw new ClassCastException(type.getClass().getName());
-            }
-        }
-        return null;
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeElement.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,360 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.ast;
-
-import java.io.*;
-import java.lang.annotation.*;
-import java.util.*;
-
-import javax.lang.model.element.*;
-
-import com.oracle.truffle.codegen.processor.api.element.*;
-import com.oracle.truffle.codegen.processor.codewriter.*;
-
-public abstract class CodeElement<E extends Element> implements WritableElement, GeneratedElement {
-
-    private final Set<Modifier> modifiers;
-    private List<AnnotationMirror> annotations;
-    private List<E> enclosedElements;
-
-    private Element enclosingElement;
-
-    private Element generatorElement;
-    private AnnotationMirror generatorAnnotationMirror;
-
-    public CodeElement() {
-        this.modifiers = new LinkedHashSet<>();
-    }
-
-    @Override
-    public void setGeneratorAnnotationMirror(AnnotationMirror mirror) {
-        this.generatorAnnotationMirror = mirror;
-    }
-
-    @Override
-    public void setGeneratorElement(Element element) {
-        this.generatorElement = element;
-    }
-
-    @Override
-    public AnnotationMirror getGeneratorAnnotationMirror() {
-        return generatorAnnotationMirror;
-    }
-
-    @Override
-    public Element getGeneratorElement() {
-        return generatorElement;
-    }
-
-    public CodeElement(Set<Modifier> modifiers) {
-        this.modifiers = new LinkedHashSet<>(modifiers);
-    }
-
-    public E add(E element) {
-        if (element == null) {
-            throw new NullPointerException();
-        }
-        getEnclosedElements().add(element);
-        return element;
-    }
-
-    public void remove(E element) {
-        getEnclosedElements().remove(element);
-    }
-
-    @Override
-    public Set<Modifier> getModifiers() {
-        return modifiers;
-    }
-
-    @Override
-    public List<E> getEnclosedElements() {
-        if (enclosedElements == null) {
-            enclosedElements = parentableList(this, new ArrayList<E>());
-        }
-        return enclosedElements;
-    }
-
-    @Override
-    public List<AnnotationMirror> getAnnotationMirrors() {
-        if (annotations == null) {
-            annotations = parentableList(this, new ArrayList<AnnotationMirror>());
-        }
-        return annotations;
-    }
-
-    /**
-     * Support JDK8 langtools.
-     * 
-     * @param annotationType
-     */
-    public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType) {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Support for some JDK8 builds. (remove after jdk8 is released)
-     * 
-     * @param annotationType
-     */
-    public <A extends Annotation> A[] getAnnotations(Class<A> annotationType) {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Support for some JDK8 builds. (remove after jdk8 is released)
-     * 
-     * @param annotationType
-     */
-    public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void addAnnotationMirror(AnnotationMirror annotationMirror) {
-        getAnnotationMirrors().add(annotationMirror);
-    }
-
-    public void removeAnnotationMirror(AnnotationMirror annotationMirror) {
-        getAnnotationMirrors().remove(annotationMirror);
-    }
-
-    void setEnclosingElement(Element parent) {
-        this.enclosingElement = parent;
-    }
-
-    public Element getEnclosingElement() {
-        return enclosingElement;
-    }
-
-    public CodeTypeElement getEnclosingClass() {
-        Element p = enclosingElement;
-        while (p != null && p.getKind() != ElementKind.CLASS && p.getKind() != ElementKind.ENUM) {
-            p = p.getEnclosingElement();
-        }
-        return (CodeTypeElement) p;
-    }
-
-    <T> List<T> parentableList(Element parent, List<T> list) {
-        return new ParentableList<>(parent, list);
-    }
-
-    @Override
-    public String toString() {
-        StringBuilderCodeWriter codeWriter = new StringBuilderCodeWriter();
-        accept(codeWriter, null);
-        return codeWriter.getString();
-    }
-
-    private static class StringBuilderCodeWriter extends AbstractCodeWriter {
-
-        public StringBuilderCodeWriter() {
-            this.writer = new CharArrayWriter();
-        }
-
-        @Override
-        protected Writer createWriter(CodeTypeElement clazz) throws IOException {
-            return writer;
-        }
-
-        public String getString() {
-            return new String(((CharArrayWriter) writer).toCharArray()).trim();
-        }
-
-    }
-
-    private static class ParentableList<T> implements List<T> {
-
-        private final Element parent;
-        private final List<T> delegate;
-
-        public ParentableList(Element parent, List<T> delegate) {
-            this.parent = parent;
-            this.delegate = delegate;
-        }
-
-        private void addImpl(T element) {
-            if (element != null) {
-                if (element instanceof CodeElement<?>) {
-                    ((CodeElement<?>) element).setEnclosingElement(parent);
-                }
-            }
-        }
-
-        private static void removeImpl(Object element) {
-            if (element instanceof CodeElement<?>) {
-                ((CodeElement<?>) element).setEnclosingElement(null);
-            }
-        }
-
-        @Override
-        public int size() {
-            return delegate.size();
-        }
-
-        @Override
-        public boolean isEmpty() {
-            return delegate.isEmpty();
-        }
-
-        @Override
-        public boolean contains(Object o) {
-            return delegate.contains(o);
-        }
-
-        @Override
-        public Iterator<T> iterator() {
-            return delegate.iterator();
-        }
-
-        @Override
-        public Object[] toArray() {
-            return delegate.toArray();
-        }
-
-        @Override
-        public <E> E[] toArray(E[] a) {
-            return delegate.toArray(a);
-        }
-
-        @Override
-        public boolean add(T e) {
-            addImpl(e);
-            return delegate.add(e);
-        }
-
-        @Override
-        public boolean remove(Object o) {
-            boolean removed = delegate.remove(o);
-            if (removed) {
-                removeImpl(o);
-            }
-            return removed;
-        }
-
-        @Override
-        public boolean containsAll(Collection<?> c) {
-            return delegate.containsAll(c);
-        }
-
-        @Override
-        public boolean addAll(Collection<? extends T> c) {
-            if (c != null) {
-                for (T t : c) {
-                    addImpl(t);
-                }
-            }
-            return delegate.addAll(c);
-        }
-
-        @Override
-        public boolean addAll(int index, Collection<? extends T> c) {
-            if (c != null) {
-                for (T t : c) {
-                    addImpl(t);
-                }
-            }
-            return delegate.addAll(index, c);
-        }
-
-        @Override
-        public boolean removeAll(Collection<?> c) {
-            if (c != null) {
-                for (Object t : c) {
-                    removeImpl(t);
-                }
-            }
-            return delegate.removeAll(c);
-        }
-
-        @Override
-        public String toString() {
-            return delegate.toString();
-        }
-
-        @Override
-        public boolean retainAll(Collection<?> c) {
-            throw new UnsupportedOperationException("Not supported by parentable list");
-        }
-
-        @Override
-        public void clear() {
-            for (Object e : this) {
-                removeImpl(e);
-            }
-            delegate.clear();
-        }
-
-        @Override
-        public T get(int index) {
-            return delegate.get(index);
-        }
-
-        @Override
-        public T set(int index, T element) {
-            removeImpl(delegate.get(index));
-            addImpl(element);
-            return delegate.set(index, element);
-        }
-
-        @Override
-        public void add(int index, T element) {
-            addImpl(element);
-            delegate.add(index, element);
-        }
-
-        @Override
-        public T remove(int index) {
-            T element = delegate.remove(index);
-            removeImpl(element);
-            return element;
-        }
-
-        @Override
-        public int indexOf(Object o) {
-            return delegate.indexOf(o);
-        }
-
-        @Override
-        public int lastIndexOf(Object o) {
-            return delegate.lastIndexOf(o);
-        }
-
-        @Override
-        public ListIterator<T> listIterator() {
-            return delegate.listIterator();
-        }
-
-        @Override
-        public ListIterator<T> listIterator(int index) {
-            return delegate.listIterator(index);
-        }
-
-        @Override
-        public List<T> subList(int fromIndex, int toIndex) {
-            return new ParentableList<>(parent, delegate.subList(fromIndex, toIndex));
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeElementScanner.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.ast;
-
-import javax.lang.model.element.*;
-import javax.lang.model.util.*;
-
-public abstract class CodeElementScanner<R, P> extends ElementScanner7<R, P> {
-
-    @Override
-    public final R visitExecutable(ExecutableElement e, P p) {
-        return visitExecutable(cast(e, CodeExecutableElement.class), p);
-    }
-
-    public R visitExecutable(CodeExecutableElement e, P p) {
-        R ret = super.visitExecutable(e, p);
-        if (e.getBodyTree() != null) {
-            visitTree(e.getBodyTree(), p);
-        }
-        return ret;
-    }
-
-    @Override
-    public R visitPackage(PackageElement e, P p) {
-        return super.visitPackage(e, p);
-    }
-
-    @Override
-    public final R visitType(TypeElement e, P p) {
-        return visitType(cast(e, CodeTypeElement.class), p);
-    }
-
-    public R visitType(CodeTypeElement e, P p) {
-        return super.visitType(e, p);
-    }
-
-    @Override
-    public R visitTypeParameter(TypeParameterElement e, P p) {
-        return super.visitTypeParameter(e, p);
-    }
-
-    private static <E> E cast(Element element, Class<E> clazz) {
-        return clazz.cast(element);
-    }
-
-    public void visitTree(CodeTree e, P p) {
-        for (CodeTree tree : e.getEnclosedElements()) {
-            tree.acceptCodeElementScanner(this, p);
-        }
-    }
-
-    @SuppressWarnings("unused")
-    public void visitImport(CodeImport e, P p) {
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeExecutableElement.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,231 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.ast;
-
-import java.util.*;
-
-import javax.annotation.processing.*;
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.api.element.*;
-
-public class CodeExecutableElement extends CodeElement<Element> implements WritableExecutableElement {
-
-    private final List<TypeMirror> throwables = new ArrayList<>();
-    private final List<VariableElement> parameters = parentableList(this, new ArrayList<VariableElement>());
-
-    private TypeMirror returnType;
-    private Name name;
-
-    private CodeTree bodyTree;
-    private String body;
-    private AnnotationValue defaultValue;
-    private boolean varArgs;
-
-    public CodeExecutableElement(TypeMirror returnType, String name) {
-        super(Utils.modifiers());
-        this.returnType = returnType;
-        this.name = CodeNames.of(name);
-    }
-
-    public CodeExecutableElement(Set<Modifier> modifiers, TypeMirror returnType, String name, CodeVariableElement... parameters) {
-        super(modifiers);
-        this.returnType = returnType;
-        this.name = CodeNames.of(name);
-        for (CodeVariableElement codeParameter : parameters) {
-            addParameter(codeParameter);
-        }
-    }
-
-    /* Support JDK8 langtools. */
-    public boolean isDefault() {
-        return false;
-    }
-
-    @Override
-    public List<TypeMirror> getThrownTypes() {
-        return throwables;
-    }
-
-    @Override
-    public TypeMirror asType() {
-        return returnType;
-    }
-
-    @Override
-    public ElementKind getKind() {
-        if (getReturnType() == null) {
-            return ElementKind.CONSTRUCTOR;
-        } else {
-            return ElementKind.METHOD;
-        }
-    }
-
-    @Override
-    public List<? extends TypeParameterElement> getTypeParameters() {
-        return Collections.emptyList();
-    }
-
-    @Override
-    public void setVarArgs(boolean varargs) {
-        this.varArgs = varargs;
-    }
-
-    @Override
-    public boolean isVarArgs() {
-        return varArgs;
-    }
-
-    @Override
-    public void setDefaultValue(AnnotationValue defaultValue) {
-        this.defaultValue = defaultValue;
-    }
-
-    @Override
-    public AnnotationValue getDefaultValue() {
-        return defaultValue;
-    }
-
-    @Override
-    public Name getSimpleName() {
-        return name;
-    }
-
-    public CodeTreeBuilder createBuilder() {
-        CodeTreeBuilder builder = new CodeTreeBuilder(null);
-        this.bodyTree = builder.getTree();
-        this.bodyTree.setEnclosingElement(this);
-        this.body = null;
-        return builder;
-    }
-
-    public void setBodyTree(CodeTree body) {
-        this.bodyTree = body;
-    }
-
-    public CodeTree getBodyTree() {
-        return bodyTree;
-    }
-
-    public TypeMirror getReturnType() {
-        return returnType;
-    }
-
-    @Override
-    public List<VariableElement> getParameters() {
-        return parameters;
-    }
-
-    public TypeMirror[] getParameterTypes() {
-        TypeMirror[] types = new TypeMirror[getParameters().size()];
-        for (int i = 0; i < types.length; i++) {
-            types[i] = parameters.get(i).asType();
-        }
-        return types;
-    }
-
-    @Override
-    public void setReturnType(TypeMirror type) {
-        returnType = type;
-    }
-
-    @Override
-    public void addParameter(VariableElement parameter) {
-        parameters.add(parameter);
-    }
-
-    @Override
-    public void removeParameter(VariableElement parameter) {
-        parameters.remove(parameter);
-    }
-
-    public void removeParameter(String varName) {
-        VariableElement remove = null;
-        for (VariableElement var : getParameters()) {
-            if (var.getSimpleName().toString().equals(varName)) {
-                remove = var;
-                break;
-            }
-        }
-        if (remove != null) {
-            parameters.remove(remove);
-        }
-    }
-
-    @Override
-    public void addThrownType(TypeMirror thrownType) {
-        throwables.add(thrownType);
-    }
-
-    @Override
-    public void removeThrownType(TypeMirror thrownType) {
-        throwables.remove(thrownType);
-    }
-
-    @Override
-    public void setSimpleName(Name name) {
-        this.name = name;
-    }
-
-    @Override
-    public void setBody(String body) {
-        this.body = body;
-    }
-
-    @Override
-    public String getBody() {
-        return body;
-    }
-
-    @Override
-    public <R, P> R accept(ElementVisitor<R, P> v, P p) {
-        return v.visitExecutable(this, p);
-    }
-
-    public static CodeExecutableElement clone(@SuppressWarnings("unused") ProcessingEnvironment env, ExecutableElement method) {
-        CodeExecutableElement copy = new CodeExecutableElement(method.getReturnType(), method.getSimpleName().toString());
-        for (TypeMirror thrownType : method.getThrownTypes()) {
-            copy.addThrownType(thrownType);
-        }
-        copy.setDefaultValue(method.getDefaultValue());
-
-        for (AnnotationMirror mirror : method.getAnnotationMirrors()) {
-            copy.addAnnotationMirror(mirror);
-        }
-        for (VariableElement var : method.getParameters()) {
-            copy.addParameter(CodeVariableElement.clone(var));
-        }
-        for (Element element : method.getEnclosedElements()) {
-            copy.add(element);
-        }
-        copy.getModifiers().addAll(method.getModifiers());
-        copy.setVarArgs(method.isVarArgs());
-        return copy;
-    }
-
-    public TypeMirror getReceiverType() {
-        throw new UnsupportedOperationException();
-    }
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeImport.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.ast;
-
-import javax.lang.model.type.*;
-
-public class CodeImport implements Comparable<CodeImport> {
-
-    private final TypeMirror importType;
-    private final String importString;
-    private final boolean staticImport;
-
-    public CodeImport(TypeMirror importedType, String importString, boolean staticImport) {
-        this.importType = importedType;
-        this.importString = importString;
-        this.staticImport = staticImport;
-    }
-
-    public TypeMirror getImportType() {
-        return importType;
-    }
-
-    public boolean isStaticImport() {
-        return staticImport;
-    }
-
-    public String getImportString() {
-        return importString;
-    }
-
-    @Override
-    public int compareTo(CodeImport o) {
-        if (staticImport && !o.staticImport) {
-            return 1;
-        } else if (!staticImport && o.staticImport) {
-            return -1;
-        } else {
-            return importString.compareTo(o.getImportString());
-        }
-    }
-
-    public <P> void accept(CodeElementScanner<?, P> s, P p) {
-        s.visitImport(this, p);
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + ((importString == null) ? 0 : importString.hashCode());
-        result = prime * result + (staticImport ? 1231 : 1237);
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        CodeImport other = (CodeImport) obj;
-        if (importString == null) {
-            if (other.importString != null) {
-                return false;
-            }
-        } else if (!importString.equals(other.importString)) {
-            return false;
-        }
-        if (staticImport != other.staticImport) {
-            return false;
-        }
-        return true;
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeNames.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.ast;
-
-import java.util.*;
-
-import javax.lang.model.element.*;
-
-public abstract class CodeNames {
-
-    private static Map<String, Name> names = new HashMap<>();
-
-    public static Name of(String value) {
-        Name name = names.get(value);
-        if (name == null) {
-            name = new NameImpl(value);
-            names.put(value, name);
-        }
-        return name;
-    }
-
-    private static class NameImpl implements Name {
-
-        private final String name;
-
-        public NameImpl(String name) {
-            this.name = name;
-        }
-
-        @Override
-        public int length() {
-            return name.length();
-        }
-
-        @Override
-        public char charAt(int index) {
-            return name.charAt(index);
-        }
-
-        @Override
-        public CharSequence subSequence(int start, int end) {
-            return name.subSequence(start, end);
-        }
-
-        @Override
-        public boolean contentEquals(CharSequence cs) {
-            return name.contentEquals(cs);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (obj instanceof Name) {
-                return ((Name) obj).contentEquals(name);
-            }
-            return super.equals(obj);
-        }
-
-        @Override
-        public int hashCode() {
-            return name.hashCode();
-        }
-
-        @Override
-        public String toString() {
-            return name;
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTree.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.ast;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-
-public class CodeTree extends CodeElement<CodeTree> {
-
-    private final CodeTreeKind kind;
-
-    private final TypeMirror type;
-    private final String string;
-
-    public CodeTree(CodeTreeKind kind, TypeMirror type, String string) {
-        this.kind = kind;
-        this.type = type;
-        this.string = string;
-    }
-
-    public TypeMirror getType() {
-        return type;
-    }
-
-    public CodeTreeKind getCodeKind() {
-        return kind;
-    }
-
-    public String getString() {
-        return string;
-    }
-
-    public <P> void acceptCodeElementScanner(CodeElementScanner<?, P> s, P p) {
-        s.visitTree(this, p);
-    }
-
-    @Override
-    public TypeMirror asType() {
-        return type;
-    }
-
-    @Override
-    public ElementKind getKind() {
-        return ElementKind.OTHER;
-    }
-
-    @Override
-    public Name getSimpleName() {
-        return CodeNames.of(getString());
-    }
-
-    @Override
-    public <R, P> R accept(ElementVisitor<R, P> v, P p) {
-        if (v instanceof CodeElementScanner<?, ?>) {
-            acceptCodeElementScanner((CodeElementScanner<?, P>) v, p);
-            return null;
-        } else {
-            throw new UnsupportedOperationException();
-        }
-    }
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTreeBuilder.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,818 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.ast;
-
-import static com.oracle.truffle.codegen.processor.ast.CodeTreeKind.*;
-
-import java.util.*;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-
-import com.oracle.truffle.codegen.processor.*;
-
-public class CodeTreeBuilder {
-
-    private final CodeTreeBuilder parent;
-
-    private BuilderCodeTree currentElement;
-    private final BuilderCodeTree root;
-
-    private int treeCount;
-
-    public CodeTreeBuilder(CodeTreeBuilder parent) {
-        this.root = new BuilderCodeTree(GROUP, null, null);
-        this.currentElement = root;
-        this.parent = parent;
-    }
-
-    @Override
-    public String toString() {
-        return root.toString();
-    }
-
-    public int getTreeCount() {
-        return treeCount;
-    }
-
-    public boolean isEmpty() {
-        return treeCount == 0;
-    }
-
-    public CodeTreeBuilder statement(String statement) {
-        return startStatement().string(statement).end();
-    }
-
-    public CodeTreeBuilder statement(CodeTree statement) {
-        return startStatement().tree(statement).end();
-    }
-
-    public static CodeTreeBuilder createBuilder() {
-        return new CodeTreeBuilder(null);
-    }
-
-    public static CodeTree singleString(String s) {
-        return new CodeTreeBuilder(null).string(s).getTree();
-    }
-
-    public static CodeTree singleType(TypeMirror s) {
-        return new CodeTreeBuilder(null).type(s).getTree();
-    }
-
-    private CodeTreeBuilder push(CodeTreeKind kind) {
-        return push(new BuilderCodeTree(kind, null, null));
-    }
-
-    private CodeTreeBuilder push(String string) {
-        return push(new BuilderCodeTree(CodeTreeKind.STRING, null, string));
-    }
-
-    private CodeTreeBuilder push(TypeMirror type) {
-        return push(new BuilderCodeTree(CodeTreeKind.TYPE, type, null));
-    }
-
-    private CodeTreeBuilder push(CodeTreeKind kind, TypeMirror type, String string) {
-        return push(new BuilderCodeTree(kind, type, string));
-    }
-
-    private CodeTreeBuilder push(BuilderCodeTree tree) {
-        if (currentElement != null) {
-            currentElement.add(tree);
-        }
-        switch (tree.getCodeKind()) {
-            case COMMA_GROUP:
-            case GROUP:
-            case INDENT:
-                currentElement = tree;
-                break;
-        }
-        treeCount++;
-        return this;
-    }
-
-    private void clearLast(CodeTreeKind kind) {
-        if (clearLastRec(kind, currentElement.getEnclosedElements())) {
-            treeCount--;
-        }
-    }
-
-    public CodeTreeBuilder startStatement() {
-        startGroup();
-        registerCallBack(new EndCallback() {
-
-            @Override
-            public void beforeEnd() {
-                string(";").newLine();
-            }
-
-            @Override
-            public void afterEnd() {
-            }
-        });
-        return this;
-    }
-
-    public CodeTreeBuilder startGroup() {
-        return push(CodeTreeKind.GROUP);
-    }
-
-    public CodeTreeBuilder startCommaGroup() {
-        return push(CodeTreeKind.COMMA_GROUP);
-    }
-
-    public CodeTreeBuilder startCall(String callSite) {
-        return startCall(null, callSite);
-    }
-
-    public CodeTreeBuilder startCall(String receiver, String callSite) {
-        if (receiver == null) {
-            return startGroup().string(callSite).startParanthesesCommaGroup().endAfter();
-        } else {
-            return startGroup().string(receiver).string(".").string(callSite).startParanthesesCommaGroup().endAfter();
-        }
-    }
-
-    public CodeTreeBuilder startStaticCall(TypeMirror type, String methodName) {
-        return startGroup().push(CodeTreeKind.STATIC_METHOD_REFERENCE, type, methodName).startParanthesesCommaGroup().endAfter();
-    }
-
-    public CodeTreeBuilder startStaticCall(ExecutableElement method) {
-        return startStaticCall(Utils.findNearestEnclosingType(method).asType(), method.getSimpleName().toString());
-    }
-
-    public CodeTreeBuilder staticReference(TypeMirror type, String fieldName) {
-        return push(CodeTreeKind.STATIC_FIELD_REFERENCE, type, fieldName);
-    }
-
-    private CodeTreeBuilder endAndWhitespaceAfter() {
-        registerCallBack(new EndCallback() {
-
-            @Override
-            public void beforeEnd() {
-            }
-
-            @Override
-            public void afterEnd() {
-                string(" ");
-                end();
-            }
-        });
-        return this;
-    }
-
-    private CodeTreeBuilder endAfter() {
-        registerCallBack(new EndCallback() {
-
-            @Override
-            public void beforeEnd() {
-            }
-
-            @Override
-            public void afterEnd() {
-                end();
-            }
-        });
-        return this;
-    }
-
-    private CodeTreeBuilder startParanthesesCommaGroup() {
-        startGroup();
-        string("(").startCommaGroup();
-        registerCallBack(new EndCallback() {
-
-            @Override
-            public void beforeEnd() {
-            }
-
-            @Override
-            public void afterEnd() {
-                string(")");
-            }
-        });
-        endAfter();
-        return this;
-    }
-
-    private CodeTreeBuilder startCurlyBracesCommaGroup() {
-        startGroup();
-        string("{").startCommaGroup();
-        registerCallBack(new EndCallback() {
-
-            @Override
-            public void beforeEnd() {
-            }
-
-            @Override
-            public void afterEnd() {
-                string("}");
-            }
-        });
-        endAfter();
-        return this;
-    }
-
-    public CodeTreeBuilder startParantheses() {
-        startGroup();
-        string("(").startGroup();
-        registerCallBack(new EndCallback() {
-
-            @Override
-            public void beforeEnd() {
-            }
-
-            @Override
-            public void afterEnd() {
-                string(")");
-            }
-        });
-        endAfter();
-        return this;
-    }
-
-    public CodeTreeBuilder doubleQuote(String s) {
-        return startGroup().string("\"" + s + "\"").end();
-    }
-
-    public CodeTreeBuilder string(String chunk1) {
-        return push(chunk1);
-    }
-
-    public CodeTreeBuilder string(String chunk1, String chunk2) {
-        return push(GROUP).string(chunk1).string(chunk2).end();
-    }
-
-    public CodeTreeBuilder string(String chunk1, String chunk2, String chunk3) {
-        return push(GROUP).string(chunk1).string(chunk2).string(chunk3).end();
-    }
-
-    public CodeTreeBuilder string(String chunk1, String chunk2, String chunk3, String chunk4) {
-        return push(GROUP).string(chunk1).string(chunk2).string(chunk3).string(chunk4).end();
-    }
-
-    public CodeTreeBuilder tree(CodeTree treeToAdd) {
-        if (treeToAdd instanceof BuilderCodeTree) {
-            return push((BuilderCodeTree) treeToAdd).end();
-        } else {
-            BuilderCodeTree tree = new BuilderCodeTree(GROUP, null, null);
-            tree.add(treeToAdd);
-            return push(tree).end();
-        }
-    }
-
-    public CodeTreeBuilder string(String chunk1, String chunk2, String chunk3, String chunk4, String... chunks) {
-        push(GROUP).string(chunk1).string(chunk2).string(chunk3).string(chunk4);
-        for (int i = 0; i < chunks.length; i++) {
-            string(chunks[i]);
-        }
-        return end();
-    }
-
-    public CodeTreeBuilder dot() {
-        return string(".");
-    }
-
-    public CodeTreeBuilder newLine() {
-        return push(NEW_LINE);
-    }
-
-    public CodeTreeBuilder startWhile() {
-        return startGroup().string("while ").startParanthesesCommaGroup().endAndWhitespaceAfter().startGroup().endAfter();
-    }
-
-    public CodeTreeBuilder startIf() {
-        return startGroup().string("if ").startParanthesesCommaGroup().endAndWhitespaceAfter().startGroup().endAfter();
-    }
-
-    public boolean startIf(boolean elseIf) {
-        if (elseIf) {
-            startElseIf();
-        } else {
-            startIf();
-        }
-        return true;
-    }
-
-    public CodeTreeBuilder startElseIf() {
-        clearLast(CodeTreeKind.NEW_LINE);
-        return startGroup().string(" else if ").startParanthesesCommaGroup().endAndWhitespaceAfter().startGroup().endAfter();
-    }
-
-    public CodeTreeBuilder startElseBlock() {
-        clearLast(CodeTreeKind.NEW_LINE);
-        return startGroup().string(" else ").startBlock().endAfter();
-    }
-
-    private boolean clearLastRec(CodeTreeKind kind, List<CodeTree> children) {
-        for (int i = children.size() - 1; i >= 0; i--) {
-            CodeTree child = children.get(i);
-            if (child.getCodeKind() == kind) {
-                children.remove(children.get(i));
-                return true;
-            } else {
-                if (clearLastRec(kind, child.getEnclosedElements())) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    public CodeTreeBuilder startCase() {
-        startGroup().string("case ");
-        registerCallBack(new EndCallback() {
-
-            @Override
-            public void beforeEnd() {
-                string(" :").newLine();
-            }
-
-            @Override
-            public void afterEnd() {
-            }
-        });
-        return this;
-    }
-
-    public CodeTreeBuilder caseDefault() {
-        return startGroup().string("default :").newLine().end();
-    }
-
-    public CodeTreeBuilder startSwitch() {
-        return startGroup().string("switch ").startParanthesesCommaGroup().endAndWhitespaceAfter();
-    }
-
-    public CodeTreeBuilder startReturn() {
-        ExecutableElement method = findMethod();
-        if (method != null && Utils.isVoid(method.getReturnType())) {
-            startGroup();
-            registerCallBack(new EndCallback() {
-
-                @Override
-                public void beforeEnd() {
-                    string(";").newLine(); // complete statement to execute
-                }
-
-                @Override
-                public void afterEnd() {
-                    string("return").string(";").newLine(); // emit a return;
-                }
-            });
-            return this;
-        } else {
-            return startStatement().string("return ");
-        }
-    }
-
-    public CodeTreeBuilder startAssert() {
-        return startStatement().string("assert ");
-    }
-
-    public CodeTreeBuilder startNewArray(ArrayType arrayType, CodeTree size) {
-        startGroup().string("new ").type(arrayType.getComponentType()).string("[");
-        if (size != null) {
-            tree(size);
-        }
-        string("]");
-        if (size == null) {
-            string(" ");
-            startCurlyBracesCommaGroup().endAfter();
-        }
-        return this;
-    }
-
-    public CodeTreeBuilder startNew(TypeMirror uninializedNodeClass) {
-        return startGroup().string("new ").type(uninializedNodeClass).startParanthesesCommaGroup().endAfter();
-    }
-
-    public CodeTreeBuilder startNew(String typeName) {
-        return startGroup().string("new ").string(typeName).startParanthesesCommaGroup().endAfter();
-    }
-
-    public CodeTreeBuilder startIndention() {
-        return push(CodeTreeKind.INDENT);
-    }
-
-    public CodeTreeBuilder end(int times) {
-        for (int i = 0; i < times; i++) {
-            end();
-        }
-        return this;
-    }
-
-    public CodeTreeBuilder end() {
-        BuilderCodeTree tree = currentElement;
-        EndCallback callback = tree.getAtEndListener();
-        if (callback != null) {
-            callback.beforeEnd();
-            toParent();
-            callback.afterEnd();
-        } else {
-            toParent();
-        }
-        return this;
-    }
-
-    private void toParent() {
-        Element parentElement = currentElement.getEnclosingElement();
-        if (currentElement != root) {
-            this.currentElement = (BuilderCodeTree) parentElement;
-        } else {
-            this.currentElement = root;
-        }
-    }
-
-    public CodeTreeBuilder startBlock() {
-        startGroup();
-        string("{").newLine().startIndention();
-        registerCallBack(new EndCallback() {
-
-            @Override
-            public void beforeEnd() {
-            }
-
-            @Override
-            public void afterEnd() {
-                string("}").newLine();
-            }
-        });
-        endAfter();
-        return this;
-    }
-
-    private void registerCallBack(EndCallback callback) {
-        currentElement.registerAtEnd(callback);
-    }
-
-    public CodeTreeBuilder defaultDeclaration(TypeMirror type, String name) {
-        if (!Utils.isVoid(type)) {
-            startStatement();
-            type(type);
-            string(" ");
-            string(name);
-            string(" = ");
-            defaultValue(type);
-            end(); // statement
-        }
-        return this;
-    }
-
-    public CodeTreeBuilder declaration(TypeMirror type, String name, String init) {
-        return declaration(type, name, singleString(init));
-    }
-
-    public CodeTreeBuilder declaration(TypeMirror type, String name, CodeTree init) {
-        if (Utils.isVoid(type)) {
-            startStatement();
-            tree(init);
-            end();
-        } else {
-            startStatement();
-            type(type);
-            string(" ");
-            string(name);
-            if (init != null) {
-                string(" = ");
-                tree(init);
-            }
-            end(); // statement
-        }
-        return this;
-    }
-
-    public CodeTreeBuilder declaration(TypeMirror type, String name, CodeTreeBuilder init) {
-        if (init == this) {
-            throw new IllegalArgumentException("Recursive builder usage.");
-        }
-        return declaration(type, name, init.getTree());
-    }
-
-    public CodeTreeBuilder declaration(TypeMirror type, String name) {
-        return declaration(type, name, (CodeTree) null);
-    }
-
-    public CodeTreeBuilder create() {
-        return new CodeTreeBuilder(this);
-    }
-
-    public CodeTreeBuilder type(TypeMirror type) {
-        return push(type);
-    }
-
-    public CodeTreeBuilder typeLiteral(TypeMirror type) {
-        return startGroup().type(type).string(".class").end();
-    }
-
-    private void assertRoot() {
-        if (currentElement != root) {
-            throw new IllegalStateException("CodeTreeBuilder was not ended properly.");
-        }
-    }
-
-    public CodeTreeBuilder startCaseBlock() {
-        return startIndention();
-    }
-
-    public CodeTreeBuilder startThrow() {
-        return startStatement().string("throw ");
-    }
-
-    public CodeTree getTree() {
-        assertRoot();
-        return root;
-    }
-
-    public CodeTree getRoot() {
-        return root;
-    }
-
-    public CodeTreeBuilder cast(String baseClassName) {
-        string("(").string(baseClassName).string(") ");
-        return this;
-    }
-
-    public CodeTreeBuilder cast(TypeMirror type, CodeTree content) {
-        if (Utils.isVoid(type)) {
-            tree(content);
-            return this;
-        } else if (type.getKind() == TypeKind.DECLARED && Utils.getQualifiedName(type).equals("java.lang.Object")) {
-            tree(content);
-            return this;
-        } else {
-            return startGroup().string("(").type(type).string(")").string(" ").tree(content).end();
-        }
-    }
-
-    public CodeTreeBuilder startSuperCall() {
-        return string("super").startParanthesesCommaGroup();
-    }
-
-    public CodeTreeBuilder returnFalse() {
-        return startReturn().string("false").end();
-    }
-
-    public CodeTreeBuilder returnStatement() {
-        return statement("return");
-    }
-
-    public ExecutableElement findMethod() {
-        Element element = currentElement;
-        while (element != null && (element.getKind() != ElementKind.METHOD && (element.getKind() != ElementKind.CONSTRUCTOR))) {
-            element = element.getEnclosingElement();
-        }
-        ExecutableElement found = element != null ? (ExecutableElement) element : null;
-        if (found == null && parent != null) {
-            found = parent.findMethod();
-        }
-        return found;
-    }
-
-    public CodeTreeBuilder returnTrue() {
-        return startReturn().string("true").end();
-    }
-
-    public CodeTreeBuilder instanceOf(CodeTree var, CodeTree type) {
-        tree(var).string(" instanceof ").tree(type);
-        return this;
-    }
-
-    public CodeTreeBuilder instanceOf(String var, String type) {
-        return instanceOf(singleString(var), singleString(type));
-    }
-
-    public CodeTreeBuilder instanceOf(String var, TypeMirror type) {
-        TypeElement element = Utils.fromTypeMirror(type);
-        if (element == null) {
-            throw new IllegalArgumentException("Cannot call instanceof for a non supported type: " + type.getKind());
-        }
-        return instanceOf(singleString(var), singleType(type));
-    }
-
-    public CodeTreeBuilder defaultValue(TypeMirror mirror) {
-        switch (mirror.getKind()) {
-            case VOID:
-                return string("");
-            case ARRAY:
-            case DECLARED:
-            case PACKAGE:
-            case NULL:
-                return string("null");
-            case BOOLEAN:
-                return string("false");
-            case BYTE:
-                return string("(byte) 0");
-            case CHAR:
-                return string("(char) 0");
-            case DOUBLE:
-                return string("0.0D");
-            case LONG:
-                return string("0L");
-            case INT:
-                return string("0");
-            case FLOAT:
-                return string("0.0F");
-            case SHORT:
-                return string("(short) 0");
-            default:
-                throw new AssertionError();
-        }
-    }
-
-    public CodeTreeBuilder assertFalse() {
-        return startAssert().string("false").end();
-    }
-
-    public CodeTreeBuilder breakStatement() {
-        return statement("break");
-    }
-
-    public CodeTreeBuilder isNull() {
-        return string(" == null");
-    }
-
-    public CodeTreeBuilder isNotNull() {
-        return string(" != null");
-    }
-
-    public CodeTreeBuilder is(CodeTree tree) {
-        return string(" == ").tree(tree);
-    }
-
-    public CodeTreeBuilder startTryBlock() {
-        return string("try ").startBlock();
-    }
-
-    public CodeTreeBuilder startCatchBlock(TypeMirror exceptionType, String localVarName) {
-        clearLast(CodeTreeKind.NEW_LINE);
-        string(" catch (").type(exceptionType).string(" ").string(localVarName).string(") ");
-        return startBlock();
-    }
-
-    public CodeTreeBuilder startFinallyBlock() {
-        clearLast(CodeTreeKind.NEW_LINE);
-        string(" finally ");
-        return startBlock();
-    }
-
-    public CodeTreeBuilder nullLiteral() {
-        return string("null");
-    }
-
-    private static class BuilderCodeTree extends CodeTree {
-
-        private EndCallback atEndListener;
-
-        public BuilderCodeTree(CodeTreeKind kind, TypeMirror type, String string) {
-            super(kind, type, string);
-        }
-
-        public void registerAtEnd(EndCallback atEnd) {
-            if (this.atEndListener != null) {
-                this.atEndListener = new CompoundCallback(this.atEndListener, atEnd);
-            } else {
-                this.atEndListener = atEnd;
-            }
-        }
-
-        public EndCallback getAtEndListener() {
-            return atEndListener;
-        }
-
-        @Override
-        public String toString() {
-            final StringBuilder b = new StringBuilder();
-            acceptCodeElementScanner(new Printer(b), null);
-            return b.toString();
-        }
-
-        private static class CompoundCallback implements EndCallback {
-
-            private final EndCallback callback1;
-            private final EndCallback callback2;
-
-            public CompoundCallback(EndCallback callback1, EndCallback callback2) {
-                this.callback1 = callback1;
-                this.callback2 = callback2;
-            }
-
-            @Override
-            public void afterEnd() {
-                callback1.afterEnd();
-                callback2.afterEnd();
-            }
-
-            @Override
-            public void beforeEnd() {
-                callback1.beforeEnd();
-                callback1.beforeEnd();
-            }
-        }
-
-    }
-
-    private interface EndCallback {
-
-        void beforeEnd();
-
-        void afterEnd();
-    }
-
-    private static class Printer extends CodeElementScanner<Void, Void> {
-
-        private int indent;
-        private boolean newLine;
-        private final String ln = "\n";
-
-        private final StringBuilder b;
-
-        Printer(StringBuilder b) {
-            this.b = b;
-        }
-
-        @Override
-        public void visitTree(CodeTree e, Void p) {
-            switch (e.getCodeKind()) {
-                case COMMA_GROUP:
-                    List<CodeTree> children = e.getEnclosedElements();
-                    for (int i = 0; i < children.size(); i++) {
-                        children.get(i).acceptCodeElementScanner(this, p);
-                        if (i < e.getEnclosedElements().size() - 1) {
-                            b.append(", ");
-                        }
-                    }
-                    break;
-                case GROUP:
-                    super.visitTree(e, p);
-                    break;
-                case INDENT:
-                    indent();
-                    super.visitTree(e, p);
-                    dedent();
-                    break;
-                case NEW_LINE:
-                    writeLn();
-                    break;
-                case STRING:
-                    if (e.getString() != null) {
-                        write(e.getString());
-                    } else {
-                        write("null");
-                    }
-                    break;
-                case TYPE:
-                    write(Utils.getSimpleName(e.getType()));
-                    break;
-                default:
-                    assert false;
-                    return;
-            }
-        }
-
-        private void indent() {
-            indent++;
-        }
-
-        private void dedent() {
-            indent--;
-        }
-
-        private void writeLn() {
-            write(ln);
-            newLine = true;
-        }
-
-        private void write(String m) {
-            if (newLine && m != ln) {
-                writeIndent();
-                newLine = false;
-            }
-            b.append(m);
-        }
-
-        private void writeIndent() {
-            for (int i = 0; i < indent; i++) {
-                b.append("    ");
-            }
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTreeKind.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.ast;
-
-public enum CodeTreeKind {
-    STATIC_FIELD_REFERENCE, STATIC_METHOD_REFERENCE, GROUP, COMMA_GROUP, INDENT, STRING, NEW_LINE, TYPE;
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTreeVariable.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.ast;
-
-public class CodeTreeVariable extends CodeTree {
-
-    private final String name;
-
-    private CodeTree value;
-
-    public CodeTreeVariable() {
-        super(CodeTreeKind.GROUP, null, null);
-        this.name = "";
-    }
-
-    public CodeTreeVariable(String name) {
-        super(CodeTreeKind.GROUP, null, null);
-        this.name = name;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void set(CodeTree tree) {
-        if (value == tree) {
-            return;
-        }
-        if (this.value != null) {
-            remove(this.value);
-        }
-        this.value = tree;
-        add(tree);
-    }
-
-    public CodeTree get() {
-        return value;
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTypeElement.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,212 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.ast;
-
-import java.util.*;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-import javax.lang.model.util.*;
-
-import com.oracle.truffle.codegen.processor.ast.CodeTypeMirror.DeclaredCodeTypeMirror;
-
-public class CodeTypeElement extends CodeElement<Element> implements TypeElement {
-
-    private final List<? extends CodeImport> imports = parentableList(this, new ArrayList<CodeImport>());
-
-    private final PackageElement packageElement;
-
-    private final Name simpleName;
-    private final Name packageName;
-    private Name qualifiedName;
-
-    private final List<TypeMirror> implementsInterfaces = new ArrayList<>();
-    private final ElementKind kind;
-    private TypeMirror superClass;
-
-    private final DeclaredCodeTypeMirror mirror = new DeclaredCodeTypeMirror(this);
-
-    public CodeTypeElement(Set<Modifier> modifiers, ElementKind kind, PackageElement packageElement, String simpleName) {
-        super(modifiers);
-        this.kind = kind;
-        this.packageElement = packageElement;
-        this.simpleName = CodeNames.of(simpleName);
-        if (this.packageElement != null) {
-            this.packageName = packageElement.getQualifiedName();
-        } else {
-            this.packageName = CodeNames.of("default");
-        }
-        this.qualifiedName = createQualifiedName();
-    }
-
-    @Override
-    public TypeMirror asType() {
-        return mirror;
-    }
-
-    @Override
-    public ElementKind getKind() {
-        return kind;
-    }
-
-    public boolean containsField(String name) {
-        for (VariableElement field : getFields()) {
-            if (field.getSimpleName().toString().equals(name)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public NestingKind getNestingKind() {
-        return isTopLevelClass() ? NestingKind.TOP_LEVEL : NestingKind.LOCAL;
-    }
-
-    @Override
-    public Element getEnclosingElement() {
-        if (isTopLevelClass()) {
-            return packageElement;
-        } else {
-            return super.getEnclosingElement();
-        }
-    }
-
-    @Override
-    public TypeMirror getSuperclass() {
-        return superClass;
-    }
-
-    @Override
-    public List<TypeMirror> getInterfaces() {
-        return implementsInterfaces;
-    }
-
-    @Override
-    public List<? extends TypeParameterElement> getTypeParameters() {
-        return Collections.emptyList();
-    }
-
-    public boolean isTopLevelClass() {
-        return super.getEnclosingElement() instanceof CodeCompilationUnit;
-    }
-
-    public CodeVariableElement getField(String name) {
-        for (VariableElement field : ElementFilter.fieldsIn(getEnclosedElements())) {
-            if (field.getSimpleName().toString().equals(name)) {
-                return (CodeVariableElement) field;
-            }
-        }
-        return null;
-    }
-
-    private Name createQualifiedName() {
-        TypeElement enclosingType = getEnclosingClass();
-        if (enclosingType == null) {
-            return CodeNames.of(packageName + "." + simpleName);
-        } else {
-            return CodeNames.of(enclosingType.getQualifiedName() + "." + simpleName);
-        }
-    }
-
-    @Override
-    void setEnclosingElement(Element element) {
-        super.setEnclosingElement(element);
-
-        // update qualified name on container change
-        this.qualifiedName = createQualifiedName();
-    }
-
-    public Name getPackageName() {
-        return packageName;
-    }
-
-    @Override
-    public Name getQualifiedName() {
-        return qualifiedName;
-    }
-
-    @Override
-    public Name getSimpleName() {
-        return simpleName;
-    }
-
-    public void setSuperClass(TypeMirror superType) {
-        this.superClass = superType;
-    }
-
-    public List<? extends CodeImport> getImports() {
-        return imports;
-    }
-
-    public List<TypeMirror> getImplements() {
-        return implementsInterfaces;
-    }
-
-    @Override
-    public int hashCode() {
-        return getQualifiedName().hashCode();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == this) {
-            return true;
-        } else if (obj instanceof TypeElement) {
-            return getQualifiedName().equals(((TypeElement) obj).getQualifiedName());
-        }
-        return false;
-    }
-
-    public List<VariableElement> getFields() {
-        return ElementFilter.fieldsIn(getEnclosedElements());
-    }
-
-    public ExecutableElement getMethod(String name) {
-        for (Element element : getEnclosedElements()) {
-            if (element.getKind() == ElementKind.METHOD && element.getSimpleName().toString().equals(name)) {
-                return (ExecutableElement) element;
-            }
-        }
-        return null;
-    }
-
-    public List<ExecutableElement> getMethods() {
-        return ElementFilter.methodsIn(getEnclosedElements());
-    }
-
-    public List<TypeElement> getInnerClasses() {
-        return ElementFilter.typesIn(getEnclosedElements());
-    }
-
-    @Override
-    public String toString() {
-        return getQualifiedName().toString();
-    }
-
-    @Override
-    public <R, P> R accept(ElementVisitor<R, P> v, P p) {
-        return v.visitType(this, p);
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTypeMirror.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.ast;
-
-import java.lang.annotation.*;
-import java.util.*;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-
-public class CodeTypeMirror implements TypeMirror {
-
-    private final TypeKind kind;
-
-    public CodeTypeMirror(TypeKind kind) {
-        this.kind = kind;
-    }
-
-    @Override
-    public TypeKind getKind() {
-        return kind;
-    }
-
-    @Override
-    public <R, P> R accept(TypeVisitor<R, P> v, P p) {
-        throw new UnsupportedOperationException();
-    }
-
-    public static class ArrayCodeTypeMirror extends CodeTypeMirror implements ArrayType {
-
-        private final TypeMirror component;
-
-        public ArrayCodeTypeMirror(TypeMirror component) {
-            super(TypeKind.ARRAY);
-            this.component = component;
-        }
-
-        @Override
-        public TypeMirror getComponentType() {
-            return component;
-        }
-
-    }
-
-    public static class DeclaredCodeTypeMirror extends CodeTypeMirror implements DeclaredType {
-
-        private final TypeElement clazz;
-        private final List<? extends TypeMirror> typeArguments;
-
-        public DeclaredCodeTypeMirror(TypeElement clazz) {
-            this(clazz, Collections.<TypeMirror> emptyList());
-        }
-
-        public DeclaredCodeTypeMirror(TypeElement clazz, List<? extends TypeMirror> typeArguments) {
-            super(TypeKind.DECLARED);
-            this.clazz = clazz;
-            this.typeArguments = typeArguments;
-        }
-
-        @Override
-        public Element asElement() {
-            return clazz;
-        }
-
-        @Override
-        public TypeMirror getEnclosingType() {
-            return clazz.getEnclosingElement().asType();
-        }
-
-        @Override
-        public List<? extends TypeMirror> getTypeArguments() {
-            return typeArguments;
-        }
-
-        @Override
-        public String toString() {
-            return clazz.getQualifiedName().toString();
-        }
-
-    }
-
-    public List<? extends AnnotationMirror> getAnnotationMirrors() {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * @param annotationType
-     */
-    public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * @param annotationType
-     */
-    public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType) {
-        throw new UnsupportedOperationException();
-    }
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeVariableElement.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,143 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.ast;
-
-import java.util.*;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.api.element.*;
-
-public final class CodeVariableElement extends CodeElement<Element> implements WritableVariableElement {
-
-    private Name name;
-    private TypeMirror type;
-    private Object constantValue;
-
-    private CodeTree init;
-
-    public CodeVariableElement(TypeMirror type, String name) {
-        super(Utils.modifiers());
-        this.type = type;
-        this.name = CodeNames.of(name);
-    }
-
-    public CodeVariableElement(Set<Modifier> modifiers, TypeMirror type, String name) {
-        super(modifiers);
-        this.type = type;
-        this.name = CodeNames.of(name);
-    }
-
-    public CodeVariableElement(Set<Modifier> modifiers, TypeMirror type, String name, String init) {
-        this(modifiers, type, name);
-        if (init != null) {
-            this.init = new CodeTree(CodeTreeKind.STRING, null, init);
-        }
-    }
-
-    public CodeTreeBuilder createInitBuilder() {
-        CodeTreeBuilder builder = new CodeTreeBuilder(null);
-        init = builder.getTree();
-        init.setEnclosingElement(this);
-        return builder;
-    }
-
-    public void setInit(CodeTree init) {
-        this.init = init;
-    }
-
-    public CodeTree getInit() {
-        return init;
-    }
-
-    public Name getSimpleName() {
-        return name;
-    }
-
-    public TypeMirror getType() {
-        return type;
-    }
-
-    @Override
-    public TypeMirror asType() {
-        return type;
-    }
-
-    @Override
-    public ElementKind getKind() {
-        if (getEnclosingElement() instanceof ExecutableElement) {
-            return ElementKind.PARAMETER;
-        } else if (getEnclosingElement() instanceof TypeElement) {
-            return ElementKind.FIELD;
-        } else {
-            return ElementKind.PARAMETER;
-        }
-    }
-
-    public void setConstantValue(Object constantValue) {
-        this.constantValue = constantValue;
-    }
-
-    @Override
-    public Object getConstantValue() {
-        return constantValue;
-    }
-
-    public String getName() {
-        return getSimpleName().toString();
-    }
-
-    @Override
-    public void setSimpleName(Name name) {
-        this.name = name;
-    }
-
-    public void setName(String name) {
-        this.name = CodeNames.of(name);
-    }
-
-    @Override
-    public void setType(TypeMirror type) {
-        this.type = type;
-    }
-
-    @Override
-    public <R, P> R accept(ElementVisitor<R, P> v, P p) {
-        return v.visitVariable(this, p);
-    }
-
-    public static CodeVariableElement clone(VariableElement var) {
-        CodeVariableElement copy = new CodeVariableElement(var.getModifiers(), var.asType(), var.getSimpleName().toString());
-        copy.setConstantValue(var.getConstantValue());
-        for (AnnotationMirror mirror : var.getAnnotationMirrors()) {
-            copy.addAnnotationMirror(mirror);
-        }
-        for (Element element : var.getEnclosedElements()) {
-            copy.add(element);
-        }
-        return copy;
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/GeneratedElement.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.ast;
-
-import javax.lang.model.element.*;
-
-public interface GeneratedElement {
-
-    AnnotationMirror getGeneratorAnnotationMirror();
-
-    void setGeneratorAnnotationMirror(AnnotationMirror mirror);
-
-    Element getGeneratorElement();
-
-    void setGeneratorElement(Element element);
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/codewriter/AbstractCodeWriter.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,705 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.codewriter;
-
-import static com.oracle.truffle.codegen.processor.Utils.*;
-
-import java.io.*;
-import java.util.*;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-import javax.lang.model.util.*;
-
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.ast.*;
-
-public abstract class AbstractCodeWriter extends CodeElementScanner<Void, Void> {
-
-    private static final int LINE_LENGTH = 200;
-    private static final int LINE_WRAP_INDENTS = 3;
-    private static final String IDENT_STRING = "    ";
-    private static final String LN = "\n"; /* unix style */
-
-    protected Writer writer;
-    private int indent;
-    private boolean newLine;
-    private int lineLength;
-    private boolean lineWrapping = false;
-
-    private OrganizedImports imports;
-
-    public void visitCompilationUnit(CodeCompilationUnit e) {
-        for (TypeElement clazz : e.getEnclosedElements()) {
-            clazz.accept(this, null);
-        }
-    }
-
-    protected abstract Writer createWriter(CodeTypeElement clazz) throws IOException;
-
-    @Override
-    public Void visitType(CodeTypeElement e, Void p) {
-        if (e.isTopLevelClass()) {
-            Writer w = null;
-            try {
-                imports = OrganizedImports.organize(e);
-                w = new TrimTrailingSpaceWriter(createWriter(e));
-                writer = w;
-                writeRootClass(e);
-            } catch (IOException ex) {
-                throw new RuntimeException(ex);
-            } finally {
-                if (w != null) {
-                    try {
-                        w.close();
-                    } catch (Throwable e1) {
-                        // see eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=361378
-                        // TODO temporary suppress errors on close.
-                    }
-                }
-                writer = null;
-            }
-        } else {
-            writeClassImpl(e);
-        }
-        return null;
-    }
-
-    private void writeRootClass(CodeTypeElement e) {
-        writeHeader();
-        write("package ").write(e.getPackageName()).write(";").writeLn();
-        writeEmptyLn();
-
-        Set<CodeImport> generateImports = imports.generateImports();
-        List<CodeImport> typeImports = new ArrayList<>();
-        List<CodeImport> staticImports = new ArrayList<>();
-
-        for (CodeImport codeImport : generateImports) {
-            if (codeImport.isStaticImport()) {
-                staticImports.add(codeImport);
-            } else {
-                typeImports.add(codeImport);
-            }
-        }
-        Collections.sort(typeImports);
-        Collections.sort(staticImports);
-
-        for (CodeImport imp : staticImports) {
-            imp.accept(this, null);
-            writeLn();
-        }
-        if (!staticImports.isEmpty()) {
-            writeEmptyLn();
-        }
-
-        for (CodeImport imp : typeImports) {
-            imp.accept(this, null);
-            writeLn();
-        }
-        if (!typeImports.isEmpty()) {
-            writeEmptyLn();
-        }
-
-        writeClassImpl(e);
-    }
-
-    private String useImport(Element enclosedType, TypeMirror type) {
-        if (imports != null) {
-            return imports.createTypeReference(enclosedType, type);
-        } else {
-            return Utils.getSimpleName(type);
-        }
-    }
-
-    private void writeClassImpl(CodeTypeElement e) {
-        for (AnnotationMirror annotation : e.getAnnotationMirrors()) {
-            visitAnnotation(e, annotation);
-            writeLn();
-        }
-
-        writeModifiers(e.getModifiers());
-        if (e.getKind() == ElementKind.ENUM) {
-            write("enum ");
-        } else {
-            write("class ");
-        }
-        write(e.getSimpleName());
-        if (e.getSuperclass() != null && !getQualifiedName(e.getSuperclass()).equals("java.lang.Object")) {
-            write(" extends ").write(useImport(e, e.getSuperclass()));
-        }
-        if (e.getImplements().size() > 0) {
-            write(" implements ");
-            for (int i = 0; i < e.getImplements().size(); i++) {
-                write(useImport(e, e.getImplements().get(i)));
-                if (i < e.getImplements().size() - 1) {
-                    write(", ");
-                }
-            }
-        }
-
-        write(" {").writeLn();
-        writeEmptyLn();
-        indent(1);
-
-        List<VariableElement> staticFields = getStaticFields(e);
-        List<VariableElement> instanceFields = getInstanceFields(e);
-
-        for (int i = 0; i < staticFields.size(); i++) {
-            VariableElement field = staticFields.get(i);
-            field.accept(this, null);
-            if (e.getKind() == ElementKind.ENUM && i < staticFields.size() - 1) {
-                write(",");
-                writeLn();
-            } else {
-                write(";");
-                writeLn();
-            }
-        }
-
-        if (staticFields.size() > 0) {
-            writeEmptyLn();
-        }
-
-        for (VariableElement field : instanceFields) {
-            field.accept(this, null);
-            write(";");
-            writeLn();
-        }
-        if (instanceFields.size() > 0) {
-            writeEmptyLn();
-        }
-
-        for (ExecutableElement method : ElementFilter.constructorsIn(e.getEnclosedElements())) {
-            method.accept(this, null);
-        }
-
-        for (ExecutableElement method : getInstanceMethods(e)) {
-            method.accept(this, null);
-        }
-
-        for (ExecutableElement method : getStaticMethods(e)) {
-            method.accept(this, null);
-        }
-
-        for (TypeElement clazz : e.getInnerClasses()) {
-            clazz.accept(this, null);
-        }
-
-        dedent(1);
-        write("}");
-        writeEmptyLn();
-    }
-
-    private static List<VariableElement> getStaticFields(CodeTypeElement clazz) {
-        List<VariableElement> staticFields = new ArrayList<>();
-        for (VariableElement field : clazz.getFields()) {
-            if (field.getModifiers().contains(Modifier.STATIC)) {
-                staticFields.add(field);
-            }
-        }
-        return staticFields;
-    }
-
-    private static List<VariableElement> getInstanceFields(CodeTypeElement clazz) {
-        List<VariableElement> instanceFields = new ArrayList<>();
-        for (VariableElement field : clazz.getFields()) {
-            if (!field.getModifiers().contains(Modifier.STATIC)) {
-                instanceFields.add(field);
-            }
-        }
-        return instanceFields;
-    }
-
-    private static List<ExecutableElement> getStaticMethods(CodeTypeElement clazz) {
-        List<ExecutableElement> staticMethods = new ArrayList<>();
-        for (ExecutableElement method : clazz.getMethods()) {
-            if (method.getModifiers().contains(Modifier.STATIC)) {
-                staticMethods.add(method);
-            }
-        }
-        return staticMethods;
-    }
-
-    private static List<ExecutableElement> getInstanceMethods(CodeTypeElement clazz) {
-        List<ExecutableElement> instanceMethods = new ArrayList<>();
-        for (ExecutableElement method : clazz.getMethods()) {
-            if (!method.getModifiers().contains(Modifier.STATIC)) {
-                instanceMethods.add(method);
-            }
-        }
-        return instanceMethods;
-    }
-
-    @Override
-    public Void visitVariable(VariableElement f, Void p) {
-        Element parent = f.getEnclosingElement();
-
-        for (AnnotationMirror annotation : f.getAnnotationMirrors()) {
-            visitAnnotation(f, annotation);
-            write(" ");
-        }
-
-        CodeTree init = null;
-        if (f instanceof CodeVariableElement) {
-            init = ((CodeVariableElement) f).getInit();
-        }
-
-        if (parent.getKind() == ElementKind.ENUM && f.getModifiers().contains(Modifier.STATIC)) {
-            write(f.getSimpleName());
-            if (init != null) {
-                if (init != null) {
-                    write("(");
-                    init.acceptCodeElementScanner(this, p);
-                    write(")");
-                }
-            }
-        } else {
-            writeModifiers(f.getModifiers());
-            write(useImport(f, f.asType()));
-
-            if (f.getEnclosingElement().getKind() == ElementKind.METHOD) {
-                ExecutableElement method = (ExecutableElement) f.getEnclosingElement();
-                if (method.isVarArgs() && method.getParameters().indexOf(f) == method.getParameters().size() - 1) {
-                    write("...");
-                }
-            }
-
-            write(" ");
-            write(f.getSimpleName());
-            if (init != null) {
-                write(" = ");
-                init.acceptCodeElementScanner(this, p);
-            }
-        }
-        return null;
-    }
-
-    public void visitAnnotation(Element enclosedElement, AnnotationMirror e) {
-        write("@").write(useImport(enclosedElement, e.getAnnotationType()));
-
-        if (!e.getElementValues().isEmpty()) {
-            write("(");
-            final ExecutableElement defaultElement = findExecutableElement(e.getAnnotationType(), "value");
-
-            Map<? extends ExecutableElement, ? extends AnnotationValue> values = e.getElementValues();
-            if (defaultElement != null && values.size() == 1 && values.get(defaultElement) != null) {
-                visitAnnotationValue(enclosedElement, values.get(defaultElement));
-            } else {
-                Set<? extends ExecutableElement> methodsSet = values.keySet();
-                List<ExecutableElement> methodsList = new ArrayList<>();
-                for (ExecutableElement method : methodsSet) {
-                    if (values.get(method) == null) {
-                        continue;
-                    }
-                    methodsList.add(method);
-                }
-
-                Collections.sort(methodsList, new Comparator<ExecutableElement>() {
-
-                    @Override
-                    public int compare(ExecutableElement o1, ExecutableElement o2) {
-                        return o1.getSimpleName().toString().compareTo(o2.getSimpleName().toString());
-                    }
-                });
-
-                for (int i = 0; i < methodsList.size(); i++) {
-                    ExecutableElement method = methodsList.get(i);
-                    AnnotationValue value = values.get(method);
-                    write(method.getSimpleName().toString());
-                    write(" = ");
-                    visitAnnotationValue(enclosedElement, value);
-
-                    if (i < methodsList.size() - 1) {
-                        write(", ");
-                    }
-                }
-            }
-
-            write(")");
-        }
-    }
-
-    public void visitAnnotationValue(Element enclosedElement, AnnotationValue e) {
-        e.accept(new AnnotationValueWriterVisitor(enclosedElement), null);
-    }
-
-    private class AnnotationValueWriterVisitor extends AbstractAnnotationValueVisitor7<Void, Void> {
-
-        private final Element enclosedElement;
-
-        public AnnotationValueWriterVisitor(Element enclosedElement) {
-            this.enclosedElement = enclosedElement;
-        }
-
-        @Override
-        public Void visitBoolean(boolean b, Void p) {
-            write(Boolean.toString(b));
-            return null;
-        }
-
-        @Override
-        public Void visitByte(byte b, Void p) {
-            write(Byte.toString(b));
-            return null;
-        }
-
-        @Override
-        public Void visitChar(char c, Void p) {
-            write(Character.toString(c));
-            return null;
-        }
-
-        @Override
-        public Void visitDouble(double d, Void p) {
-            write(Double.toString(d));
-            return null;
-        }
-
-        @Override
-        public Void visitFloat(float f, Void p) {
-            write(Float.toString(f));
-            return null;
-        }
-
-        @Override
-        public Void visitInt(int i, Void p) {
-            write(Integer.toString(i));
-            return null;
-        }
-
-        @Override
-        public Void visitLong(long i, Void p) {
-            write(Long.toString(i));
-            return null;
-        }
-
-        @Override
-        public Void visitShort(short s, Void p) {
-            write(Short.toString(s));
-            return null;
-        }
-
-        @Override
-        public Void visitString(String s, Void p) {
-            write("\"");
-            write(s);
-            write("\"");
-            return null;
-        }
-
-        @Override
-        public Void visitType(TypeMirror t, Void p) {
-            write(useImport(enclosedElement, t));
-            write(".class");
-            return null;
-        }
-
-        @Override
-        public Void visitEnumConstant(VariableElement c, Void p) {
-            write(useImport(enclosedElement, c.asType()));
-            write(".");
-            write(c.getSimpleName().toString());
-            return null;
-        }
-
-        @Override
-        public Void visitAnnotation(AnnotationMirror a, Void p) {
-            AbstractCodeWriter.this.visitAnnotation(enclosedElement, a);
-            return null;
-        }
-
-        @Override
-        public Void visitArray(List<? extends AnnotationValue> vals, Void p) {
-            write("{");
-            for (int i = 0; i < vals.size(); i++) {
-                AnnotationValue value = vals.get(i);
-                AbstractCodeWriter.this.visitAnnotationValue(enclosedElement, value);
-                if (i < vals.size() - 1) {
-                    write(", ");
-                }
-            }
-            write("}");
-            return null;
-        }
-    }
-
-    public ExecutableElement findExecutableElement(DeclaredType type, String name) {
-        List<? extends ExecutableElement> elements = ElementFilter.methodsIn(type.asElement().getEnclosedElements());
-        for (ExecutableElement executableElement : elements) {
-            if (executableElement.getSimpleName().toString().equals(name)) {
-                return executableElement;
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public void visitImport(CodeImport e, Void p) {
-        if (e.isStaticImport()) {
-            write("import static ").write(e.getImportString()).write(";");
-        } else {
-            write("import ").write(e.getImportString()).write(";");
-        }
-    }
-
-    @Override
-    public Void visitExecutable(CodeExecutableElement e, Void p) {
-        for (AnnotationMirror annotation : e.getAnnotationMirrors()) {
-            visitAnnotation(e, annotation);
-            writeLn();
-        }
-
-        writeModifiers(e.getModifiers());
-
-        if (e.getReturnType() != null) {
-            write(useImport(e, e.getReturnType()));
-            write(" ");
-        }
-        write(e.getSimpleName());
-        write("(");
-
-        for (int i = 0; i < e.getParameters().size(); i++) {
-            VariableElement param = e.getParameters().get(i);
-            param.accept(this, p);
-            if (i < e.getParameters().size() - 1) {
-                write(", ");
-            }
-        }
-        write(")");
-
-        List<TypeMirror> throwables = e.getThrownTypes();
-        if (throwables.size() > 0) {
-            write(" throws ");
-            for (int i = 0; i < throwables.size(); i++) {
-                write(useImport(e, throwables.get(i)));
-                if (i < throwables.size() - 1) {
-                    write(", ");
-                }
-            }
-        }
-
-        if (e.getModifiers().contains(Modifier.ABSTRACT)) {
-            writeLn(";");
-        } else if (e.getBodyTree() != null) {
-            writeLn(" {");
-            indent(1);
-            e.getBodyTree().acceptCodeElementScanner(this, p);
-            dedent(1);
-            writeLn("}");
-        } else if (e.getBody() != null) {
-            write(" {");
-            write(e.getBody());
-            writeLn("}");
-        } else {
-            writeLn("{ }");
-        }
-        writeEmptyLn();
-        return null;
-    }
-
-    @Override
-    public void visitTree(CodeTree e, Void p) {
-        CodeTreeKind kind = e.getCodeKind();
-
-        switch (kind) {
-            case COMMA_GROUP:
-                List<CodeTree> children = e.getEnclosedElements();
-                for (int i = 0; i < children.size(); i++) {
-                    children.get(i).acceptCodeElementScanner(this, p);
-                    if (i < e.getEnclosedElements().size() - 1) {
-                        write(", ");
-                    }
-                }
-                break;
-            case GROUP:
-                for (CodeTree tree : e.getEnclosedElements()) {
-                    tree.acceptCodeElementScanner(this, p);
-                }
-                break;
-            case INDENT:
-                indent(1);
-                for (CodeTree tree : e.getEnclosedElements()) {
-                    tree.acceptCodeElementScanner(this, p);
-                }
-                dedent(1);
-                break;
-            case NEW_LINE:
-                writeLn();
-                break;
-            case STRING:
-                if (e.getString() != null) {
-                    write(e.getString());
-                } else {
-                    write("null");
-                }
-                break;
-            case STATIC_FIELD_REFERENCE:
-                if (e.getString() != null) {
-                    write(imports.createStaticFieldReference(e, e.getType(), e.getString()));
-                } else {
-                    write("null");
-                }
-                break;
-            case STATIC_METHOD_REFERENCE:
-                if (e.getString() != null) {
-                    write(imports.createStaticMethodReference(e, e.getType(), e.getString()));
-                } else {
-                    write("null");
-                }
-                break;
-            case TYPE:
-                write(useImport(e, e.getType()));
-                break;
-            default:
-                assert false;
-                return;
-        }
-    }
-
-    protected void writeHeader() {
-        // default implementation does nothing
-    }
-
-    private void writeModifiers(Set<Modifier> modifiers) {
-        if (modifiers != null) {
-            for (Modifier modifier : modifiers) {
-                write(modifier.toString());
-                write(" ");
-            }
-        }
-    }
-
-    protected void indent(int count) {
-        indent += count;
-    }
-
-    protected void dedent(int count) {
-        indent -= count;
-    }
-
-    protected void writeLn() {
-        writeLn("");
-    }
-
-    protected void writeLn(String text) {
-        write(text);
-        write(LN);
-        lineLength = 0;
-        newLine = true;
-        if (lineWrapping) {
-            dedent(LINE_WRAP_INDENTS);
-            lineWrapping = false;
-        }
-        lineWrapping = false;
-    }
-
-    protected void writeEmptyLn() {
-        writeLn();
-    }
-
-    private AbstractCodeWriter write(Name name) {
-        return write(name.toString());
-    }
-
-    private AbstractCodeWriter write(String m) {
-        try {
-            lineLength += m.length();
-            if (newLine && m != LN) {
-                writeIndent();
-                newLine = false;
-            }
-            if (lineLength > LINE_LENGTH && m.length() > 0) {
-                char firstChar = m.charAt(0);
-                if (Character.isAlphabetic(firstChar)) {
-                    if (!lineWrapping) {
-                        indent(LINE_WRAP_INDENTS);
-                    }
-                    lineWrapping = true;
-                    lineLength = 0;
-                    write(LN);
-                    writeIndent();
-                }
-            }
-            writer.write(m);
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-        return this;
-    }
-
-    private void writeIndent() throws IOException {
-        for (int i = 0; i < indent; i++) {
-            lineLength += IDENT_STRING.length();
-            writer.write(IDENT_STRING);
-        }
-    }
-
-    private static class TrimTrailingSpaceWriter extends Writer {
-
-        private final Writer delegate;
-        private final StringBuilder buffer = new StringBuilder();
-
-        public TrimTrailingSpaceWriter(Writer delegate) {
-            this.delegate = delegate;
-        }
-
-        @Override
-        public void close() throws IOException {
-            this.delegate.close();
-        }
-
-        @Override
-        public void flush() throws IOException {
-            this.delegate.flush();
-        }
-
-        @Override
-        public void write(char[] cbuf, int off, int len) throws IOException {
-            buffer.append(cbuf, off, len);
-            int newLinePoint = buffer.indexOf(LN);
-
-            if (newLinePoint != -1) {
-                String lhs = trimTrailing(buffer.substring(0, newLinePoint));
-                delegate.write(lhs);
-                delegate.write(LN);
-                buffer.delete(0, newLinePoint + 1);
-            }
-        }
-
-        private static String trimTrailing(String s) {
-            int cut = 0;
-            for (int i = s.length() - 1; i >= 0; i--) {
-                if (Character.isWhitespace(s.charAt(i))) {
-                    cut++;
-                } else {
-                    break;
-                }
-            }
-            if (cut > 0) {
-                return s.substring(0, s.length() - cut);
-            }
-            return s;
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/codewriter/FixWarningsVisitor.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.codewriter;
-
-import static com.oracle.truffle.codegen.processor.Utils.*;
-import static javax.lang.model.element.Modifier.*;
-
-import java.io.*;
-import java.util.*;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.ast.*;
-
-public class FixWarningsVisitor extends CodeElementScanner<Void, Void> {
-
-    private final Set<String> symbolsUsed = new HashSet<>();
-
-    private final ProcessorContext context;
-    private final DeclaredType unusedAnnotation;
-    private final DeclaredType overrideType;
-
-    public FixWarningsVisitor(ProcessorContext context, DeclaredType unusedAnnotation, DeclaredType overrideType) {
-        this.context = context;
-        this.unusedAnnotation = unusedAnnotation;
-        this.overrideType = overrideType;
-    }
-
-    @Override
-    public Void visitType(CodeTypeElement e, Void p) {
-        List<TypeElement> superTypes = Utils.getSuperTypes(e);
-        for (TypeElement type : superTypes) {
-            String qualifiedName = Utils.getQualifiedName(type);
-            if (qualifiedName.equals(Serializable.class.getCanonicalName())) {
-                if (!e.containsField("serialVersionUID")) {
-                    e.add(new CodeVariableElement(modifiers(PRIVATE, STATIC, FINAL), context.getType(long.class), "serialVersionUID", "1L"));
-                }
-                break;
-            }
-        }
-
-        return super.visitType(e, p);
-    }
-
-    @Override
-    public Void visitExecutable(CodeExecutableElement e, Void p) {
-        if (e.getParameters().isEmpty()) {
-            return null;
-        } else if (e.getModifiers().contains(Modifier.ABSTRACT)) {
-            return null;
-        } else if (containsOverride(e)) {
-            return null;
-        }
-
-        symbolsUsed.clear();
-        super.visitExecutable(e, p);
-        if (e.getBodyTree() == null && e.getBody() != null) {
-            computeSymbols(e.getBody());
-        }
-
-        for (VariableElement parameter : e.getParameters()) {
-            if (!symbolsUsed.contains(parameter.getSimpleName().toString())) {
-                e.getAnnotationMirrors().add(createUnusedAnnotationMirror());
-                break;
-            }
-        }
-        return null;
-    }
-
-    private boolean containsOverride(CodeExecutableElement e) {
-        for (AnnotationMirror mirror : e.getAnnotationMirrors()) {
-            if (Utils.typeEquals(overrideType, mirror.getAnnotationType())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private CodeAnnotationMirror createUnusedAnnotationMirror() {
-        CodeAnnotationMirror mirror = new CodeAnnotationMirror(unusedAnnotation);
-        mirror.setElementValue(mirror.findExecutableElement("value"), new CodeAnnotationValue("unused"));
-        return mirror;
-    }
-
-    @Override
-    public void visitTree(CodeTree e, Void p) {
-        if (e.getString() != null) {
-            computeSymbols(e.getString());
-        }
-        super.visitTree(e, p);
-    }
-
-    private void computeSymbols(String s) {
-        // TODO there should not be any need for a StringTokenizer if we have a real AST for
-        // method bodies. Also the current solution is not perfect. What if one token
-        // is spread across multiple CodeTree instances? But for now that works.
-        StringTokenizer tokenizer = new StringTokenizer(s, ".= :,()[];{}\"\"'' ", false);
-        while (tokenizer.hasMoreElements()) {
-            String token = tokenizer.nextToken().trim();
-            if (token.length() > 0) {
-                symbolsUsed.add(token);
-            }
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/codewriter/GenerateOverrideVisitor.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.codewriter;
-
-import static com.oracle.truffle.codegen.processor.Utils.*;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.ast.*;
-
-public class GenerateOverrideVisitor extends CodeElementScanner<Void, Void> {
-
-    private final DeclaredType overrideType;
-
-    public GenerateOverrideVisitor(DeclaredType overrideType) {
-        this.overrideType = overrideType;
-    }
-
-    @Override
-    public Void visitExecutable(CodeExecutableElement e, Void p) {
-        if (!e.getModifiers().contains(Modifier.STATIC) && !e.getModifiers().contains(Modifier.PRIVATE)) {
-            String name = e.getSimpleName().toString();
-            TypeMirror[] params = e.getParameterTypes();
-
-            for (AnnotationMirror mirror : e.getAnnotationMirrors()) {
-                if (Utils.typeEquals(overrideType, mirror.getAnnotationType())) {
-                    // already declared (may happen if method copied from super class)
-                    return super.visitExecutable(e, p);
-                }
-            }
-
-            if (isDeclaredMethodInSuperType(e.getEnclosingClass(), name, params)) {
-                e.addAnnotationMirror(new CodeAnnotationMirror(overrideType));
-            }
-        }
-        return super.visitExecutable(e, p);
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/codewriter/OrganizedImports.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,491 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.codewriter;
-
-import static com.oracle.truffle.codegen.processor.Utils.*;
-
-import java.util.*;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-import javax.lang.model.util.*;
-
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.ast.*;
-
-public final class OrganizedImports {
-
-    private final Set<TypeMirror> staticImportUsage = new HashSet<>();
-
-    private final Map<String, TypeMirror> simpleNamesUsed = new HashMap<>();
-
-    private final Set<String> declaredStaticMethods = new HashSet<>();
-    private final Set<String> declaredStaticFields = new HashSet<>();
-    private final Set<String> ambiguousStaticMethods = new HashSet<>();
-    private final Set<String> ambiguousStaticFields = new HashSet<>();
-
-    private final CodeTypeElement topLevelClass;
-
-    private OrganizedImports(CodeTypeElement topLevelClass) {
-        this.topLevelClass = topLevelClass;
-    }
-
-    public static OrganizedImports organize(CodeTypeElement topLevelClass) {
-        OrganizedImports organized = new OrganizedImports(topLevelClass);
-        organized.organizeImpl();
-        return organized;
-    }
-
-    private void organizeImpl() {
-        ImportTypeReferenceVisitor reference = new ImportTypeReferenceVisitor();
-        topLevelClass.accept(reference, null);
-
-        processStaticImports(topLevelClass);
-        List<TypeElement> types = Utils.getSuperTypes(topLevelClass);
-        for (TypeElement typeElement : types) {
-            processStaticImports(typeElement);
-        }
-
-        for (TypeMirror type : staticImportUsage) {
-            TypeElement element = fromTypeMirror(type);
-            if (element != null) {
-                // already processed by supertype
-                if (types.contains(element)) {
-                    continue;
-                }
-                processStaticImports(element);
-            }
-        }
-    }
-
-    public String createTypeReference(Element enclosedElement, TypeMirror type) {
-        switch (type.getKind()) {
-            case BOOLEAN:
-            case BYTE:
-            case CHAR:
-            case DOUBLE:
-            case FLOAT:
-            case SHORT:
-            case INT:
-            case LONG:
-            case VOID:
-                return Utils.getSimpleName(type);
-            case DECLARED:
-                return createDeclaredTypeName(enclosedElement, (DeclaredType) type);
-            case ARRAY:
-                return createTypeReference(enclosedElement, ((ArrayType) type).getComponentType()) + "[]";
-            case WILDCARD:
-                return createWildcardName(enclosedElement, (WildcardType) type);
-            case TYPEVAR:
-                return "?";
-            default:
-                throw new RuntimeException("Unknown type specified " + type.getKind() + " mirror: " + type);
-        }
-    }
-
-    public String createStaticFieldReference(Element enclosedElement, TypeMirror type, String fieldName) {
-        return createStaticReference(enclosedElement, type, fieldName, ambiguousStaticFields, declaredStaticFields);
-    }
-
-    public String createStaticMethodReference(Element enclosedElement, TypeMirror type, String methodName) {
-        return createStaticReference(enclosedElement, type, methodName, ambiguousStaticMethods, declaredStaticMethods);
-    }
-
-    private String createStaticReference(Element enclosedElement, TypeMirror type, String name, Set<String> ambiguousSymbols, Set<String> declaredSymbols) {
-        if (ambiguousSymbols.contains(name)) {
-            // ambiguous import
-            return createTypeReference(enclosedElement, type) + "." + name;
-        } else if (!declaredSymbols.contains(name)) {
-            // not imported at all
-            return createTypeReference(enclosedElement, type) + "." + name;
-        } else {
-            // import declared and not ambiguous
-            return name;
-        }
-    }
-
-    private String createWildcardName(Element enclosedElement, WildcardType type) {
-        StringBuilder b = new StringBuilder();
-        if (type.getExtendsBound() != null) {
-            b.append("? extends ").append(createTypeReference(enclosedElement, type.getExtendsBound()));
-        } else if (type.getSuperBound() != null) {
-            b.append("? super ").append(createTypeReference(enclosedElement, type.getExtendsBound()));
-        }
-        return b.toString();
-    }
-
-    private String createDeclaredTypeName(Element enclosedElement, DeclaredType type) {
-        String name = type.asElement().getSimpleName().toString();
-
-        if (needsImport(enclosedElement, type)) {
-            TypeMirror usedByType = simpleNamesUsed.get(name);
-            if (usedByType == null) {
-                simpleNamesUsed.put(name, type);
-                usedByType = type;
-            }
-
-            if (!typeEquals(type, usedByType)) {
-                name = getQualifiedName(type);
-            }
-        }
-
-        if (type.getTypeArguments().size() == 0) {
-            return name;
-        }
-
-        StringBuilder b = new StringBuilder(name);
-        b.append("<");
-        if (type.getTypeArguments().size() > 0) {
-            for (int i = 0; i < type.getTypeArguments().size(); i++) {
-                b.append(createTypeReference(enclosedElement, type.getTypeArguments().get(i)));
-                if (i < type.getTypeArguments().size() - 1) {
-                    b.append(", ");
-                }
-            }
-        }
-        b.append(">");
-        return b.toString();
-    }
-
-    public Set<CodeImport> generateImports() {
-        Set<CodeImport> imports = new HashSet<>();
-
-        imports.addAll(generateImports(simpleNamesUsed.values()));
-        imports.addAll(generateStaticImports(staticImportUsage));
-
-        return imports;
-    }
-
-    boolean processStaticImports(TypeElement element) {
-        Set<String> importedMethods = new HashSet<>();
-        List<ExecutableElement> methods = ElementFilter.methodsIn(element.getEnclosedElements());
-        for (ExecutableElement method : methods) {
-            if (method.getModifiers().contains(Modifier.STATIC)) {
-                importedMethods.add(method.getSimpleName().toString());
-            }
-        }
-
-        boolean allMethodsAmbiguous = processStaticImportElements(importedMethods, this.ambiguousStaticMethods, this.declaredStaticMethods);
-
-        Set<String> importedFields = new HashSet<>();
-        List<VariableElement> fields = ElementFilter.fieldsIn(element.getEnclosedElements());
-        for (VariableElement field : fields) {
-            if (field.getModifiers().contains(Modifier.STATIC)) {
-                importedFields.add(field.getSimpleName().toString());
-            }
-        }
-
-        boolean allFieldsAmbiguous = processStaticImportElements(importedFields, this.ambiguousStaticFields, this.declaredStaticFields);
-
-        return allMethodsAmbiguous && allFieldsAmbiguous;
-    }
-
-    private static boolean processStaticImportElements(Set<String> newElements, Set<String> ambiguousElements, Set<String> declaredElements) {
-        boolean allAmbiguous = false;
-        if (declaredElements.containsAll(newElements)) {
-            // all types already declared -> we can remove the import completely -> they will all
-            // get ambiguous
-            allAmbiguous = true;
-        }
-        Set<String> newAmbiguous = new HashSet<>();
-        Set<String> newDeclared = new HashSet<>();
-
-        for (String newElement : newElements) {
-            if (declaredElements.contains(newElement)) {
-                newAmbiguous.add(newElement);
-            } else if (ambiguousElements.contains(newElement)) {
-                // nothing to do
-            } else {
-                newDeclared.add(newElement);
-            }
-        }
-
-        ambiguousElements.addAll(newAmbiguous);
-        declaredElements.addAll(newDeclared);
-        return allAmbiguous;
-    }
-
-    private boolean needsImport(Element enclosedElement, TypeMirror importType) {
-        String importPackagName = getPackageName(importType);
-        if (importPackagName == null) {
-            return false;
-        } else if (importPackagName.equals("java.lang")) {
-            return false;
-        } else if (importPackagName.equals(getPackageName(topLevelClass)) && Utils.isTopLevelClass(importType)) {
-            return false; // same package name -> no import
-        }
-
-        List<Element> elements = Utils.getElementHierarchy(enclosedElement);
-
-        Set<String> autoImportedTypes = new HashSet<>();
-        for (Element element : elements) {
-            if (element.getKind().isClass()) {
-                collectSuperTypeImports((TypeElement) element, autoImportedTypes);
-                collectInnerTypeImports((TypeElement) element, autoImportedTypes);
-            }
-        }
-
-        String qualifiedName = getQualifiedName(importType);
-        if (autoImportedTypes.contains(qualifiedName)) {
-            return false;
-        }
-
-        return true;
-    }
-
-    private static Set<CodeImport> generateImports(Collection<TypeMirror> toGenerate) {
-        TreeSet<CodeImport> importObjects = new TreeSet<>();
-        for (TypeMirror importType : toGenerate) {
-            importObjects.add(new CodeImport(importType, getQualifiedName(importType), false));
-        }
-        return importObjects;
-    }
-
-    private static void collectInnerTypeImports(TypeElement e, Set<String> autoImportedTypes) {
-        autoImportedTypes.add(getQualifiedName(e));
-        for (TypeElement innerClass : ElementFilter.typesIn(e.getEnclosedElements())) {
-            collectInnerTypeImports(innerClass, autoImportedTypes);
-        }
-    }
-
-    private static void collectSuperTypeImports(TypeElement e, Set<String> autoImportedTypes) {
-        List<TypeElement> superTypes = getSuperTypes(e);
-        for (TypeElement superType : superTypes) {
-            List<TypeElement> declaredTypes = getDeclaredTypes(superType);
-            for (TypeElement declaredType : declaredTypes) {
-                autoImportedTypes.add(getQualifiedName(declaredType));
-            }
-        }
-    }
-
-    private Set<CodeImport> generateStaticImports(Set<TypeMirror> toGenerate) {
-        Set<String> autoImportedStaticTypes = new HashSet<>();
-
-        // if type is declared inside a super type of this class -> no import
-        autoImportedStaticTypes.add(getQualifiedName(topLevelClass));
-        autoImportedStaticTypes.addAll(getQualifiedSuperTypeNames(topLevelClass));
-
-        TreeSet<CodeImport> importObjects = new TreeSet<>();
-        for (TypeMirror importType : toGenerate) {
-            if (getPackageName(importType) == null) {
-                continue; // no package name -> no import
-            }
-
-            String qualifiedName = getQualifiedName(importType);
-            if (autoImportedStaticTypes.contains(qualifiedName)) {
-                continue;
-            }
-
-            importObjects.add(new CodeImport(importType, qualifiedName + ".*", true));
-        }
-
-        return importObjects;
-    }
-
-    private abstract static class TypeReferenceVisitor extends CodeElementScanner<Void, Void> {
-
-        @Override
-        public void visitTree(CodeTree e, Void p) {
-            if (e.getCodeKind() == CodeTreeKind.STATIC_FIELD_REFERENCE) {
-                visitStaticFieldReference(e, e.getType(), e.getString());
-            } else if (e.getCodeKind() == CodeTreeKind.STATIC_METHOD_REFERENCE) {
-                visitStaticMethodReference(e, e.getType(), e.getString());
-            } else if (e.getType() != null) {
-                visitTypeReference(e, e.getType());
-            }
-            super.visitTree(e, p);
-        }
-
-        @Override
-        public Void visitExecutable(CodeExecutableElement e, Void p) {
-            visitAnnotations(e, e.getAnnotationMirrors());
-            if (e.getReturnType() != null) {
-                visitTypeReference(e, e.getReturnType());
-            }
-            for (TypeMirror type : e.getThrownTypes()) {
-                visitTypeReference(e, type);
-            }
-            return super.visitExecutable(e, p);
-        }
-
-        @Override
-        public Void visitType(CodeTypeElement e, Void p) {
-            visitAnnotations(e, e.getAnnotationMirrors());
-
-            visitTypeReference(e, e.getSuperclass());
-            for (TypeMirror type : e.getImplements()) {
-                visitTypeReference(e, type);
-            }
-
-            return super.visitType(e, p);
-        }
-
-        private void visitAnnotations(Element enclosingElement, List<? extends AnnotationMirror> mirrors) {
-            for (AnnotationMirror mirror : mirrors) {
-                visitAnnotation(enclosingElement, mirror);
-            }
-        }
-
-        public void visitAnnotation(Element enclosingElement, AnnotationMirror e) {
-            visitTypeReference(enclosingElement, e.getAnnotationType());
-            if (!e.getElementValues().isEmpty()) {
-                Map<? extends ExecutableElement, ? extends AnnotationValue> values = e.getElementValues();
-                Set<? extends ExecutableElement> methodsSet = values.keySet();
-                List<ExecutableElement> methodsList = new ArrayList<>();
-                for (ExecutableElement method : methodsSet) {
-                    if (values.get(method) == null) {
-                        continue;
-                    }
-                    methodsList.add(method);
-                }
-
-                for (int i = 0; i < methodsList.size(); i++) {
-                    AnnotationValue value = values.get(methodsList.get(i));
-                    visitAnnotationValue(enclosingElement, value);
-                }
-            }
-        }
-
-        public void visitAnnotationValue(Element enclosingElement, AnnotationValue e) {
-            e.accept(new AnnotationValueReferenceVisitor(enclosingElement), null);
-        }
-
-        private class AnnotationValueReferenceVisitor extends AbstractAnnotationValueVisitor7<Void, Void> {
-
-            private final Element enclosingElement;
-
-            public AnnotationValueReferenceVisitor(Element enclosedElement) {
-                this.enclosingElement = enclosedElement;
-            }
-
-            @Override
-            public Void visitBoolean(boolean b, Void p) {
-                return null;
-            }
-
-            @Override
-            public Void visitByte(byte b, Void p) {
-                return null;
-            }
-
-            @Override
-            public Void visitChar(char c, Void p) {
-                return null;
-            }
-
-            @Override
-            public Void visitDouble(double d, Void p) {
-                return null;
-            }
-
-            @Override
-            public Void visitFloat(float f, Void p) {
-                return null;
-            }
-
-            @Override
-            public Void visitInt(int i, Void p) {
-                return null;
-            }
-
-            @Override
-            public Void visitLong(long i, Void p) {
-                return null;
-            }
-
-            @Override
-            public Void visitShort(short s, Void p) {
-                return null;
-            }
-
-            @Override
-            public Void visitString(String s, Void p) {
-                return null;
-            }
-
-            @Override
-            public Void visitType(TypeMirror t, Void p) {
-                visitTypeReference(enclosingElement, t);
-                return null;
-            }
-
-            @Override
-            public Void visitEnumConstant(VariableElement c, Void p) {
-                visitTypeReference(enclosingElement, c.asType());
-                return null;
-            }
-
-            @Override
-            public Void visitAnnotation(AnnotationMirror a, Void p) {
-                TypeReferenceVisitor.this.visitAnnotation(enclosingElement, a);
-                return null;
-            }
-
-            @Override
-            public Void visitArray(List<? extends AnnotationValue> vals, Void p) {
-                for (int i = 0; i < vals.size(); i++) {
-                    TypeReferenceVisitor.this.visitAnnotationValue(enclosingElement, vals.get(i));
-                }
-                return null;
-            }
-        }
-
-        @Override
-        public Void visitVariable(VariableElement f, Void p) {
-            visitAnnotations(f, f.getAnnotationMirrors());
-            visitTypeReference(f, f.asType());
-            return super.visitVariable(f, p);
-        }
-
-        @Override
-        public void visitImport(CodeImport e, Void p) {
-        }
-
-        public abstract void visitTypeReference(Element enclosedType, TypeMirror type);
-
-        public abstract void visitStaticMethodReference(Element enclosedType, TypeMirror type, String elementName);
-
-        public abstract void visitStaticFieldReference(Element enclosedType, TypeMirror type, String elementName);
-
-    }
-
-    private class ImportTypeReferenceVisitor extends TypeReferenceVisitor {
-
-        @Override
-        public void visitStaticFieldReference(Element enclosedType, TypeMirror type, String elementName) {
-            staticImportUsage.add(type);
-        }
-
-        @Override
-        public void visitStaticMethodReference(Element enclosedType, TypeMirror type, String elementName) {
-            staticImportUsage.add(type);
-        }
-
-        @Override
-        public void visitTypeReference(Element enclosedType, TypeMirror type) {
-            createTypeReference(enclosedType, type);
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/compiler/AbstractCompiler.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.compiler;
-
-import java.lang.reflect.*;
-
-public abstract class AbstractCompiler implements Compiler {
-
-    protected static Object method(Object o, String methodName) throws Exception {
-        Method method = o.getClass().getMethod(methodName);
-        method.setAccessible(true);
-        return method.invoke(o);
-    }
-
-    protected static Object method(Object o, String methodName, Class[] paramTypes, Object... values) throws Exception {
-        Method method = o.getClass().getMethod(methodName, paramTypes);
-        method.setAccessible(true);
-        return method.invoke(o, values);
-    }
-
-    protected static Object field(Object o, String fieldName) throws Exception {
-        if (o == null) {
-            return null;
-        }
-        Field field = o.getClass().getField(fieldName);
-        field.setAccessible(true);
-        return field.get(o);
-    }
-
-    protected static String parseHeader(String content) {
-        int index = content.indexOf("/*");
-        if (index == -1) {
-            return null;
-        }
-        if (!content.substring(0, index).trim().equals("")) {
-            // just whitespace before
-            return null;
-        }
-
-        int endIndex = content.indexOf("*/", index);
-        if (endIndex == -1) {
-            return null;
-        }
-        return content.substring(index, endIndex + 2);
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/compiler/Compiler.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.compiler;
-
-import javax.annotation.processing.*;
-import javax.lang.model.element.*;
-
-public interface Compiler {
-
-    String getMethodBody(ProcessingEnvironment env, ExecutableElement method);
-
-    String getHeaderComment(ProcessingEnvironment env, Element type);
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/compiler/CompilerFactory.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.compiler;
-
-import javax.lang.model.element.*;
-
-public class CompilerFactory {
-
-    private static Compiler javac;
-    private static Compiler jdt;
-
-    public static Compiler getCompiler(Element currentElement) {
-        if (JavaCCompiler.isValidElement(currentElement)) {
-            if (javac == null) {
-                javac = new JavaCCompiler();
-            }
-            return javac;
-        } else if (JDTCompiler.isValidElement(currentElement)) {
-            if (jdt == null) {
-                jdt = new JDTCompiler();
-            }
-            return jdt;
-        } else {
-            throw new UnsupportedOperationException("Unsupported compiler for element " + currentElement.getClass().getName() + ".");
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/compiler/JDTCompiler.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.compiler;
-
-import javax.annotation.processing.*;
-import javax.lang.model.element.*;
-
-import com.oracle.truffle.codegen.processor.*;
-
-public class JDTCompiler extends AbstractCompiler {
-
-    public static boolean isValidElement(Element currentElement) {
-        try {
-            Class<?> elementClass = Class.forName("org.eclipse.jdt.internal.compiler.apt.model.ElementImpl");
-            return elementClass.isAssignableFrom(currentElement.getClass());
-        } catch (ClassNotFoundException e) {
-            return false;
-        }
-    }
-
-    @Override
-    public String getMethodBody(ProcessingEnvironment env, ExecutableElement method) {
-        try {
-
-            char[] source = getSource(method);
-            if (source == null) {
-                return null;
-            }
-
-            /*
-             * AbstractMethodDeclaration decl =
-             * ((MethodBinding)(((ElementImpl)method)._binding)).sourceMethod(); int bodyStart =
-             * decl.bodyStart; int bodyEnd = decl.bodyEnd;
-             */
-            Object decl = method(field(method, "_binding"), "sourceMethod");
-            int bodyStart = (int) field(decl, "bodyStart");
-            int bodyEnd = (int) field(decl, "bodyEnd");
-
-            int length = bodyEnd - bodyStart;
-            char[] target = new char[length];
-            System.arraycopy(source, bodyStart, target, 0, length);
-
-            return new String(target);
-        } catch (Exception e) {
-            return Utils.printException(e);
-        }
-    }
-
-    private static char[] getSource(Element element) throws Exception {
-        /*
-         * Binding binding = ((ElementImpl)element)._binding; char[] source = null; if (binding
-         * instanceof MethodBinding) { source = ((MethodBinding)
-         * binding).sourceMethod().compilationResult.getCompilationUnit().getContents(); } else if
-         * (binding instanceof SourceTypeBinding) { source =
-         * ((SourceTypeBinding)binding).scope.referenceContext
-         * .compilationResult.compilationUnit.getContents(); } return source;
-         */
-
-        Object binding = field(element, "_binding");
-        Class<?> methodBindingClass = Class.forName("org.eclipse.jdt.internal.compiler.lookup.MethodBinding");
-        Class<?> referenceBindingClass = Class.forName("org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding");
-
-        char[] source = null;
-        if (methodBindingClass.isAssignableFrom(binding.getClass())) {
-            Object sourceMethod = method(binding, "sourceMethod");
-            if (sourceMethod == null) {
-                return null;
-            }
-            source = (char[]) method(method(field(sourceMethod, "compilationResult"), "getCompilationUnit"), "getContents");
-        } else if (referenceBindingClass.isAssignableFrom(binding.getClass())) {
-            source = (char[]) method(field(field(field(field(binding, "scope"), "referenceContext"), "compilationResult"), "compilationUnit"), "getContents");
-        }
-        return source;
-    }
-
-    @Override
-    public String getHeaderComment(ProcessingEnvironment env, Element type) {
-        try {
-            char[] source = getSource(type);
-            if (source == null) {
-                return null;
-            }
-            return parseHeader(new String(source));
-        } catch (Exception e) {
-            return Utils.printException(e);
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/compiler/JavaCCompiler.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.compiler;
-
-import javax.annotation.processing.*;
-import javax.lang.model.element.*;
-
-import com.oracle.truffle.codegen.processor.*;
-
-public class JavaCCompiler extends AbstractCompiler {
-
-    public static boolean isValidElement(Element currentElement) {
-        try {
-            Class<?> elementClass = Class.forName("com.sun.tools.javac.code.Symbol");
-            return elementClass.isAssignableFrom(currentElement.getClass());
-        } catch (ClassNotFoundException e) {
-            return false;
-        }
-    }
-
-    private static final Class[] getTreeAndTopLevelSignature = new Class[]{Element.class, AnnotationMirror.class, AnnotationValue.class};
-    private static final Class[] getCharContentSignature = new Class[]{boolean.class};
-
-    @Override
-    public String getMethodBody(ProcessingEnvironment env, ExecutableElement method) {
-        try {
-            /*
-             * if (false) { Pair<JCTree, JCCompilationUnit> treeAndTopLevel = ((JavacElements)
-             * env.getElementUtils()).getTreeAndTopLevel(method, null, null); JCBlock block =
-             * ((JCMethodDecl) treeAndTopLevel.fst).getBody(); int startPos = block.pos; int endPos
-             * = block.endpos; String methodBody =
-             * treeAndTopLevel.snd.getSourceFile().getCharContent(true).subSequence(startPos + 1,
-             * endPos).toString(); return methodBody; }
-             */
-
-            Object treeAndTopLevel = getTreeAndTopLevel(env, method);
-            Object block = method(field(treeAndTopLevel, "fst"), "getBody");
-            int startPos = (int) field(block, "pos");
-            int endPos = (int) field(block, "endpos");
-            return getContent(treeAndTopLevel).subSequence(startPos + 1, endPos).toString();
-        } catch (Exception e) {
-            return Utils.printException(e);
-        }
-    }
-
-    private static CharSequence getContent(Object treeAndTopLevel) throws Exception {
-        /*
-         * CharSequence content = treeAndTopLevel.snd.getSourceFile().getCharContent(true);
-         */
-        return (CharSequence) method(method(field(treeAndTopLevel, "snd"), "getSourceFile"), "getCharContent", getCharContentSignature, true);
-    }
-
-    private static Object getTreeAndTopLevel(ProcessingEnvironment env, Element element) throws Exception {
-        /*
-         * Pair<JCTree, JCCompilationUnit> treeAndTopLevel = ((JavacElements)
-         * env.getElementUtils()).getTreeAndTopLevel(method, null, null);
-         */
-        return method(method(env, "getElementUtils"), "getTreeAndTopLevel", getTreeAndTopLevelSignature, element, null, null);
-    }
-
-    @Override
-    public String getHeaderComment(ProcessingEnvironment env, Element type) {
-        try {
-            String content = getContent(getTreeAndTopLevel(env, type)).toString();
-            return parseHeader(content);
-        } catch (Exception e) {
-            return Utils.printException(e);
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/CreateCastData.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.node;
-
-import java.util.*;
-
-import com.oracle.truffle.codegen.processor.template.*;
-
-public class CreateCastData extends TemplateMethod {
-
-    private final List<String> childNames;
-
-    public CreateCastData(TemplateMethod method, List<String> childNames) {
-        super(method);
-        this.childNames = childNames;
-    }
-
-    public List<String> getChildNames() {
-        return childNames;
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/CreateCastParser.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.node;
-
-import java.lang.annotation.*;
-import java.util.*;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-
-import com.oracle.truffle.api.codegen.*;
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.template.*;
-
-public class CreateCastParser extends NodeMethodParser<CreateCastData> {
-
-    public CreateCastParser(ProcessorContext context, NodeData operation) {
-        super(context, operation);
-    }
-
-    @Override
-    public Class<? extends Annotation> getAnnotationType() {
-        return CreateCast.class;
-    }
-
-    @Override
-    public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
-        List<String> childNames = Utils.getAnnotationValueList(String.class, mirror, "value");
-        TypeMirror baseType = getContext().getTruffleTypes().getNode();
-        for (String childName : childNames) {
-            NodeChildData child = getNode().findChild(childName);
-            if (child != null) {
-                baseType = child.getOriginalType();
-                break;
-            }
-        }
-        MethodSpec spec = new MethodSpec(new InheritsParameterSpec(getContext(), "child", baseType));
-        addDefaultFieldMethodSpec(method, spec);
-        spec.addRequired(new ParameterSpec("castedChild", baseType)).setSignature(true);
-        return spec;
-    }
-
-    @Override
-    public CreateCastData create(TemplateMethod method) {
-        AnnotationMirror mirror = method.getMarkerAnnotation();
-        List<String> childNames = Utils.getAnnotationValueList(String.class, mirror, "value");
-        CreateCastData cast = new CreateCastData(method, childNames);
-        AnnotationValue value = Utils.getAnnotationValue(mirror, "value");
-        TypeMirror type = null;
-        if (childNames == null || childNames.isEmpty()) {
-            cast.addError(value, "No value specified but required.");
-            return cast;
-        }
-
-        for (String childName : childNames) {
-            NodeChildData child = getNode().findChild(childName);
-            if (child == null) {
-                // error
-                cast.addError(value, "Specified child '%s' not found.", childName);
-                continue;
-            }
-            if (type == null) {
-                type = child.getNodeType();
-            } else if (!Utils.typeEquals(type, child.getNodeType())) {
-                cast.addError(value, "All child nodes for a cast must have the same node type.");
-                continue;
-            }
-        }
-        return cast;
-    }
-
-    private static class InheritsParameterSpec extends ParameterSpec {
-
-        private final ProcessorContext context;
-
-        public InheritsParameterSpec(ProcessorContext context, String name, TypeMirror... allowedTypes) {
-            super(name, Arrays.asList(allowedTypes));
-            this.context = context;
-        }
-
-        @Override
-        public boolean matches(TypeMirror actualType) {
-            boolean found = false;
-            for (TypeMirror specType : getAllowedTypes()) {
-                if (Utils.isAssignable(context, actualType, specType)) {
-                    found = true;
-                    break;
-                }
-            }
-            return found;
-        }
-    }
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ExecutableTypeData.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.node;
-
-import javax.lang.model.element.*;
-
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.template.*;
-import com.oracle.truffle.codegen.processor.typesystem.*;
-
-public class ExecutableTypeData extends TemplateMethod {
-
-    private final TypeSystemData typeSystem;
-    private final TypeData type;
-
-    public ExecutableTypeData(TemplateMethod method, ExecutableElement executable, TypeSystemData typeSystem, TypeData type) {
-        super(method, executable);
-        this.typeSystem = typeSystem;
-        this.type = type;
-    }
-
-    public TypeData getType() {
-        return type;
-    }
-
-    public TypeSystemData getTypeSystem() {
-        return typeSystem;
-    }
-
-    public boolean hasFrame() {
-        return getMethod().getParameters().size() > 0;
-    }
-
-    public boolean hasUnexpectedValue(ProcessorContext context) {
-        return Utils.canThrowType(getMethod().getThrownTypes(), context.getTruffleTypes().getUnexpectedValueException());
-    }
-
-    public boolean isFinal() {
-        return getMethod().getModifiers().contains(Modifier.FINAL);
-    }
-
-    public boolean isAbstract() {
-        return getMethod().getModifiers().contains(Modifier.ABSTRACT);
-    }
-
-    public int getEvaluatedCount() {
-        int count = 0;
-        for (ActualParameter parameter : getParameters()) {
-            if (parameter.getSpecification().isSignature()) {
-                count++;
-            }
-        }
-        return count;
-    }
-
-    @Override
-    public int hashCode() {
-        return type.hashCode();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj instanceof ExecutableTypeData) {
-            return type.equals(((ExecutableTypeData) obj).type);
-        }
-        return super.equals(obj);
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ExecutableTypeMethodParser.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.node;
-
-import java.lang.annotation.*;
-import java.util.*;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.node.NodeChildData.Cardinality;
-import com.oracle.truffle.codegen.processor.template.*;
-import com.oracle.truffle.codegen.processor.typesystem.*;
-
-public class ExecutableTypeMethodParser extends NodeMethodParser<ExecutableTypeData> {
-
-    public ExecutableTypeMethodParser(ProcessorContext context, NodeData node) {
-        super(context, node);
-        setEmitErrors(false);
-        setParseNullOnError(false);
-    }
-
-    @Override
-    public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
-        MethodSpec spec = createDefaultMethodSpec(method, mirror, false, null);
-        List<ParameterSpec> requiredSpecs = new ArrayList<>(spec.getRequired());
-        spec.getRequired().clear();
-
-        for (ParameterSpec originalSpec : requiredSpecs) {
-            spec.addRequired(new ParameterSpec(originalSpec, Arrays.asList(getNode().getTypeSystem().getGenericType())));
-        }
-
-        spec.setVariableRequiredArguments(true);
-        ParameterSpec other = new ParameterSpec("other", Arrays.asList(getNode().getTypeSystem().getGenericType()));
-        other.setCardinality(Cardinality.MANY);
-        other.setSignature(true);
-        other.setIndexed(true);
-        spec.addRequired(other);
-        return spec;
-    }
-
-    @Override
-    public final boolean isParsable(ExecutableElement method) {
-        if (method.getModifiers().contains(Modifier.STATIC)) {
-            return false;
-        } else if (method.getModifiers().contains(Modifier.NATIVE)) {
-            return false;
-        }
-        return method.getSimpleName().toString().startsWith("execute");
-    }
-
-    @Override
-    protected List<TypeMirror> nodeTypeMirrors(NodeData nodeData) {
-        // executable types not yet available
-        List<TypeMirror> types = new ArrayList<>(nodeData.getTypeSystem().getPrimitiveTypeMirrors());
-        types.add(nodeData.getTypeSystem().getVoidType().getPrimitiveType());
-        return types;
-    }
-
-    @Override
-    public ExecutableTypeData create(TemplateMethod method) {
-        TypeData resolvedType = method.getReturnType().getTypeSystemType();
-        return new ExecutableTypeData(method, method.getMethod(), getNode().getTypeSystem(), resolvedType);
-    }
-
-    @Override
-    public Class<? extends Annotation> getAnnotationType() {
-        return null;
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/GenericParser.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.node;
-
-import java.lang.annotation.*;
-import java.util.*;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-
-import com.oracle.truffle.api.codegen.*;
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.template.*;
-
-public class GenericParser extends NodeMethodParser<SpecializationData> {
-
-    public GenericParser(ProcessorContext context, NodeData node) {
-        super(context, node);
-    }
-
-    @Override
-    public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
-        return createDefaultMethodSpec(method, mirror, true, null);
-    }
-
-    @Override
-    protected ParameterSpec createValueParameterSpec(String valueName, NodeData nodeData, int evaluatedCount) {
-        List<ExecutableTypeData> execTypes = nodeData.findGenericExecutableTypes(getContext(), evaluatedCount);
-        List<TypeMirror> types = new ArrayList<>();
-        for (ExecutableTypeData type : execTypes) {
-            types.add(type.getType().getPrimitiveType());
-        }
-        ParameterSpec spec = new ParameterSpec(valueName, types);
-        spec.setSignature(true);
-        return spec;
-    }
-
-    @Override
-    protected ParameterSpec createReturnParameterSpec() {
-        return super.createValueParameterSpec("returnValue", getNode(), 0);
-    }
-
-    @Override
-    public SpecializationData create(TemplateMethod method) {
-        SpecializationData data = new SpecializationData(method, true, false, false);
-        return data;
-    }
-
-    @Override
-    public Class<? extends Annotation> getAnnotationType() {
-        return Generic.class;
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeChildData.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,161 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.node;
-
-import java.util.*;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.template.*;
-import com.oracle.truffle.codegen.processor.typesystem.*;
-
-public class NodeChildData extends MessageContainer {
-
-    public enum Cardinality {
-        ONE, MANY;
-
-        public boolean isMany() {
-            return this == MANY;
-        }
-
-        public boolean isOne() {
-            return this == ONE;
-        }
-    }
-
-    public enum ExecutionKind {
-        DEFAULT, SHORT_CIRCUIT
-    }
-
-    private final Element sourceElement;
-    private final AnnotationMirror sourceAnnotationMirror;
-
-    private final String name;
-    private final TypeMirror type;
-    private final TypeMirror originalType;
-    private final Element accessElement;
-
-    private final Cardinality cardinality;
-    private final ExecutionKind executionKind;
-
-    private List<NodeChildData> executeWith = Collections.emptyList();
-
-    private NodeData nodeData;
-
-    public NodeChildData(Element sourceElement, AnnotationMirror sourceMirror, String name, TypeMirror nodeType, TypeMirror originalNodeType, Element accessElement, Cardinality cardinality,
-                    ExecutionKind executionKind) {
-        this.sourceElement = sourceElement;
-        this.sourceAnnotationMirror = sourceMirror;
-        this.name = name;
-        this.type = nodeType;
-        this.originalType = originalNodeType;
-        this.accessElement = accessElement;
-        this.cardinality = cardinality;
-        this.executionKind = executionKind;
-    }
-
-    public List<NodeChildData> getExecuteWith() {
-        return executeWith;
-    }
-
-    void setExecuteWith(List<NodeChildData> executeWith) {
-        this.executeWith = executeWith;
-    }
-
-    public ExecutableTypeData findExecutableType(ProcessorContext context, TypeData targetType) {
-        ExecutableTypeData executableType = nodeData.findExecutableType(targetType, getExecuteWith().size());
-        if (executableType == null) {
-            executableType = findAnyGenericExecutableType(context);
-        }
-        return executableType;
-    }
-
-    public List<ExecutableTypeData> findGenericExecutableTypes(ProcessorContext context) {
-        return nodeData.findGenericExecutableTypes(context, getExecuteWith().size());
-    }
-
-    public ExecutableTypeData findAnyGenericExecutableType(ProcessorContext context) {
-        return nodeData.findAnyGenericExecutableType(context, getExecuteWith().size());
-    }
-
-    public List<ExecutableTypeData> findExecutableTypes() {
-        return nodeData.getExecutableTypes(getExecuteWith().size());
-    }
-
-    public TypeMirror getOriginalType() {
-        return originalType;
-    }
-
-    @Override
-    public Element getMessageElement() {
-        return sourceElement;
-    }
-
-    @Override
-    public AnnotationMirror getMessageAnnotation() {
-        return sourceAnnotationMirror;
-    }
-
-    public boolean isShortCircuit() {
-        return executionKind == ExecutionKind.SHORT_CIRCUIT;
-    }
-
-    void setNode(NodeData nodeData) {
-        this.nodeData = nodeData;
-        if (nodeData != null) {
-            getMessages().addAll(nodeData.collectMessages());
-        }
-    }
-
-    public Element getAccessElement() {
-        return accessElement;
-    }
-
-    public TypeMirror getNodeType() {
-        return type;
-    }
-
-    public Cardinality getCardinality() {
-        return cardinality;
-    }
-
-    public ExecutionKind getExecutionKind() {
-        return executionKind;
-    }
-
-    public NodeData getNodeData() {
-        return nodeData;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    @Override
-    public String toString() {
-        return "NodeFieldData[name=" + getName() + ", kind=" + cardinality + ", execution=" + executionKind + ", node=" + getNodeData() + "]";
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2438 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.node;
-
-import static com.oracle.truffle.codegen.processor.Utils.*;
-import static javax.lang.model.element.Modifier.*;
-
-import java.util.*;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-import javax.lang.model.util.*;
-
-import com.oracle.truffle.api.codegen.*;
-import com.oracle.truffle.api.nodes.NodeInfo.Kind;
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.ast.*;
-import com.oracle.truffle.codegen.processor.node.NodeChildData.Cardinality;
-import com.oracle.truffle.codegen.processor.node.NodeChildData.ExecutionKind;
-import com.oracle.truffle.codegen.processor.template.*;
-import com.oracle.truffle.codegen.processor.typesystem.*;
-
-public class NodeCodeGenerator extends CompilationUnitFactory<NodeData> {
-
-    private static final String THIS_NODE_LOCAL_VAR_NAME = "thisNode";
-
-    private static final String EXECUTE_GENERIC_NAME = "executeGeneric0";
-    private static final String EXECUTE_SPECIALIZE_NAME = "executeAndSpecialize0";
-
-    public NodeCodeGenerator(ProcessorContext context) {
-        super(context);
-    }
-
-    private TypeMirror getUnexpectedValueException() {
-        return getContext().getTruffleTypes().getUnexpectedValueException();
-    }
-
-    private static String factoryClassName(NodeData node) {
-        return node.getNodeId() + "Factory";
-    }
-
-    private static String nodeSpecializationClassName(SpecializationData specialization) {
-        String nodeid = specialization.getNode().getNodeId();
-        if (nodeid.endsWith("Node") && !nodeid.equals("Node")) {
-            nodeid = nodeid.substring(0, nodeid.length() - 4);
-        }
-
-        String name = Utils.firstLetterUpperCase(nodeid);
-        name += Utils.firstLetterUpperCase(specialization.getId());
-        name += "Node";
-        return name;
-    }
-
-    private static String nodePolymorphicClassName(NodeData node, SpecializationData specialization) {
-        String nodeid = node.getNodeId();
-        if (nodeid.endsWith("Node") && !nodeid.equals("Node")) {
-            nodeid = nodeid.substring(0, nodeid.length() - 4);
-        }
-
-        String name = Utils.firstLetterUpperCase(nodeid);
-        int index = specialization == null ? 0 : node.getPolymorphicSpecializations().indexOf(specialization);
-        if (index == 0) {
-            name += "PolymorphicNode";
-        } else {
-            name += "Polymorphic" + index + "Node";
-        }
-        return name;
-    }
-
-    private static String valueNameEvaluated(ActualParameter targetParameter) {
-        return valueName(targetParameter) + "Evaluated";
-    }
-
-    private static String valueName(ActualParameter param) {
-        return param.getLocalName();
-    }
-
-    private static String castValueName(ActualParameter parameter) {
-        return valueName(parameter) + "Cast";
-    }
-
-    private void addInternalValueParameters(CodeExecutableElement method, TemplateMethod specialization, boolean forceFrame, boolean evaluated) {
-        if (forceFrame && specialization.getSpecification().findParameterSpec("frame") != null) {
-            method.addParameter(new CodeVariableElement(getContext().getTruffleTypes().getFrame(), "frameValue"));
-        }
-        for (ActualParameter parameter : specialization.getParameters()) {
-            ParameterSpec spec = parameter.getSpecification();
-            if (forceFrame && spec.getName().equals("frame")) {
-                continue;
-            }
-            if (spec.isLocal()) {
-                continue;
-            }
-
-            String name = valueName(parameter);
-            if (evaluated && spec.isSignature()) {
-                name = valueNameEvaluated(parameter);
-            }
-
-            method.addParameter(new CodeVariableElement(parameter.getType(), name));
-        }
-    }
-
-    private void addInternalValueParameterNames(CodeTreeBuilder builder, TemplateMethod source, TemplateMethod specialization, String unexpectedValueName, boolean forceFrame, boolean includeImplicit) {
-        if (forceFrame && specialization.getSpecification().findParameterSpec("frame") != null) {
-            builder.string("frameValue");
-        }
-        for (ActualParameter parameter : specialization.getParameters()) {
-            ParameterSpec spec = parameter.getSpecification();
-            if (forceFrame && spec.getName().equals("frame")) {
-                continue;
-            }
-
-            if (!includeImplicit && (parameter.isImplicit())) {
-                continue;
-            }
-            if (parameter.getSpecification().isLocal()) {
-                continue;
-            }
-
-            ActualParameter sourceParameter = source.findParameter(parameter.getLocalName());
-
-            if (unexpectedValueName != null && parameter.getLocalName().equals(unexpectedValueName)) {
-                builder.cast(parameter.getType(), CodeTreeBuilder.singleString("ex.getResult()"));
-            } else if (sourceParameter != null) {
-                builder.string(valueName(sourceParameter, parameter));
-            } else {
-                builder.string(valueName(parameter));
-            }
-        }
-    }
-
-    private String valueName(ActualParameter sourceParameter, ActualParameter targetParameter) {
-        if (sourceParameter != null) {
-            if (!sourceParameter.getSpecification().isSignature()) {
-                return valueName(targetParameter);
-            } else if (sourceParameter.getTypeSystemType() != null && targetParameter.getTypeSystemType() != null) {
-                if (sourceParameter.getTypeSystemType().needsCastTo(getContext(), targetParameter.getTypeSystemType())) {
-                    return castValueName(targetParameter);
-                }
-            }
-            return valueName(targetParameter);
-        } else {
-            return valueName(targetParameter);
-        }
-    }
-
-    private CodeTree createTemplateMethodCall(CodeTreeBuilder parent, CodeTree target, TemplateMethod sourceMethod, TemplateMethod targetMethod, String unexpectedValueName,
-                    String... customSignatureValueNames) {
-        CodeTreeBuilder builder = parent.create();
-
-        boolean castedValues = sourceMethod != targetMethod;
-
-        builder.startGroup();
-        ExecutableElement method = targetMethod.getMethod();
-        if (method == null) {
-            throw new UnsupportedOperationException();
-        }
-        TypeElement targetClass = Utils.findNearestEnclosingType(method.getEnclosingElement());
-        NodeData node = (NodeData) targetMethod.getTemplate();
-
-        if (target == null) {
-            boolean accessible = targetMethod.canBeAccessedByInstanceOf(getContext(), node.getNodeType());
-            if (accessible) {
-                if (builder.findMethod().getModifiers().contains(STATIC)) {
-                    if (method.getModifiers().contains(STATIC)) {
-                        builder.type(targetClass.asType());
-                    } else {
-                        builder.string(THIS_NODE_LOCAL_VAR_NAME);
-                    }
-                } else {
-                    if (targetMethod instanceof ExecutableTypeData) {
-                        builder.string("this");
-                    } else {
-                        builder.string("super");
-                    }
-                }
-            } else {
-                if (method.getModifiers().contains(STATIC)) {
-                    builder.type(targetClass.asType());
-                } else {
-                    ActualParameter parameter = null;
-                    for (ActualParameter searchParameter : targetMethod.getParameters()) {
-                        if (searchParameter.getSpecification().isSignature()) {
-                            parameter = searchParameter;
-                            break;
-                        }
-                    }
-                    ActualParameter sourceParameter = sourceMethod.findParameter(parameter.getLocalName());
-                    assert parameter != null;
-
-                    if (castedValues && sourceParameter != null) {
-                        builder.string(valueName(sourceParameter, parameter));
-                    } else {
-                        builder.string(valueName(parameter));
-                    }
-                }
-            }
-            builder.string(".");
-        } else {
-            builder.tree(target);
-        }
-        builder.startCall(method.getSimpleName().toString());
-
-        int signatureIndex = 0;
-
-        for (ActualParameter targetParameter : targetMethod.getParameters()) {
-            ActualParameter valueParameter = null;
-            if (sourceMethod != null) {
-                valueParameter = sourceMethod.findParameter(targetParameter.getLocalName());
-            }
-            if (valueParameter == null) {
-                valueParameter = targetParameter;
-            }
-            TypeData targetType = targetParameter.getTypeSystemType();
-
-            if (targetParameter.isImplicit() || valueParameter.isImplicit()) {
-                continue;
-            }
-
-            TypeData valueType = null;
-            if (valueParameter != null) {
-                valueType = valueParameter.getTypeSystemType();
-            }
-
-            if (signatureIndex < customSignatureValueNames.length && targetParameter.getSpecification().isSignature()) {
-                builder.string(customSignatureValueNames[signatureIndex]);
-                signatureIndex++;
-            } else if (targetParameter.getSpecification().isLocal()) {
-                builder.startGroup();
-                if (builder.findMethod().getModifiers().contains(Modifier.STATIC)) {
-                    builder.string(THIS_NODE_LOCAL_VAR_NAME).string(".");
-                } else {
-                    builder.string("this.");
-                }
-                builder.string(targetParameter.getSpecification().getName());
-                builder.end();
-            } else if (unexpectedValueName != null && targetParameter.getLocalName().equals(unexpectedValueName)) {
-                builder.string("ex.getResult()");
-            } else if (targetType == null || targetType.isGeneric() || (valueType != null && valueType.equalsType(targetType))) {
-                builder.startGroup();
-
-                if (valueType != null && sourceMethod.getMethodName().equals(targetMethod.getMethodName()) && !valueType.isGeneric() && targetType.isGeneric()) {
-                    builder.string("(");
-                    builder.type(targetType.getPrimitiveType());
-                    builder.string(") ");
-                }
-                builder.string(valueName(targetParameter));
-                builder.end();
-            } else {
-                builder.string(castValueName(targetParameter));
-            }
-        }
-
-        builder.end().end();
-
-        return builder.getRoot();
-    }
-
-    private static String baseClassName(NodeData node) {
-        String nodeid = node.getNodeId();
-        if (nodeid.endsWith("Node") && !nodeid.equals("Node")) {
-            nodeid = nodeid.substring(0, nodeid.length() - 4);
-        }
-        String name = Utils.firstLetterUpperCase(nodeid);
-        name += "BaseNode";
-        return name;
-    }
-
-    private static CodeTree createCallTypeSystemMethod(ProcessorContext context, CodeTreeBuilder parent, NodeData node, String methodName, CodeTree value) {
-        CodeTreeBuilder builder = new CodeTreeBuilder(parent);
-        startCallTypeSystemMethod(context, builder, node, methodName);
-        builder.tree(value);
-        builder.end().end();
-        return builder.getRoot();
-    }
-
-    private static void startCallTypeSystemMethod(ProcessorContext context, CodeTreeBuilder body, NodeData node, String methodName) {
-        VariableElement singleton = TypeSystemCodeGenerator.findSingleton(context, node.getTypeSystem());
-        assert singleton != null;
-
-        body.startGroup();
-        body.staticReference(singleton.getEnclosingElement().asType(), singleton.getSimpleName().toString());
-        body.string(".").startCall(methodName);
-    }
-
-    private CodeTree createGuardAndCast(CodeTreeBuilder parent, String conditionPrefix, SpecializationData sourceSpecialization, SpecializationData targetSpecialization, boolean castValues,
-                    CodeTree guardedStatements, CodeTree elseStatements, boolean emitAssumptions, boolean forceElse) {
-
-        NodeData node = targetSpecialization.getNode();
-        CodeTreeBuilder builder = new CodeTreeBuilder(parent);
-        CodeTree implicitGuards = createImplicitGuards(parent, conditionPrefix, sourceSpecialization, targetSpecialization, emitAssumptions);
-        CodeTree explicitGuards = createExplicitGuards(parent, implicitGuards == null ? conditionPrefix : null, sourceSpecialization, targetSpecialization);
-
-        Set<String> valuesNeedsCast;
-        if (castValues) {
-            // cast all
-            valuesNeedsCast = null;
-        } else {
-            // find out which values needs a cast
-            valuesNeedsCast = new HashSet<>();
-            for (GuardData guard : targetSpecialization.getGuards()) {
-                for (ActualParameter targetParameter : guard.getParameters()) {
-                    NodeChildData field = node.findChild(targetParameter.getSpecification().getName());
-                    if (field == null) {
-                        continue;
-                    }
-                    TypeData targetType = targetParameter.getTypeSystemType();
-                    ActualParameter sourceParameter = sourceSpecialization.findParameter(targetParameter.getLocalName());
-                    if (sourceParameter == null) {
-                        sourceParameter = targetParameter;
-                    }
-                    TypeData sourceType = sourceParameter.getTypeSystemType();
-
-                    if (sourceType.needsCastTo(getContext(), targetType)) {
-                        valuesNeedsCast.add(targetParameter.getLocalName());
-                    }
-                }
-            }
-        }
-
-        int ifCount = 0;
-
-        if (implicitGuards != null) {
-            builder.startIf();
-            builder.tree(implicitGuards);
-            builder.end();
-            builder.startBlock();
-            ifCount++;
-        }
-
-        builder.tree(createCasts(parent, valuesNeedsCast, sourceSpecialization, targetSpecialization));
-
-        if (explicitGuards != null) {
-            builder.startIf();
-            builder.tree(explicitGuards);
-            builder.end();
-            builder.startBlock();
-            ifCount++;
-        }
-
-        if (implicitGuards == null && explicitGuards == null && conditionPrefix != null && !conditionPrefix.isEmpty()) {
-            builder.startIf();
-            builder.string(conditionPrefix);
-            builder.end().startBlock();
-            ifCount++;
-        }
-
-        builder.tree(guardedStatements);
-
-        builder.end(ifCount);
-        if (elseStatements != null && (forceElse || ifCount > 0)) {
-            builder.tree(elseStatements);
-        }
-        return builder.getRoot();
-    }
-
-    private CodeTree createExplicitGuards(CodeTreeBuilder parent, String conditionPrefix, TemplateMethod valueSpecialization, SpecializationData guardedSpecialization) {
-        CodeTreeBuilder builder = new CodeTreeBuilder(parent);
-        String andOperator = conditionPrefix != null ? conditionPrefix + " && " : "";
-        if (guardedSpecialization.getGuards().size() > 0) {
-            // Explicitly specified guards
-            for (GuardData guard : guardedSpecialization.getGuards()) {
-                builder.string(andOperator);
-                builder.tree(createTemplateMethodCall(parent, null, valueSpecialization, guard, null));
-                andOperator = " && ";
-            }
-        }
-
-        return builder.isEmpty() ? null : builder.getRoot();
-    }
-
-    private CodeTree createCasts(CodeTreeBuilder parent, Set<String> castWhiteList, TemplateMethod valueSpecialization, SpecializationData guardedSpecialization) {
-        CodeTreeBuilder builder = new CodeTreeBuilder(parent);
-        // Implict guards based on method signature
-        for (ActualParameter guardedParam : guardedSpecialization.getParameters()) {
-            NodeChildData field = guardedSpecialization.getNode().findChild(guardedParam.getSpecification().getName());
-            if (field == null) {
-                continue;
-            }
-            ActualParameter valueParam = valueSpecialization.findParameter(guardedParam.getLocalName());
-
-            if (valueParam == null) {
-                /*
-                 * If used inside a function execute method. The value param may not exist. In that
-                 * case it assumes that the value is already converted.
-                 */
-                valueParam = guardedParam;
-            }
-
-            if (castWhiteList != null && !castWhiteList.contains(guardedParam.getLocalName())) {
-                continue;
-            }
-
-            CodeTree cast = createCast(parent, field, valueParam, guardedParam);
-            if (cast == null) {
-                continue;
-            }
-            builder.tree(cast);
-        }
-
-        return builder.getRoot();
-    }
-
-    private CodeTree createImplicitGuards(CodeTreeBuilder parent, String conditionPrefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization, boolean emitAssumptions) {
-        CodeTreeBuilder builder = new CodeTreeBuilder(parent);
-        // Implict guards based on method signature
-        String andOperator = conditionPrefix != null ? conditionPrefix + " && " : "";
-
-        if (emitAssumptions) {
-            for (String assumption : guardedSpecialization.getAssumptions()) {
-                builder.string(andOperator);
-                builder.string("this");
-                builder.string(".").string(assumption).string(".isValid()");
-                andOperator = " && ";
-            }
-        }
-
-        for (ActualParameter guardedParam : guardedSpecialization.getParameters()) {
-            NodeChildData field = guardedSpecialization.getNode().findChild(guardedParam.getSpecification().getName());
-            if (field == null) {
-                continue;
-            }
-            ActualParameter valueParam = valueSpecialization.findParameter(guardedParam.getLocalName());
-
-            if (valueParam == null) {
-                /*
-                 * If used inside a function execute method. The value param may not exist. In that
-                 * case it assumes that the value is already converted.
-                 */
-                valueParam = guardedParam;
-            }
-
-            CodeTree implicitGuard = createImplicitGuard(builder, field, valueParam, guardedParam);
-            if (implicitGuard == null) {
-                continue;
-            }
-
-            builder.string(andOperator);
-            builder.tree(implicitGuard);
-            andOperator = " && ";
-        }
-
-        return builder.isEmpty() ? null : builder.getRoot();
-    }
-
-    private CodeTree createImplicitGuard(CodeTreeBuilder parent, NodeChildData field, ActualParameter source, ActualParameter target) {
-        NodeData node = field.getNodeData();
-        CodeTreeBuilder builder = new CodeTreeBuilder(parent);
-
-        TypeData targetType = target.getTypeSystemType();
-        TypeData sourceType = source.getTypeSystemType();
-
-        if (!sourceType.needsCastTo(getContext(), targetType)) {
-            return null;
-        }
-
-        builder.startGroup();
-
-        if (field.isShortCircuit()) {
-            ActualParameter shortCircuit = target.getPreviousParameter();
-            assert shortCircuit != null;
-            builder.string("(");
-            builder.string("!").string(valueName(shortCircuit));
-            builder.string(" || ");
-        }
-
-        startCallTypeSystemMethod(getContext(), builder, node, TypeSystemCodeGenerator.isTypeMethodName(target.getTypeSystemType()));
-        builder.string(valueName(source));
-        builder.end().end(); // call
-
-        if (field.isShortCircuit()) {
-            builder.string(")");
-        }
-
-        builder.end(); // group
-
-        return builder.getRoot();
-    }
-
-    private CodeTree createCast(CodeTreeBuilder parent, NodeChildData field, ActualParameter source, ActualParameter target) {
-        NodeData node = field.getNodeData();
-        TypeData sourceType = source.getTypeSystemType();
-        TypeData targetType = target.getTypeSystemType();
-
-        if (!sourceType.needsCastTo(getContext(), targetType)) {
-            return null;
-        }
-
-        CodeTree condition = null;
-        if (field.isShortCircuit()) {
-            ActualParameter shortCircuit = target.getPreviousParameter();
-            assert shortCircuit != null;
-            condition = CodeTreeBuilder.singleString(valueName(shortCircuit));
-        }
-
-        CodeTree value = createCallTypeSystemMethod(context, parent, node, TypeSystemCodeGenerator.asTypeMethodName(targetType), CodeTreeBuilder.singleString(valueName(target)));
-
-        return createLazyAssignment(parent, castValueName(target), target.getType(), condition, value);
-    }
-
-    /**
-     * <pre>
-     * variant1 $condition != null
-     * 
-     * $type $name = defaultValue($type);
-     * if ($condition) {
-     *     $name = $value;
-     * }
-     * 
-     * variant2 $condition != null
-     * $type $name = $value;
-     * </pre>
-     * 
-     * .
-     */
-    private static CodeTree createLazyAssignment(CodeTreeBuilder parent, String name, TypeMirror type, CodeTree condition, CodeTree value) {
-        CodeTreeBuilder builder = new CodeTreeBuilder(parent);
-        if (condition == null) {
-            builder.declaration(type, name, value);
-        } else {
-            builder.declaration(type, name, new CodeTreeBuilder(parent).defaultValue(type).getRoot());
-
-            builder.startIf().tree(condition).end();
-            builder.startBlock();
-            builder.startStatement();
-            builder.string(name);
-            builder.string(" = ");
-            builder.tree(value);
-            builder.end(); // statement
-            builder.end(); // block
-        }
-        return builder.getRoot();
-    }
-
-    protected void emitEncounteredSynthetic(CodeTreeBuilder builder, TemplateMethod current) {
-        builder.startThrow().startNew(getContext().getType(UnsupportedOperationException.class));
-        builder.startCall("createInfo0");
-        builder.doubleQuote("Unsupported values");
-        addInternalValueParameterNames(builder, current, current, null, false, true);
-        builder.end().end().end();
-    }
-
-    private static List<ExecutableElement> findUserConstructors(TypeMirror nodeType) {
-        List<ExecutableElement> constructors = new ArrayList<>();
-        for (ExecutableElement constructor : ElementFilter.constructorsIn(Utils.fromTypeMirror(nodeType).getEnclosedElements())) {
-            if (constructor.getModifiers().contains(PRIVATE)) {
-                continue;
-            }
-            if (isCopyConstructor(constructor)) {
-                continue;
-            }
-            constructors.add(constructor);
-        }
-
-        if (constructors.isEmpty()) {
-            constructors.add(new CodeExecutableElement(null, Utils.getSimpleName(nodeType)));
-        }
-
-        return constructors;
-    }
-
-    private static ExecutableElement findCopyConstructor(TypeMirror type) {
-        for (ExecutableElement constructor : ElementFilter.constructorsIn(Utils.fromTypeMirror(type).getEnclosedElements())) {
-            if (constructor.getModifiers().contains(PRIVATE)) {
-                continue;
-            }
-            if (isCopyConstructor(constructor)) {
-                return constructor;
-            }
-        }
-
-        return null;
-    }
-
-    private static boolean isCopyConstructor(ExecutableElement element) {
-        if (element.getParameters().size() != 1) {
-            return false;
-        }
-        VariableElement var = element.getParameters().get(0);
-        TypeElement type = Utils.findNearestEnclosingType(var);
-
-        if (!Utils.typeEquals(var.asType(), type.asType())) {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    protected void createChildren(NodeData node) {
-        Map<NodeData, List<TypeElement>> childTypes = new LinkedHashMap<>();
-        if (node.getDeclaredNodes() != null && !node.getDeclaredNodes().isEmpty()) {
-            for (NodeData nodeChild : node.getDeclaredNodes()) {
-                NodeCodeGenerator generator = new NodeCodeGenerator(getContext());
-                childTypes.put(nodeChild, generator.process(null, nodeChild).getEnclosedElements());
-            }
-        }
-
-        if (node.needsFactory() || node.getNodeDeclaringChildren().size() > 0) {
-            add(new NodeFactoryFactory(context, childTypes), node);
-        }
-    }
-
-    private class NodeFactoryFactory extends ClassElementFactory<NodeData> {
-
-        private final Map<NodeData, List<TypeElement>> childTypes;
-
-        private CodeTypeElement generatedNode;
-
-        public NodeFactoryFactory(ProcessorContext context, Map<NodeData, List<TypeElement>> childElements) {
-            super(context);
-            this.childTypes = childElements;
-        }
-
-        @Override
-        protected CodeTypeElement create(NodeData node) {
-            Modifier visibility = Utils.getVisibility(node.getTemplateType().getModifiers());
-            CodeTypeElement clazz = createClass(node, modifiers(), factoryClassName(node), null, false);
-            if (visibility != null) {
-                clazz.getModifiers().add(visibility);
-            }
-            clazz.getModifiers().add(Modifier.FINAL);
-            clazz.add(createConstructorUsingFields(modifiers(PRIVATE), clazz));
-            return clazz;
-        }
-
-        @Override
-        protected void createChildren(NodeData node) {
-            CodeTypeElement clazz = getElement();
-
-            Modifier createVisibility = Utils.getVisibility(clazz.getModifiers());
-
-            if (node.needsFactory()) {
-                NodeBaseFactory factory = new NodeBaseFactory(context);
-                add(factory, node.getGenericSpecialization() == null ? node.getSpecializations().get(0) : node.getGenericSpecialization());
-                generatedNode = factory.getElement();
-
-                if (node.needsRewrites(context)) {
-                    clazz.add(createCreateGenericMethod(node, createVisibility));
-                }
-
-                createFactoryMethods(node, clazz, createVisibility);
-
-                PolymorphicNodeFactory generic = null;
-                for (SpecializationData specialization : node.getPolymorphicSpecializations()) {
-                    PolymorphicNodeFactory polymorphicFactory = new PolymorphicNodeFactory(context, generic == null ? generatedNode : generic.getElement(), generic == null);
-                    add(polymorphicFactory, specialization);
-                    if (generic == null) {
-                        generic = polymorphicFactory;
-                    }
-                }
-
-                for (SpecializationData specialization : node.getSpecializations()) {
-                    if (!specialization.isReachable()) {
-                        continue;
-                    }
-                    add(new SpecializedNodeFactory(context, generatedNode), specialization);
-                }
-
-                TypeMirror nodeFactory = Utils.getDeclaredType(Utils.fromTypeMirror(getContext().getType(NodeFactory.class)), node.getNodeType());
-                clazz.getImplements().add(nodeFactory);
-                clazz.add(createCreateNodeMethod(node));
-                clazz.add(createCreateNodeGenericMethod(node));
-                clazz.add(createGetNodeClassMethod(node));
-                clazz.add(createGetNodeSignaturesMethod());
-                clazz.add(createGetChildrenSignatureMethod(node));
-                clazz.add(createGetInstanceMethod(node, createVisibility));
-                clazz.add(createInstanceConstant(node, clazz.asType()));
-            }
-
-            for (NodeData childNode : childTypes.keySet()) {
-                if (childNode.getTemplateType().getModifiers().contains(Modifier.PRIVATE)) {
-                    continue;
-                }
-
-                for (TypeElement type : childTypes.get(childNode)) {
-                    Set<Modifier> typeModifiers = ((CodeTypeElement) type).getModifiers();
-                    Modifier visibility = Utils.getVisibility(type.getModifiers());
-                    typeModifiers.clear();
-                    if (visibility != null) {
-                        typeModifiers.add(visibility);
-                    }
-
-                    typeModifiers.add(Modifier.STATIC);
-                    typeModifiers.add(Modifier.FINAL);
-                    clazz.add(type);
-                }
-            }
-
-            List<NodeData> children = node.getNodeDeclaringChildren();
-            if (node.getParent() == null && children.size() > 0) {
-                clazz.add(createGetFactories(node));
-            }
-
-        }
-
-        private CodeExecutableElement createGetNodeClassMethod(NodeData node) {
-            TypeMirror returnType = Utils.getDeclaredType(Utils.fromTypeMirror(getContext().getType(Class.class)), node.getNodeType());
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), returnType, "getNodeClass");
-            CodeTreeBuilder builder = method.createBuilder();
-            builder.startReturn().typeLiteral(node.getNodeType()).end();
-            return method;
-        }
-
-        private CodeExecutableElement createGetNodeSignaturesMethod() {
-            TypeElement listType = Utils.fromTypeMirror(getContext().getType(List.class));
-            TypeMirror classType = getContext().getType(Class.class);
-            TypeMirror returnType = Utils.getDeclaredType(listType, Utils.getDeclaredType(listType, classType));
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), returnType, "getNodeSignatures");
-            CodeTreeBuilder builder = method.createBuilder();
-            builder.startReturn();
-            builder.startStaticCall(getContext().getType(Arrays.class), "asList");
-            List<ExecutableElement> constructors = findUserConstructors(generatedNode.asType());
-            for (ExecutableElement constructor : constructors) {
-                builder.tree(createAsList(builder, Utils.asTypeMirrors(constructor.getParameters()), classType));
-            }
-            builder.end();
-            builder.end();
-            return method;
-        }
-
-        private CodeExecutableElement createGetChildrenSignatureMethod(NodeData node) {
-            Types types = getContext().getEnvironment().getTypeUtils();
-            TypeElement listType = Utils.fromTypeMirror(getContext().getType(List.class));
-            TypeMirror classType = getContext().getType(Class.class);
-            TypeMirror nodeType = getContext().getTruffleTypes().getNode();
-            TypeMirror wildcardNodeType = types.getWildcardType(nodeType, null);
-            classType = Utils.getDeclaredType(Utils.fromTypeMirror(classType), wildcardNodeType);
-            TypeMirror returnType = Utils.getDeclaredType(listType, classType);
-
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), returnType, "getExecutionSignature");
-            CodeTreeBuilder builder = method.createBuilder();
-
-            List<TypeMirror> signatureTypes = new ArrayList<>();
-            assert !node.getSpecializations().isEmpty();
-            SpecializationData data = node.getSpecializations().get(0);
-            for (ActualParameter parameter : data.getParameters()) {
-                ParameterSpec spec = parameter.getSpecification();
-                NodeChildData field = node.findChild(spec.getName());
-                if (field == null) {
-                    continue;
-                }
-
-                TypeMirror type;
-                if (field.getCardinality() == Cardinality.MANY && field.getNodeType().getKind() == TypeKind.ARRAY) {
-                    type = ((ArrayType) field.getNodeType()).getComponentType();
-                } else {
-                    type = field.getNodeType();
-                }
-
-                signatureTypes.add(type);
-            }
-
-            builder.startReturn().tree(createAsList(builder, signatureTypes, classType)).end();
-            return method;
-        }
-
-        private CodeTree createAsList(CodeTreeBuilder parent, List<TypeMirror> types, TypeMirror elementClass) {
-            CodeTreeBuilder builder = parent.create();
-            builder.startGroup();
-            builder.type(getContext().getType(Arrays.class));
-            builder.string(".<").type(elementClass).string(">");
-            builder.startCall("asList");
-            for (TypeMirror typeMirror : types) {
-                builder.typeLiteral(typeMirror);
-            }
-            builder.end().end();
-            return builder.getRoot();
-        }
-
-        private CodeExecutableElement createCreateNodeMethod(NodeData node) {
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), node.getNodeType(), "createNode");
-            CodeVariableElement arguments = new CodeVariableElement(getContext().getType(Object.class), "arguments");
-            method.setVarArgs(true);
-            method.addParameter(arguments);
-
-            CodeTreeBuilder builder = method.createBuilder();
-            List<ExecutableElement> signatures = findUserConstructors(generatedNode.asType());
-            boolean ifStarted = false;
-
-            for (ExecutableElement element : signatures) {
-                ifStarted = builder.startIf(ifStarted);
-                builder.string("arguments.length == " + element.getParameters().size());
-
-                int index = 0;
-                for (VariableElement param : element.getParameters()) {
-                    builder.string(" && ");
-                    if (!param.asType().getKind().isPrimitive()) {
-                        builder.string("(arguments[" + index + "] == null || ");
-                    }
-                    builder.string("arguments[" + index + "] instanceof ");
-                    builder.type(Utils.boxType(getContext(), param.asType()));
-                    if (!param.asType().getKind().isPrimitive()) {
-                        builder.string(")");
-                    }
-                    index++;
-                }
-                builder.end();
-                builder.startBlock();
-
-                builder.startReturn().startCall("create");
-                index = 0;
-                for (VariableElement param : element.getParameters()) {
-                    builder.startGroup();
-                    builder.string("(").type(param.asType()).string(") ");
-                    builder.string("arguments[").string(String.valueOf(index)).string("]");
-                    builder.end();
-                    index++;
-                }
-                builder.end().end();
-
-                builder.end(); // block
-            }
-
-            builder.startElseBlock();
-            builder.startThrow().startNew(getContext().getType(IllegalArgumentException.class));
-            builder.doubleQuote("Invalid create signature.");
-            builder.end().end();
-            builder.end(); // else block
-            return method;
-        }
-
-        private CodeExecutableElement createCreateNodeGenericMethod(NodeData node) {
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), node.getNodeType(), "createNodeGeneric");
-            CodeVariableElement nodeParam = new CodeVariableElement(node.getNodeType(), THIS_NODE_LOCAL_VAR_NAME);
-            method.addParameter(nodeParam);
-
-            CodeTreeBuilder builder = method.createBuilder();
-            if (!node.needsRewrites(getContext())) {
-                builder.startThrow().startNew(getContext().getType(UnsupportedOperationException.class)).doubleQuote("No specialized version.").end().end();
-            } else {
-                builder.startReturn().startCall("createGeneric");
-                builder.string(THIS_NODE_LOCAL_VAR_NAME);
-                builder.end().end();
-            }
-            return method;
-        }
-
-        private ExecutableElement createGetInstanceMethod(NodeData node, Modifier visibility) {
-            TypeElement nodeFactoryType = Utils.fromTypeMirror(getContext().getType(NodeFactory.class));
-            TypeMirror returnType = Utils.getDeclaredType(nodeFactoryType, node.getNodeType());
-
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(), returnType, "getInstance");
-            if (visibility != null) {
-                method.getModifiers().add(visibility);
-            }
-            method.getModifiers().add(Modifier.STATIC);
-
-            String varName = instanceVarName(node);
-
-            CodeTreeBuilder builder = method.createBuilder();
-            builder.startIf();
-            builder.string(varName).string(" == null");
-            builder.end().startBlock();
-
-            builder.startStatement();
-            builder.string(varName);
-            builder.string(" = ");
-            builder.startNew(factoryClassName(node)).end();
-            builder.end();
-
-            builder.end();
-            builder.startReturn().string(varName).end();
-            return method;
-        }
-
-        private String instanceVarName(NodeData node) {
-            if (node.getParent() != null) {
-                return Utils.firstLetterLowerCase(factoryClassName(node)) + "Instance";
-            } else {
-                return "instance";
-            }
-        }
-
-        private CodeVariableElement createInstanceConstant(NodeData node, TypeMirror factoryType) {
-            String varName = instanceVarName(node);
-            CodeVariableElement var = new CodeVariableElement(modifiers(), factoryType, varName);
-            var.getModifiers().add(Modifier.PRIVATE);
-            var.getModifiers().add(Modifier.STATIC);
-            return var;
-        }
-
-        private ExecutableElement createGetFactories(NodeData node) {
-            List<NodeData> children = node.getNodeDeclaringChildren();
-            if (node.needsFactory()) {
-                children.add(node);
-            }
-
-            List<TypeMirror> nodeTypesList = new ArrayList<>();
-            TypeMirror prev = null;
-            boolean allSame = true;
-            for (NodeData child : children) {
-                nodeTypesList.add(child.getNodeType());
-                if (prev != null && !Utils.typeEquals(child.getNodeType(), prev)) {
-                    allSame = false;
-                }
-                prev = child.getNodeType();
-            }
-            TypeMirror commonNodeSuperType = Utils.getCommonSuperType(getContext(), nodeTypesList.toArray(new TypeMirror[nodeTypesList.size()]));
-
-            Types types = getContext().getEnvironment().getTypeUtils();
-            TypeMirror factoryType = getContext().getType(NodeFactory.class);
-            TypeMirror baseType;
-            if (allSame) {
-                baseType = Utils.getDeclaredType(Utils.fromTypeMirror(factoryType), commonNodeSuperType);
-            } else {
-                baseType = Utils.getDeclaredType(Utils.fromTypeMirror(factoryType), types.getWildcardType(commonNodeSuperType, null));
-            }
-            TypeMirror listType = Utils.getDeclaredType(Utils.fromTypeMirror(getContext().getType(List.class)), baseType);
-
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, STATIC), listType, "getFactories");
-
-            CodeTreeBuilder builder = method.createBuilder();
-            builder.startReturn();
-            builder.startStaticCall(getContext().getType(Arrays.class), "asList");
-
-            for (NodeData child : children) {
-                builder.startGroup();
-                NodeData childNode = child;
-                List<NodeData> factories = new ArrayList<>();
-                while (childNode.getParent() != null) {
-                    factories.add(childNode);
-                    childNode = childNode.getParent();
-                }
-                Collections.reverse(factories);
-                for (NodeData nodeData : factories) {
-                    builder.string(factoryClassName(nodeData)).string(".");
-                }
-                builder.string("getInstance()");
-                builder.end();
-            }
-            builder.end();
-            builder.end();
-            return method;
-        }
-
-        private void createFactoryMethods(NodeData node, CodeTypeElement clazz, Modifier createVisibility) {
-            List<ExecutableElement> constructors = findUserConstructors(generatedNode.asType());
-            for (ExecutableElement constructor : constructors) {
-                clazz.add(createCreateMethod(node, createVisibility, constructor));
-            }
-        }
-
-        private CodeExecutableElement createCreateMethod(NodeData node, Modifier visibility, ExecutableElement constructor) {
-            CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), constructor);
-            method.setSimpleName(CodeNames.of("create"));
-            method.getModifiers().clear();
-            if (visibility != null) {
-                method.getModifiers().add(visibility);
-            }
-            method.getModifiers().add(Modifier.STATIC);
-            method.setReturnType(node.getNodeType());
-
-            CodeTreeBuilder body = method.createBuilder();
-            body.startReturn();
-            if (node.getSpecializations().isEmpty()) {
-                body.nullLiteral();
-            } else {
-                body.startNew(nodeSpecializationClassName(node.getSpecializations().get(0)));
-                for (VariableElement var : method.getParameters()) {
-                    body.string(var.getSimpleName().toString());
-                }
-                body.end();
-            }
-            body.end();
-            return method;
-        }
-
-        private CodeExecutableElement createCreateGenericMethod(NodeData node, Modifier visibility) {
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(), node.getNodeType(), "createGeneric");
-            if (visibility != null) {
-                method.getModifiers().add(visibility);
-            }
-            method.getModifiers().add(Modifier.STATIC);
-            method.addParameter(new CodeVariableElement(node.getNodeType(), THIS_NODE_LOCAL_VAR_NAME));
-
-            CodeTreeBuilder body = method.createBuilder();
-
-            SpecializationData found = null;
-            List<SpecializationData> specializations = node.getSpecializations();
-            for (int i = 0; i < specializations.size(); i++) {
-                if (specializations.get(i).isReachable()) {
-                    found = specializations.get(i);
-                }
-            }
-
-            if (found == null) {
-                body.startThrow().startNew(getContext().getType(UnsupportedOperationException.class)).end().end();
-            } else {
-                body.startReturn().startNew(nodeSpecializationClassName(found)).startGroup().cast(baseClassName(node)).string(THIS_NODE_LOCAL_VAR_NAME).end().end().end();
-            }
-            return method;
-        }
-    }
-
-    private class NodeBaseFactory extends ClassElementFactory<SpecializationData> {
-
-        public NodeBaseFactory(ProcessorContext context) {
-            super(context);
-        }
-
-        @Override
-        protected CodeTypeElement create(SpecializationData specialization) {
-            NodeData node = specialization.getNode();
-            CodeTypeElement clazz = createClass(node, modifiers(PRIVATE, ABSTRACT, STATIC), baseClassName(node), node.getNodeType(), false);
-
-            for (NodeChildData child : node.getChildren()) {
-                clazz.add(createChildField(child));
-
-                if (child.getAccessElement() != null && child.getAccessElement().getModifiers().contains(Modifier.ABSTRACT)) {
-                    ExecutableElement getter = (ExecutableElement) child.getAccessElement();
-                    CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), getter);
-                    method.getModifiers().remove(Modifier.ABSTRACT);
-                    method.createBuilder().startReturn().string("this.").string(child.getName()).end();
-                    clazz.add(method);
-                }
-            }
-
-            for (String assumption : node.getAssumptions()) {
-                clazz.add(createAssumptionField(assumption));
-            }
-
-            createConstructors(node, clazz);
-
-            return clazz;
-        }
-
-        protected String typeGetterName(ActualParameter parameter) {
-            return "get" + Utils.firstLetterUpperCase(parameter.getLocalName()) + "Type";
-        }
-
-        @Override
-        protected void createChildren(SpecializationData specialization) {
-            NodeData node = specialization.getNode();
-            CodeTypeElement clazz = getElement();
-
-            if (node.needsRewrites(context)) {
-
-                if (node.getPolymorphicDepth() > 1) {
-
-                    CodeVariableElement var = new CodeVariableElement(modifiers(PROTECTED), clazz.asType(), "next0");
-                    var.getAnnotationMirrors().add(new CodeAnnotationMirror(getContext().getTruffleTypes().getChildAnnotation()));
-                    clazz.add(var);
-
-                    CodeExecutableElement setter = new CodeExecutableElement(modifiers(PROTECTED), context.getType(void.class), "setNext0");
-                    setter.getParameters().add(new CodeVariableElement(clazz.asType(), "next0"));
-                    CodeTreeBuilder builder = setter.createBuilder();
-                    builder.statement("this.next0 = adoptChild(next0)");
-                    clazz.add(setter);
-
-                    createTypeGetters(clazz, node.getGenericSpecialization());
-
-                    clazz.add(createCreateSpecialization(node));
-
-                    CodeExecutableElement genericCachedExecute = null;
-                    for (SpecializationData polymorph : node.getPolymorphicSpecializations()) {
-                        CodeExecutableElement cachedExecute = createCachedExecute(node, polymorph, genericCachedExecute);
-                        clazz.add(cachedExecute);
-                        if (genericCachedExecute == null) {
-                            genericCachedExecute = cachedExecute;
-                        }
-                    }
-                }
-
-                clazz.add(createGenericExecuteAndSpecialize(node));
-                clazz.add(createInfoMessage(node));
-            }
-
-            if (node.getGenericSpecialization() != null && node.getGenericSpecialization().isReachable()) {
-                clazz.add(createGenericExecute(node));
-            }
-        }
-
-        private Element createInfoMessage(NodeData node) {
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, STATIC), getContext().getType(String.class), "createInfo0");
-            method.addParameter(new CodeVariableElement(getContext().getType(String.class), "message"));
-            addInternalValueParameters(method, node.getGenericSpecialization(), false, false);
-
-            CodeTreeBuilder builder = method.createBuilder();
-            builder.startStatement().string("StringBuilder builder = new StringBuilder(message)").end();
-            builder.startStatement().startCall("builder", "append").doubleQuote(" (").end().end();
-
-            String sep = null;
-            for (ActualParameter parameter : node.getGenericSpecialization().getParameters()) {
-                if (!parameter.getSpecification().isSignature()) {
-                    continue;
-                }
-
-                builder.startStatement();
-                builder.string("builder");
-                if (sep != null) {
-                    builder.startCall(".append").doubleQuote(sep).end();
-                }
-                builder.startCall(".append").doubleQuote(parameter.getLocalName()).end();
-                builder.startCall(".append").doubleQuote(" = ").end();
-                builder.startCall(".append").string(parameter.getLocalName()).end();
-                builder.end();
-
-                if (!Utils.isPrimitive(parameter.getType())) {
-                    builder.startIf().string(parameter.getLocalName() + " != null").end();
-                    builder.startBlock();
-                }
-                builder.startStatement();
-                if (Utils.isPrimitive(parameter.getType())) {
-                    builder.startCall("builder.append").doubleQuote(" (" + Utils.getSimpleName(parameter.getType()) + ")").end();
-                } else {
-                    builder.startCall("builder.append").doubleQuote(" (").end();
-                    builder.startCall(".append").string(parameter.getLocalName() + ".getClass().getSimpleName()").end();
-                    builder.startCall(".append").doubleQuote(")").end();
-                }
-                builder.end();
-                if (!Utils.isPrimitive(parameter.getType())) {
-                    builder.end();
-                }
-
-                sep = ", ";
-            }
-
-            builder.startStatement().startCall("builder", "append").doubleQuote(")").end().end();
-
-            builder.startReturn().string("builder.toString()").end();
-
-            return method;
-        }
-
-        protected void createTypeGetters(CodeTypeElement clazz, SpecializationData specialization) {
-            for (ActualParameter parameter : specialization.getReturnTypeAndParameters()) {
-                if (!parameter.getSpecification().isSignature()) {
-                    continue;
-                }
-                CodeExecutableElement typeGetter = new CodeExecutableElement(modifiers(PROTECTED), context.getType(Class.class), typeGetterName(parameter));
-                CodeTreeBuilder builder = typeGetter.createBuilder();
-                builder.startReturn().typeLiteral(parameter.getType()).end();
-                clazz.add(typeGetter);
-            }
-        }
-
-        private CodeExecutableElement createCachedExecute(NodeData node, SpecializationData polymorph, CodeExecutableElement genericPolymorphMethod) {
-            int index = node.getPolymorphicSpecializations().indexOf(polymorph);
-            assert index != -1;
-            boolean generic = index == 0;
-
-            String name = "executeCached" + index;
-            CodeExecutableElement cachedExecute = new CodeExecutableElement(modifiers(PROTECTED), polymorph.getReturnType().getType(), name);
-            addInternalValueParameters(cachedExecute, polymorph, true, true);
-
-            if (generic) {
-                cachedExecute.getModifiers().add(ABSTRACT);
-            } else {
-                SpecializationData genericPolymorph = node.getPolymorphicSpecializations().get(0);
-                CodeTreeBuilder builder = cachedExecute.createBuilder();
-                ExecutableTypeData genericExecutable = new ExecutableTypeData(genericPolymorph, genericPolymorphMethod, node.getTypeSystem(), genericPolymorph.getReturnType().getTypeSystemType());
-                ExecutableTypeData specificExecutable = new ExecutableTypeData(polymorph, cachedExecute, node.getTypeSystem(), polymorph.getReturnType().getTypeSystemType());
-                builder.tree(createCastingExecute(builder, polymorph, specificExecutable, genericExecutable));
-            }
-
-            return cachedExecute;
-
-        }
-
-        private CodeExecutableElement createCreateSpecialization(NodeData node) {
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE), getElement().asType(), "createSpezialization0");
-            method.getParameters().add(new CodeVariableElement(context.getType(Class.class), "clazz"));
-            CodeTreeBuilder builder = method.createBuilder();
-
-            builder.startStatement().type(getElement().asType()).string(" node").end();
-
-            boolean elseIf = false;
-            for (SpecializationData specialization : node.getSpecializations()) {
-                if (specialization.isGeneric() || specialization.isUninitialized()) {
-                    continue;
-                }
-
-                elseIf = builder.startIf(elseIf);
-                builder.startGroup().string("clazz == ").string(nodeSpecializationClassName(specialization)).string(".class").end();
-                builder.end();
-                builder.startBlock();
-                builder.startStatement();
-                builder.string("node = ");
-                builder.startNew(nodeSpecializationClassName(specialization)).string("this").end();
-                builder.end();
-                builder.end();
-            }
-
-            builder.startElseBlock();
-            builder.startThrow().startNew(context.getType(AssertionError.class)).end().end();
-            builder.end();
-
-            builder.startStatement().startCall("node", "setNext0");
-            builder.startNew(nodeSpecializationClassName(node.getUninitializedSpecialization())).string("this").end();
-            builder.end().end();
-
-            builder.startReturn().string("node").end();
-
-            return method;
-        }
-
-        private void createConstructors(NodeData node, CodeTypeElement clazz) {
-            List<ExecutableElement> constructors = findUserConstructors(node.getNodeType());
-            if (constructors.isEmpty()) {
-                clazz.add(createUserConstructor(clazz, null));
-            } else {
-                for (ExecutableElement constructor : constructors) {
-                    clazz.add(createUserConstructor(clazz, constructor));
-                }
-            }
-            if (node.needsRewrites(getContext())) {
-                clazz.add(createCopyConstructor(clazz, findCopyConstructor(node.getNodeType())));
-            }
-        }
-
-        private CodeExecutableElement createUserConstructor(CodeTypeElement type, ExecutableElement superConstructor) {
-            CodeExecutableElement method = new CodeExecutableElement(null, type.getSimpleName().toString());
-            CodeTreeBuilder builder = method.createBuilder();
-
-            NodeData node = getModel().getNode();
-
-            if (superConstructor != null) {
-                for (VariableElement param : superConstructor.getParameters()) {
-                    method.getParameters().add(CodeVariableElement.clone(param));
-                }
-            }
-
-            for (VariableElement var : type.getFields()) {
-                NodeChildData child = node.findChild(var.getSimpleName().toString());
-                if (child != null) {
-                    method.getParameters().add(new CodeVariableElement(child.getOriginalType(), child.getName()));
-                } else {
-                    method.getParameters().add(new CodeVariableElement(var.asType(), var.getSimpleName().toString()));
-                }
-            }
-
-            if (superConstructor != null) {
-                builder.startStatement().startSuperCall();
-                for (VariableElement param : superConstructor.getParameters()) {
-                    builder.string(param.getSimpleName().toString());
-                }
-                builder.end().end();
-            }
-
-            for (VariableElement var : type.getFields()) {
-                builder.startStatement();
-                String fieldName = var.getSimpleName().toString();
-
-                CodeTree fieldInit = CodeTreeBuilder.singleString(var.getSimpleName().toString());
-                builder.string("this.").string(var.getSimpleName().toString());
-
-                NodeChildData child = node.findChild(fieldName);
-                if (child != null) {
-                    CreateCastData createCast = node.findCast(child.getName());
-                    if (createCast != null) {
-                        fieldInit = createTemplateMethodCall(builder, null, node.getGenericSpecialization(), createCast, null, child.getName());
-                    }
-                }
-
-                if (Utils.isAssignable(getContext(), var.asType(), getContext().getTruffleTypes().getNode())) {
-                    builder.string(" = adoptChild(").tree(fieldInit).string(")");
-                } else if (Utils.isAssignable(getContext(), var.asType(), getContext().getTruffleTypes().getNodeArray())) {
-                    builder.string(" = adoptChildren(").tree(fieldInit).string(")");
-                } else {
-                    builder.string(" = ").tree(fieldInit);
-                }
-                builder.end();
-            }
-            return method;
-        }
-
-        private CodeExecutableElement createCopyConstructor(CodeTypeElement type, ExecutableElement superConstructor) {
-            CodeExecutableElement method = new CodeExecutableElement(null, type.getSimpleName().toString());
-            CodeTreeBuilder builder = method.createBuilder();
-            if (!(superConstructor == null && type.getFields().isEmpty())) {
-                method.getParameters().add(new CodeVariableElement(type.asType(), "copy"));
-            }
-
-            if (superConstructor != null) {
-                builder.startStatement().startSuperCall().string("copy").end().end();
-            }
-
-            for (VariableElement var : type.getFields()) {
-                builder.startStatement();
-                String varName = var.getSimpleName().toString();
-                builder.string("this.").string(varName);
-                if (Utils.isAssignable(getContext(), var.asType(), getContext().getTruffleTypes().getNode())) {
-                    builder.string(" = adoptChild(copy.").string(varName).string(")");
-                } else if (Utils.isAssignable(getContext(), var.asType(), getContext().getTruffleTypes().getNodeArray())) {
-                    builder.string(" = adoptChildren(copy.").string(varName).string(")");
-                } else {
-                    builder.string(" = copy.").string(varName);
-                }
-                builder.end();
-            }
-            if (getModel().getNode().getPolymorphicDepth() > 1) {
-                builder.statement("this.next0 = adoptChild(copy.next0)");
-            }
-
-            return method;
-        }
-
-        private CodeVariableElement createAssumptionField(String assumption) {
-            CodeVariableElement var = new CodeVariableElement(getContext().getTruffleTypes().getAssumption(), assumption);
-            var.getModifiers().add(Modifier.FINAL);
-            return var;
-        }
-
-        private CodeVariableElement createChildField(NodeChildData child) {
-            CodeVariableElement var = new CodeVariableElement(child.getNodeType(), child.getName());
-            var.getModifiers().add(Modifier.PROTECTED);
-
-            DeclaredType annotationType;
-            if (child.getCardinality() == Cardinality.MANY) {
-                annotationType = getContext().getTruffleTypes().getChildrenAnnotation();
-            } else {
-                annotationType = getContext().getTruffleTypes().getChildAnnotation();
-            }
-
-            var.getAnnotationMirrors().add(new CodeAnnotationMirror(annotationType));
-            return var;
-        }
-
-        private CodeExecutableElement createGenericExecuteAndSpecialize(NodeData node) {
-
-            TypeMirror genericReturnType = node.getGenericSpecialization().getReturnType().getType();
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED), genericReturnType, EXECUTE_SPECIALIZE_NAME);
-            method.addParameter(new CodeVariableElement(getContext().getType(Class.class), "minimumState"));
-            addInternalValueParameters(method, node.getGenericSpecialization(), true, false);
-            method.addParameter(new CodeVariableElement(getContext().getType(String.class), "reason"));
-
-            CodeTreeBuilder builder = method.createBuilder();
-            builder.startStatement();
-            builder.startStaticCall(getContext().getTruffleTypes().getCompilerAsserts(), "neverPartOfCompilation").end();
-            builder.end();
-
-            emitSpecializationListeners(builder, node);
-            builder.defaultDeclaration(node.getGenericSpecialization().getReturnType().getTypeSystemType().getPrimitiveType(), "result");
-
-            builder.defaultDeclaration(getContext().getType(Class.class), "resultClass");
-
-            builder.startStatement().string("boolean allowed = (minimumState == ").string(nodeSpecializationClassName(node.getSpecializations().get(0))).string(".class)").end();
-
-            builder.startStatement().string("String message = ").startCall("createInfo0").string("reason");
-            addInternalValueParameterNames(builder, node.getGenericSpecialization(), node.getGenericSpecialization(), null, false, true);
-            builder.end().end();
-
-            String prefix = null;
-
-            List<SpecializationData> specializations = node.getSpecializations();
-
-            for (SpecializationData current : specializations) {
-                if (current.isUninitialized() || !current.isReachable()) {
-                    continue;
-                }
-                CodeTreeBuilder execute = new CodeTreeBuilder(builder);
-
-                execute.tree(createGenericInvokeAndSpecialize(builder, node.getGenericSpecialization(), current));
-
-                if (!current.isGeneric()) {
-                    builder.startStatement().string("allowed = allowed || (minimumState == ").string(nodeSpecializationClassName(current)).string(".class)").end();
-                }
-
-                builder.tree(createGuardAndCast(builder, prefix, current.getNode().getGenericSpecialization(), current, true, execute.getRoot(), null, true, false));
-            }
-
-            for (SpecializationData current : specializations) {
-                if (current.isUninitialized() || current.isReachable()) {
-                    continue;
-                }
-                builder.string("// unreachable ").string(current.getId()).newLine();
-            }
-
-            return method;
-        }
-
-        private CodeExecutableElement createGenericExecute(NodeData node) {
-            TypeMirror genericReturnType = node.getGenericSpecialization().getReturnType().getType();
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED), genericReturnType, EXECUTE_GENERIC_NAME);
-            addInternalValueParameters(method, node.getGenericSpecialization(), true, false);
-            CodeTreeBuilder builder = method.createBuilder();
-
-            String prefix = null;
-            List<SpecializationData> specializations = node.getSpecializations();
-
-            for (SpecializationData current : specializations) {
-                if (current.isUninitialized() || !current.isReachable()) {
-                    continue;
-                }
-                CodeTreeBuilder execute = new CodeTreeBuilder(builder);
-                execute.tree(createGenericInvoke(builder, node.getGenericSpecialization(), current));
-                builder.tree(createGuardAndCast(builder, prefix, current.getNode().getGenericSpecialization(), current, true, execute.getRoot(), null, true, false));
-            }
-
-            for (SpecializationData current : specializations) {
-                if (current.isUninitialized() || current.isReachable()) {
-                    continue;
-                }
-                builder.string("// unreachable ").string(current.getId()).newLine();
-            }
-
-            return method;
-        }
-
-        protected CodeTree createGenericInvoke(CodeTreeBuilder parent, SpecializationData source, SpecializationData current) {
-            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
-
-            if (current.getMethod() == null) {
-                emitEncounteredSynthetic(builder, current);
-            } else {
-                builder.startReturn().tree(createTemplateMethodCall(builder, null, source, current, null)).end();
-            }
-
-            return encloseThrowsWithFallThrough(current, builder.getRoot());
-        }
-
-        protected CodeTree createGenericInvokeAndSpecialize(CodeTreeBuilder parent, SpecializationData source, SpecializationData current) {
-            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
-
-            NodeData node = current.getNode();
-
-            builder.startIf().string("resultClass == null").end().startBlock();
-            if (current.getMethod() != null) {
-                CodeTree executeCall = createTemplateMethodCall(builder, null, source, current, null);
-                if (current.getReturnType().getTypeSystemType().isVoid()) {
-                    builder.statement(executeCall);
-                } else {
-                    builder.startStatement().string("result = ").tree(executeCall).end();
-                }
-                builder.startStatement();
-                builder.string("resultClass = ").string(nodeSpecializationClassName(current)).string(".class");
-                builder.end();
-            } else {
-                emitEncounteredSynthetic(builder, current);
-            }
-            builder.end();
-
-            boolean ifAllowed = current.hasRewrite(getContext());
-            if (ifAllowed) {
-                builder.startIf().string("allowed").end().startBlock();
-            }
-
-            if (!current.isGeneric() || node.getPolymorphicDepth() <= 1) {
-                // generic rewrite
-                builder.tree(createRewriteGeneric(builder, current));
-            } else {
-                boolean rewriteableToGeneric = node.getGenericSpecialization().getMethod() != null && node.getGenericSpecialization().isReachable();
-                if (rewriteableToGeneric) {
-                    builder.startIf().string("resultClass == ").string(nodeSpecializationClassName(node.getGenericSpecialization())).string(".class").end();
-                    builder.startBlock();
-
-                    boolean maybePolymorphic = node.getPolymorphicDepth() > 1;
-                    if (maybePolymorphic) {
-                        builder.startIf().string("next0 == null").end();
-                        builder.startBlock();
-                    }
-                    builder.tree(createRewriteGeneric(builder, current));
-                    if (maybePolymorphic) {
-                        builder.end().startElseBlock();
-                        builder.statement("Node searchNode = super.getParent()");
-                        builder.startWhile().string("searchNode != null").end();
-                        builder.startBlock();
-                        builder.statement("searchNode = searchNode.getParent()");
-                        builder.startIf().instanceOf("searchNode", nodePolymorphicClassName(node, node.getPolymorphicSpecializations().get(0))).end();
-                        builder.startBlock().breakStatement().end();
-                        builder.end();
-                        builder.startStatement().startCall("searchNode", "replace");
-                        builder.startGroup().startNew(nodeSpecializationClassName(current)).startGroup().cast(baseClassName(node)).string("searchNode").end().end().end();
-                        builder.string("message");
-                        builder.end().end().end();
-                    }
-
-                    builder.end().startElseBlock();
-                }
-
-                // polymorphic rewrite
-                builder.tree(createRewritePolymorphic(builder, node));
-
-                if (rewriteableToGeneric) {
-                    builder.end();
-                }
-            }
-
-            if (current.getReturnType().getTypeSystemType().isVoid()) {
-                builder.returnStatement();
-            } else {
-                builder.startReturn().string("result").end();
-            }
-            if (ifAllowed) {
-                builder.end();
-            }
-
-            return encloseThrowsWithFallThrough(current, builder.getRoot());
-        }
-
-        private CodeTree encloseThrowsWithFallThrough(SpecializationData current, CodeTree tree) {
-            if (current.getExceptions().isEmpty()) {
-                return tree;
-            }
-            CodeTreeBuilder builder = new CodeTreeBuilder(null);
-
-            builder.startTryBlock();
-            builder.tree(tree);
-            for (SpecializationThrowsData exception : current.getExceptions()) {
-                builder.end().startCatchBlock(exception.getJavaClass(), "rewriteEx");
-                builder.string("// fall through").newLine();
-            }
-            builder.end();
-
-            return builder.getRoot();
-        }
-
-        private CodeTree createRewriteGeneric(CodeTreeBuilder parent, SpecializationData current) {
-            CodeTreeBuilder builder = parent.create();
-            builder.startStatement().startCall("super", "replace");
-            builder.startGroup().startNew(nodeSpecializationClassName(current)).string("this").end().end();
-            builder.string("message");
-            builder.end().end();
-            return builder.getRoot();
-        }
-
-        private CodeTree createRewritePolymorphic(CodeTreeBuilder parent, NodeData node) {
-            CodeTreeBuilder builder = parent.create();
-            builder.startStatement();
-            builder.string(nodePolymorphicClassName(node, null));
-            builder.string(" polymorphic = ");
-            builder.startNew(nodePolymorphicClassName(node, null)).string("this").end();
-            builder.end();
-            for (NodeChildData child : node.getChildren()) {
-                builder.startStatement().string("this.").string(child.getName()).string(" = null").end();
-            }
-            builder.startStatement().startCall("super", "replace");
-            builder.string("polymorphic");
-            builder.string("message");
-            builder.end().end();
-
-            builder.statement("polymorphic.setNext0(this)");
-            builder.statement("setNext0(createSpezialization0(resultClass))");
-
-            builder.statement("polymorphic.optimizeTypes()");
-            return builder.getRoot();
-        }
-
-        private void emitSpecializationListeners(CodeTreeBuilder builder, NodeData node) {
-            for (TemplateMethod listener : node.getSpecializationListeners()) {
-                builder.startStatement();
-                builder.tree(createTemplateMethodCall(builder, null, listener, listener, null));
-                builder.end(); // statement
-            }
-        }
-
-        protected CodeTree createCastingExecute(CodeTreeBuilder parent, SpecializationData specialization, ExecutableTypeData executable, ExecutableTypeData castExecutable) {
-            TypeData type = executable.getType();
-            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
-            NodeData node = specialization.getNode();
-
-            ExecutableTypeData castedType = node.findExecutableType(type, 0);
-            TypeData primaryType = castExecutable.getType();
-
-            boolean needsTry = castExecutable.hasUnexpectedValue(getContext());
-            boolean returnVoid = type.isVoid();
-
-            List<ActualParameter> executeParameters = new ArrayList<>();
-            for (ActualParameter sourceParameter : executable.getParameters()) {
-                if (!sourceParameter.getSpecification().isSignature()) {
-                    continue;
-                }
-
-                ActualParameter targetParameter = castExecutable.findParameter(sourceParameter.getLocalName());
-                if (targetParameter != null) {
-                    executeParameters.add(targetParameter);
-                }
-            }
-
-            builder.tree(createExecuteChildren(builder, executable, specialization, executeParameters, null, true));
-
-            CodeTree primaryExecuteCall = createTemplateMethodCall(builder, null, executable, castExecutable, null);
-            if (needsTry) {
-                if (!returnVoid) {
-                    builder.declaration(primaryType.getPrimitiveType(), "value");
-                }
-                builder.startTryBlock();
-
-                if (returnVoid) {
-                    builder.statement(primaryExecuteCall);
-                } else {
-                    builder.startStatement();
-                    builder.string("value = ");
-                    builder.tree(primaryExecuteCall);
-                    builder.end();
-                }
-
-                builder.end().startCatchBlock(getUnexpectedValueException(), "ex");
-                if (returnVoid) {
-                    builder.string("// ignore").newLine();
-                } else {
-                    builder.startReturn();
-                    builder.tree(createExpectExecutableType(node, specialization.getNode().getTypeSystem().getGenericTypeData(), castedType, CodeTreeBuilder.singleString("ex.getResult()")));
-                    builder.end();
-                }
-                builder.end();
-
-                if (!returnVoid) {
-                    builder.startReturn();
-                    builder.tree(createExpectExecutableType(node, castExecutable.getReturnType().getTypeSystemType(), executable, CodeTreeBuilder.singleString("value")));
-                    builder.end();
-                }
-            } else {
-                if (returnVoid) {
-                    builder.statement(primaryExecuteCall);
-                } else {
-                    builder.startReturn();
-                    builder.tree(createExpectExecutableType(node, castExecutable.getReturnType().getTypeSystemType(), executable, primaryExecuteCall));
-                    builder.end();
-                }
-            }
-
-            return builder.getRoot();
-        }
-
-        protected CodeTree createExpectExecutableType(NodeData node, TypeData sourceType, ExecutableTypeData castedType, CodeTree value) {
-            boolean hasUnexpected = castedType.hasUnexpectedValue(getContext());
-            return createCastType(node, sourceType, castedType.getType(), hasUnexpected, value);
-        }
-
-        protected CodeTree createCastType(NodeData node, TypeData sourceType, TypeData targetType, boolean expect, CodeTree value) {
-            if (targetType == null) {
-                return value;
-            } else if (!sourceType.needsCastTo(getContext(), targetType)) {
-                return value;
-            }
-
-            CodeTreeBuilder builder = CodeTreeBuilder.createBuilder();
-            String targetMethodName;
-            if (expect) {
-                targetMethodName = TypeSystemCodeGenerator.expectTypeMethodName(targetType);
-            } else {
-                targetMethodName = TypeSystemCodeGenerator.asTypeMethodName(targetType);
-            }
-            startCallTypeSystemMethod(getContext(), builder, node, targetMethodName);
-
-            builder.tree(value);
-            builder.end().end();
-            return builder.getRoot();
-        }
-
-        protected CodeTree createExecuteChildren(CodeTreeBuilder parent, ExecutableTypeData sourceExecutable, SpecializationData specialization, List<ActualParameter> targetParameters,
-                        ActualParameter unexpectedParameter, boolean cast) {
-            NodeData sourceNode = specialization.getNode();
-
-            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
-
-            for (ActualParameter targetParameter : targetParameters) {
-                NodeChildData field = sourceNode.findChild(targetParameter.getSpecification().getName());
-                if (!targetParameter.getSpecification().isSignature()) {
-                    continue;
-                }
-
-                TypeData targetType = targetParameter.getTypeSystemType();
-                ExecutableTypeData targetExecutable = null;
-                if (field != null) {
-                    targetExecutable = field.findExecutableType(getContext(), targetType);
-                }
-
-                ActualParameter sourceParameter = sourceExecutable.findParameter(targetParameter.getLocalName());
-
-                String targetVariableName = valueName(targetParameter);
-                CodeTree executionExpression = null;
-                if ((sourceParameter != null && cast) || sourceParameter != null) {
-                    TypeData sourceType = sourceParameter.getTypeSystemType();
-                    if (targetExecutable == null || !sourceType.needsCastTo(getContext(), targetType)) {
-                        if (field != null && field.isShortCircuit() && sourceParameter != null) {
-                            builder.tree(createShortCircuitValue(builder, specialization, field, targetParameter.getPreviousParameter(), unexpectedParameter));
-                        }
-                        builder.startStatement();
-                        builder.type(targetParameter.getType()).string(" ");
-                        builder.string(valueName(targetParameter)).string(" = ");
-                        builder.tree(CodeTreeBuilder.singleString(valueNameEvaluated(targetParameter)));
-                        builder.end();
-                        continue;
-                    } else {
-                        CodeTree valueTree = CodeTreeBuilder.singleString(valueNameEvaluated(targetParameter));
-                        executionExpression = createExpectExecutableType(sourceNode, sourceType, targetExecutable, valueTree);
-                    }
-                } else if (sourceParameter == null) {
-                    executionExpression = createExecuteChildExpression(builder, field, targetParameter, unexpectedParameter);
-                }
-
-                if (executionExpression != null) {
-                    CodeTreeVariable executionVar = new CodeTreeVariable();
-                    CodeTree shortCircuitTree = createShortCircuitTree(builder, executionVar, targetVariableName, specialization, targetParameter, unexpectedParameter);
-                    CodeTree unexpectedTree = createCatchUnexpectedTree(builder, executionExpression, targetVariableName, specialization, sourceExecutable, targetExecutable, targetParameter,
-                                    shortCircuitTree != executionVar);
-
-                    executionVar.set(unexpectedTree);
-                    builder.tree(shortCircuitTree);
-                }
-            }
-            return builder.getRoot();
-        }
-
-        private CodeTree createCatchUnexpectedTree(CodeTreeBuilder parent, CodeTree body, String targetVariableName, SpecializationData specialization, ExecutableTypeData currentExecutable,
-                        ExecutableTypeData targetExecutable, ActualParameter param, boolean shortCircuit) {
-            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
-            boolean unexpected = targetExecutable.hasUnexpectedValue(getContext());
-            boolean cast = false;
-            if (targetExecutable.getType().needsCastTo(getContext(), param.getTypeSystemType())) {
-                unexpected = true;
-                cast = true;
-            }
-
-            if (specialization.isGeneric() && unexpected) {
-                throw new AssertionError("Generic has unexpected parameters. " + specialization.toString());
-            }
-
-            builder.startStatement();
-
-            if (!shortCircuit) {
-                builder.type(param.getType()).string(" ").string(targetVariableName);
-            }
-
-            if (unexpected) {
-                if (!shortCircuit) {
-                    builder.end();
-                }
-                builder.startTryBlock();
-                builder.startStatement();
-                builder.string(targetVariableName);
-            } else if (shortCircuit) {
-                builder.startStatement();
-                builder.string(targetVariableName);
-            }
-            builder.string(" = ");
-            if (cast) {
-                builder.tree(createCastType(specialization.getNode(), targetExecutable.getType(), param.getTypeSystemType(), true, body));
-            } else {
-                builder.tree(body);
-            }
-            builder.end();
-
-            if (unexpected) {
-                builder.end().startCatchBlock(getUnexpectedValueException(), "ex");
-                SpecializationData generic = specialization.getNode().getGenericSpecialization();
-                ActualParameter genericParameter = generic.findParameter(param.getLocalName());
-
-                List<ActualParameter> genericParameters = generic.getParametersAfter(genericParameter);
-                builder.tree(createDeoptimize(builder));
-                builder.tree(createExecuteChildren(parent, currentExecutable, generic, genericParameters, genericParameter, false));
-                if (specialization.isPolymorphic()) {
-                    builder.tree(createReturnOptimizeTypes(builder, specialization, param));
-                } else {
-                    builder.tree(createReturnExecuteAndSpecialize(builder, currentExecutable, specialization.findNextSpecialization(), param, "Expected " + param.getLocalName() + " instanceof " +
-                                    Utils.getSimpleName(param.getType())));
-                }
-                builder.end(); // catch block
-            }
-
-            return builder.getRoot();
-        }
-
-        private CodeTree createReturnOptimizeTypes(CodeTreeBuilder parent, SpecializationData specialization, ActualParameter param) {
-            NodeData node = specialization.getNode();
-            assert !node.getPolymorphicSpecializations().isEmpty();
-            SpecializationData generic = node.getPolymorphicSpecializations().get(0);
-
-            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
-            builder.startReturn();
-
-            CodeTreeBuilder execute = new CodeTreeBuilder(builder);
-            execute.startCall("next0", "executeCached0");
-            addInternalValueParameterNames(execute, specialization, generic, param.getLocalName(), true, true);
-            execute.end();
-
-            TypeData sourceType = generic.getReturnType().getTypeSystemType();
-            TypeData targetType = specialization.getReturnType().getTypeSystemType();
-
-            builder.tree(createCastType(node, sourceType, targetType, true, execute.getRoot()));
-
-            builder.end();
-            return builder.getRoot();
-        }
-
-        private CodeTree createExecuteChildExpression(CodeTreeBuilder parent, NodeChildData targetField, ActualParameter sourceParameter, ActualParameter unexpectedParameter) {
-            TypeData type = sourceParameter.getTypeSystemType();
-            ExecutableTypeData execType = targetField.findExecutableType(getContext(), type);
-
-            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
-            if (targetField != null) {
-                Element accessElement = targetField.getAccessElement();
-                if (accessElement == null || accessElement.getKind() == ElementKind.METHOD) {
-                    builder.string("this.").string(targetField.getName());
-                } else if (accessElement.getKind() == ElementKind.FIELD) {
-                    builder.string("this.").string(accessElement.getSimpleName().toString());
-                } else {
-                    throw new AssertionError();
-                }
-                if (sourceParameter.getSpecification().isIndexed()) {
-                    builder.string("[" + sourceParameter.getIndex() + "]");
-                }
-                builder.string(".");
-            }
-
-            builder.startCall(execType.getMethodName());
-
-            int index = 0;
-            for (ActualParameter parameter : execType.getParameters()) {
-
-                if (!parameter.getSpecification().isSignature()) {
-                    builder.string(parameter.getLocalName());
-                } else {
-                    if (index < targetField.getExecuteWith().size()) {
-                        NodeChildData child = targetField.getExecuteWith().get(index);
-
-                        ParameterSpec spec = getModel().getSpecification().findParameterSpec(child.getName());
-                        List<ActualParameter> specializationParams = getModel().findParameters(spec);
-
-                        if (specializationParams.isEmpty()) {
-                            builder.defaultValue(parameter.getType());
-                            continue;
-                        }
-
-                        ActualParameter specializationParam = specializationParams.get(0);
-
-                        TypeData targetType = parameter.getTypeSystemType();
-                        TypeData sourceType = specializationParam.getTypeSystemType();
-                        String localName = specializationParam.getLocalName();
-
-                        if (unexpectedParameter != null && unexpectedParameter.getLocalName().equals(specializationParam.getLocalName())) {
-                            localName = "ex.getResult()";
-                            sourceType = getModel().getNode().getTypeSystem().getGenericTypeData();
-                        }
-
-                        CodeTree value = CodeTreeBuilder.singleString(localName);
-
-                        if (sourceType.needsCastTo(getContext(), targetType)) {
-                            value = createCallTypeSystemMethod(getContext(), builder, getModel().getNode(), TypeSystemCodeGenerator.asTypeMethodName(targetType), value);
-                        }
-                        builder.tree(value);
-                    } else {
-                        builder.defaultValue(parameter.getType());
-                    }
-                    index++;
-                }
-            }
-
-            builder.end();
-
-            return builder.getRoot();
-        }
-
-        private CodeTree createShortCircuitTree(CodeTreeBuilder parent, CodeTree body, String targetVariableName, SpecializationData specialization, ActualParameter parameter,
-                        ActualParameter exceptionParam) {
-            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
-
-            NodeChildData forField = specialization.getNode().findChild(parameter.getSpecification().getName());
-            if (forField == null) {
-                return body;
-            }
-
-            if (forField.getExecutionKind() != ExecutionKind.SHORT_CIRCUIT) {
-                return body;
-            }
-
-            ActualParameter shortCircuitParam = specialization.getPreviousParam(parameter);
-
-            builder.tree(createShortCircuitValue(builder, specialization, forField, shortCircuitParam, exceptionParam));
-
-            builder.declaration(parameter.getType(), targetVariableName, CodeTreeBuilder.createBuilder().defaultValue(parameter.getType()));
-            builder.startIf().string(shortCircuitParam.getLocalName()).end();
-            builder.startBlock();
-            builder.tree(body);
-            builder.end();
-
-            return builder.getRoot();
-        }
-
-        private CodeTree createShortCircuitValue(CodeTreeBuilder parent, SpecializationData specialization, NodeChildData forField, ActualParameter shortCircuitParam, ActualParameter exceptionParam) {
-            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
-            int shortCircuitIndex = 0;
-            for (NodeChildData field : specialization.getNode().getChildren()) {
-                if (field.getExecutionKind() == ExecutionKind.SHORT_CIRCUIT) {
-                    if (field == forField) {
-                        break;
-                    }
-                    shortCircuitIndex++;
-                }
-            }
-
-            builder.startStatement().type(shortCircuitParam.getType()).string(" ").string(valueName(shortCircuitParam)).string(" = ");
-            ShortCircuitData shortCircuitData = specialization.getShortCircuits().get(shortCircuitIndex);
-            builder.tree(createTemplateMethodCall(builder, null, specialization, shortCircuitData, exceptionParam != null ? exceptionParam.getLocalName() : null));
-            builder.end(); // statement
-
-            return builder.getRoot();
-        }
-
-        protected CodeTree createDeoptimize(CodeTreeBuilder parent) {
-            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
-            builder.startStatement();
-            builder.startStaticCall(getContext().getTruffleTypes().getCompilerDirectives(), "transferToInterpreter").end();
-            builder.end();
-            return builder.getRoot();
-        }
-
-        protected CodeTree createReturnExecuteAndSpecialize(CodeTreeBuilder parent, ExecutableTypeData executable, SpecializationData nextSpecialization, ActualParameter exceptionParam, String reason) {
-            SpecializationData generic = getModel().getNode().getGenericSpecialization();
-            CodeTreeBuilder specializeCall = new CodeTreeBuilder(parent);
-            specializeCall.startCall(EXECUTE_SPECIALIZE_NAME);
-            specializeCall.string(nodeSpecializationClassName(nextSpecialization) + ".class");
-            addInternalValueParameterNames(specializeCall, generic, nextSpecialization.getNode().getGenericSpecialization(), exceptionParam != null ? exceptionParam.getLocalName() : null, true, true);
-            specializeCall.doubleQuote(reason);
-            specializeCall.end().end();
-
-            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
-
-            builder.startReturn();
-            builder.tree(createExpectExecutableType(nextSpecialization.getNode(), generic.getReturnType().getTypeSystemType(), executable, specializeCall.getRoot()));
-            builder.end();
-
-            return builder.getRoot();
-        }
-    }
-
-    private class PolymorphicNodeFactory extends SpecializedNodeFactory {
-
-        private final boolean generic;
-
-        public PolymorphicNodeFactory(ProcessorContext context, CodeTypeElement nodeGen, boolean generic) {
-            super(context, nodeGen);
-            this.generic = generic;
-        }
-
-        @Override
-        public CodeTypeElement create(SpecializationData specialization) {
-            NodeData node = specialization.getNode();
-            TypeMirror baseType = node.getNodeType();
-            if (nodeGen != null) {
-                baseType = nodeGen.asType();
-            }
-            CodeTypeElement clazz = createClass(node, modifiers(PRIVATE, STATIC), nodePolymorphicClassName(node, specialization), baseType, false);
-
-            if (!generic) {
-                clazz.getModifiers().add(Modifier.FINAL);
-            }
-
-            clazz.getAnnotationMirrors().add(createNodeInfo(node, Kind.POLYMORPHIC));
-
-            return clazz;
-        }
-
-        @Override
-        protected void createChildren(SpecializationData specialization) {
-// super.createChildren(specialization);
-            CodeTypeElement clazz = getElement();
-
-            createConstructors(clazz);
-            createExecuteMethods(specialization);
-
-            if (generic) {
-                getElement().add(createOptimizeTypes());
-                createCachedExecuteMethods(specialization);
-            }
-        }
-
-        private CodeExecutableElement createOptimizeTypes() {
-            NodeData node = getModel().getNode();
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), getContext().getType(void.class), "optimizeTypes");
-            CodeTreeBuilder builder = method.createBuilder();
-            builder.startStatement().string(baseClassName(node)).string(" node = this.next0").end();
-            TypeMirror classType = getContext().getType(Class.class);
-
-            SpecializationData genericSpecialization = node.getGenericSpecialization();
-
-            CodeTreeBuilder whileBodyBuilder = builder.create();
-            for (ActualParameter parameter : node.getGenericSpecialization().getReturnTypeAndParameters()) {
-                if (!parameter.getSpecification().isSignature()) {
-                    continue;
-                }
-
-                ActualParameter genericParameter = genericSpecialization.findParameter(parameter.getLocalName());
-
-                String name = parameter.getLocalName() + "Type";
-
-                builder.declaration(classType, name, builder.create().startCall("node", typeGetterName(parameter)).end().getRoot());
-
-                whileBodyBuilder.startIf().string(name).string(" != ").startCall("node", typeGetterName(parameter)).end().end();
-                whileBodyBuilder.startBlock();
-                whileBodyBuilder.startStatement().string(name).string(" = ").typeLiteral(genericParameter.getType()).end();
-                whileBodyBuilder.end();
-            }
-
-            builder.startWhile().string("node != null && !(").instanceOf("node", nodeSpecializationClassName(node.getUninitializedSpecialization())).string(")").end();
-            builder.startBlock();
-            builder.tree(whileBodyBuilder.getRoot());
-            builder.statement("node = node.next0");
-            builder.end();
-
-            boolean elseIf = false;
-            for (SpecializationData polymorph : node.getPolymorphicSpecializations()) {
-                elseIf = builder.startIf(elseIf);
-                String and = "";
-                StringBuilder reason = new StringBuilder("Optimized polymorphic types for (");
-                for (ActualParameter parameter : polymorph.getReturnTypeAndParameters()) {
-                    if (!parameter.getSpecification().isSignature()) {
-                        continue;
-                    }
-                    String name = parameter.getLocalName() + "Type";
-                    builder.string(and).string(name).string(" == ").typeLiteral(parameter.getType());
-
-                    if (!and.isEmpty()) {
-                        reason.append(", ");
-                    }
-                    reason.append(Utils.getSimpleName(parameter.getType()));
-                    and = " && ";
-                }
-                reason.append(")");
-                builder.end();
-                builder.startBlock();
-
-                String className = nodePolymorphicClassName(node, polymorph);
-                builder.startIf().string("getClass() != ").string(className).string(".class").end();
-                builder.startBlock();
-                builder.startStatement().startCall("super", "replace");
-                builder.startNew(className).string("this").end();
-                builder.doubleQuote(reason.toString());
-                builder.end().end(); // call
-                builder.end(); // block
-                builder.end();
-            }
-            return method;
-        }
-    }
-
-    private class SpecializedNodeFactory extends NodeBaseFactory {
-
-        protected final CodeTypeElement nodeGen;
-
-        public SpecializedNodeFactory(ProcessorContext context, CodeTypeElement nodeGen) {
-            super(context);
-            this.nodeGen = nodeGen;
-        }
-
-        @Override
-        public CodeTypeElement create(SpecializationData specialization) {
-            NodeData node = specialization.getNode();
-            TypeMirror baseType = node.getNodeType();
-            if (nodeGen != null) {
-                baseType = nodeGen.asType();
-            }
-            CodeTypeElement clazz = createClass(node, modifiers(PRIVATE, STATIC, FINAL), nodeSpecializationClassName(specialization), baseType, false);
-
-            Kind kind;
-            if (specialization.isGeneric()) {
-                kind = Kind.GENERIC;
-            } else if (specialization.isUninitialized()) {
-                kind = Kind.UNINITIALIZED;
-            } else {
-                kind = Kind.SPECIALIZED;
-            }
-            clazz.getAnnotationMirrors().add(createNodeInfo(node, kind));
-
-            return clazz;
-        }
-
-        protected CodeAnnotationMirror createNodeInfo(NodeData node, Kind kind) {
-            String shortName = node.getShortName();
-            CodeAnnotationMirror nodeInfoMirror = new CodeAnnotationMirror(getContext().getTruffleTypes().getNodeInfoAnnotation());
-            if (shortName != null) {
-                nodeInfoMirror.setElementValue(nodeInfoMirror.findExecutableElement("shortName"), new CodeAnnotationValue(shortName));
-            }
-
-            DeclaredType nodeinfoKind = getContext().getTruffleTypes().getNodeInfoKind();
-            VariableElement varKind = Utils.findVariableElement(nodeinfoKind, kind.name());
-
-            nodeInfoMirror.setElementValue(nodeInfoMirror.findExecutableElement("kind"), new CodeAnnotationValue(varKind));
-            return nodeInfoMirror;
-        }
-
-        @Override
-        protected void createChildren(SpecializationData specialization) {
-            CodeTypeElement clazz = getElement();
-            createConstructors(clazz);
-
-            NodeData node = specialization.getNode();
-
-            if (!specialization.isGeneric() && !specialization.isUninitialized() && !specialization.isPolymorphic() && node.needsRewrites(getContext()) && node.getPolymorphicDepth() > 1) {
-
-                createTypeGetters(clazz, specialization);
-            }
-
-            createExecuteMethods(specialization);
-            createCachedExecuteMethods(specialization);
-        }
-
-        protected void createConstructors(CodeTypeElement clazz) {
-            TypeElement superTypeElement = Utils.fromTypeMirror(clazz.getSuperclass());
-            for (ExecutableElement constructor : ElementFilter.constructorsIn(superTypeElement.getEnclosedElements())) {
-                if (getModel().getNode().getUninitializedSpecialization() != null && !getModel().isUninitialized() && constructor.getParameters().size() != 1 ||
-                                constructor.getParameters().get(0).getSimpleName().toString().equals(baseClassName(getModel().getNode()))) {
-                    continue;
-                }
-
-                CodeExecutableElement superConstructor = createSuperConstructor(clazz, constructor);
-                if (superConstructor != null) {
-                    if (getModel().isGeneric() && getModel().getNode().getPolymorphicDepth() > 1) {
-                        CodeTree body = superConstructor.getBodyTree();
-                        CodeTreeBuilder builder = superConstructor.createBuilder();
-                        builder.tree(body);
-                        builder.statement("this.next0 = null");
-                    }
-
-                    clazz.add(superConstructor);
-                }
-            }
-        }
-
-        protected void createExecuteMethods(SpecializationData specialization) {
-            NodeData node = specialization.getNode();
-            CodeTypeElement clazz = getElement();
-
-            for (ExecutableTypeData execType : node.getExecutableTypes()) {
-                if (execType.isFinal()) {
-                    continue;
-                }
-                CodeExecutableElement executeMethod = createExecutableTypeOverride(execType, true);
-                clazz.add(executeMethod);
-                CodeTreeBuilder builder = executeMethod.createBuilder();
-                CodeTree result = createExecuteBody(builder, specialization, execType);
-                if (result != null) {
-                    builder.tree(result);
-                } else {
-                    clazz.remove(executeMethod);
-                }
-            }
-        }
-
-        protected void createCachedExecuteMethods(SpecializationData specialization) {
-            NodeData node = specialization.getNode();
-            CodeTypeElement clazz = getElement();
-            int index = 0;
-            for (SpecializationData polymorphic : node.getPolymorphicSpecializations()) {
-                boolean matchFound = false;
-                if (!specialization.isGeneric() && !specialization.isUninitialized() && !specialization.isPolymorphic()) {
-                    matchFound = polymorphic.getSignature().hasAnyParameterMatch(specialization.getSignature());
-                }
-
-                if (matchFound || index == 0) {
-                    ExecutableElement executeCached = nodeGen.getMethod("executeCached" + index);
-                    ExecutableTypeData execType = new ExecutableTypeData(polymorphic, executeCached, node.getTypeSystem(), polymorphic.getReturnType().getTypeSystemType());
-
-                    CodeExecutableElement executeMethod = createExecutableTypeOverride(execType, false);
-                    CodeTreeBuilder builder = executeMethod.createBuilder();
-
-                    if (specialization.isGeneric() || specialization.isPolymorphic()) {
-                        builder.startThrow().startNew(getContext().getType(AssertionError.class));
-                        builder.doubleQuote("Should not be reached.");
-                        builder.end().end();
-                    } else if (specialization.isUninitialized()) {
-                        builder.tree(createAppendPolymorphic(builder, specialization));
-                    } else {
-                        CodeTreeBuilder elseBuilder = new CodeTreeBuilder(builder);
-                        elseBuilder.startReturn().startCall("this.next0", "executeCached" + index);
-                        addInternalValueParameterNames(elseBuilder, polymorphic, polymorphic, null, true, true);
-                        elseBuilder.end().end();
-                        CodeTreeBuilder execute = new CodeTreeBuilder(builder);
-                        execute.tree(createGenericInvoke(builder, polymorphic, specialization));
-                        boolean forceElse = !specialization.getExceptions().isEmpty();
-                        builder.tree(createGuardAndCast(builder, null, polymorphic, specialization, true, execute.getRoot(), elseBuilder.getRoot(), true, forceElse));
-                    }
-                    clazz.add(executeMethod);
-                }
-                index++;
-            }
-        }
-
-        private CodeTree createAppendPolymorphic(CodeTreeBuilder parent, SpecializationData specialization) {
-            NodeData node = specialization.getNode();
-            String genericClassName = nodePolymorphicClassName(node, null);
-
-            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
-            builder.startStatement().startStaticCall(getContext().getTruffleTypes().getCompilerDirectives(), "transferToInterpreter").end().end();
-
-            builder.declaration(getContext().getTruffleTypes().getNode(), "searchNode", "super.getParent()");
-            builder.declaration(getContext().getType(int.class), "depth", "0");
-            builder.startWhile().string("searchNode != null").end();
-            builder.startBlock();
-            builder.statement("depth++");
-            builder.statement("searchNode = searchNode.getParent()");
-
-            builder.startIf().instanceOf("searchNode", genericClassName).end();
-            builder.startBlock().breakStatement().end();
-            builder.end(); // if
-            builder.end(); // while
-
-            builder.startAssert().instanceOf("searchNode", genericClassName).end();
-
-            builder.startStatement();
-            builder.string(genericClassName).string(" ").string("polymorphic = ").string("(").string(genericClassName).string(") searchNode");
-            builder.end();
-
-            builder.startIf().string("depth >= ").string(String.valueOf(node.getPolymorphicDepth())).end();
-            builder.startBlock();
-            builder.startStatement();
-            builder.startCall("searchNode", "replace");
-            builder.startNew(nodeSpecializationClassName(node.getGenericSpecialization())).string("this").end();
-            builder.doubleQuote("Polymorphic limit reached (" + node.getPolymorphicDepth() + ")");
-            builder.end();
-            builder.end();
-
-            builder.startReturn().startCall("super", EXECUTE_GENERIC_NAME);
-            addInternalValueParameterNames(builder, specialization, node.getGenericSpecialization(), null, true, true);
-            builder.end().end();
-
-            builder.end().startElseBlock();
-            builder.startStatement().startCall("super", "setNext0");
-            builder.startNew(nodeSpecializationClassName(node.getUninitializedSpecialization())).string("this").end();
-            builder.end().end();
-
-            CodeTreeBuilder specializeCall = new CodeTreeBuilder(builder);
-            specializeCall.startCall(EXECUTE_SPECIALIZE_NAME);
-            specializeCall.string(nodeSpecializationClassName(node.getUninitializedSpecialization()) + ".class");
-            addInternalValueParameterNames(specializeCall, specialization, node.getGenericSpecialization(), null, true, true);
-            specializeCall.startGroup().doubleQuote("Uninitialized polymorphic (").string(" + depth + ").doubleQuote("/" + node.getPolymorphicDepth() + ")").end();
-            specializeCall.end().end();
-
-            builder.declaration(node.getGenericSpecialization().getReturnType().getType(), "result", specializeCall.getRoot());
-
-            builder.statement("polymorphic.optimizeTypes()");
-
-            if (Utils.isVoid(builder.findMethod().getReturnType())) {
-                builder.returnStatement();
-            } else {
-                builder.startReturn().string("result").end();
-            }
-
-            builder.end();
-
-            return builder.getRoot();
-        }
-
-        private CodeTree createExecuteBody(CodeTreeBuilder parent, SpecializationData specialization, ExecutableTypeData execType) {
-            TypeData primaryType = specialization.getReturnType().getTypeSystemType();
-
-            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
-
-            List<ExecutableTypeData> primaryExecutes = findFunctionalExecutableType(specialization, execType.getEvaluatedCount());
-
-            if (primaryExecutes.contains(execType) || primaryExecutes.isEmpty()) {
-                builder.tree(createFunctionalExecute(builder, specialization, execType));
-            } else if (needsCastingExecuteMethod(execType, primaryType)) {
-                assert !primaryExecutes.isEmpty();
-                builder.tree(createCastingExecute(builder, specialization, execType, primaryExecutes.get(0)));
-            } else {
-                return null;
-            }
-
-            return builder.getRoot();
-        }
-
-        private CodeExecutableElement createExecutableTypeOverride(ExecutableTypeData execType, boolean evaluated) {
-            CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), execType.getMethod());
-
-            int i = 0;
-            for (VariableElement param : method.getParameters()) {
-                CodeVariableElement var = CodeVariableElement.clone(param);
-                ActualParameter actualParameter = execType.getParameters().get(i);
-                if (evaluated && actualParameter.getSpecification().isSignature()) {
-                    var.setName(valueNameEvaluated(actualParameter));
-                } else {
-                    var.setName(valueName(actualParameter));
-                }
-                method.getParameters().set(i, var);
-                i++;
-            }
-
-            method.getAnnotationMirrors().clear();
-            method.getModifiers().remove(Modifier.ABSTRACT);
-            return method;
-        }
-
-        private boolean needsCastingExecuteMethod(ExecutableTypeData execType, TypeData primaryType) {
-            if (execType.isAbstract()) {
-                return true;
-            }
-            if (Utils.isPrimitiveOrVoid(primaryType.getPrimitiveType()) && Utils.isPrimitiveOrVoid(execType.getType().getPrimitiveType())) {
-                return true;
-            }
-            if (execType.getType().isGeneric()) {
-                return true;
-            }
-            return false;
-        }
-
-        private List<ExecutableTypeData> findFunctionalExecutableType(SpecializationData specialization, int evaluatedCount) {
-            TypeData primaryType = specialization.getReturnType().getTypeSystemType();
-            List<ExecutableTypeData> otherTypes = specialization.getNode().getExecutableTypes(evaluatedCount);
-
-            List<ExecutableTypeData> filteredTypes = new ArrayList<>();
-            for (ExecutableTypeData compareType : otherTypes) {
-                if (!Utils.typeEquals(compareType.getType().getPrimitiveType(), primaryType.getPrimitiveType())) {
-                    continue;
-                }
-                filteredTypes.add(compareType);
-            }
-
-            // no direct matches found use generic where the type is Object
-            if (filteredTypes.isEmpty()) {
-                for (ExecutableTypeData compareType : otherTypes) {
-                    if (compareType.getType().isGeneric() && !compareType.hasUnexpectedValue(getContext())) {
-                        filteredTypes.add(compareType);
-                    }
-                }
-            }
-
-            if (filteredTypes.isEmpty()) {
-                for (ExecutableTypeData compareType : otherTypes) {
-                    if (compareType.getType().isGeneric()) {
-                        filteredTypes.add(compareType);
-                    }
-                }
-            }
-
-            return filteredTypes;
-        }
-
-        private CodeTree createFunctionalExecute(CodeTreeBuilder parent, SpecializationData specialization, ExecutableTypeData executable) {
-            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
-            if (specialization.isUninitialized()) {
-                builder.tree(createDeoptimize(builder));
-            }
-
-            builder.tree(createExecuteChildren(builder, executable, specialization, specialization.getParameters(), null, false));
-
-            CodeTree executeNode = createExecute(builder, executable, specialization);
-
-            SpecializationData next = specialization.findNextSpecialization();
-            CodeTree returnSpecialized = null;
-            if (next != null) {
-                CodeTreeBuilder returnBuilder = new CodeTreeBuilder(builder);
-                returnBuilder.tree(createDeoptimize(builder));
-                returnBuilder.tree(createReturnExecuteAndSpecialize(builder, executable, next, null, "One of guards " + specialization.getGuards() + " failed"));
-                returnSpecialized = returnBuilder.getRoot();
-            }
-            builder.tree(createGuardAndCast(builder, null, specialization, specialization, true, executeNode, returnSpecialized, false, false));
-
-            return builder.getRoot();
-        }
-
-        private CodeTree createExecute(CodeTreeBuilder parent, ExecutableTypeData executable, SpecializationData specialization) {
-            NodeData node = specialization.getNode();
-            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
-            if (!specialization.getExceptions().isEmpty() || !specialization.getAssumptions().isEmpty()) {
-                builder.startTryBlock();
-            }
-
-            for (String assumption : specialization.getAssumptions()) {
-                builder.startStatement();
-                builder.string("this.").string(assumption).string(".check()");
-                builder.end();
-            }
-
-            CodeTreeBuilder returnBuilder = new CodeTreeBuilder(parent);
-            if (specialization.isPolymorphic()) {
-                int index = 0;
-                if (executable.hasUnexpectedValue(getContext())) {
-                    index = specialization.getNode().getPolymorphicSpecializations().indexOf(specialization);
-                }
-                returnBuilder.startCall("next0", "executeCached" + index);
-                addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, true);
-                returnBuilder.end();
-            } else if (specialization.isUninitialized()) {
-                returnBuilder.startCall("super", EXECUTE_SPECIALIZE_NAME);
-                returnBuilder.startGroup().string(nodeSpecializationClassName(specialization)).string(".class").end();
-                addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, true);
-                returnBuilder.doubleQuote("Uninitialized monomorphic");
-                returnBuilder.end();
-            } else if (specialization.getMethod() == null && !node.needsRewrites(context)) {
-                emitEncounteredSynthetic(builder, specialization);
-            } else if (specialization.isGeneric()) {
-                returnBuilder.startCall("super", EXECUTE_GENERIC_NAME);
-                addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, true);
-                returnBuilder.end();
-            } else {
-                returnBuilder.tree(createTemplateMethodCall(returnBuilder, null, specialization, specialization, null));
-            }
-
-            if (!returnBuilder.isEmpty()) {
-                builder.startReturn();
-
-                TypeData targetType = node.getTypeSystem().findTypeData(builder.findMethod().getReturnType());
-                TypeData sourceType = specialization.getReturnType().getTypeSystemType();
-
-                if (targetType == null || sourceType == null) {
-                    builder.tree(returnBuilder.getRoot());
-                } else if (sourceType.needsCastTo(getContext(), targetType)) {
-                    builder.tree(createCallTypeSystemMethod(context, parent, node, TypeSystemCodeGenerator.expectTypeMethodName(targetType), returnBuilder.getRoot()));
-                } else {
-                    builder.tree(returnBuilder.getRoot());
-                }
-                builder.end();
-            }
-
-            if (!specialization.getExceptions().isEmpty()) {
-                for (SpecializationThrowsData exception : specialization.getExceptions()) {
-                    builder.end().startCatchBlock(exception.getJavaClass(), "ex");
-                    builder.tree(createDeoptimize(builder));
-                    builder.tree(createReturnExecuteAndSpecialize(parent, executable, exception.getTransitionTo(), null, "Thrown " + Utils.getSimpleName(exception.getJavaClass())));
-                }
-                builder.end();
-            }
-            if (!specialization.getAssumptions().isEmpty()) {
-                builder.end().startCatchBlock(getContext().getTruffleTypes().getInvalidAssumption(), "ex");
-                builder.tree(createReturnExecuteAndSpecialize(parent, executable, specialization.findNextSpecialization(), null, "Assumption failed"));
-                builder.end();
-            }
-
-            return builder.getRoot();
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,552 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.node;
-
-import java.util.*;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.node.NodeChildData.ExecutionKind;
-import com.oracle.truffle.codegen.processor.template.*;
-import com.oracle.truffle.codegen.processor.typesystem.*;
-
-public class NodeData extends Template {
-
-    private final String nodeId;
-    private NodeData declaringNode;
-    private List<NodeData> declaredNodes = new ArrayList<>();
-    private boolean nodeContainer;
-
-    private TypeSystemData typeSystem;
-    private List<NodeChildData> children;
-    private List<NodeFieldData> fields;
-    private TypeMirror nodeType;
-    private ParameterSpec instanceParameterSpec;
-
-    private List<SpecializationData> specializations;
-    private List<SpecializationData> polymorphicSpecializations;
-    private List<SpecializationListenerData> specializationListeners;
-    private Map<Integer, List<ExecutableTypeData>> executableTypes;
-    private List<ShortCircuitData> shortCircuits;
-    private List<String> assumptions;
-    private List<CreateCastData> casts;
-
-    private int polymorphicDepth = -1;
-    private String shortName;
-
-    public NodeData(TypeElement type, String id) {
-        super(type, null, null);
-        this.nodeId = id;
-    }
-
-    public NodeData(NodeData splitSource, String templateMethodName, String nodeId) {
-        super(splitSource.getTemplateType(), templateMethodName, null);
-        this.nodeId = nodeId;
-        this.declaringNode = splitSource.declaringNode;
-        this.declaredNodes = splitSource.declaredNodes;
-        this.typeSystem = splitSource.typeSystem;
-        this.nodeType = splitSource.nodeType;
-        this.specializations = splitSource.specializations;
-        this.specializationListeners = splitSource.specializationListeners;
-        this.executableTypes = splitSource.executableTypes;
-        this.shortCircuits = splitSource.shortCircuits;
-        this.fields = splitSource.fields;
-        this.children = splitSource.children;
-        this.assumptions = splitSource.assumptions;
-    }
-
-    public int getPolymorphicDepth() {
-        return polymorphicDepth;
-    }
-
-    void setPolymorphicDepth(int polymorphicDepth) {
-        this.polymorphicDepth = polymorphicDepth;
-    }
-
-    public List<CreateCastData> getCasts() {
-        return casts;
-    }
-
-    void setCasts(List<CreateCastData> casts) {
-        this.casts = casts;
-    }
-
-    void setShortName(String shortName) {
-        this.shortName = shortName;
-    }
-
-    public String getShortName() {
-        return shortName;
-    }
-
-    public boolean isNodeContainer() {
-        return nodeContainer;
-    }
-
-    void setTypeSystem(TypeSystemData typeSystem) {
-        this.typeSystem = typeSystem;
-    }
-
-    void setFields(List<NodeFieldData> fields) {
-        this.fields = fields;
-    }
-
-    public List<NodeFieldData> getFields() {
-        return fields;
-    }
-
-    void setNodeContainer(boolean splitByMethodName) {
-        this.nodeContainer = splitByMethodName;
-    }
-
-    @Override
-    protected List<MessageContainer> findChildContainers() {
-        List<MessageContainer> containerChildren = new ArrayList<>();
-        if (declaredNodes != null) {
-            containerChildren.addAll(declaredNodes);
-        }
-        if (typeSystem != null) {
-            containerChildren.add(typeSystem);
-        }
-        if (specializations != null) {
-            for (MessageContainer specialization : specializations) {
-                if (specialization.getMessageElement() != null) {
-                    containerChildren.add(specialization);
-                }
-            }
-        }
-        if (specializationListeners != null) {
-            containerChildren.addAll(specializationListeners);
-        }
-        if (executableTypes != null) {
-            containerChildren.addAll(getExecutableTypes());
-        }
-        if (shortCircuits != null) {
-            containerChildren.addAll(shortCircuits);
-        }
-        if (children != null) {
-            containerChildren.addAll(children);
-        }
-        if (fields != null) {
-            containerChildren.addAll(fields);
-        }
-        if (casts != null) {
-            containerChildren.addAll(casts);
-        }
-        return containerChildren;
-    }
-
-    public ParameterSpec getInstanceParameterSpec() {
-        return instanceParameterSpec;
-    }
-
-    public void setInstanceParameterSpec(ParameterSpec instanceParameter) {
-        this.instanceParameterSpec = instanceParameter;
-    }
-
-    public String getNodeId() {
-        return nodeId;
-    }
-
-    public TypeMirror getNodeType() {
-        if (nodeType != null) {
-            return nodeType;
-        }
-        return getTemplateType().asType();
-    }
-
-    void setAssumptions(List<String> assumptions) {
-        this.assumptions = assumptions;
-    }
-
-    public List<String> getAssumptions() {
-        return assumptions;
-    }
-
-    public boolean needsFactory() {
-        if (specializations == null) {
-            return false;
-        }
-        if (getTemplateType().getModifiers().contains(Modifier.PRIVATE)) {
-            return false;
-        }
-
-        boolean noSpecialization = true;
-        for (SpecializationData specialization : specializations) {
-            noSpecialization = noSpecialization && specialization.isGeneric() || specialization.isUninitialized();
-        }
-        return !noSpecialization;
-    }
-
-    public boolean supportsFrame() {
-        if (executableTypes != null) {
-            for (ExecutableTypeData execType : getExecutableTypes(-1)) {
-                if (execType.findParameter("frameValue") == null) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    public List<NodeData> getNodeDeclaringChildren() {
-        List<NodeData> nodeChildren = new ArrayList<>();
-        for (NodeData child : getDeclaredNodes()) {
-            if (child.needsFactory()) {
-                nodeChildren.add(child);
-            }
-            nodeChildren.addAll(child.getNodeDeclaringChildren());
-        }
-        return nodeChildren;
-    }
-
-    void setDeclaredNodes(List<NodeData> declaredChildren) {
-        this.declaredNodes = declaredChildren;
-
-        for (NodeData child : declaredChildren) {
-            child.declaringNode = this;
-        }
-    }
-
-    public NodeData getParent() {
-        return declaringNode;
-    }
-
-    public List<NodeData> getDeclaredNodes() {
-        return declaredNodes;
-    }
-
-    public void setNodeType(TypeMirror nodeType) {
-        this.nodeType = nodeType;
-    }
-
-    public List<TemplateMethod> getAllTemplateMethods() {
-        List<TemplateMethod> methods = new ArrayList<>();
-
-        for (SpecializationData specialization : getSpecializations()) {
-            methods.add(specialization);
-        }
-
-        methods.addAll(getSpecializationListeners());
-        methods.addAll(getExecutableTypes());
-        methods.addAll(getShortCircuits());
-        if (getCasts() != null) {
-            methods.addAll(getCasts());
-        }
-
-        return methods;
-    }
-
-    public ExecutableTypeData findGenericExecutableType(ProcessorContext context, TypeData type, int evaluatedCount) {
-        List<ExecutableTypeData> types = findGenericExecutableTypes(context, evaluatedCount);
-        for (ExecutableTypeData availableType : types) {
-            if (Utils.typeEquals(availableType.getType().getBoxedType(), type.getBoxedType())) {
-                return availableType;
-            }
-        }
-        return null;
-    }
-
-    public ExecutableTypeData findAnyGenericExecutableType(ProcessorContext context, int evaluatedCount) {
-        List<ExecutableTypeData> types = findGenericExecutableTypes(context, evaluatedCount);
-        for (ExecutableTypeData type : types) {
-            if (type.getType().isGeneric()) {
-                return type;
-            }
-        }
-
-        for (ExecutableTypeData type : types) {
-            if (!type.getType().isVoid()) {
-                return type;
-            }
-        }
-
-        for (ExecutableTypeData type : types) {
-            return type;
-        }
-        return null;
-    }
-
-    public List<ExecutableTypeData> getExecutableTypes(int evaluatedCount) {
-        if (executableTypes == null) {
-            return Collections.emptyList();
-        }
-        if (evaluatedCount == -1) {
-            List<ExecutableTypeData> typeData = new ArrayList<>();
-            for (int currentEvaluationCount : executableTypes.keySet()) {
-                typeData.addAll(executableTypes.get(currentEvaluationCount));
-            }
-            return typeData;
-        } else {
-            List<ExecutableTypeData> types = executableTypes.get(evaluatedCount);
-            if (types == null) {
-                return Collections.emptyList();
-            }
-            return types;
-        }
-    }
-
-    public List<ExecutableTypeData> findGenericExecutableTypes(ProcessorContext context, int evaluatedCount) {
-        List<ExecutableTypeData> types = new ArrayList<>();
-        for (ExecutableTypeData type : getExecutableTypes(evaluatedCount)) {
-            if (!type.hasUnexpectedValue(context)) {
-                types.add(type);
-            }
-        }
-        return types;
-    }
-
-    public ExecutableTypeData findExecutableType(TypeData prmitiveType, int evaluatedCount) {
-        for (ExecutableTypeData type : getExecutableTypes(evaluatedCount)) {
-            if (Utils.typeEquals(type.getType().getPrimitiveType(), prmitiveType.getPrimitiveType())) {
-                return type;
-            }
-        }
-        return null;
-    }
-
-    public SpecializationData findUniqueSpecialization(TypeData type) {
-        SpecializationData result = null;
-        for (SpecializationData specialization : specializations) {
-            if (specialization.getReturnType().getTypeSystemType() == type) {
-                if (result != null) {
-                    // Result not unique;
-                    return null;
-                }
-                result = specialization;
-            }
-        }
-        return result;
-    }
-
-    public NodeChildData[] filterFields(ExecutionKind usage) {
-        List<NodeChildData> filteredFields = new ArrayList<>();
-        for (NodeChildData field : getChildren()) {
-            if (usage == null || field.getExecutionKind() == usage) {
-                filteredFields.add(field);
-            }
-        }
-        return filteredFields.toArray(new NodeChildData[filteredFields.size()]);
-    }
-
-    public boolean needsRewrites(ProcessorContext context) {
-        boolean needsRewrites = false;
-
-        for (SpecializationData specialization : getSpecializations()) {
-            if (specialization.hasRewrite(context)) {
-                needsRewrites = true;
-                break;
-            }
-        }
-        return needsRewrites || getSpecializations().size() > 1;
-    }
-
-    public SpecializationData getGenericSpecialization() {
-        for (SpecializationData specialization : specializations) {
-            if (specialization.isGeneric()) {
-                return specialization;
-            }
-        }
-        return null;
-    }
-
-    public SpecializationData getUninitializedSpecialization() {
-        for (SpecializationData specialization : specializations) {
-            if (specialization.isUninitialized()) {
-                return specialization;
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public TypeSystemData getTypeSystem() {
-        return typeSystem;
-    }
-
-    public String dump() {
-        return dump(0);
-    }
-
-    private String dump(int level) {
-        String indent = "";
-        for (int i = 0; i < level; i++) {
-            indent += "    ";
-        }
-        StringBuilder builder = new StringBuilder();
-
-        builder.append(String.format("%s%s {", indent, toString()));
-
-        dumpProperty(builder, indent, "templateClass", Utils.getQualifiedName(getTemplateType()));
-        dumpProperty(builder, indent, "typeSystem", getTypeSystem());
-        dumpProperty(builder, indent, "fields", getChildren());
-        dumpProperty(builder, indent, "executableTypes", getExecutableTypes());
-        dumpProperty(builder, indent, "specializations", getSpecializations());
-        dumpProperty(builder, indent, "polymorphicDepth", getPolymorphicDepth());
-        dumpProperty(builder, indent, "polymorphic", getPolymorphicSpecializations());
-        dumpProperty(builder, indent, "assumptions", getAssumptions());
-        dumpProperty(builder, indent, "casts", getCasts());
-        dumpProperty(builder, indent, "messages", collectMessages());
-        if (getDeclaredNodes().size() > 0) {
-            builder.append(String.format("\n%s  children = [", indent));
-            for (NodeData node : getDeclaredNodes()) {
-                builder.append("\n");
-                builder.append(node.dump(level + 1));
-            }
-            builder.append(String.format("\n%s  ]", indent));
-        }
-        builder.append(String.format("%s}", indent));
-        return builder.toString();
-    }
-
-    private static void dumpProperty(StringBuilder b, String indent, String propertyName, Object value) {
-        if (value instanceof List) {
-            List<?> list = (List<?>) value;
-            if (!list.isEmpty()) {
-                b.append(String.format("\n%s  %s = %s", indent, propertyName, dumpList(indent, (List<?>) value)));
-            }
-        } else {
-            if (value != null) {
-                b.append(String.format("\n%s  %s = %s", indent, propertyName, value));
-            }
-        }
-    }
-
-    private static String dumpList(String indent, List<?> array) {
-        if (array == null) {
-            return "null";
-        }
-
-        if (array.isEmpty()) {
-            return "[]";
-        } else if (array.size() == 1) {
-            return "[" + array.get(0).toString() + "]";
-        }
-
-        StringBuilder b = new StringBuilder();
-        b.append("[");
-        for (Object object : array) {
-            b.append("\n        ");
-            b.append(indent);
-            b.append(object);
-            b.append(", ");
-        }
-        b.append("\n    ").append(indent).append("]");
-        return b.toString();
-    }
-
-    public NodeChildData findChild(String name) {
-        for (NodeChildData field : getChildren()) {
-            if (field.getName().equals(name)) {
-                return field;
-            }
-        }
-        return null;
-    }
-
-    public List<NodeChildData> getChildren() {
-        return children;
-    }
-
-    void setChildren(List<NodeChildData> fields) {
-        this.children = fields;
-    }
-
-    public List<SpecializationData> getSpecializations() {
-        return getSpecializations(false);
-    }
-
-    public List<SpecializationData> getSpecializations(boolean userDefinedOnly) {
-        if (userDefinedOnly) {
-            List<SpecializationData> specs = new ArrayList<>();
-            for (SpecializationData spec : specializations) {
-                if (spec.getMethod() != null) {
-                    specs.add(spec);
-                }
-            }
-            return specs;
-        } else {
-            return specializations;
-        }
-    }
-
-    public List<SpecializationListenerData> getSpecializationListeners() {
-        return specializationListeners;
-    }
-
-    public List<ExecutableTypeData> getExecutableTypes() {
-        return getExecutableTypes(-1);
-    }
-
-    public List<ShortCircuitData> getShortCircuits() {
-        return shortCircuits;
-    }
-
-    void setSpecializations(List<SpecializationData> specializations) {
-        this.specializations = specializations;
-        if (this.specializations != null) {
-            for (SpecializationData specialization : specializations) {
-                specialization.setNode(this);
-            }
-        }
-    }
-
-    void setPolymorphicSpecializations(List<SpecializationData> polymorphicSpecializations) {
-        this.polymorphicSpecializations = polymorphicSpecializations;
-    }
-
-    public List<SpecializationData> getPolymorphicSpecializations() {
-        return polymorphicSpecializations;
-    }
-
-    void setSpecializationListeners(List<SpecializationListenerData> specializationListeners) {
-        this.specializationListeners = specializationListeners;
-    }
-
-    void setExecutableTypes(Map<Integer, List<ExecutableTypeData>> executableTypes) {
-        this.executableTypes = executableTypes;
-    }
-
-    void setShortCircuits(List<ShortCircuitData> shortCircuits) {
-        this.shortCircuits = shortCircuits;
-    }
-
-    @Override
-    public String toString() {
-        return getClass().getSimpleName() + "[" + getNodeId() + "]";
-    }
-
-    public CreateCastData findCast(String name) {
-        if (getCasts() != null) {
-            for (CreateCastData cast : getCasts()) {
-                if (cast.getChildNames().contains(name)) {
-                    return cast;
-                }
-            }
-        }
-        return null;
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeFieldData.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.node;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-
-import com.oracle.truffle.codegen.processor.template.*;
-
-public class NodeFieldData extends MessageContainer {
-
-    private VariableElement variable;
-
-    public NodeFieldData(VariableElement var) {
-        this.variable = var;
-    }
-
-    @Override
-    public Element getMessageElement() {
-        return variable;
-    }
-
-    public String getName() {
-        return variable.getSimpleName().toString();
-    }
-
-    public TypeMirror getType() {
-        return variable.asType();
-    }
-
-    public VariableElement getVariable() {
-        return variable;
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeMethodParser.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,145 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.node;
-
-import java.util.*;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.node.NodeChildData.Cardinality;
-import com.oracle.truffle.codegen.processor.node.NodeChildData.ExecutionKind;
-import com.oracle.truffle.codegen.processor.template.*;
-
-public abstract class NodeMethodParser<E extends TemplateMethod> extends TemplateMethodParser<NodeData, E> {
-
-    public NodeMethodParser(ProcessorContext context, NodeData node) {
-        super(context, node);
-    }
-
-    public NodeData getNode() {
-        return template;
-    }
-
-    @SuppressWarnings("unused")
-    protected ParameterSpec createValueParameterSpec(String valueName, NodeData nodeData, int evaluatedCount) {
-        ParameterSpec spec = new ParameterSpec(valueName, nodeTypeMirrors(nodeData));
-        spec.setSignature(true);
-        return spec;
-    }
-
-    protected List<TypeMirror> nodeTypeMirrors(NodeData nodeData) {
-        Set<TypeMirror> typeMirrors = new LinkedHashSet<>();
-
-        for (ExecutableTypeData typeData : nodeData.getExecutableTypes()) {
-            typeMirrors.add(typeData.getType().getPrimitiveType());
-        }
-
-        typeMirrors.add(nodeData.getTypeSystem().getGenericType());
-
-        return new ArrayList<>(typeMirrors);
-    }
-
-    protected ParameterSpec createReturnParameterSpec() {
-        return createValueParameterSpec("returnValue", getNode(), 0);
-    }
-
-    @Override
-    public boolean isParsable(ExecutableElement method) {
-        if (getAnnotationType() != null) {
-            return Utils.findAnnotationMirror(getContext().getEnvironment(), method, getAnnotationType()) != null;
-        }
-
-        return true;
-    }
-
-    @SuppressWarnings("unused")
-    protected final MethodSpec createDefaultMethodSpec(ExecutableElement method, AnnotationMirror mirror, boolean shortCircuitsEnabled, String shortCircuitName) {
-        MethodSpec methodSpec = new MethodSpec(createReturnParameterSpec());
-
-        addDefaultFrame(methodSpec);
-        addDefaultImplicitThis(method, methodSpec);
-        addDefaultFieldMethodSpec(method, methodSpec);
-        addDefaultChildren(shortCircuitsEnabled, shortCircuitName, methodSpec);
-
-        return methodSpec;
-    }
-
-    private void addDefaultChildren(boolean shortCircuitsEnabled, String shortCircuitName, MethodSpec methodSpec) {
-        // children are null when parsing executable types
-        if (getNode().getChildren() != null) {
-            for (NodeChildData child : getNode().getChildren()) {
-                if (child.getExecutionKind() == ExecutionKind.DEFAULT) {
-                    ParameterSpec spec = createValueParameterSpec(child.getName(), child.getNodeData(), child.getExecuteWith().size());
-                    if (child.getCardinality().isMany()) {
-                        spec.setCardinality(Cardinality.MANY);
-                        spec.setIndexed(true);
-                    }
-                    methodSpec.addRequired(spec);
-                } else if (child.getExecutionKind() == ExecutionKind.SHORT_CIRCUIT) {
-                    String valueName = child.getName();
-                    if (shortCircuitName != null && valueName.equals(shortCircuitName)) {
-                        break;
-                    }
-
-                    if (shortCircuitsEnabled) {
-                        methodSpec.addRequired(new ParameterSpec(shortCircuitValueName(valueName), getContext().getType(boolean.class)));
-                    }
-                    methodSpec.addRequired(createValueParameterSpec(valueName, child.getNodeData(), child.getExecuteWith().size()));
-                } else {
-                    assert false;
-                }
-            }
-        }
-    }
-
-    private void addDefaultFrame(MethodSpec methodSpec) {
-        if (getNode().supportsFrame()) {
-            methodSpec.addOptional(new ParameterSpec("frame", getContext().getTruffleTypes().getFrame()));
-        }
-    }
-
-    protected void addDefaultFieldMethodSpec(ExecutableElement method, MethodSpec methodSpec) {
-        for (NodeFieldData field : getNode().getFields()) {
-            if (!Utils.isFieldAccessible(method, field.getVariable())) {
-                ParameterSpec spec = new ParameterSpec(field.getName(), field.getType());
-                spec.setLocal(true);
-                methodSpec.addOptional(spec);
-            }
-        }
-    }
-
-    protected void addDefaultImplicitThis(ExecutableElement method, MethodSpec methodSpec) {
-        TypeMirror declaredType = Utils.findNearestEnclosingType(method).asType();
-
-        if (!method.getModifiers().contains(Modifier.STATIC) && !Utils.isAssignable(getContext(), declaredType, getContext().getTruffleTypes().getNode())) {
-            methodSpec.addImplicitRequiredType(getNode().getTemplateType().asType());
-        }
-    }
-
-    private static String shortCircuitValueName(String valueName) {
-        return "has" + Utils.firstLetterUpperCase(valueName);
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1190 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.node;
-
-import java.lang.annotation.*;
-import java.util.*;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-import javax.lang.model.util.*;
-import javax.tools.Diagnostic.Kind;
-
-import com.oracle.truffle.api.codegen.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.node.NodeChildData.Cardinality;
-import com.oracle.truffle.codegen.processor.node.NodeChildData.ExecutionKind;
-import com.oracle.truffle.codegen.processor.template.*;
-import com.oracle.truffle.codegen.processor.template.TemplateMethod.Signature;
-import com.oracle.truffle.codegen.processor.typesystem.*;
-
-public class NodeParser extends TemplateParser<NodeData> {
-
-    public static final List<Class<? extends Annotation>> ANNOTATIONS = Arrays.asList(Generic.class, TypeSystemReference.class, ShortCircuit.class, Specialization.class, SpecializationListener.class,
-                    NodeContainer.class, NodeChild.class, NodeChildren.class, NodeId.class);
-
-    private Map<String, NodeData> parsedNodes;
-
-    public NodeParser(ProcessorContext c) {
-        super(c);
-    }
-
-    @Override
-    protected NodeData parse(Element element, AnnotationMirror mirror) {
-        assert element instanceof TypeElement;
-        NodeData node = null;
-        try {
-            parsedNodes = new HashMap<>();
-            node = resolveNode((TypeElement) element);
-            if (Log.DEBUG) {
-                NodeData parsed = parsedNodes.get(Utils.getQualifiedName((TypeElement) element));
-                if (node != null) {
-                    String dump = parsed.dump();
-                    log.message(Kind.ERROR, null, null, null, dump);
-                }
-            }
-        } finally {
-            parsedNodes = null;
-        }
-
-        return node;
-    }
-
-    @Override
-    protected NodeData filterErrorElements(NodeData model) {
-        for (Iterator<NodeData> iterator = model.getDeclaredNodes().iterator(); iterator.hasNext();) {
-            NodeData node = filterErrorElements(iterator.next());
-            if (node == null) {
-                iterator.remove();
-            }
-        }
-        if (model.hasErrors()) {
-            return null;
-        }
-        return model;
-    }
-
-    @Override
-    public boolean isDelegateToRootDeclaredType() {
-        return true;
-    }
-
-    @Override
-    public Class<? extends Annotation> getAnnotationType() {
-        return null;
-    }
-
-    @Override
-    public List<Class<? extends Annotation>> getTypeDelegatedAnnotationTypes() {
-        return ANNOTATIONS;
-    }
-
-    private NodeData resolveNode(TypeElement rootType) {
-        String typeName = Utils.getQualifiedName(rootType);
-        if (parsedNodes.containsKey(typeName)) {
-            return parsedNodes.get(typeName);
-        }
-
-        List<? extends TypeElement> types = ElementFilter.typesIn(rootType.getEnclosedElements());
-
-        List<NodeData> children = new ArrayList<>();
-        for (TypeElement childElement : types) {
-            NodeData childNode = resolveNode(childElement);
-            if (childNode != null) {
-                children.add(childNode);
-            }
-        }
-
-        NodeData rootNode = parseNode(rootType);
-        if (rootNode == null && children.size() > 0) {
-            rootNode = new NodeData(rootType, rootType.getSimpleName().toString());
-        }
-
-        parsedNodes.put(typeName, rootNode);
-
-        if (rootNode != null) {
-            children.addAll(rootNode.getDeclaredNodes());
-            rootNode.setDeclaredNodes(children);
-        }
-
-        return rootNode;
-    }
-
-    private NodeData parseNode(TypeElement originalTemplateType) {
-        // reloading the type elements is needed for ecj
-        TypeElement templateType = Utils.fromTypeMirror(context.reloadTypeElement(originalTemplateType));
-
-        if (Utils.findAnnotationMirror(processingEnv, originalTemplateType, GeneratedBy.class) != null) {
-            // generated nodes should not get called again.
-            return null;
-        }
-
-        List<TypeElement> lookupTypes = findSuperClasses(new ArrayList<TypeElement>(), templateType);
-        Collections.reverse(lookupTypes);
-
-        AnnotationMirror nodeClass = findFirstAnnotation(lookupTypes, NodeContainer.class);
-        TypeMirror nodeType = null;
-        if (Utils.isAssignable(context, templateType.asType(), context.getTruffleTypes().getNode())) {
-            nodeType = templateType.asType();
-        }
-        if (nodeClass != null) {
-            nodeType = inheritType(nodeClass, "value", nodeType);
-        }
-
-        if (nodeType == null) {
-            return null;
-        }
-
-        Elements elementUtil = context.getEnvironment().getElementUtils();
-        Set<Element> elementSet = new HashSet<>(elementUtil.getAllMembers(templateType));
-        if (!Utils.typeEquals(templateType.asType(), nodeType)) {
-            elementSet.addAll(elementUtil.getAllMembers(Utils.fromTypeMirror(nodeType)));
-
-            List<TypeElement> nodeLookupTypes = findSuperClasses(new ArrayList<TypeElement>(), Utils.fromTypeMirror(nodeType));
-            Collections.reverse(nodeLookupTypes);
-            lookupTypes.addAll(nodeLookupTypes);
-
-            Set<TypeElement> types = new HashSet<>();
-            for (ListIterator<TypeElement> iterator = lookupTypes.listIterator(); iterator.hasNext();) {
-                TypeElement typeElement = iterator.next();
-                if (types.contains(typeElement)) {
-                    iterator.remove();
-                } else {
-                    types.add(typeElement);
-                }
-            }
-        }
-        List<Element> elements = new ArrayList<>(elementSet);
-
-        NodeData node = parseNodeData(templateType, nodeType, elements, lookupTypes);
-
-        if (node.hasErrors()) {
-            return node; // error sync point
-        }
-
-        parseMethods(node, elements);
-
-        if (node.hasErrors()) {
-            return node;
-        }
-
-        List<NodeData> nodes;
-
-        if (node.isNodeContainer()) {
-            nodes = splitNodeData(node);
-        } else {
-            nodes = new ArrayList<>();
-            nodes.add(node);
-        }
-
-        for (NodeData splittedNode : nodes) {
-            finalizeSpecializations(elements, splittedNode);
-            verifyNode(splittedNode, elements);
-            splittedNode.setPolymorphicSpecializations(createPolymorphicSpecializations(splittedNode));
-            assignShortCircuitsToSpecializations(splittedNode);
-        }
-
-        if (node.isNodeContainer()) {
-            node.setDeclaredNodes(nodes);
-            node.setSpecializationListeners(new ArrayList<SpecializationListenerData>());
-            node.setSpecializations(new ArrayList<SpecializationData>());
-        }
-        return node;
-    }
-
-    private List<SpecializationData> createPolymorphicSpecializations(NodeData node) {
-        if (!node.needsRewrites(context) || node.getPolymorphicDepth() <= 1) {
-            return Collections.emptyList();
-        }
-
-        Signature genericSignature = node.getGenericSpecialization().getSignature();
-        Set<Signature> signatures = new HashSet<>();
-
-        for (SpecializationData specialization1 : node.getSpecializations()) {
-            Signature signature = specialization1.getSignature();
-
-            for (SpecializationData specialization2 : node.getSpecializations()) {
-                if (specialization1 == specialization2) {
-                    continue;
-                }
-                signatures.add(signature.combine(genericSignature, specialization2.getSignature()));
-            }
-        }
-
-        while (true) {
-            List<Signature> newSignatures = new ArrayList<>();
-            for (Signature signature1 : signatures) {
-                for (Signature signature2 : signatures) {
-                    if (signature1 == signature2) {
-                        continue;
-                    }
-                    newSignatures.add(signature1.combine(genericSignature, signature2));
-                }
-            }
-            if (!signatures.addAll(newSignatures)) {
-                break;
-            }
-        }
-
-        List<Signature> sortedSignatures = new ArrayList<>(signatures);
-        Collections.sort(sortedSignatures);
-
-        List<SpecializationData> specializations = new ArrayList<>();
-        SpecializationData generic = node.getGenericSpecialization();
-        for (Signature signature : sortedSignatures) {
-            SpecializationData specialization = new SpecializationData(generic, false, false, true);
-            specialization.forceFrame(context.getTruffleTypes().getFrame());
-            specialization.setNode(node);
-            specialization.updateSignature(signature);
-
-            if (specialization.isGenericSpecialization(context)) {
-                specializations.add(0, specialization);
-            } else {
-                specializations.add(specialization);
-            }
-        }
-
-        return specializations;
-    }
-
-    private NodeData parseNodeData(TypeElement templateType, TypeMirror nodeType, List<? extends Element> elements, List<TypeElement> lookupTypes) {
-        NodeData nodeData = new NodeData(templateType, templateType.getSimpleName().toString());
-
-        AnnotationMirror typeSystemMirror = findFirstAnnotation(lookupTypes, TypeSystemReference.class);
-        if (typeSystemMirror == null) {
-            nodeData.addError("No @%s annotation found in type hierarchy of %s.", TypeSystemReference.class.getSimpleName(), Utils.getQualifiedName(nodeType));
-            return nodeData;
-        }
-
-        TypeMirror typeSytemType = Utils.getAnnotationValue(TypeMirror.class, typeSystemMirror, "value");
-        final TypeSystemData typeSystem = (TypeSystemData) context.getTemplate(typeSytemType, true);
-        if (typeSystem == null) {
-            nodeData.addError("The used type system '%s' is invalid or not a Node.", Utils.getQualifiedName(typeSytemType));
-            return nodeData;
-        }
-
-        AnnotationMirror polymorphicMirror = findFirstAnnotation(lookupTypes, PolymorphicLimit.class);
-        if (polymorphicMirror != null) {
-            AnnotationValue limitValue = Utils.getAnnotationValue(polymorphicMirror, "value");
-            int polymorphicLimit = Utils.getAnnotationValue(Integer.class, polymorphicMirror, "value");
-            if (polymorphicLimit < 1) {
-                nodeData.addError(limitValue, "Invalid polymorphic limit %s.", polymorphicLimit);
-            }
-            nodeData.setPolymorphicDepth(polymorphicLimit);
-        }
-
-        List<String> assumptionsList = new ArrayList<>();
-        for (int i = lookupTypes.size() - 1; i >= 0; i--) {
-            TypeElement type = lookupTypes.get(i);
-            AnnotationMirror assumptions = Utils.findAnnotationMirror(context.getEnvironment(), type, NodeAssumptions.class);
-            if (assumptions != null) {
-                List<String> assumptionStrings = Utils.getAnnotationValueList(String.class, assumptions, "value");
-                for (String string : assumptionStrings) {
-                    if (assumptionsList.contains(string)) {
-                        assumptionsList.remove(string);
-                    }
-                    assumptionsList.add(string);
-                }
-            }
-        }
-        AnnotationMirror nodeInfoMirror = findFirstAnnotation(lookupTypes, NodeInfo.class);
-        if (nodeInfoMirror != null) {
-            nodeData.setShortName(Utils.getAnnotationValue(String.class, nodeInfoMirror, "shortName"));
-        }
-
-        nodeData.setAssumptions(new ArrayList<>(assumptionsList));
-        nodeData.setNodeType(nodeType);
-        AnnotationMirror nodeContainer = findFirstAnnotation(lookupTypes, NodeContainer.class);
-        nodeData.setNodeContainer(nodeContainer != null);
-        nodeData.setTypeSystem(typeSystem);
-        nodeData.setFields(parseFields(elements));
-        parsedNodes.put(Utils.getQualifiedName(templateType), nodeData);
-        // parseChildren invokes cyclic parsing.
-        nodeData.setChildren(parseChildren(elements, lookupTypes));
-        nodeData.setExecutableTypes(groupExecutableTypes(new ExecutableTypeMethodParser(context, nodeData).parse(elements)));
-
-        return nodeData;
-    }
-
-    private static List<NodeFieldData> parseFields(List<? extends Element> elements) {
-        List<NodeFieldData> fields = new ArrayList<>();
-        for (VariableElement field : ElementFilter.fieldsIn(elements)) {
-            if (field.getModifiers().contains(Modifier.STATIC)) {
-                continue;
-            }
-            if (field.getModifiers().contains(Modifier.PUBLIC) || field.getModifiers().contains(Modifier.PROTECTED)) {
-                fields.add(new NodeFieldData(field));
-            }
-        }
-        return fields;
-    }
-
-    private List<NodeChildData> parseChildren(List<? extends Element> elements, final List<TypeElement> typeHierarchy) {
-        Set<String> shortCircuits = new HashSet<>();
-        for (ExecutableElement method : ElementFilter.methodsIn(elements)) {
-            AnnotationMirror mirror = Utils.findAnnotationMirror(processingEnv, method, ShortCircuit.class);
-            if (mirror != null) {
-                shortCircuits.add(Utils.getAnnotationValue(String.class, mirror, "value"));
-            }
-        }
-        Map<String, TypeMirror> castNodeTypes = new HashMap<>();
-        for (ExecutableElement method : ElementFilter.methodsIn(elements)) {
-            AnnotationMirror mirror = Utils.findAnnotationMirror(processingEnv, method, CreateCast.class);
-            if (mirror != null) {
-                List<String> children = (Utils.getAnnotationValueList(String.class, mirror, "value"));
-                if (children != null) {
-                    for (String child : children) {
-                        castNodeTypes.put(child, method.getReturnType());
-                    }
-                }
-            }
-        }
-
-        List<NodeChildData> parsedChildren = new ArrayList<>();
-        List<TypeElement> typeHierarchyReversed = new ArrayList<>(typeHierarchy);
-        Collections.reverse(typeHierarchyReversed);
-        for (TypeElement type : typeHierarchyReversed) {
-            AnnotationMirror nodeClassMirror = Utils.findAnnotationMirror(processingEnv, type, NodeContainer.class);
-            AnnotationMirror nodeChildrenMirror = Utils.findAnnotationMirror(processingEnv, type, NodeChildren.class);
-
-            TypeMirror nodeClassType = type.getSuperclass();
-            if (!Utils.isAssignable(context, nodeClassType, context.getTruffleTypes().getNode())) {
-                nodeClassType = null;
-            }
-
-            if (nodeClassMirror != null) {
-                nodeClassType = inheritType(nodeClassMirror, "value", nodeClassType);
-            }
-
-            List<AnnotationMirror> children = Utils.collectAnnotations(context, nodeChildrenMirror, "value", type, NodeChild.class);
-            int index = 0;
-            for (AnnotationMirror childMirror : children) {
-                String name = Utils.getAnnotationValue(String.class, childMirror, "value");
-                if (name.equals("")) {
-                    name = "child" + index;
-                }
-
-                Cardinality cardinality = Cardinality.ONE;
-
-                TypeMirror childType = inheritType(childMirror, "type", nodeClassType);
-                if (childType.getKind() == TypeKind.ARRAY) {
-                    cardinality = Cardinality.MANY;
-                }
-
-                TypeMirror originalChildType = childType;
-                TypeMirror castNodeType = castNodeTypes.get(name);
-                if (castNodeType != null) {
-                    childType = castNodeType;
-                }
-
-                Element getter = findGetter(elements, name, childType);
-
-                ExecutionKind kind = ExecutionKind.DEFAULT;
-                if (shortCircuits.contains(name)) {
-                    kind = ExecutionKind.SHORT_CIRCUIT;
-                }
-
-                NodeChildData nodeChild = new NodeChildData(type, childMirror, name, childType, originalChildType, getter, cardinality, kind);
-
-                parsedChildren.add(nodeChild);
-
-                verifyNodeChild(nodeChild);
-                if (nodeChild.hasErrors()) {
-                    continue;
-                }
-
-                NodeData fieldNodeData = resolveNode(Utils.fromTypeMirror(childType));
-                nodeChild.setNode(fieldNodeData);
-                if (fieldNodeData == null) {
-                    nodeChild.addError("Node type '%s' is invalid or not a valid Node.", Utils.getQualifiedName(childType));
-                }
-
-            }
-            index++;
-        }
-
-        List<NodeChildData> filteredChildren = new ArrayList<>();
-        Set<String> encounteredNames = new HashSet<>();
-        for (int i = parsedChildren.size() - 1; i >= 0; i--) {
-            NodeChildData child = parsedChildren.get(i);
-            if (!encounteredNames.contains(child.getName())) {
-                filteredChildren.add(0, child);
-                encounteredNames.add(child.getName());
-            }
-        }
-
-        for (NodeChildData child : filteredChildren) {
-            List<String> executeWithStrings = Utils.getAnnotationValueList(String.class, child.getMessageAnnotation(), "executeWith");
-            AnnotationValue executeWithValue = Utils.getAnnotationValue(child.getMessageAnnotation(), "executeWith");
-            List<NodeChildData> executeWith = new ArrayList<>();
-            for (String executeWithString : executeWithStrings) {
-
-                if (child.getName().equals(executeWithString)) {
-                    child.addError(executeWithValue, "The child node '%s' cannot be executed with itself.", executeWithString);
-                    continue;
-                }
-
-                NodeChildData found = null;
-                boolean before = true;
-                for (NodeChildData resolveChild : filteredChildren) {
-                    if (resolveChild == child) {
-                        before = false;
-                        continue;
-                    }
-                    if (resolveChild.getName().equals(executeWithString)) {
-                        found = resolveChild;
-                        break;
-                    }
-                }
-
-                if (found == null) {
-                    child.addError(executeWithValue, "The child node '%s' cannot be executed with '%s'. The child node was not found.", child.getName(), executeWithString);
-                    continue;
-                } else if (!before) {
-                    child.addError(executeWithValue, "The child node '%s' cannot be executed with '%s'. The node %s is executed after the current node.", child.getName(), executeWithString,
-                                    executeWithString);
-                    continue;
-                }
-                executeWith.add(found);
-            }
-            child.setExecuteWith(executeWith);
-            if (child.getNodeData() == null) {
-                continue;
-            }
-
-            List<ExecutableTypeData> types = child.findGenericExecutableTypes(context);
-            if (types.isEmpty()) {
-                child.addError(executeWithValue, "No generic execute method found with %s evaluated arguments for node type %s.", executeWith.size(), Utils.getSimpleName(child.getNodeType()));
-                continue;
-            }
-        }
-
-        return filteredChildren;
-    }
-
-    private void parseMethods(final NodeData node, List<Element> elements) {
-        node.setShortCircuits(new ShortCircuitParser(context, node).parse(elements));
-        node.setSpecializationListeners(new SpecializationListenerParser(context, node).parse(elements));
-        List<SpecializationData> generics = new GenericParser(context, node).parse(elements);
-        List<SpecializationData> specializations = new SpecializationMethodParser(context, node).parse(elements);
-        node.setCasts(new CreateCastParser(context, node).parse(elements));
-
-        List<SpecializationData> allSpecializations = new ArrayList<>();
-        allSpecializations.addAll(generics);
-        allSpecializations.addAll(specializations);
-
-        node.setSpecializations(allSpecializations);
-    }
-
-    private static List<NodeData> splitNodeData(NodeData node) {
-        SortedMap<String, List<SpecializationData>> groupedSpecializations = groupByNodeId(node.getSpecializations());
-        SortedMap<String, List<SpecializationListenerData>> groupedListeners = groupByNodeId(node.getSpecializationListeners());
-        SortedMap<String, List<CreateCastData>> groupedCasts = groupByNodeId(node.getCasts());
-
-        Set<String> ids = new TreeSet<>();
-        ids.addAll(groupedSpecializations.keySet());
-        ids.addAll(groupedListeners.keySet());
-
-        List<NodeData> splitted = new ArrayList<>();
-        for (String id : ids) {
-            List<SpecializationData> specializations = groupedSpecializations.get(id);
-            List<SpecializationListenerData> listeners = groupedListeners.get(id);
-            List<CreateCastData> casts = groupedCasts.get(id);
-
-            if (specializations == null) {
-                specializations = new ArrayList<>();
-            }
-
-            if (listeners == null) {
-                listeners = new ArrayList<>();
-            }
-
-            String nodeId = node.getNodeId();
-            if (nodeId.endsWith("Node") && !nodeId.equals("Node")) {
-                nodeId = nodeId.substring(0, nodeId.length() - 4);
-            }
-            String newNodeId = nodeId + Utils.firstLetterUpperCase(id);
-            NodeData copy = new NodeData(node, id, newNodeId);
-
-            copy.setSpecializations(specializations);
-            copy.setSpecializationListeners(listeners);
-            copy.setCasts(casts);
-
-            splitted.add(copy);
-        }
-
-        node.setSpecializations(new ArrayList<SpecializationData>());
-        node.setSpecializationListeners(new ArrayList<SpecializationListenerData>());
-        node.setCasts(new ArrayList<CreateCastData>());
-
-        return splitted;
-    }
-
-    private void finalizeSpecializations(List<Element> elements, final NodeData node) {
-        List<SpecializationData> specializations = new ArrayList<>(node.getSpecializations());
-
-        if (specializations.isEmpty()) {
-            return;
-        }
-
-        for (SpecializationData specialization : specializations) {
-            matchGuards(elements, specialization);
-        }
-
-        List<SpecializationData> generics = new ArrayList<>();
-        for (SpecializationData spec : specializations) {
-            if (spec.isGeneric()) {
-                generics.add(spec);
-            }
-        }
-
-        if (generics.size() == 1 && specializations.size() == 1) {
-            for (SpecializationData generic : generics) {
-                generic.addError("@%s defined but no @%s.", Generic.class.getSimpleName(), Specialization.class.getSimpleName());
-            }
-        }
-
-        SpecializationData genericSpecialization = null;
-        if (generics.size() > 1) {
-            for (SpecializationData generic : generics) {
-                generic.addError("Only @%s is allowed per operation.", Generic.class.getSimpleName());
-            }
-            return;
-        } else if (generics.size() == 1) {
-            genericSpecialization = generics.get(0);
-        } else if (node.needsRewrites(context)) {
-            SpecializationData specialization = specializations.get(0);
-            GenericParser parser = new GenericParser(context, node);
-            MethodSpec specification = parser.createDefaultMethodSpec(specialization.getMethod(), null, true, null);
-
-            ExecutableTypeData anyGenericReturnType = node.findAnyGenericExecutableType(context, 0);
-            assert anyGenericReturnType != null;
-
-            ActualParameter returnType = new ActualParameter(specification.getReturnType(), anyGenericReturnType.getType(), 0, false);
-            List<ActualParameter> parameters = new ArrayList<>();
-            for (ActualParameter specializationParameter : specialization.getParameters()) {
-                ParameterSpec parameterSpec = specification.findParameterSpec(specializationParameter.getSpecification().getName());
-                NodeChildData child = node.findChild(parameterSpec.getName());
-                TypeData actualType;
-                if (child == null) {
-                    actualType = specializationParameter.getTypeSystemType();
-                } else {
-                    ExecutableTypeData paramType = child.findAnyGenericExecutableType(context);
-                    assert paramType != null;
-                    actualType = paramType.getType();
-                }
-
-                if (actualType != null) {
-                    parameters.add(new ActualParameter(parameterSpec, actualType, specializationParameter.getIndex(), specializationParameter.isImplicit()));
-                } else {
-                    parameters.add(new ActualParameter(parameterSpec, specializationParameter.getType(), specializationParameter.getIndex(), specializationParameter.isImplicit()));
-                }
-            }
-            TemplateMethod genericMethod = new TemplateMethod("Generic", node, specification, null, null, returnType, parameters);
-            genericSpecialization = new SpecializationData(genericMethod, true, false, false);
-
-            specializations.add(genericSpecialization);
-        }
-
-        if (genericSpecialization != null) {
-            for (ActualParameter parameter : genericSpecialization.getReturnTypeAndParameters()) {
-                if (Utils.isObject(parameter.getType())) {
-                    continue;
-                }
-                Set<String> types = new HashSet<>();
-                for (SpecializationData specialization : specializations) {
-                    ActualParameter actualParameter = specialization.findParameter(parameter.getLocalName());
-                    if (actualParameter != null) {
-                        types.add(Utils.getQualifiedName(actualParameter.getType()));
-                    }
-                }
-                if (types.size() > 1) {
-                    genericSpecialization.replaceParameter(parameter.getLocalName(), new ActualParameter(parameter, node.getTypeSystem().getGenericTypeData()));
-                }
-            }
-            TemplateMethod uninializedMethod = new TemplateMethod("Uninitialized", node, genericSpecialization.getSpecification(), null, null, genericSpecialization.getReturnType(),
-                            genericSpecialization.getParameters());
-            // should not use messages from generic specialization
-            uninializedMethod.getMessages().clear();
-            specializations.add(new SpecializationData(uninializedMethod, false, true, false));
-        }
-
-        Collections.sort(specializations);
-
-        node.setSpecializations(specializations);
-
-        List<SpecializationData> needsId = new ArrayList<>();
-        for (SpecializationData specialization : specializations) {
-            if (specialization.isGeneric()) {
-                specialization.setId("Generic");
-            } else if (specialization.isUninitialized()) {
-                specialization.setId("Uninitialized");
-            } else {
-                needsId.add(specialization);
-            }
-        }
-
-        // verify specialization parameter length
-        if (verifySpecializationParameters(node)) {
-            List<String> ids = calculateSpecializationIds(needsId);
-            for (int i = 0; i < ids.size(); i++) {
-                needsId.get(i).setId(ids.get(i));
-            }
-        }
-
-        // calculate reachability
-        int specializationCount = 0;
-        boolean reachable = true;
-        for (SpecializationData specialization : specializations) {
-            if (specialization.isUninitialized()) {
-                specialization.setReachable(true);
-                continue;
-            }
-            if (!reachable && specialization.getMethod() != null) {
-                specialization.addError("%s is not reachable.", specialization.isGeneric() ? "Generic" : "Specialization");
-            }
-            specialization.setReachable(reachable);
-            if (!specialization.hasRewrite(context)) {
-                reachable = false;
-            }
-            if (!specialization.isGeneric()) {
-                specializationCount++;
-            }
-        }
-
-        if (node.getPolymorphicDepth() < 0) {
-            node.setPolymorphicDepth(specializationCount - 1);
-        }
-
-        // reduce polymorphicness if generic is not reachable
-        if (node.getGenericSpecialization() != null && !node.getGenericSpecialization().isReachable()) {
-            node.setPolymorphicDepth(1);
-        }
-    }
-
-    private void assignShortCircuitsToSpecializations(NodeData node) {
-        Map<String, List<ShortCircuitData>> groupedShortCircuits = groupShortCircuits(node.getShortCircuits());
-
-        boolean valid = true;
-        for (NodeChildData field : node.filterFields(ExecutionKind.SHORT_CIRCUIT)) {
-            String valueName = field.getName();
-            List<ShortCircuitData> availableCircuits = groupedShortCircuits.get(valueName);
-
-            if (availableCircuits == null || availableCircuits.isEmpty()) {
-                node.addError("@%s method for short cut value '%s' required.", ShortCircuit.class.getSimpleName(), valueName);
-                valid = false;
-                continue;
-            }
-
-            boolean sameMethodName = true;
-            String methodName = availableCircuits.get(0).getMethodName();
-            for (ShortCircuitData circuit : availableCircuits) {
-                if (!circuit.getMethodName().equals(methodName)) {
-                    sameMethodName = false;
-                }
-            }
-
-            if (!sameMethodName) {
-                for (ShortCircuitData circuit : availableCircuits) {
-                    circuit.addError("All short circuits for short cut value '%s' must have the same method name.", valueName);
-                }
-                valid = false;
-                continue;
-            }
-
-            ShortCircuitData genericCircuit = null;
-            for (ShortCircuitData circuit : availableCircuits) {
-                if (isGenericShortCutMethod(node, circuit)) {
-                    genericCircuit = circuit;
-                    break;
-                }
-            }
-
-            if (genericCircuit == null) {
-                node.addError("No generic @%s method available for short cut value '%s'.", ShortCircuit.class.getSimpleName(), valueName);
-                valid = false;
-                continue;
-            }
-
-            for (ShortCircuitData circuit : availableCircuits) {
-                if (circuit != genericCircuit) {
-                    circuit.setGenericShortCircuitMethod(genericCircuit);
-                }
-            }
-        }
-
-        if (!valid) {
-            return;
-        }
-
-        NodeChildData[] fields = node.filterFields(ExecutionKind.SHORT_CIRCUIT);
-        List<SpecializationData> specializations = new ArrayList<>();
-        specializations.addAll(node.getSpecializations());
-        specializations.addAll(node.getPolymorphicSpecializations());
-
-        for (SpecializationData specialization : specializations) {
-            List<ShortCircuitData> assignedShortCuts = new ArrayList<>(fields.length);
-
-            for (int i = 0; i < fields.length; i++) {
-                List<ShortCircuitData> availableShortCuts = groupedShortCircuits.get(fields[i].getName());
-
-                ShortCircuitData genericShortCircuit = null;
-                ShortCircuitData compatibleShortCircuit = null;
-                for (ShortCircuitData circuit : availableShortCuts) {
-                    if (circuit.isGeneric()) {
-                        genericShortCircuit = circuit;
-                    } else if (circuit.isCompatibleTo(specialization)) {
-                        compatibleShortCircuit = circuit;
-                    }
-                }
-
-                if (compatibleShortCircuit == null) {
-                    compatibleShortCircuit = genericShortCircuit;
-                }
-                assignedShortCuts.add(compatibleShortCircuit);
-            }
-            specialization.setShortCircuits(assignedShortCuts);
-        }
-    }
-
-    private void matchGuards(List<Element> elements, SpecializationData specialization) {
-        if (specialization.getGuardDefinitions().isEmpty()) {
-            specialization.setGuards(Collections.<GuardData> emptyList());
-            return;
-        }
-
-        List<GuardData> foundGuards = new ArrayList<>();
-        List<ExecutableElement> methods = ElementFilter.methodsIn(elements);
-        for (String guardDefinition : specialization.getGuardDefinitions()) {
-            GuardParser parser = new GuardParser(context, specialization, guardDefinition);
-            List<GuardData> guards = parser.parse(methods);
-            if (!guards.isEmpty()) {
-                foundGuards.add(guards.get(0));
-            } else {
-                // error no guard found
-                MethodSpec spec = parser.createSpecification(specialization.getMethod(), null);
-                spec.applyTypeDefinitions("types");
-                specialization.addError("Guard with method name '%s' not found. Expected signature: %n%s", guardDefinition, spec.toSignatureString("guard"));
-            }
-        }
-
-        specialization.setGuards(foundGuards);
-
-    }
-
-    private static List<String> calculateSpecializationIds(List<SpecializationData> specializations) {
-        int lastSize = -1;
-        List<List<String>> signatureChunks = new ArrayList<>();
-        for (SpecializationData other : specializations) {
-            if (other.isUninitialized() || other.isGeneric()) {
-                continue;
-            }
-            List<String> paramIds = new LinkedList<>();
-            paramIds.add(Utils.getTypeId(other.getReturnType().getType()));
-            for (ActualParameter param : other.getParameters()) {
-                if (other.getNode().findChild(param.getSpecification().getName()) == null) {
-                    continue;
-                }
-                paramIds.add(Utils.getTypeId(param.getType()));
-            }
-            assert lastSize == -1 || lastSize == paramIds.size();
-            if (lastSize != -1 && lastSize != paramIds.size()) {
-                throw new AssertionError();
-            }
-            signatureChunks.add(paramIds);
-            lastSize = paramIds.size();
-        }
-
-        // reduce id vertically
-        for (int i = 0; i < lastSize; i++) {
-            String prev = null;
-            boolean allSame = true;
-            for (List<String> signature : signatureChunks) {
-                String arg = signature.get(i);
-                if (prev == null) {
-                    prev = arg;
-                    continue;
-                } else if (!prev.equals(arg)) {
-                    allSame = false;
-                    break;
-                }
-                prev = arg;
-            }
-
-            if (allSame) {
-                for (List<String> signature : signatureChunks) {
-                    signature.remove(i);
-                }
-                lastSize--;
-            }
-        }
-
-        // reduce id horizontally
-        for (List<String> signature : signatureChunks) {
-            if (signature.isEmpty()) {
-                continue;
-            }
-            String prev = null;
-            boolean allSame = true;
-            for (String arg : signature) {
-                if (prev == null) {
-                    prev = arg;
-                    continue;
-                } else if (!prev.equals(arg)) {
-                    allSame = false;
-                    break;
-                }
-                prev = arg;
-            }
-
-            if (allSame) {
-                signature.clear();
-                signature.add(prev);
-            }
-        }
-
-        // create signatures
-        List<String> signatures = new ArrayList<>();
-        for (List<String> signatureChunk : signatureChunks) {
-            StringBuilder b = new StringBuilder();
-            if (signatureChunk.isEmpty()) {
-                b.append("Default");
-            } else {
-                for (String s : signatureChunk) {
-                    b.append(s);
-                }
-            }
-            signatures.add(b.toString());
-        }
-
-        Map<String, Integer> counts = new HashMap<>();
-        for (String s1 : signatures) {
-            Integer count = counts.get(s1);
-            if (count == null) {
-                count = 0;
-            }
-            count++;
-            counts.put(s1, count);
-        }
-
-        for (String s : counts.keySet()) {
-            int count = counts.get(s);
-            if (count > 1) {
-                int number = 0;
-                for (ListIterator<String> iterator = signatures.listIterator(); iterator.hasNext();) {
-                    String s2 = iterator.next();
-                    if (s.equals(s2)) {
-                        iterator.set(s2 + number);
-                        number++;
-                    }
-                }
-            }
-        }
-
-        return signatures;
-    }
-
-    private void verifyNode(NodeData nodeData, List<? extends Element> elements) {
-        // verify order is not ambiguous
-        verifySpecializationOrder(nodeData);
-
-        verifyMissingAbstractMethods(nodeData, elements);
-
-        verifyConstructors(nodeData);
-
-        verifyNamingConvention(nodeData.getShortCircuits(), "needs");
-
-        verifySpecializationThrows(nodeData);
-    }
-
-    private static void verifyNodeChild(NodeChildData nodeChild) {
-        if (nodeChild.getNodeType() == null) {
-            nodeChild.addError("No valid node type could be resoleved.");
-        }
-        // FIXME verify node child
-        // FIXME verify node type set
-    }
-
-    private static void verifyMissingAbstractMethods(NodeData nodeData, List<? extends Element> originalElements) {
-        if (!nodeData.needsFactory()) {
-            // missing abstract methods only needs to be implemented
-            // if we need go generate factory for it.
-            return;
-        }
-
-        List<Element> elements = new ArrayList<>(originalElements);
-
-        Set<Element> unusedElements = new HashSet<>(elements);
-        for (TemplateMethod method : nodeData.getAllTemplateMethods()) {
-            unusedElements.remove(method.getMethod());
-        }
-        if (nodeData.getExtensionElements() != null) {
-            unusedElements.removeAll(nodeData.getExtensionElements());
-        }
-
-        for (NodeChildData child : nodeData.getChildren()) {
-            if (child.getAccessElement() != null) {
-                unusedElements.remove(child.getAccessElement());
-            }
-        }
-
-        for (ExecutableElement unusedMethod : ElementFilter.methodsIn(unusedElements)) {
-            if (unusedMethod.getModifiers().contains(Modifier.ABSTRACT)) {
-                nodeData.addError("The type %s must implement the inherited abstract method %s.", Utils.getSimpleName(nodeData.getTemplateType()), Utils.getReadableSignature(unusedMethod));
-            }
-        }
-    }
-
-    private void verifyConstructors(NodeData nodeData) {
-        if (!nodeData.needsRewrites(context)) {
-            // no specialization constructor is needed if the node never rewrites.
-            return;
-        }
-
-        TypeElement type = Utils.fromTypeMirror(nodeData.getNodeType());
-        List<ExecutableElement> constructors = ElementFilter.constructorsIn(type.getEnclosedElements());
-
-        boolean parametersFound = false;
-        for (ExecutableElement constructor : constructors) {
-            if (!constructor.getParameters().isEmpty()) {
-                parametersFound = true;
-            }
-        }
-        if (!parametersFound) {
-            return;
-        }
-        for (ExecutableElement e : constructors) {
-            if (e.getParameters().size() == 1) {
-                TypeMirror firstArg = e.getParameters().get(0).asType();
-                if (Utils.typeEquals(firstArg, nodeData.getNodeType())) {
-                    if (e.getModifiers().contains(Modifier.PRIVATE)) {
-                        nodeData.addError("The specialization constructor must not be private.");
-                    } else if (constructors.size() <= 1) {
-                        nodeData.addError("The specialization constructor must not be the only constructor. The definition of an alternative constructor is required.");
-                    }
-                    return;
-                }
-            }
-        }
-
-        // not found
-        nodeData.addError("Specialization constructor '%s(%s previousNode) { this(...); }' is required.", Utils.getSimpleName(type), Utils.getSimpleName(type));
-    }
-
-    private static boolean verifySpecializationParameters(NodeData nodeData) {
-        boolean valid = true;
-        int args = -1;
-        for (SpecializationData specializationData : nodeData.getSpecializations()) {
-            int signatureArgs = 0;
-            for (ActualParameter param : specializationData.getParameters()) {
-                if (param.getSpecification().isSignature()) {
-                    signatureArgs++;
-                }
-            }
-            if (args != -1 && args != signatureArgs) {
-                valid = false;
-                break;
-            }
-            args = signatureArgs;
-        }
-        if (!valid) {
-            for (SpecializationData specialization : nodeData.getSpecializations()) {
-                specialization.addError("All specializations must have the same number of arguments.");
-            }
-        }
-        return valid;
-    }
-
-    private static void verifySpecializationOrder(NodeData node) {
-        List<SpecializationData> specializations = node.getSpecializations();
-        for (int i = 0; i < specializations.size(); i++) {
-            SpecializationData m1 = specializations.get(i);
-            for (int j = i + 1; j < specializations.size(); j++) {
-                SpecializationData m2 = specializations.get(j);
-                int inferredOrder = m1.compareBySignature(m2);
-
-                if (m1.getOrder() != Specialization.DEFAULT_ORDER && m2.getOrder() != Specialization.DEFAULT_ORDER) {
-                    int specOrder = m1.getOrder() - m2.getOrder();
-                    if (specOrder == 0) {
-                        m1.addError("Order value %d used multiple times", m1.getOrder());
-                        m2.addError("Order value %d used multiple times", m1.getOrder());
-                        return;
-                    } else if ((specOrder < 0 && inferredOrder > 0) || (specOrder > 0 && inferredOrder < 0)) {
-                        m1.addError("Explicit order values %d and %d are inconsistent with type lattice ordering.", m1.getOrder(), m2.getOrder());
-                        m2.addError("Explicit order values %d and %d are inconsistent with type lattice ordering.", m1.getOrder(), m2.getOrder());
-                        return;
-                    }
-                } else if (inferredOrder == 0) {
-                    SpecializationData m = (m1.getOrder() == Specialization.DEFAULT_ORDER ? m1 : m2);
-                    m.addError("Cannot calculate a consistent order for this specialization. Define the order attribute to resolve this.");
-                    return;
-                }
-            }
-        }
-    }
-
-    private static void verifySpecializationThrows(NodeData node) {
-        Map<String, SpecializationData> specializationMap = new HashMap<>();
-        for (SpecializationData spec : node.getSpecializations()) {
-            specializationMap.put(spec.getMethodName(), spec);
-        }
-        for (SpecializationData sourceSpecialization : node.getSpecializations()) {
-            if (sourceSpecialization.getExceptions() != null) {
-                for (SpecializationThrowsData throwsData : sourceSpecialization.getExceptions()) {
-                    for (SpecializationThrowsData otherThrowsData : sourceSpecialization.getExceptions()) {
-                        if (otherThrowsData != throwsData && Utils.typeEquals(otherThrowsData.getJavaClass(), throwsData.getJavaClass())) {
-                            throwsData.addError("Duplicate exception type.");
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    private static void verifyNamingConvention(List<? extends TemplateMethod> methods, String prefix) {
-        for (int i = 0; i < methods.size(); i++) {
-            TemplateMethod m1 = methods.get(i);
-            if (m1.getMethodName().length() < 3 || !m1.getMethodName().startsWith(prefix)) {
-                m1.addError("Naming convention: method name must start with '%s'.", prefix);
-            }
-        }
-    }
-
-    private static Map<Integer, List<ExecutableTypeData>> groupExecutableTypes(List<ExecutableTypeData> executableTypes) {
-        Map<Integer, List<ExecutableTypeData>> groupedTypes = new HashMap<>();
-        for (ExecutableTypeData type : executableTypes) {
-            int evaluatedCount = type.getEvaluatedCount();
-
-            List<ExecutableTypeData> types = groupedTypes.get(evaluatedCount);
-            if (types == null) {
-                types = new ArrayList<>();
-                groupedTypes.put(evaluatedCount, types);
-            }
-            types.add(type);
-        }
-
-        for (List<ExecutableTypeData> types : groupedTypes.values()) {
-            Collections.sort(types);
-        }
-        return groupedTypes;
-    }
-
-    private AnnotationMirror findFirstAnnotation(List<? extends Element> elements, Class<? extends Annotation> annotation) {
-        for (Element element : elements) {
-            AnnotationMirror mirror = Utils.findAnnotationMirror(processingEnv, element, annotation);
-            if (mirror != null) {
-                return mirror;
-            }
-        }
-        return null;
-    }
-
-    private TypeMirror inheritType(AnnotationMirror annotation, String valueName, TypeMirror parentType) {
-        TypeMirror inhertNodeType = context.getTruffleTypes().getNode();
-        TypeMirror value = Utils.getAnnotationValue(TypeMirror.class, annotation, valueName);
-        if (Utils.typeEquals(inhertNodeType, value)) {
-            return parentType;
-        } else {
-            return value;
-        }
-    }
-
-    private Element findGetter(List<? extends Element> elements, String variableName, TypeMirror type) {
-        if (type == null) {
-            return null;
-        }
-        String methodName;
-        if (Utils.typeEquals(type, context.getType(boolean.class))) {
-            methodName = "is" + Utils.firstLetterUpperCase(variableName);
-        } else {
-            methodName = "get" + Utils.firstLetterUpperCase(variableName);
-        }
-
-        for (ExecutableElement method : ElementFilter.methodsIn(elements)) {
-            if (method.getSimpleName().toString().equals(methodName) && method.getParameters().size() == 0 && Utils.isAssignable(context, type, method.getReturnType())) {
-                return method;
-            }
-        }
-        return null;
-    }
-
-    private boolean isGenericShortCutMethod(NodeData node, TemplateMethod method) {
-        for (ActualParameter parameter : method.getParameters()) {
-            NodeChildData field = node.findChild(parameter.getSpecification().getName());
-            if (field == null) {
-                continue;
-            }
-            ExecutableTypeData found = null;
-            List<ExecutableTypeData> executableElements = field.findGenericExecutableTypes(context);
-            for (ExecutableTypeData executable : executableElements) {
-                if (executable.getType().equalsType(parameter.getTypeSystemType())) {
-                    found = executable;
-                    break;
-                }
-            }
-            if (found == null) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private static Map<String, List<ShortCircuitData>> groupShortCircuits(List<ShortCircuitData> shortCircuits) {
-        Map<String, List<ShortCircuitData>> group = new HashMap<>();
-        for (ShortCircuitData shortCircuit : shortCircuits) {
-            List<ShortCircuitData> circuits = group.get(shortCircuit.getValueName());
-            if (circuits == null) {
-                circuits = new ArrayList<>();
-                group.put(shortCircuit.getValueName(), circuits);
-            }
-            circuits.add(shortCircuit);
-        }
-        return group;
-    }
-
-    private static <M extends TemplateMethod> SortedMap<String, List<M>> groupByNodeId(List<M> methods) {
-        SortedMap<String, List<M>> grouped = new TreeMap<>();
-        for (M m : methods) {
-            List<M> list = grouped.get(m.getId());
-            if (list == null) {
-                list = new ArrayList<>();
-                grouped.put(m.getId(), list);
-            }
-            list.add(m);
-        }
-        return grouped;
-    }
-
-    private static List<TypeElement> findSuperClasses(List<TypeElement> collection, TypeElement element) {
-        if (element.getSuperclass() != null) {
-            TypeElement superElement = Utils.fromTypeMirror(element.getSuperclass());
-            if (superElement != null) {
-                findSuperClasses(collection, superElement);
-            }
-        }
-        collection.add(element);
-        return collection;
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ShortCircuitData.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.node;
-
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.template.*;
-
-public class ShortCircuitData extends TemplateMethod {
-
-    private ShortCircuitData genericShortCircuitMethod;
-    private final String valueName;
-
-    public ShortCircuitData(TemplateMethod template, String valueName) {
-        super(template);
-        this.valueName = valueName;
-    }
-
-    public String getValueName() {
-        return valueName;
-    }
-
-    public void setGenericShortCircuitMethod(ShortCircuitData genericShortCircuitMethod) {
-        this.genericShortCircuitMethod = genericShortCircuitMethod;
-    }
-
-    public boolean isGeneric() {
-        return genericShortCircuitMethod == null;
-    }
-
-    public ShortCircuitData getGeneric() {
-        if (isGeneric()) {
-            return this;
-        } else {
-            return genericShortCircuitMethod;
-        }
-    }
-
-    public boolean isCompatibleTo(SpecializationData specialization) {
-        if (isGeneric() && specialization.isGeneric()) {
-            return true;
-        }
-
-        for (ActualParameter param : getParameters()) {
-            ActualParameter specializationParam = specialization.findParameter(param.getLocalName());
-            if (!Utils.typeEquals(param.getType(), specializationParam.getType())) {
-                return false;
-            }
-        }
-        return true;
-    }
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ShortCircuitParser.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.node;
-
-import java.lang.annotation.*;
-import java.util.*;
-
-import javax.lang.model.element.*;
-
-import com.oracle.truffle.api.codegen.*;
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.node.NodeChildData.ExecutionKind;
-import com.oracle.truffle.codegen.processor.template.*;
-
-public class ShortCircuitParser extends NodeMethodParser<ShortCircuitData> {
-
-    private final Set<String> shortCircuitValues;
-
-    public ShortCircuitParser(ProcessorContext context, NodeData node) {
-        super(context, node);
-
-        shortCircuitValues = new HashSet<>();
-        NodeChildData[] shortCircuitFields = node.filterFields(ExecutionKind.SHORT_CIRCUIT);
-        for (NodeChildData field : shortCircuitFields) {
-            shortCircuitValues.add(field.getName());
-        }
-    }
-
-    @Override
-    public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
-        String shortCircuitValue = Utils.getAnnotationValue(String.class, mirror, "value");
-        return createDefaultMethodSpec(method, mirror, true, shortCircuitValue);
-    }
-
-    @Override
-    protected ParameterSpec createReturnParameterSpec() {
-        return new ParameterSpec("has", getContext().getType(boolean.class));
-    }
-
-    @Override
-    public ShortCircuitData create(TemplateMethod method) {
-        String shortCircuitValue = Utils.getAnnotationValue(String.class, method.getMarkerAnnotation(), "value");
-
-        if (!shortCircuitValues.contains(shortCircuitValue)) {
-            method.addError("Invalid short circuit value %s.", shortCircuitValue);
-        }
-
-        return new ShortCircuitData(method, shortCircuitValue);
-    }
-
-    @Override
-    public Class<? extends Annotation> getAnnotationType() {
-        return ShortCircuit.class;
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationData.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,251 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.node;
-
-import java.util.*;
-
-import javax.lang.model.type.*;
-
-import com.oracle.truffle.api.codegen.*;
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.template.*;
-import com.oracle.truffle.codegen.processor.typesystem.*;
-
-public class SpecializationData extends TemplateMethod {
-
-    private final int order;
-    private final boolean generic;
-    private final boolean polymorphic;
-    private final boolean uninitialized;
-    private final List<SpecializationThrowsData> exceptions;
-    private List<String> guardDefinitions = Collections.emptyList();
-    private List<GuardData> guards = Collections.emptyList();
-    private List<ShortCircuitData> shortCircuits;
-    private List<String> assumptions = Collections.emptyList();
-    private NodeData node;
-    private boolean reachable;
-
-    public SpecializationData(TemplateMethod template, int order, List<SpecializationThrowsData> exceptions) {
-        super(template);
-        this.order = order;
-        this.generic = false;
-        this.uninitialized = false;
-        this.polymorphic = false;
-        this.exceptions = exceptions;
-
-        for (SpecializationThrowsData exception : exceptions) {
-            exception.setSpecialization(this);
-        }
-    }
-
-    public SpecializationData(TemplateMethod template, boolean generic, boolean uninitialized, boolean polymorphic) {
-        super(template);
-        this.order = Specialization.DEFAULT_ORDER;
-        this.generic = generic;
-        this.uninitialized = uninitialized;
-        this.polymorphic = polymorphic;
-        this.exceptions = Collections.emptyList();
-    }
-
-    public void setReachable(boolean reachable) {
-        this.reachable = reachable;
-    }
-
-    public boolean isReachable() {
-        return reachable;
-    }
-
-    public boolean isPolymorphic() {
-        return polymorphic;
-    }
-
-    @Override
-    protected List<MessageContainer> findChildContainers() {
-        List<MessageContainer> sinks = new ArrayList<>();
-        if (exceptions != null) {
-            sinks.addAll(exceptions);
-        }
-        if (guards != null) {
-            sinks.addAll(guards);
-        }
-        return sinks;
-    }
-
-    public boolean isGenericSpecialization(ProcessorContext context) {
-        if (isGeneric()) {
-            return true;
-        }
-        if (hasRewrite(context)) {
-            return false;
-        }
-
-        for (ActualParameter parameter : getParameters()) {
-            if (!parameter.getSpecification().isSignature()) {
-                continue;
-            }
-            NodeChildData child = getNode().findChild(parameter.getSpecification().getName());
-            if (child == null) {
-                continue;
-            }
-            if (!parameter.getTypeSystemType().isGeneric()) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    public boolean hasRewrite(ProcessorContext context) {
-        if (!getExceptions().isEmpty()) {
-            return true;
-        }
-        if (!getGuards().isEmpty()) {
-            return true;
-        }
-        if (!getAssumptions().isEmpty()) {
-            return true;
-        }
-        for (ActualParameter parameter : getParameters()) {
-            NodeChildData child = getNode().findChild(parameter.getSpecification().getName());
-            if (child == null) {
-                continue;
-            }
-            ExecutableTypeData type = child.findExecutableType(context, parameter.getTypeSystemType());
-            if (type.hasUnexpectedValue(context)) {
-                return true;
-            }
-            if (type.getReturnType().getTypeSystemType().needsCastTo(context, parameter.getTypeSystemType())) {
-                return true;
-            }
-
-        }
-        return false;
-    }
-
-    @Override
-    public int compareBySignature(TemplateMethod other) {
-        if (this == other) {
-            return 0;
-        } else if (!(other instanceof SpecializationData)) {
-            return super.compareBySignature(other);
-        }
-
-        SpecializationData m2 = (SpecializationData) other;
-
-        if (getOrder() != Specialization.DEFAULT_ORDER && m2.getOrder() != Specialization.DEFAULT_ORDER) {
-            return getOrder() - m2.getOrder();
-        } else if (isUninitialized() ^ m2.isUninitialized()) {
-            return isUninitialized() ? -1 : 1;
-        } else if (isGeneric() ^ m2.isGeneric()) {
-            return isGeneric() ? 1 : -1;
-        }
-
-        if (getTemplate() != m2.getTemplate()) {
-            throw new UnsupportedOperationException("Cannot compare two specializations with different templates.");
-        }
-
-        return super.compareBySignature(m2);
-    }
-
-    public NodeData getNode() {
-        return node;
-    }
-
-    public void setNode(NodeData node) {
-        this.node = node;
-    }
-
-    public void setGuards(List<GuardData> guards) {
-        this.guards = guards;
-    }
-
-    public void setGuardDefinitions(List<String> guardDefinitions) {
-        this.guardDefinitions = guardDefinitions;
-    }
-
-    public int getOrder() {
-        return order;
-    }
-
-    public boolean isGeneric() {
-        return generic;
-    }
-
-    public boolean isUninitialized() {
-        return uninitialized;
-    }
-
-    public List<SpecializationThrowsData> getExceptions() {
-        return exceptions;
-    }
-
-    public List<String> getGuardDefinitions() {
-        return guardDefinitions;
-    }
-
-    public List<GuardData> getGuards() {
-        return guards;
-    }
-
-    public void setShortCircuits(List<ShortCircuitData> shortCircuits) {
-        this.shortCircuits = shortCircuits;
-    }
-
-    public List<ShortCircuitData> getShortCircuits() {
-        return shortCircuits;
-    }
-
-    public List<String> getAssumptions() {
-        return assumptions;
-    }
-
-    void setAssumptions(List<String> assumptions) {
-        this.assumptions = assumptions;
-    }
-
-    public SpecializationData findNextSpecialization() {
-        List<SpecializationData> specializations = node.getSpecializations();
-        for (int i = 0; i < specializations.size() - 1; i++) {
-            if (specializations.get(i) == this) {
-                return specializations.get(i + 1);
-            }
-        }
-        return null;
-    }
-
-    public boolean hasDynamicGuards() {
-        return !getGuards().isEmpty();
-    }
-
-    @Override
-    public String toString() {
-        return String.format("%s [id = %s, method = %s, guards = %s, signature = %s]", getClass().getSimpleName(), getId(), getMethod(), getGuards(), getSignature());
-    }
-
-    public void forceFrame(TypeMirror frameType) {
-        if (getParameters().isEmpty() || !Utils.typeEquals(getParameters().get(0).getType(), frameType)) {
-            ParameterSpec frameSpec = getSpecification().findParameterSpec("frame");
-            getParameters().add(0, new ActualParameter(frameSpec, frameType, -1, false));
-        }
-    }
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationGuardData.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.node;
-
-import javax.lang.model.element.*;
-
-import com.oracle.truffle.codegen.processor.template.*;
-import com.oracle.truffle.codegen.processor.typesystem.*;
-
-public class SpecializationGuardData extends MessageContainer {
-
-    private final SpecializationData specialization;
-    private final AnnotationValue value;
-    private final String guardMethod;
-    private final boolean onSpecialization;
-    private final boolean onExecution;
-
-    private GuardData guardDeclaration;
-
-    public SpecializationGuardData(SpecializationData specialization, AnnotationValue value, String guardMethod, boolean onSpecialization, boolean onExecution) {
-        this.specialization = specialization;
-        this.guardMethod = guardMethod;
-        this.onSpecialization = onSpecialization;
-        this.onExecution = onExecution;
-        this.value = value;
-    }
-
-    @Override
-    public Element getMessageElement() {
-        return specialization.getMessageElement();
-    }
-
-    @Override
-    public AnnotationMirror getMessageAnnotation() {
-        return specialization.getMessageAnnotation();
-    }
-
-    @Override
-    public AnnotationValue getMessageAnnotationValue() {
-        return value;
-    }
-
-    public String getGuardMethod() {
-        return guardMethod;
-    }
-
-    public boolean isOnExecution() {
-        return onExecution;
-    }
-
-    public boolean isOnSpecialization() {
-        return onSpecialization;
-    }
-
-    public void setGuardDeclaration(GuardData compatibleGuard) {
-        this.guardDeclaration = compatibleGuard;
-    }
-
-    public GuardData getGuardDeclaration() {
-        return guardDeclaration;
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationListenerData.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.node;
-
-import com.oracle.truffle.codegen.processor.template.*;
-
-public class SpecializationListenerData extends TemplateMethod {
-
-    public SpecializationListenerData(TemplateMethod method) {
-        super(method);
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationListenerParser.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.node;
-
-import java.lang.annotation.*;
-
-import javax.lang.model.element.*;
-
-import com.oracle.truffle.api.codegen.*;
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.template.*;
-
-public class SpecializationListenerParser extends NodeMethodParser<SpecializationListenerData> {
-
-    public SpecializationListenerParser(ProcessorContext context, NodeData node) {
-        super(context, node);
-    }
-
-    @Override
-    public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
-        return createDefaultMethodSpec(method, mirror, true, null);
-    }
-
-    @Override
-    protected ParameterSpec createReturnParameterSpec() {
-        return new ParameterSpec("void", getContext().getType(void.class));
-    }
-
-    @Override
-    public SpecializationListenerData create(TemplateMethod method) {
-        return new SpecializationListenerData(method);
-    }
-
-    @Override
-    public Class<? extends Annotation> getAnnotationType() {
-        return SpecializationListener.class;
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationMethodParser.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.node;
-
-import java.lang.annotation.*;
-import java.util.*;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-
-import com.oracle.truffle.api.codegen.*;
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.template.*;
-
-public class SpecializationMethodParser extends NodeMethodParser<SpecializationData> {
-
-    public SpecializationMethodParser(ProcessorContext context, NodeData operation) {
-        super(context, operation);
-    }
-
-    @Override
-    public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
-        return createDefaultMethodSpec(method, mirror, true, null);
-    }
-
-    @Override
-    public SpecializationData create(TemplateMethod method) {
-        return parseSpecialization(method);
-    }
-
-    @Override
-    public Class<? extends Annotation> getAnnotationType() {
-        return Specialization.class;
-    }
-
-    private SpecializationData parseSpecialization(TemplateMethod method) {
-        int order = Utils.getAnnotationValue(Integer.class, method.getMarkerAnnotation(), "order");
-        if (order < 0 && order != Specialization.DEFAULT_ORDER) {
-            method.addError("Invalid order attribute %d. The value must be >= 0 or the default value.");
-            return null;
-        }
-
-        AnnotationValue rewriteValue = Utils.getAnnotationValue(method.getMarkerAnnotation(), "rewriteOn");
-        List<TypeMirror> exceptionTypes = Utils.getAnnotationValueList(TypeMirror.class, method.getMarkerAnnotation(), "rewriteOn");
-        List<SpecializationThrowsData> exceptionData = new ArrayList<>();
-        for (TypeMirror exceptionType : exceptionTypes) {
-            SpecializationThrowsData throwsData = new SpecializationThrowsData(method.getMarkerAnnotation(), rewriteValue, exceptionType);
-            if (!Utils.canThrowType(method.getMethod().getThrownTypes(), exceptionType)) {
-                throwsData.addError("Method must specify a throws clause with the exception type '%s'.", Utils.getQualifiedName(exceptionType));
-            }
-            exceptionData.add(throwsData);
-        }
-
-        Collections.sort(exceptionData, new Comparator<SpecializationThrowsData>() {
-
-            @Override
-            public int compare(SpecializationThrowsData o1, SpecializationThrowsData o2) {
-                return Utils.compareByTypeHierarchy(o1.getJavaClass(), o2.getJavaClass());
-            }
-        });
-        SpecializationData specialization = new SpecializationData(method, order, exceptionData);
-        List<String> guardDefs = Utils.getAnnotationValueList(String.class, specialization.getMarkerAnnotation(), "guards");
-        specialization.setGuardDefinitions(guardDefs);
-
-        List<String> assumptionDefs = Utils.getAnnotationValueList(String.class, specialization.getMarkerAnnotation(), "assumptions");
-        specialization.setAssumptions(assumptionDefs);
-
-        for (String assumption : assumptionDefs) {
-            if (!getNode().getAssumptions().contains(assumption)) {
-                specialization.addError("Undeclared assumption '%s' used. Use @NodeAssumptions to declare them.", assumption);
-            }
-        }
-
-        return specialization;
-    }
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationThrowsData.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.node;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-
-import com.oracle.truffle.codegen.processor.template.*;
-
-public class SpecializationThrowsData extends MessageContainer {
-
-    private final AnnotationValue annotationValue;
-    private final AnnotationMirror annotationMirror;
-    private final TypeMirror javaClass;
-    private SpecializationData specialization;
-
-    public SpecializationThrowsData(AnnotationMirror annotationMirror, AnnotationValue value, TypeMirror javaClass) {
-        this.annotationMirror = annotationMirror;
-        this.annotationValue = value;
-        this.javaClass = javaClass;
-    }
-
-    void setSpecialization(SpecializationData specialization) {
-        this.specialization = specialization;
-    }
-
-    @Override
-    public Element getMessageElement() {
-        return specialization.getMessageElement();
-    }
-
-    @Override
-    public AnnotationMirror getMessageAnnotation() {
-        return annotationMirror;
-    }
-
-    @Override
-    public AnnotationValue getMessageAnnotationValue() {
-        return annotationValue;
-    }
-
-    public TypeMirror getJavaClass() {
-        return javaClass;
-    }
-
-    public SpecializationData getSpecialization() {
-        return specialization;
-    }
-
-    public AnnotationMirror getAnnotationMirror() {
-        return annotationMirror;
-    }
-
-    public SpecializationData getTransitionTo() {
-        return specialization.findNextSpecialization();
-    }
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ActualParameter.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.template;
-
-import javax.lang.model.type.*;
-
-import com.oracle.truffle.codegen.processor.typesystem.*;
-
-public class ActualParameter {
-
-    private final ParameterSpec specification;
-    private TypeData typeSystemType;
-    private TemplateMethod method;
-    private final String localName;
-    private final int index;
-    private final boolean implicit;
-    private final TypeMirror type;
-
-    public ActualParameter(ParameterSpec specification, TypeMirror actualType, int index, boolean implicit) {
-        this.specification = specification;
-        this.type = actualType;
-        this.typeSystemType = null;
-
-        this.index = index;
-        this.implicit = implicit;
-        String valueName = specification.getName() + "Value";
-
-        if (specification.isIndexed()) {
-            valueName += index;
-        }
-        this.localName = valueName;
-    }
-
-    public ActualParameter(ParameterSpec specification, TypeData actualType, int index, boolean implicit) {
-        this(specification, actualType.getPrimitiveType(), index, implicit);
-        this.typeSystemType = actualType;
-    }
-
-    public ActualParameter(ActualParameter parameter, TypeData otherType) {
-        this(parameter.specification, otherType, parameter.index, parameter.implicit);
-    }
-
-    public ActualParameter(ActualParameter parameter) {
-        this.specification = parameter.specification;
-        this.type = parameter.type;
-        this.typeSystemType = parameter.typeSystemType;
-        this.index = parameter.index;
-        this.implicit = parameter.implicit;
-        this.localName = parameter.localName;
-    }
-
-    public boolean isImplicit() {
-        return implicit;
-    }
-
-    public int getIndex() {
-        return index;
-    }
-
-    public String getLocalName() {
-        return localName;
-    }
-
-    void setMethod(TemplateMethod method) {
-        this.method = method;
-    }
-
-    public ParameterSpec getSpecification() {
-        return specification;
-    }
-
-    public TemplateMethod getMethod() {
-        return method;
-    }
-
-    public TypeMirror getType() {
-        return type;
-    }
-
-    public TypeData getTypeSystemType() {
-        return typeSystemType;
-    }
-
-    public ActualParameter getPreviousParameter() {
-        return method.getPreviousParam(this);
-    }
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ClassElementFactory.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,140 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.template;
-
-import static com.oracle.truffle.codegen.processor.Utils.*;
-import static javax.lang.model.element.Modifier.*;
-
-import java.util.*;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-import javax.lang.model.util.*;
-
-import com.oracle.truffle.api.codegen.*;
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.ast.*;
-
-public abstract class ClassElementFactory<M> extends CodeElementFactory<M> {
-
-    public ClassElementFactory(ProcessorContext context) {
-        super(context);
-    }
-
-    @Override
-    protected abstract CodeTypeElement create(M m);
-
-    @Override
-    public CodeTypeElement getElement() {
-        return (CodeTypeElement) super.getElement();
-    }
-
-    protected CodeExecutableElement createConstructorUsingFields(Set<Modifier> modifiers, CodeTypeElement clazz) {
-        CodeExecutableElement method = new CodeExecutableElement(modifiers, null, clazz.getSimpleName().toString());
-        CodeTreeBuilder builder = method.createBuilder();
-        TypeElement superClass = fromTypeMirror(clazz.getSuperclass());
-        ExecutableElement constructor = findConstructor(superClass);
-        if (constructor != null && constructor.getParameters().size() > 0) {
-            builder.startStatement();
-            builder.startSuperCall();
-            for (VariableElement parameter : constructor.getParameters()) {
-                method.addParameter(new CodeVariableElement(parameter.asType(), parameter.getSimpleName().toString()));
-                builder.string(parameter.getSimpleName().toString());
-            }
-            builder.end(); // super
-            builder.end(); // statement
-        }
-
-        for (VariableElement field : clazz.getFields()) {
-            if (field.getModifiers().contains(STATIC)) {
-                continue;
-            }
-            String fieldName = field.getSimpleName().toString();
-            method.addParameter(new CodeVariableElement(field.asType(), fieldName));
-            builder.startStatement();
-            builder.string("this.");
-            builder.string(fieldName);
-            builder.string(" = ");
-            if (isAssignable(getContext(), field.asType(), getContext().getTruffleTypes().getNode())) {
-                builder.string("adoptChild(").string(fieldName).string(")");
-            } else {
-                builder.string(fieldName);
-            }
-            builder.end(); // statement
-        }
-
-        return method;
-    }
-
-    private static ExecutableElement findConstructor(TypeElement clazz) {
-        List<ExecutableElement> constructors = ElementFilter.constructorsIn(clazz.getEnclosedElements());
-        if (constructors.isEmpty()) {
-            return null;
-        } else {
-            return constructors.get(0);
-        }
-    }
-
-    protected CodeExecutableElement createSuperConstructor(TypeElement type, ExecutableElement element) {
-        if (element.getModifiers().contains(Modifier.PRIVATE)) {
-            return null;
-        }
-        CodeExecutableElement executable = CodeExecutableElement.clone(getContext().getEnvironment(), element);
-        executable.setReturnType(null);
-        executable.setSimpleName(CodeNames.of(type.getSimpleName().toString()));
-        CodeTreeBuilder b = executable.createBuilder();
-        b.startStatement();
-        b.startSuperCall();
-        for (VariableElement v : element.getParameters()) {
-            b.string(v.getSimpleName().toString());
-        }
-        b.end();
-        b.end();
-
-        return executable;
-    }
-
-    protected CodeTypeElement createClass(Template model, Set<Modifier> modifiers, String simpleName, TypeMirror superType, boolean enumType) {
-        TypeElement templateType = model.getTemplateType();
-
-        PackageElement pack = getContext().getEnvironment().getElementUtils().getPackageOf(templateType);
-        CodeTypeElement clazz = new CodeTypeElement(modifiers, enumType ? ElementKind.ENUM : ElementKind.CLASS, pack, simpleName);
-        TypeMirror resolvedSuperType = superType;
-        if (resolvedSuperType == null) {
-            resolvedSuperType = getContext().getType(Object.class);
-        }
-        clazz.setSuperClass(resolvedSuperType);
-
-        CodeAnnotationMirror generatedByAnnotation = new CodeAnnotationMirror((DeclaredType) getContext().getType(GeneratedBy.class));
-        generatedByAnnotation.setElementValue(generatedByAnnotation.findExecutableElement("value"), new CodeAnnotationValue(templateType.asType()));
-        if (model.getTemplateMethodName() != null) {
-            generatedByAnnotation.setElementValue(generatedByAnnotation.findExecutableElement("methodName"), new CodeAnnotationValue(model.getTemplateMethodName()));
-        }
-
-        clazz.addAnnotationMirror(generatedByAnnotation);
-
-        context.registerType(model.getTemplateType(), clazz.asType());
-
-        return clazz;
-    }
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/CodeElementFactory.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.template;
-
-import javax.lang.model.element.*;
-
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.ast.*;
-
-public abstract class CodeElementFactory<M> {
-
-    protected final ProcessorContext context;
-    private M model;
-
-    private CodeElement<? super Element> element;
-
-    public CodeElementFactory(ProcessorContext context) {
-        this.context = context;
-    }
-
-    protected abstract CodeElement<?> create(M m);
-
-    @SuppressWarnings("unused")
-    protected void createChildren(M m) {
-    }
-
-    @SuppressWarnings("unchecked")
-    public CodeElement<?> process(CodeElement parent, M m) {
-        model = m;
-        element = (CodeElement<? super Element>) create(model);
-        if (parent != null) {
-            parent.add(element);
-        }
-        if (element != null) {
-            createChildren(model);
-        }
-        return element;
-    }
-
-    public CodeElement getElement() {
-        return element;
-    }
-
-    protected <MO, K extends Element> void add(CodeElementFactory<MO> factory, MO m) {
-        factory.process(this.element, m);
-    }
-
-    public ProcessorContext getContext() {
-        return context;
-    }
-
-    public M getModel() {
-        return model;
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/CompilationUnitFactory.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.template;
-
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.ast.*;
-
-public abstract class CompilationUnitFactory<M> extends CodeElementFactory<M> {
-
-    public CompilationUnitFactory(ProcessorContext context) {
-        super(context);
-    }
-
-    @Override
-    public final CodeCompilationUnit create(M m) {
-        return new CodeCompilationUnit();
-    }
-
-    @Override
-    public CodeCompilationUnit process(CodeElement parent, M m) {
-        return (CodeCompilationUnit) super.process(parent, m);
-    }
-
-    @Override
-    protected abstract void createChildren(M m);
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/JavaName.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.template;
-
-import java.util.*;
-import java.util.regex.*;
-
-public final class JavaName {
-
-    private static final String[] RESERVED_NAMES = new String[]{"abstract", "continue", "for", "new", "switch", "assert", "default", "goto", "package", "synchronized", "boolean", "do", "if",
-                    "private", "this", "break", "double", "implements", "protected", "throw", "byte", "else", "import", "public", "throws", "case", "enum", "instanceof", "return", "transient",
-                    "catch", "extends", "int", "short", "try", "char", "final", "interface", "static", "void", "class", "finally", "long", "strictfp", "volatile", "const", "float", "native", "super",
-                    "while"};
-
-    private static final Set<String> RESERVED_NAMES_SET = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(RESERVED_NAMES)));
-
-    private static final Pattern VALID_JAVA_NAME_PATTERN = Pattern.compile("[_a-zA-z][_a-zA-Z0-9]*");
-
-    private JavaName() {
-        super();
-    }
-
-    public static boolean isReserved(String name) {
-        return RESERVED_NAMES_SET.contains(name);
-    }
-
-    public static boolean isValid(String typeName) {
-        return VALID_JAVA_NAME_PATTERN.matcher(typeName).matches();
-    }
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/MessageContainer.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,191 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.template;
-
-import java.util.*;
-
-import javax.lang.model.element.*;
-import javax.tools.Diagnostic.Kind;
-
-import com.oracle.truffle.codegen.processor.*;
-
-public abstract class MessageContainer {
-
-    private final List<Message> messages = new ArrayList<>();
-
-    public final void addWarning(String text, Object... params) {
-        getMessages().add(new Message(null, this, String.format(text, params), Kind.WARNING));
-    }
-
-    public final void addError(String text, Object... params) {
-        addError(null, text, params);
-    }
-
-    public final void addError(AnnotationValue value, String text, Object... params) {
-        getMessages().add(new Message(value, this, String.format(text, params), Kind.ERROR));
-    }
-
-    protected List<MessageContainer> findChildContainers() {
-        return Collections.emptyList();
-    }
-
-    public abstract Element getMessageElement();
-
-    public final void emitMessages(TypeElement baseElement, Log log) {
-        emitMessagesImpl(baseElement, log, new HashSet<MessageContainer>());
-    }
-
-    private void emitMessagesImpl(TypeElement baseElement, Log log, Set<MessageContainer> visitedSinks) {
-        for (Message message : getMessages()) {
-            emitDefault(baseElement, log, message);
-        }
-
-        for (MessageContainer sink : findChildContainers()) {
-            if (visitedSinks.contains(sink)) {
-                continue;
-            }
-
-            visitedSinks.add(sink);
-            sink.emitMessagesImpl(baseElement, log, visitedSinks);
-        }
-    }
-
-    private void emitDefault(TypeElement baseType, Log log, Message message) {
-        TypeElement rootEnclosing = Utils.findRootEnclosingType(getMessageElement());
-        if (rootEnclosing != null && Utils.typeEquals(baseType.asType(), rootEnclosing.asType()) && this == message.getOriginalContainer()) {
-            log.message(message.getKind(), getMessageElement(), getMessageAnnotation(), getMessageAnnotationValue(), message.getText());
-        } else {
-            MessageContainer original = message.getOriginalContainer();
-            log.message(message.getKind(), baseType, null, null, wrapText(original.getMessageElement(), original.getMessageAnnotation(), message.getText()));
-        }
-    }
-
-    private static String wrapText(Element element, AnnotationMirror mirror, String text) {
-        StringBuilder b = new StringBuilder();
-        if (element != null) {
-            b.append("Element " + element.toString());
-        }
-        if (mirror != null) {
-            b.append(" at annotation @" + Utils.getSimpleName(mirror.getAnnotationType()));
-        }
-
-        if (b.length() > 0) {
-            b.append(" is erroneous: ").append(text);
-            return b.toString();
-        } else {
-            return text;
-        }
-    }
-
-    public AnnotationMirror getMessageAnnotation() {
-        return null;
-    }
-
-    public AnnotationValue getMessageAnnotationValue() {
-        return null;
-    }
-
-    public final boolean hasErrors() {
-        return hasErrorsImpl(new HashSet<MessageContainer>());
-    }
-
-    public final List<Message> collectMessages() {
-        List<Message> collectedMessages = new ArrayList<>();
-        collectMessagesImpl(collectedMessages, new HashSet<MessageContainer>());
-        return collectedMessages;
-    }
-
-    private void collectMessagesImpl(List<Message> collectedMessages, Set<MessageContainer> visitedSinks) {
-        collectedMessages.addAll(getMessages());
-        for (MessageContainer sink : findChildContainers()) {
-            if (visitedSinks.contains(sink)) {
-                return;
-            }
-
-            visitedSinks.add(sink);
-            sink.collectMessagesImpl(collectedMessages, visitedSinks);
-        }
-    }
-
-    private boolean hasErrorsImpl(Set<MessageContainer> visitedSinks) {
-        for (Message msg : getMessages()) {
-            if (msg.getKind() == Kind.ERROR) {
-                return true;
-            }
-        }
-        for (MessageContainer sink : findChildContainers()) {
-            if (visitedSinks.contains(sink)) {
-                return false;
-            }
-
-            visitedSinks.add(sink);
-
-            if (sink.hasErrorsImpl(visitedSinks)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public List<Message> getMessages() {
-        return messages;
-    }
-
-    public static final class Message {
-
-        private final MessageContainer originalContainer;
-        private final AnnotationValue annotationValue;
-        private final String text;
-        private final Kind kind;
-
-        public Message(AnnotationValue annotationValue, MessageContainer originalContainer, String text, Kind kind) {
-            this.annotationValue = annotationValue;
-            this.originalContainer = originalContainer;
-            this.text = text;
-            this.kind = kind;
-        }
-
-        public AnnotationValue getAnnotationValue() {
-            return annotationValue;
-        }
-
-        public MessageContainer getOriginalContainer() {
-            return originalContainer;
-        }
-
-        public String getText() {
-            return text;
-        }
-
-        public Kind getKind() {
-            return kind;
-        }
-
-        @Override
-        public String toString() {
-            return kind + ": " + text;
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/MethodSpec.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,228 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.template;
-
-import java.util.*;
-
-import javax.lang.model.type.*;
-
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.node.NodeChildData.Cardinality;
-
-public class MethodSpec {
-
-    private final List<TypeMirror> implicitRequiredTypes = new ArrayList<>();
-
-    private final ParameterSpec returnType;
-    private final List<ParameterSpec> optional = new ArrayList<>();
-    private final List<ParameterSpec> required = new ArrayList<>();
-
-    private boolean variableRequiredArguments;
-    private List<TypeDef> typeDefinitions;
-
-    public MethodSpec(ParameterSpec returnType) {
-        this.returnType = returnType;
-    }
-
-    public void setVariableRequiredArguments(boolean variableArguments) {
-        this.variableRequiredArguments = variableArguments;
-    }
-
-    public boolean isVariableRequiredArguments() {
-        return variableRequiredArguments;
-    }
-
-    public void addImplicitRequiredType(TypeMirror type) {
-        this.implicitRequiredTypes.add(type);
-    }
-
-    public void addOptional(ParameterSpec spec) {
-        optional.add(spec);
-    }
-
-    public ParameterSpec addRequired(ParameterSpec spec) {
-        required.add(spec);
-        return spec;
-    }
-
-    public List<TypeMirror> getImplicitRequiredTypes() {
-        return implicitRequiredTypes;
-    }
-
-    public ParameterSpec getReturnType() {
-        return returnType;
-    }
-
-    public List<ParameterSpec> getRequired() {
-        return required;
-    }
-
-    public List<ParameterSpec> getOptional() {
-        return optional;
-    }
-
-    public List<ParameterSpec> getAll() {
-        List<ParameterSpec> specs = new ArrayList<>();
-        specs.add(getReturnType());
-        specs.addAll(getOptional());
-        specs.addAll(getRequired());
-        return specs;
-    }
-
-    public ParameterSpec findParameterSpec(String name) {
-        for (ParameterSpec spec : getAll()) {
-            if (spec.getName().equals(name)) {
-                return spec;
-            }
-        }
-        return null;
-    }
-
-    public void applyTypeDefinitions(String prefix) {
-        this.typeDefinitions = createTypeDefinitions(prefix);
-    }
-
-    private List<TypeDef> createTypeDefinitions(String prefix) {
-        List<TypeDef> typeDefs = new ArrayList<>();
-
-        int defIndex = 0;
-        for (ParameterSpec spec : getAll()) {
-            List<TypeMirror> allowedTypes = spec.getAllowedTypes();
-            List<TypeMirror> types = spec.getAllowedTypes();
-            if (types != null && allowedTypes.size() > 1) {
-                TypeDef foundDef = null;
-                for (TypeDef def : typeDefs) {
-                    if (allowedTypes.equals(def.getTypes())) {
-                        foundDef = def;
-                        break;
-                    }
-                }
-                if (foundDef == null) {
-                    foundDef = new TypeDef(types, prefix + defIndex);
-                    typeDefs.add(foundDef);
-                    defIndex++;
-                }
-
-                spec.setTypeDefinition(foundDef);
-            }
-        }
-
-        return typeDefs;
-    }
-
-    public String toSignatureString(String methodName) {
-        StringBuilder b = new StringBuilder();
-        b.append("    ");
-        b.append(createTypeSignature(returnType, true));
-
-        b.append(" ");
-        b.append(methodName);
-        b.append("(");
-
-        String sep = "";
-
-        for (ParameterSpec optionalSpec : getOptional()) {
-            b.append(sep);
-            b.append("[");
-            b.append(createTypeSignature(optionalSpec, false));
-            b.append("]");
-            sep = ", ";
-        }
-
-        for (ParameterSpec requiredSpec : getRequired()) {
-            b.append(sep);
-            if (requiredSpec.getCardinality() == Cardinality.MANY) {
-                b.append("{");
-            }
-            b.append(createTypeSignature(requiredSpec, false));
-            if (requiredSpec.getCardinality() == Cardinality.MANY) {
-                b.append("}");
-            }
-            sep = ", ";
-        }
-
-        b.append(")");
-
-        if (typeDefinitions != null && !typeDefinitions.isEmpty()) {
-            b.append("\n\n");
-
-            String lineSep = "";
-            for (TypeDef def : typeDefinitions) {
-                b.append(lineSep);
-                b.append("    <").append(def.getName()).append(">");
-                b.append(" = {");
-                String separator = "";
-                for (TypeMirror type : def.getTypes()) {
-                    b.append(separator).append(Utils.getSimpleName(type));
-                    separator = ", ";
-                }
-                b.append("}");
-                lineSep = "\n";
-
-            }
-        }
-        return b.toString();
-    }
-
-    private static String createTypeSignature(ParameterSpec spec, boolean typeOnly) {
-        StringBuilder builder = new StringBuilder();
-        TypeDef foundTypeDef = spec.getTypeDefinition();
-        if (foundTypeDef != null) {
-            builder.append("<" + foundTypeDef.getName() + ">");
-        } else if (spec.getAllowedTypes().size() >= 1) {
-            builder.append(Utils.getSimpleName(spec.getAllowedTypes().get(0)));
-        } else {
-            builder.append("void");
-        }
-        if (!typeOnly) {
-            builder.append(" ");
-            builder.append(spec.getName());
-        }
-        return builder.toString();
-    }
-
-    @Override
-    public String toString() {
-        return toSignatureString("methodName");
-    }
-
-    static class TypeDef {
-
-        private final List<TypeMirror> types;
-        private final String name;
-
-        public TypeDef(List<TypeMirror> types, String name) {
-            this.types = types;
-            this.name = name;
-        }
-
-        public List<TypeMirror> getTypes() {
-            return types;
-        }
-
-        public String getName() {
-            return name;
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ParameterSpec.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,146 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.template;
-
-import java.util.*;
-
-import javax.lang.model.type.*;
-
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.node.NodeChildData.Cardinality;
-import com.oracle.truffle.codegen.processor.template.MethodSpec.TypeDef;
-
-public class ParameterSpec {
-
-    private final String name;
-    private final List<TypeMirror> allowedTypes;
-
-    /** Cardinality one or multiple. */
-    private Cardinality cardinality = Cardinality.ONE;
-    /** Type is part of the method signature. Relevant for comparisons. */
-    private boolean signature;
-    /** Type must be indexed when parsing. */
-    private boolean indexed;
-    /** Type is bound to local final variable. */
-    private boolean local;
-
-    private TypeDef typeDefinition;
-
-    public ParameterSpec(String name, TypeMirror... allowedTypes) {
-        this(name, Arrays.asList(allowedTypes));
-    }
-
-    public ParameterSpec(String name, List<TypeMirror> allowedTypes) {
-        this.name = name;
-        this.allowedTypes = allowedTypes;
-    }
-
-    public ParameterSpec(ParameterSpec o, List<TypeMirror> allowedTypes) {
-        this.name = o.name;
-        this.cardinality = o.cardinality;
-        this.signature = o.signature;
-        this.indexed = o.indexed;
-        this.local = o.local;
-        this.typeDefinition = o.typeDefinition;
-        this.allowedTypes = allowedTypes;
-    }
-
-    void setTypeDefinition(TypeDef typeDefinition) {
-        this.typeDefinition = typeDefinition;
-    }
-
-    TypeDef getTypeDefinition() {
-        return typeDefinition;
-    }
-
-    public void setSignature(boolean signature) {
-        this.signature = signature;
-    }
-
-    public void setLocal(boolean local) {
-        this.local = local;
-    }
-
-    public boolean isSignature() {
-        return signature;
-    }
-
-    public boolean isLocal() {
-        return local;
-    }
-
-    public boolean isIndexed() {
-        return indexed;
-    }
-
-    public void setIndexed(boolean indexed) {
-        this.indexed = indexed;
-    }
-
-    public void setCardinality(Cardinality cardinality) {
-        this.cardinality = cardinality;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public Cardinality getCardinality() {
-        return cardinality;
-    }
-
-    public List<TypeMirror> getAllowedTypes() {
-        return allowedTypes;
-    }
-
-    public boolean matches(TypeMirror actualType) {
-        for (TypeMirror mirror : allowedTypes) {
-            if (Utils.typeEquals(actualType, mirror)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return toSignatureString(false);
-    }
-
-    public String toSignatureString(boolean typeOnly) {
-        StringBuilder builder = new StringBuilder();
-        if (typeDefinition != null) {
-            builder.append("<" + typeDefinition.getName() + ">");
-        } else if (getAllowedTypes().size() >= 1) {
-            builder.append(Utils.getSimpleName(getAllowedTypes().get(0)));
-        } else {
-            builder.append("void");
-        }
-        if (!typeOnly) {
-            builder.append(" ");
-            builder.append(getName());
-        }
-        return builder.toString();
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/Template.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.template;
-
-import java.util.*;
-
-import javax.lang.model.element.*;
-
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.api.element.*;
-import com.oracle.truffle.codegen.processor.typesystem.*;
-
-public abstract class Template extends MessageContainer {
-
-    private final TypeElement templateType;
-    private final String templateMethodName;
-    private final AnnotationMirror annotation;
-
-    private List<? extends WritableElement> extensionElements;
-
-    public Template(TypeElement templateType, String templateMethodName, AnnotationMirror annotation) {
-        this.templateType = templateType;
-        this.templateMethodName = templateMethodName;
-        this.annotation = annotation;
-    }
-
-    public abstract TypeSystemData getTypeSystem();
-
-    @Override
-    public Element getMessageElement() {
-        return templateType;
-    }
-
-    @Override
-    protected List<MessageContainer> findChildContainers() {
-        return Collections.emptyList();
-    }
-
-    public String getTemplateMethodName() {
-        return templateMethodName;
-    }
-
-    public TypeElement getTemplateType() {
-        return templateType;
-    }
-
-    public AnnotationMirror getTemplateTypeAnnotation() {
-        return annotation;
-    }
-
-    public List<? extends WritableElement> getExtensionElements() {
-        return extensionElements;
-    }
-
-    public void setExtensionElements(List<? extends WritableElement> extensionMethods) {
-        this.extensionElements = extensionMethods;
-    }
-
-    @Override
-    public String toString() {
-        return getClass().getSimpleName() + "[" + Utils.getSimpleName(getTemplateType()) + "]";
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethod.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,393 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.template;
-
-import java.util.*;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.typesystem.*;
-
-/**
- * Note: this class has a natural ordering that is inconsistent with equals.
- */
-public class TemplateMethod extends MessageContainer implements Comparable<TemplateMethod> {
-
-    private String id;
-    private final Template template;
-    private final MethodSpec specification;
-    private final ExecutableElement method;
-    private final AnnotationMirror markerAnnotation;
-    private ActualParameter returnType;
-    private List<ActualParameter> parameters;
-
-    public TemplateMethod(String id, Template template, MethodSpec specification, ExecutableElement method, AnnotationMirror markerAnnotation, ActualParameter returnType,
-                    List<ActualParameter> parameters) {
-        this.template = template;
-        this.specification = specification;
-        this.method = method;
-        this.markerAnnotation = markerAnnotation;
-        this.returnType = returnType;
-        this.parameters = new ArrayList<>();
-        for (ActualParameter param : parameters) {
-            ActualParameter newParam = new ActualParameter(param);
-            this.parameters.add(newParam);
-            newParam.setMethod(this);
-        }
-        this.id = id;
-    }
-
-    public TemplateMethod(TemplateMethod method) {
-        this(method.id, method.template, method.specification, method.method, method.markerAnnotation, method.returnType, method.parameters);
-        getMessages().addAll(method.getMessages());
-    }
-
-    public TemplateMethod(TemplateMethod method, ExecutableElement executable) {
-        this(method.id, method.template, method.specification, executable, method.markerAnnotation, method.returnType, method.parameters);
-        getMessages().addAll(method.getMessages());
-    }
-
-    public void setParameters(List<ActualParameter> parameters) {
-        this.parameters = parameters;
-    }
-
-    @Override
-    public Element getMessageElement() {
-        return method;
-    }
-
-    @Override
-    public AnnotationMirror getMessageAnnotation() {
-        return markerAnnotation;
-    }
-
-    @Override
-    protected List<MessageContainer> findChildContainers() {
-        return Collections.emptyList();
-    }
-
-    public void setId(String id) {
-        this.id = id;
-    }
-
-    public String getId() {
-        return id;
-    }
-
-    public Template getTemplate() {
-        return template;
-    }
-
-    public MethodSpec getSpecification() {
-        return specification;
-    }
-
-    public ActualParameter getReturnType() {
-        return returnType;
-    }
-
-    public void replaceParameter(String localName, ActualParameter newParameter) {
-        if (returnType.getLocalName().equals(localName)) {
-            returnType = newParameter;
-            returnType.setMethod(this);
-        }
-
-        for (ListIterator<ActualParameter> iterator = parameters.listIterator(); iterator.hasNext();) {
-            ActualParameter parameter = iterator.next();
-            if (parameter.getLocalName().equals(localName)) {
-                iterator.set(newParameter);
-                newParameter.setMethod(this);
-            }
-        }
-    }
-
-    public List<ActualParameter> getRequiredParameters() {
-        List<ActualParameter> requiredParameters = new ArrayList<>();
-        for (ActualParameter parameter : getParameters()) {
-            if (getSpecification().getRequired().contains(parameter.getSpecification())) {
-                requiredParameters.add(parameter);
-            }
-        }
-        return requiredParameters;
-    }
-
-    public List<ActualParameter> getParameters() {
-        return parameters;
-    }
-
-    public List<ActualParameter> findParameters(ParameterSpec spec) {
-        List<ActualParameter> foundParameters = new ArrayList<>();
-        for (ActualParameter param : getReturnTypeAndParameters()) {
-            if (param.getSpecification().equals(spec)) {
-                foundParameters.add(param);
-            }
-        }
-        return foundParameters;
-    }
-
-    public ActualParameter findParameter(String valueName) {
-        for (ActualParameter param : getReturnTypeAndParameters()) {
-            if (param.getLocalName().equals(valueName)) {
-                return param;
-            }
-        }
-        return null;
-    }
-
-    public List<ActualParameter> getReturnTypeAndParameters() {
-        List<ActualParameter> allParameters = new ArrayList<>(getParameters().size() + 1);
-        if (getReturnType() != null) {
-            allParameters.add(getReturnType());
-        }
-        allParameters.addAll(getParameters());
-        return Collections.unmodifiableList(allParameters);
-    }
-
-    public boolean canBeAccessedByInstanceOf(ProcessorContext context, TypeMirror type) {
-        TypeMirror methodType = Utils.findNearestEnclosingType(getMethod()).asType();
-        return Utils.isAssignable(context, type, methodType) || Utils.isAssignable(context, methodType, type);
-    }
-
-    public ExecutableElement getMethod() {
-        return method;
-    }
-
-    public String getMethodName() {
-        if (getMethod() != null) {
-            return getMethod().getSimpleName().toString();
-        } else {
-            return "$synthetic";
-        }
-    }
-
-    public AnnotationMirror getMarkerAnnotation() {
-        return markerAnnotation;
-    }
-
-    @Override
-    public String toString() {
-        return String.format("%s [id = %s, method = %s]", getClass().getSimpleName(), getId(), getMethod());
-    }
-
-    public ActualParameter getPreviousParam(ActualParameter searchParam) {
-        ActualParameter prev = null;
-        for (ActualParameter param : getParameters()) {
-            if (param == searchParam) {
-                return prev;
-            }
-            prev = param;
-        }
-        return prev;
-    }
-
-    public Signature getSignature() {
-        Signature signature = new Signature();
-        for (ActualParameter parameter : getReturnTypeAndParameters()) {
-            if (!parameter.getSpecification().isSignature()) {
-                continue;
-            }
-            TypeData typeData = parameter.getTypeSystemType();
-            if (typeData != null) {
-                signature.types.add(typeData);
-            }
-        }
-        return signature;
-    }
-
-    public void updateSignature(Signature signature) {
-        assert signature.size() >= 1;
-        int signatureIndex = 0;
-        for (ActualParameter parameter : getReturnTypeAndParameters()) {
-            if (!parameter.getSpecification().isSignature()) {
-                continue;
-            }
-            TypeData newType = signature.get(signatureIndex++);
-            if (!parameter.getTypeSystemType().equals(newType)) {
-                replaceParameter(parameter.getLocalName(), new ActualParameter(parameter, newType));
-            }
-        }
-    }
-
-    @Override
-    public int compareTo(TemplateMethod o) {
-        if (this == o) {
-            return 0;
-        }
-
-        int compare = compareBySignature(o);
-        if (compare == 0) {
-            // if signature sorting failed sort by id
-            compare = getId().compareTo(o.getId());
-        }
-        if (compare == 0) {
-            // if still no difference sort by enclosing type name
-            TypeElement enclosingType1 = Utils.findNearestEnclosingType(getMethod());
-            TypeElement enclosingType2 = Utils.findNearestEnclosingType(o.getMethod());
-            compare = enclosingType1.getQualifiedName().toString().compareTo(enclosingType2.getQualifiedName().toString());
-        }
-        return compare;
-    }
-
-    public List<ActualParameter> getParametersAfter(ActualParameter genericParameter) {
-        boolean found = false;
-        List<ActualParameter> foundParameters = new ArrayList<>();
-        for (ActualParameter param : getParameters()) {
-            if (param.getLocalName().equals(genericParameter.getLocalName())) {
-                found = true;
-            } else if (found) {
-                foundParameters.add(param);
-            }
-        }
-        return foundParameters;
-    }
-
-    public int compareBySignature(TemplateMethod compareMethod) {
-        TypeSystemData typeSystem = getTemplate().getTypeSystem();
-        if (typeSystem != compareMethod.getTemplate().getTypeSystem()) {
-            throw new IllegalStateException("Cannot compare two methods with different type systems.");
-        }
-
-        Signature signature1 = getSignature();
-        Signature signature2 = compareMethod.getSignature();
-        if (signature1.size() != signature2.size()) {
-            return signature2.size() - signature1.size();
-        }
-
-        int result = 0;
-        for (int i = 1; i < signature1.size(); i++) {
-            int typeResult = compareActualParameter(typeSystem, signature1.get(i), signature2.get(i));
-            if (result == 0) {
-                result = typeResult;
-            } else if (typeResult != 0 && Math.signum(result) != Math.signum(typeResult)) {
-                // We cannot define an order.
-                return 0;
-            }
-        }
-        if (result == 0 && signature1.size() > 0) {
-            result = compareActualParameter(typeSystem, signature1.get(0), signature2.get(0));
-        }
-
-        return result;
-    }
-
-    private static int compareActualParameter(TypeSystemData typeSystem, TypeData t1, TypeData t2) {
-        int index1 = typeSystem.findType(t1);
-        int index2 = typeSystem.findType(t2);
-        return index1 - index2;
-    }
-
-    public static class Signature implements Iterable<TypeData>, Comparable<Signature> {
-
-        final List<TypeData> types;
-
-        public Signature() {
-            this.types = new ArrayList<>();
-        }
-
-        public Signature(List<TypeData> signature) {
-            this.types = signature;
-        }
-
-        @Override
-        public int hashCode() {
-            return types.hashCode();
-        }
-
-        public int compareTo(Signature o) {
-            if (o.size() != size()) {
-                return size() - o.size();
-            }
-
-            int typeSum = 0;
-            int otherTypeSum = 0;
-            for (int i = 0; i < types.size(); i++) {
-                TypeData type = types.get(i);
-                TypeData otherType = o.get(i);
-                typeSum += type.isGeneric() ? 1 : 0;
-                otherTypeSum += otherType.isGeneric() ? 1 : 0;
-            }
-
-            return typeSum - otherTypeSum;
-        }
-
-        public int size() {
-            return types.size();
-        }
-
-        public TypeData get(int index) {
-            return types.get(index);
-        }
-
-        public Signature combine(Signature genericSignature, Signature other) {
-            assert types.size() == other.types.size();
-            assert genericSignature.types.size() == other.types.size();
-
-            if (this.equals(other)) {
-                return this;
-            }
-
-            Signature signature = new Signature();
-            for (int i = 0; i < types.size(); i++) {
-                TypeData type1 = types.get(i);
-                TypeData type2 = other.types.get(i);
-                if (type1.equals(type2)) {
-                    signature.types.add(type1);
-                } else {
-                    signature.types.add(genericSignature.types.get(i));
-                }
-            }
-            return signature;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (obj instanceof Signature) {
-                return ((Signature) obj).types.equals(types);
-            }
-            return super.equals(obj);
-        }
-
-        public Iterator<TypeData> iterator() {
-            return types.iterator();
-        }
-
-        @Override
-        public String toString() {
-            return types.toString();
-        }
-
-        public boolean hasAnyParameterMatch(Signature other) {
-            for (int i = 1; i < types.size(); i++) {
-                TypeData type1 = types.get(i);
-                TypeData type2 = other.types.get(i);
-                if (type1.equals(type2)) {
-                    return true;
-                }
-            }
-            return false;
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,338 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.template;
-
-import static com.oracle.truffle.codegen.processor.Utils.*;
-
-import java.lang.annotation.*;
-import java.util.*;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-import javax.lang.model.util.*;
-
-import com.oracle.truffle.api.codegen.*;
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.node.NodeChildData.Cardinality;
-import com.oracle.truffle.codegen.processor.typesystem.*;
-
-public abstract class TemplateMethodParser<T extends Template, E extends TemplateMethod> {
-
-    private final ProcessorContext context;
-
-    protected final T template;
-
-    private boolean emitErrors = true;
-    private boolean parseNullOnError = true;
-
-    public TemplateMethodParser(ProcessorContext context, T template) {
-        this.template = template;
-        this.context = context;
-    }
-
-    public boolean isEmitErrors() {
-        return emitErrors;
-    }
-
-    public void setParseNullOnError(boolean nullOnError) {
-        this.parseNullOnError = nullOnError;
-    }
-
-    public boolean isParseNullOnError() {
-        return parseNullOnError;
-    }
-
-    public void setEmitErrors(boolean emitErrors) {
-        this.emitErrors = emitErrors;
-    }
-
-    public ProcessorContext getContext() {
-        return context;
-    }
-
-    public TypeSystemData getTypeSystem() {
-        return template.getTypeSystem();
-    }
-
-    public abstract MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror);
-
-    public abstract E create(TemplateMethod method);
-
-    public abstract boolean isParsable(ExecutableElement method);
-
-    public Class<? extends Annotation> getAnnotationType() {
-        return null;
-    }
-
-    public final List<E> parse(List<? extends Element> elements) {
-        List<ExecutableElement> methods = new ArrayList<>();
-        methods.addAll(ElementFilter.methodsIn(elements));
-
-        List<E> parsedMethods = new ArrayList<>();
-        boolean valid = true;
-        for (ExecutableElement method : methods) {
-            if (!isParsable(method)) {
-                continue;
-            }
-
-            Class<? extends Annotation> annotationType = getAnnotationType();
-            AnnotationMirror mirror = null;
-            if (annotationType != null) {
-                mirror = Utils.findAnnotationMirror(getContext().getEnvironment(), method, annotationType);
-            }
-
-            E parsedMethod = parse(method, mirror);
-
-            if (method.getModifiers().contains(Modifier.PRIVATE) && emitErrors) {
-                parsedMethod.addError("Method must not be private.");
-                valid = false;
-                continue;
-            }
-
-            if (parsedMethod != null) {
-                parsedMethods.add(parsedMethod);
-            } else {
-                valid = false;
-            }
-        }
-        Collections.sort(parsedMethods);
-
-        if (!valid && parseNullOnError) {
-            return null;
-        }
-        return parsedMethods;
-    }
-
-    private E parse(ExecutableElement method, AnnotationMirror annotation) {
-        MethodSpec methodSpecification = createSpecification(method, annotation);
-        if (methodSpecification == null) {
-            return null;
-        }
-
-        methodSpecification.applyTypeDefinitions("types");
-
-        String id = method.getSimpleName().toString();
-        AnnotationMirror idAnnotation = Utils.findAnnotationMirror(context.getEnvironment(), method, NodeId.class);
-        if (idAnnotation != null) {
-            id = Utils.getAnnotationValue(String.class, idAnnotation, "value");
-        }
-
-        ParameterSpec returnTypeSpec = methodSpecification.getReturnType();
-
-        ActualParameter returnTypeMirror = matchParameter(returnTypeSpec, method.getReturnType(), template, 0, false);
-        if (returnTypeMirror == null) {
-            if (emitErrors) {
-                E invalidMethod = create(new TemplateMethod(id, template, methodSpecification, method, annotation, returnTypeMirror, Collections.<ActualParameter> emptyList()));
-                String expectedReturnType = returnTypeSpec.toSignatureString(true);
-                String actualReturnType = Utils.getSimpleName(method.getReturnType());
-
-                String message = String.format("The provided return type \"%s\" does not match expected return type \"%s\".\nExpected signature: \n %s", actualReturnType, expectedReturnType,
-                                methodSpecification.toSignatureString(method.getSimpleName().toString()));
-                invalidMethod.addError(message);
-                return invalidMethod;
-            } else {
-                return null;
-            }
-        }
-
-        List<TypeMirror> parameterTypes = new ArrayList<>();
-        for (VariableElement var : method.getParameters()) {
-            parameterTypes.add(var.asType());
-        }
-
-        List<ActualParameter> parameters = parseParameters(methodSpecification, parameterTypes);
-        if (parameters == null) {
-            if (isEmitErrors()) {
-                E invalidMethod = create(new TemplateMethod(id, template, methodSpecification, method, annotation, returnTypeMirror, Collections.<ActualParameter> emptyList()));
-                String message = String.format("Method signature %s does not match to the expected signature: \n%s", createActualSignature(methodSpecification, method),
-                                methodSpecification.toSignatureString(method.getSimpleName().toString()));
-                invalidMethod.addError(message);
-                return invalidMethod;
-            } else {
-                return null;
-            }
-        }
-
-        return create(new TemplateMethod(id, template, methodSpecification, method, annotation, returnTypeMirror, parameters));
-    }
-
-    private static String createActualSignature(MethodSpec spec, ExecutableElement method) {
-        StringBuilder b = new StringBuilder("(");
-        String sep = "";
-        for (TypeMirror implicitType : spec.getImplicitRequiredTypes()) {
-            b.append(sep);
-            b.append("implicit " + Utils.getSimpleName(implicitType));
-            sep = ", ";
-        }
-        for (VariableElement var : method.getParameters()) {
-            b.append(sep);
-            b.append(Utils.getSimpleName(var.asType()));
-            sep = ", ";
-        }
-        b.append(")");
-        return b.toString();
-    }
-
-    private List<ActualParameter> parseParameters(MethodSpec spec, List<TypeMirror> parameterTypes) {
-        List<ActualParameter> parsedParams = new ArrayList<>();
-        ConsumableListIterator<TypeMirror> types = new ConsumableListIterator<>(parameterTypes);
-
-        // parse optional parameters
-        ConsumableListIterator<ParameterSpec> optionals = new ConsumableListIterator<>(spec.getOptional());
-        for (TypeMirror type : types) {
-            int oldIndex = types.getIndex();
-            int optionalCount = 1;
-            for (ParameterSpec paramspec : optionals) {
-                ActualParameter optionalParam = matchParameter(paramspec, type, template, 0, false);
-                if (optionalParam != null) {
-                    optionals.consume(optionalCount);
-                    types.consume();
-                    parsedParams.add(optionalParam);
-                    break;
-                }
-                optionalCount++;
-            }
-            if (oldIndex == types.getIndex()) {
-                // nothing found anymore skip optional
-                break;
-            }
-        }
-
-        List<TypeMirror> typesWithImplicit = new ArrayList<>(spec.getImplicitRequiredTypes());
-        typesWithImplicit.addAll(types.toList());
-        types = new ConsumableListIterator<>(typesWithImplicit);
-
-        int specificationParameterIndex = 0;
-        ConsumableListIterator<ParameterSpec> required = new ConsumableListIterator<>(spec.getRequired());
-        while (required.get() != null || types.get() != null) {
-            if (required.get() == null || types.get() == null) {
-                if (required.get() != null && required.get().getCardinality() == Cardinality.MANY) {
-                    required.consume();
-                    specificationParameterIndex = 0;
-                    continue;
-                }
-                break;
-            }
-            boolean implicit = types.getIndex() < spec.getImplicitRequiredTypes().size();
-            ActualParameter resolvedParameter = matchParameter(required.get(), types.get(), template, specificationParameterIndex, implicit);
-            if (resolvedParameter == null) {
-                if (required.get().getCardinality() == Cardinality.MANY) {
-                    required.consume();
-                    continue;
-                }
-                // direct mismatch but required -> error
-                return null;
-            } else {
-                parsedParams.add(resolvedParameter);
-                types.consume();
-                if (required.get().getCardinality() == Cardinality.ONE) {
-                    required.consume();
-                    specificationParameterIndex = 0;
-                } else if (required.get().getCardinality() == Cardinality.MANY) {
-                    specificationParameterIndex++;
-                }
-            }
-        }
-
-        if (!types.toList().isEmpty()) {
-            // additional types -> error
-            return null;
-        }
-
-        if (!required.toList().isEmpty() && !spec.isVariableRequiredArguments()) {
-            // additional specifications -> error
-            return null;
-        }
-
-        // success!
-        return parsedParams;
-    }
-
-    private ActualParameter matchParameter(ParameterSpec specification, TypeMirror mirror, Template originalTemplate, int index, boolean implicit) {
-        TypeMirror resolvedType = mirror;
-        if (hasError(resolvedType)) {
-            resolvedType = context.resolveNotYetCompiledType(mirror, originalTemplate);
-        }
-
-        if (!specification.matches(resolvedType)) {
-            return null;
-        }
-
-        TypeData resolvedTypeData = getTypeSystem().findTypeData(resolvedType);
-        if (resolvedTypeData != null) {
-            return new ActualParameter(specification, resolvedTypeData, index, implicit);
-        } else {
-            return new ActualParameter(specification, resolvedType, index, implicit);
-        }
-    }
-
-    /* Helper class for parsing. */
-    private static class ConsumableListIterator<E> implements Iterable<E> {
-
-        private final List<E> data;
-        private int index;
-
-        public ConsumableListIterator(List<E> data) {
-            this.data = data;
-        }
-
-        public E get() {
-            if (index >= data.size()) {
-                return null;
-            }
-            return data.get(index);
-        }
-
-        public E consume() {
-            return consume(1);
-        }
-
-        public E consume(int count) {
-            if (index + count <= data.size()) {
-                index += count;
-                return get();
-            } else {
-                throw new ArrayIndexOutOfBoundsException(count + 1);
-            }
-        }
-
-        public int getIndex() {
-            return index;
-        }
-
-        @Override
-        public Iterator<E> iterator() {
-            return toList().iterator();
-        }
-
-        public List<E> toList() {
-            if (index < data.size()) {
-                return data.subList(index, data.size());
-            } else {
-                return Collections.<E> emptyList();
-            }
-        }
-
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateParser.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.template;
-
-import java.util.*;
-
-import javax.lang.model.element.*;
-import javax.lang.model.util.*;
-
-import com.oracle.truffle.codegen.processor.*;
-
-public abstract class TemplateParser<M extends Template> extends AbstractParser<M> {
-
-    public TemplateParser(ProcessorContext c) {
-        super(c);
-    }
-
-    protected void verifyExclusiveMethodAnnotation(Template template, Class<?>... annotationTypes) {
-        List<ExecutableElement> methods = ElementFilter.methodsIn(template.getTemplateType().getEnclosedElements());
-        for (ExecutableElement method : methods) {
-            List<AnnotationMirror> foundAnnotations = new ArrayList<>();
-            for (int i = 0; i < annotationTypes.length; i++) {
-                Class<?> annotationType = annotationTypes[i];
-                AnnotationMirror mirror = Utils.findAnnotationMirror(context.getEnvironment(), method, annotationType);
-                if (mirror != null) {
-                    foundAnnotations.add(mirror);
-                }
-            }
-            if (foundAnnotations.size() > 1) {
-                List<String> annotationNames = new ArrayList<>();
-                for (AnnotationMirror mirror : foundAnnotations) {
-                    annotationNames.add("@" + Utils.getSimpleName(mirror.getAnnotationType()));
-                }
-
-                template.addError("Non exclusive usage of annotations %s.", annotationNames);
-            }
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/GuardData.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.typesystem;
-
-import com.oracle.truffle.codegen.processor.node.*;
-import com.oracle.truffle.codegen.processor.template.*;
-
-public class GuardData extends TemplateMethod {
-
-    private final SpecializationData specialization;
-
-    public GuardData(TemplateMethod method, SpecializationData specialization) {
-        super(method);
-        this.specialization = specialization;
-    }
-
-    public SpecializationData getSpecialization() {
-        return specialization;
-    }
-
-    @Override
-    public String toString() {
-        return getMethodName();
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/GuardParser.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.typesystem;
-
-import java.lang.annotation.*;
-import java.util.*;
-
-import javax.lang.model.element.*;
-
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.node.*;
-import com.oracle.truffle.codegen.processor.template.*;
-
-public class GuardParser extends NodeMethodParser<GuardData> {
-
-    private final SpecializationData specialization;
-    private final String guardName;
-
-    public GuardParser(ProcessorContext context, SpecializationData specialization, String guardName) {
-        super(context, specialization.getNode());
-        this.specialization = specialization;
-        this.guardName = guardName;
-        setEmitErrors(false);
-        setParseNullOnError(false);
-    }
-
-    @Override
-    public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
-        MethodSpec spec = createDefaultMethodSpec(method, mirror, true, null);
-        spec.setVariableRequiredArguments(true);
-        spec.getRequired().clear();
-
-        for (ActualParameter parameter : specialization.getRequiredParameters()) {
-            ParameterSpec paramSpec = new ParameterSpec(parameter.getLocalName(), parameter.getType(), getNode().getTypeSystem().getGenericType());
-            paramSpec.setSignature(true);
-            spec.addRequired(paramSpec);
-        }
-
-        return spec;
-    }
-
-    @Override
-    protected ParameterSpec createReturnParameterSpec() {
-        return new ParameterSpec("returnType", getContext().getType(boolean.class));
-    }
-
-    @Override
-    public boolean isParsable(ExecutableElement method) {
-        return method.getSimpleName().toString().equals(guardName);
-    }
-
-    @Override
-    public GuardData create(TemplateMethod method) {
-        GuardData guard = new GuardData(method, specialization);
-        /*
-         * Update parameters in way that parameter specifications match again the node field names
-         * etc.
-         */
-        List<ActualParameter> newParameters = new ArrayList<>();
-        for (ActualParameter parameter : guard.getParameters()) {
-            ActualParameter specializationParameter = specialization.findParameter(parameter.getSpecification().getName());
-            if (specializationParameter == null) {
-                newParameters.add(parameter);
-            } else {
-                newParameters.add(new ActualParameter(specializationParameter.getSpecification(), parameter.getTypeSystemType(), specializationParameter.getIndex(), parameter.isImplicit()));
-            }
-        }
-        guard.setParameters(newParameters);
-
-        return guard;
-    }
-
-    @Override
-    public Class<? extends Annotation> getAnnotationType() {
-        return null;
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeCastData.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.typesystem;
-
-import com.oracle.truffle.codegen.processor.template.*;
-
-public class TypeCastData extends TemplateMethod {
-
-    private final TypeData targetType;
-    private final TypeData sourceType;
-
-    public TypeCastData(TemplateMethod method, TypeData sourceType, TypeData targetType) {
-        super(method);
-        this.sourceType = sourceType;
-        this.targetType = targetType;
-    }
-
-    public boolean isGeneric() {
-        return sourceType.isGeneric();
-    }
-
-    public TypeData getSourceType() {
-        return sourceType;
-    }
-
-    public TypeData getTargetType() {
-        return targetType;
-    }
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeCastParser.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.typesystem;
-
-import java.lang.annotation.*;
-
-import javax.lang.model.element.*;
-
-import com.oracle.truffle.api.codegen.*;
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.template.*;
-
-class TypeCastParser extends TypeSystemMethodParser<TypeCastData> {
-
-    public TypeCastParser(ProcessorContext context, TypeSystemData typeSystem) {
-        super(context, typeSystem);
-    }
-
-    @Override
-    public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
-        TypeData targetType = findTypeByMethodName(method.getSimpleName().toString(), "as");
-        if (targetType == null) {
-            return null;
-        }
-        MethodSpec spec = new MethodSpec(new ParameterSpec("returnType", targetType.getPrimitiveType()));
-        spec.addRequired(new ParameterSpec("value", getTypeSystem().getPrimitiveTypeMirrors()));
-        return spec;
-    }
-
-    @Override
-    public TypeCastData create(TemplateMethod method) {
-        TypeData targetType = findTypeByMethodName(method, "as");
-        ActualParameter parameter = method.findParameter("valueValue");
-        return new TypeCastData(method, parameter.getTypeSystemType(), targetType);
-    }
-
-    @Override
-    public Class<? extends Annotation> getAnnotationType() {
-        return TypeCast.class;
-    }
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeCheckData.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.typesystem;
-
-import com.oracle.truffle.codegen.processor.template.*;
-
-public class TypeCheckData extends TemplateMethod {
-
-    private final TypeData checkedType;
-    private final TypeData valueType;
-
-    public TypeCheckData(TemplateMethod method, TypeData checkedType, TypeData valueType) {
-        super(method);
-        this.checkedType = checkedType;
-        this.valueType = valueType;
-    }
-
-    public boolean isGeneric() {
-        return valueType.isGeneric();
-    }
-
-    public TypeData getCheckedType() {
-        return checkedType;
-    }
-
-    public TypeData getValueType() {
-        return valueType;
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeCheckParser.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.typesystem;
-
-import java.lang.annotation.*;
-
-import javax.lang.model.element.*;
-
-import com.oracle.truffle.api.codegen.*;
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.template.*;
-
-class TypeCheckParser extends TypeSystemMethodParser<TypeCheckData> {
-
-    public TypeCheckParser(ProcessorContext context, TypeSystemData typeSystem) {
-        super(context, typeSystem);
-    }
-
-    @Override
-    public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
-        TypeData targetType = findTypeByMethodName(method.getSimpleName().toString(), "is");
-        if (targetType == null) {
-            return null;
-        }
-        MethodSpec spec = new MethodSpec(new ParameterSpec("returnType", getContext().getType(boolean.class)));
-        spec.addRequired(new ParameterSpec("value", getTypeSystem().getPrimitiveTypeMirrors()));
-        return spec;
-    }
-
-    @Override
-    public TypeCheckData create(TemplateMethod method) {
-        TypeData checkedType = findTypeByMethodName(method, "is");
-        assert checkedType != null;
-        ActualParameter parameter = method.findParameter("valueValue");
-        assert parameter != null;
-        return new TypeCheckData(method, checkedType, parameter.getTypeSystemType());
-    }
-
-    @Override
-    public Class<? extends Annotation> getAnnotationType() {
-        return TypeCheck.class;
-    }
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeData.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,130 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.typesystem;
-
-import java.util.*;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.template.*;
-
-public class TypeData extends MessageContainer {
-
-    private final TypeSystemData typeSystem;
-    private final AnnotationValue annotationValue;
-    private final TypeMirror primitiveType;
-    private final TypeMirror boxedType;
-
-    private final List<TypeCastData> typeCasts = new ArrayList<>();
-    private final List<TypeCheckData> typeChecks = new ArrayList<>();
-
-    public TypeData(TypeSystemData typeSystem, AnnotationValue value, TypeMirror primitiveType, TypeMirror boxedType) {
-        this.typeSystem = typeSystem;
-        this.annotationValue = value;
-        this.primitiveType = primitiveType;
-        this.boxedType = boxedType;
-    }
-
-    @Override
-    public Element getMessageElement() {
-        return typeSystem.getMessageElement();
-    }
-
-    @Override
-    public AnnotationMirror getMessageAnnotation() {
-        return typeSystem.getMessageAnnotation();
-    }
-
-    @Override
-    public AnnotationValue getMessageAnnotationValue() {
-        return annotationValue;
-    }
-
-    void addTypeCast(TypeCastData typeCast) {
-        this.typeCasts.add(typeCast);
-    }
-
-    void addTypeCheck(TypeCheckData typeCheck) {
-        this.typeChecks.add(typeCheck);
-    }
-
-    public List<TypeCastData> getTypeCasts() {
-        return typeCasts;
-    }
-
-    public List<TypeCheckData> getTypeChecks() {
-        return typeChecks;
-    }
-
-    public TypeSystemData getTypeSystem() {
-        return typeSystem;
-    }
-
-    public TypeMirror getPrimitiveType() {
-        return primitiveType;
-    }
-
-    public TypeMirror getBoxedType() {
-        return boxedType;
-    }
-
-    public boolean isGeneric() {
-        return Utils.typeEquals(boxedType, getTypeSystem().getGenericType());
-    }
-
-    public boolean isVoid() {
-        if (getTypeSystem().getVoidType() == null) {
-            return false;
-        }
-        return Utils.typeEquals(boxedType, getTypeSystem().getVoidType().getBoxedType());
-    }
-
-    @Override
-    public String toString() {
-        return getClass().getSimpleName() + "[" + Utils.getSimpleName(primitiveType) + "]";
-    }
-
-    public boolean equalsType(TypeData actualTypeData) {
-        return Utils.typeEquals(boxedType, actualTypeData.boxedType);
-    }
-
-    public boolean needsCastTo(ProcessorContext context, TypeData targetType) {
-        if (this.equals(targetType)) {
-            return false;
-        } else if (targetType.isGeneric()) {
-            return false;
-        } else if (targetType.isVoid()) {
-            return false;
-        } else if (Utils.isAssignable(context, getPrimitiveType(), targetType.getPrimitiveType())) {
-            return false;
-        }
-        return true;
-    }
-
-    public boolean isPrimitive() {
-        return Utils.isPrimitive(getPrimitiveType());
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemCodeGenerator.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,180 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.typesystem;
-
-import static com.oracle.truffle.codegen.processor.Utils.*;
-import static javax.lang.model.element.Modifier.*;
-
-import java.util.*;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.ast.*;
-import com.oracle.truffle.codegen.processor.template.*;
-
-public class TypeSystemCodeGenerator extends CompilationUnitFactory<TypeSystemData> {
-
-    public TypeSystemCodeGenerator(ProcessorContext context) {
-        super(context);
-    }
-
-    public static String isTypeMethodName(TypeData type) {
-        return "is" + Utils.getTypeId(type.getBoxedType());
-    }
-
-    public static String asTypeMethodName(TypeData type) {
-        return "as" + Utils.getTypeId(type.getBoxedType());
-    }
-
-    public static String expectTypeMethodName(TypeData type) {
-        return "expect" + Utils.getTypeId(type.getBoxedType());
-    }
-
-    /**
-     * Finds the generated singleton field for a TypeSytemData instance. TypeSystemCodeGenerator
-     * must be applied to the TypeSystemData model before use.
-     */
-    public static VariableElement findSingleton(ProcessorContext context, TypeSystemData typeSystem) {
-        TypeMirror type = context.findGeneratedClassBySimpleName(TypeClassFactory.typeName(typeSystem), typeSystem);
-        return Utils.findDeclaredField(type, TypeClassFactory.singletonName(typeSystem.getTemplateType().asType()));
-    }
-
-    @Override
-    protected void createChildren(TypeSystemData m) {
-        add(new TypeClassFactory(context), m);
-    }
-
-    protected static class TypeClassFactory extends ClassElementFactory<TypeSystemData> {
-
-        private static final String LOCAL_VALUE = "value";
-
-        public TypeClassFactory(ProcessorContext context) {
-            super(context);
-        }
-
-        @Override
-        public CodeTypeElement create(TypeSystemData typeSystem) {
-            String name = typeName(typeSystem);
-            CodeTypeElement clazz = createClass(typeSystem, modifiers(PUBLIC), name, typeSystem.getTemplateType().asType(), false);
-
-            clazz.add(createConstructorUsingFields(modifiers(PROTECTED), clazz));
-            CodeVariableElement singleton = createSingleton(clazz);
-            clazz.add(singleton);
-
-            for (TypeData type : typeSystem.getTypes()) {
-                if (!type.isGeneric()) {
-                    CodeExecutableElement isType = createIsTypeMethod(type);
-                    if (isType != null) {
-                        clazz.add(isType);
-                    }
-                    CodeExecutableElement asType = createAsTypeMethod(type);
-                    if (asType != null) {
-                        clazz.add(asType);
-                    }
-
-                    for (TypeData sourceType : collectExpectSourceTypes(type)) {
-                        CodeExecutableElement expect = createExpectTypeMethod(type, sourceType);
-                        if (expect != null) {
-                            clazz.add(expect);
-                        }
-                    }
-                }
-            }
-
-            return clazz;
-        }
-
-        private static List<TypeData> collectExpectSourceTypes(TypeData type) {
-            Set<TypeData> sourceTypes = new HashSet<>();
-            sourceTypes.add(type.getTypeSystem().getGenericTypeData());
-            for (TypeCastData cast : type.getTypeCasts()) {
-                sourceTypes.add(cast.getSourceType());
-            }
-            for (TypeCheckData cast : type.getTypeChecks()) {
-                sourceTypes.add(cast.getCheckedType());
-            }
-            return new ArrayList<>(sourceTypes);
-        }
-
-        private static String typeName(TypeSystemData typeSystem) {
-            String name = getSimpleName(typeSystem.getTemplateType());
-            return name + "Gen";
-        }
-
-        private static String singletonName(TypeMirror type) {
-            return createConstantName(getSimpleName(type));
-        }
-
-        private CodeVariableElement createSingleton(CodeTypeElement clazz) {
-            CodeVariableElement field = new CodeVariableElement(modifiers(PUBLIC, STATIC, FINAL), clazz.asType(), singletonName(getModel().getTemplateType().asType()));
-            field.createInitBuilder().startNew(clazz.asType()).end();
-            return field;
-        }
-
-        private CodeExecutableElement createIsTypeMethod(TypeData type) {
-            if (!type.getTypeChecks().isEmpty()) {
-                return null;
-            }
-
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), getContext().getType(boolean.class), TypeSystemCodeGenerator.isTypeMethodName(type));
-            method.addParameter(new CodeVariableElement(getContext().getType(Object.class), LOCAL_VALUE));
-
-            CodeTreeBuilder body = method.createBuilder();
-            body.startReturn().instanceOf(LOCAL_VALUE, type.getBoxedType()).end();
-
-            return method;
-        }
-
-        private CodeExecutableElement createAsTypeMethod(TypeData type) {
-            if (!type.getTypeCasts().isEmpty()) {
-                return null;
-            }
-
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), type.getPrimitiveType(), TypeSystemCodeGenerator.asTypeMethodName(type));
-            method.addParameter(new CodeVariableElement(getContext().getType(Object.class), LOCAL_VALUE));
-
-            CodeTreeBuilder body = method.createBuilder();
-            body.startAssert().startCall(isTypeMethodName(type)).string(LOCAL_VALUE).end().end();
-            body.startReturn().cast(type.getPrimitiveType(), body.create().string(LOCAL_VALUE).getTree()).end();
-
-            return method;
-        }
-
-        private CodeExecutableElement createExpectTypeMethod(TypeData expectedType, TypeData sourceType) {
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), expectedType.getPrimitiveType(), TypeSystemCodeGenerator.expectTypeMethodName(expectedType));
-            method.addParameter(new CodeVariableElement(sourceType.getPrimitiveType(), LOCAL_VALUE));
-            method.addThrownType(getContext().getTruffleTypes().getUnexpectedValueException());
-
-            CodeTreeBuilder body = method.createBuilder();
-            body.startIf().startCall(null, TypeSystemCodeGenerator.isTypeMethodName(expectedType)).string(LOCAL_VALUE).end().end().startBlock();
-            body.startReturn().startCall(null, TypeSystemCodeGenerator.asTypeMethodName(expectedType)).string(LOCAL_VALUE).end().end();
-            body.end(); // if-block
-            body.startThrow().startNew(getContext().getTruffleTypes().getUnexpectedValueException()).string(LOCAL_VALUE).end().end();
-
-            return method;
-        }
-
-    }
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemData.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,147 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.typesystem;
-
-import java.util.*;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.template.*;
-
-public class TypeSystemData extends Template {
-
-    private List<TypeData> types;
-    private List<TypeMirror> primitiveTypeMirrors = new ArrayList<>();
-    private List<TypeMirror> boxedTypeMirrors = new ArrayList<>();
-
-    private TypeMirror genericType;
-    private TypeData voidType;
-
-    public TypeSystemData(TypeElement templateType, AnnotationMirror annotation) {
-        super(templateType, null, annotation);
-    }
-
-    @Override
-    public TypeSystemData getTypeSystem() {
-        return this;
-    }
-
-    void setTypes(List<TypeData> types) {
-        this.types = types;
-        if (types != null) {
-            for (TypeData typeData : types) {
-                primitiveTypeMirrors.add(typeData.getPrimitiveType());
-                boxedTypeMirrors.add(typeData.getBoxedType());
-            }
-        }
-    }
-
-    void setGenericType(TypeMirror genericType) {
-        this.genericType = genericType;
-    }
-
-    void setVoidType(TypeData voidType) {
-        this.voidType = voidType;
-    }
-
-    @Override
-    protected List<MessageContainer> findChildContainers() {
-        List<MessageContainer> sinks = new ArrayList<>();
-        if (types != null) {
-            sinks.addAll(types);
-        }
-        return sinks;
-    }
-
-    public boolean isGeneric(TypeMirror type) {
-        return Utils.typeEquals(getGenericType(), type);
-    }
-
-    public TypeData getVoidType() {
-        return voidType;
-    }
-
-    public List<TypeMirror> getBoxedTypeMirrors() {
-        return boxedTypeMirrors;
-    }
-
-    public List<TypeMirror> getPrimitiveTypeMirrors() {
-        return primitiveTypeMirrors;
-    }
-
-    public List<TypeData> getTypes() {
-        return types;
-    }
-
-    public TypeMirror getGenericType() {
-        return genericType;
-    }
-
-    public TypeData getGenericTypeData() {
-        TypeData result = types.get(types.size() - 1);
-        assert result.getBoxedType() == genericType;
-        return result;
-    }
-
-    public TypeData findType(String simpleName) {
-        for (TypeData type : types) {
-            if (Utils.getSimpleName(type.getBoxedType()).equals(simpleName)) {
-                return type;
-            }
-        }
-        return null;
-    }
-
-    public TypeData findTypeData(TypeMirror type) {
-        if (Utils.typeEquals(voidType.getPrimitiveType(), type)) {
-            return voidType;
-        }
-
-        int index = findType(type);
-        if (index == -1) {
-            return null;
-        }
-        return types.get(index);
-    }
-
-    public int findType(TypeData typeData) {
-        return findType(typeData.getPrimitiveType());
-    }
-
-    public int findType(TypeMirror type) {
-        for (int i = 0; i < types.size(); i++) {
-            if (Utils.typeEquals(types.get(i).getPrimitiveType(), type)) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    @Override
-    public String toString() {
-        return getClass().getSimpleName() + "[template = " + Utils.getSimpleName(getTemplateType()) + ", types = " + types + "]";
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemMethodParser.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.typesystem;
-
-import javax.lang.model.element.*;
-
-import com.oracle.truffle.api.codegen.*;
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.template.*;
-
-abstract class TypeSystemMethodParser<E extends TemplateMethod> extends TemplateMethodParser<TypeSystemData, E> {
-
-    public TypeSystemMethodParser(ProcessorContext context, TypeSystemData typeSystem) {
-        super(context, typeSystem);
-    }
-
-    @Override
-    public final boolean isParsable(ExecutableElement method) {
-        return Utils.findAnnotationMirror(getContext().getEnvironment(), method, getAnnotationType()) != null;
-    }
-
-    protected TypeData findTypeByMethodName(String methodName, String prefix) {
-        String typeName = methodName.substring(prefix.length(), methodName.length());
-        TypeData type = getTypeSystem().findType(typeName);
-        return type;
-    }
-
-    protected TypeData findTypeByMethodName(TemplateMethod method, String prefix) {
-        String methodName = method.getMethodName();
-        if (!methodName.startsWith(prefix)) {
-            String annotationName = Utils.getSimpleName(method.getMessageAnnotation().getAnnotationType());
-            method.addError("Methods annotated with %s must match the pattern '%s'.", annotationName, String.format("%s${typeName}", prefix));
-            return null;
-        }
-        String typeName = methodName.substring(prefix.length(), methodName.length());
-        TypeData type = getTypeSystem().findType(typeName);
-        if (type == null) {
-            String annotationName = TypeSystem.class.getSimpleName();
-            method.addError("Type '%s' is not declared in this @%s.", typeName, annotationName);
-            return null;
-        }
-
-        return type;
-    }
-
-}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemParser.java	Mon Jul 01 20:32:20 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,277 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.codegen.processor.typesystem;
-
-import static com.oracle.truffle.codegen.processor.Utils.*;
-
-import java.lang.annotation.*;
-import java.util.*;
-
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-import javax.lang.model.util.*;
-
-import com.oracle.truffle.api.codegen.*;
-import com.oracle.truffle.codegen.processor.*;
-import com.oracle.truffle.codegen.processor.template.*;
-
-public class TypeSystemParser extends TemplateParser<TypeSystemData> {
-
-    public static final List<Class<TypeSystem>> ANNOTATIONS = Arrays.asList(TypeSystem.class);
-
-    public TypeSystemParser(ProcessorContext c) {
-        super(c);
-    }
-
-    @Override
-    public Class<? extends Annotation> getAnnotationType() {
-        return TypeSystem.class;
-    }
-
-    @Override
-    protected TypeSystemData parse(Element element, AnnotationMirror mirror) {
-        TypeElement templateType = (TypeElement) element;
-        AnnotationMirror templateTypeAnnotation = mirror;
-        TypeSystemData typeSystem = new TypeSystemData(templateType, templateTypeAnnotation);
-
-        // annotation type on class path!?
-        TypeElement annotationTypeElement = processingEnv.getElementUtils().getTypeElement(getAnnotationType().getCanonicalName());
-        if (annotationTypeElement == null) {
-            typeSystem.addError("Required class %s is not on the classpath.", getAnnotationType().getName());
-        }
-        if (templateType.getModifiers().contains(Modifier.PRIVATE)) {
-            typeSystem.addError("A @%s must have at least package protected visibility.", getAnnotationType().getName());
-        }
-
-        if (templateType.getModifiers().contains(Modifier.FINAL)) {
-            typeSystem.addError("The @%s must not be final.", getAnnotationType().getName());
-        }
-        if (typeSystem.hasErrors()) {
-            return typeSystem;
-        }
-
-        typeSystem.setTypes(parseTypes(typeSystem));
-        if (typeSystem.getTypes() == null) {
-            return typeSystem;
-        }
-
-        TypeMirror genericType = context.getType(Object.class);
-        TypeData voidType = new TypeData(typeSystem, null, context.getType(void.class), context.getType(Void.class));
-
-        typeSystem.setGenericType(genericType);
-        typeSystem.setVoidType(voidType);
-
-        verifyExclusiveMethodAnnotation(typeSystem, TypeCast.class, TypeCheck.class);
-
-        List<Element> elements = new ArrayList<>(context.getEnvironment().getElementUtils().getAllMembers(templateType));
-
-        List<TypeCastData> casts = new TypeCastParser(context, typeSystem).parse(elements);
-        List<TypeCheckData> checks = new TypeCheckParser(context, typeSystem).parse(elements);
-
-        if (casts == null || checks == null) {
-            return typeSystem;
-        }
-
-        for (TypeCheckData check : checks) {
-            check.getCheckedType().addTypeCheck(check);
-        }
-
-        for (TypeCastData cast : casts) {
-            cast.getTargetType().addTypeCast(cast);
-        }
-
-        verifyGenericTypeChecksAndCasts(typeSystem);
-        verifyMethodSignatures(typeSystem);
-        verifyNamesUnique(typeSystem);
-
-        return typeSystem;
-    }
-
-    private static void verifyGenericTypeChecksAndCasts(TypeSystemData typeSystem) {
-        for (TypeData type : typeSystem.getTypes()) {
-            if (!type.getTypeChecks().isEmpty()) {
-                boolean hasGeneric = false;
-                for (TypeCheckData typeCheck : type.getTypeChecks()) {
-                    if (typeCheck.isGeneric()) {
-                        hasGeneric = true;
-                        break;
-                    }
-                }
-                if (!hasGeneric) {
-                    type.addError("No generic but specific @%s method %s for type %s specified. " + "Specify a generic @%s method with parameter type %s to resolve this.",
-                                    TypeCheck.class.getSimpleName(), TypeSystemCodeGenerator.isTypeMethodName(type), Utils.getSimpleName(type.getBoxedType()), TypeCheck.class.getSimpleName(),
-                                    Object.class.getSimpleName());
-                }
-            }
-            if (!type.getTypeCasts().isEmpty()) {
-                boolean hasGeneric = false;
-                for (TypeCastData typeCast : type.getTypeCasts()) {
-                    if (typeCast.isGeneric()) {
-                        hasGeneric = true;
-                        break;
-                    }
-                }
-                if (!hasGeneric) {
-                    type.addError("No generic but specific @%s method %s for type %s specified. " + "Specify a generic @%s method with parameter type %s to resolve this.",
-                                    TypeCast.class.getSimpleName(), TypeSystemCodeGenerator.asTypeMethodName(type), Utils.getSimpleName(type.getBoxedType()), TypeCast.class.getSimpleName(),
-                                    Object.class.getSimpleName());
-                }
-            }
-        }
-    }
-
-    private List<TypeData> parseTypes(TypeSystemData typeSystem) {
-        List<TypeData> types = new ArrayList<>();
-        List<TypeMirror> typeMirrors = Utils.getAnnotationValueList(TypeMirror.class, typeSystem.getTemplateTypeAnnotation(), "value");
-        if (typeMirrors.isEmpty()) {
-            typeSystem.addError("At least one type must be defined.");
-            return types;
-        }
-
-        final AnnotationValue annotationValue = Utils.getAnnotationValue(typeSystem.getTemplateTypeAnnotation(), "value");
-        final TypeMirror objectType = context.getType(Object.class);
-
-        for (TypeMirror primitiveType : typeMirrors) {
-            TypeMirror boxedType = Utils.boxType(context, primitiveType);
-            TypeData typeData = new TypeData(typeSystem, annotationValue, primitiveType, boxedType);
-
-            if (isPrimitiveWrapper(primitiveType)) {
-                typeData.addError("Types must not contain primitive wrapper types.");
-            }
-
-            if (Utils.typeEquals(boxedType, objectType)) {
-                typeData.addError("Types must not contain the generic type java.lang.Object.");
-            }
-
-            types.add(typeData);
-        }
-
-        verifyTypeOrder(types);
-
-        types.add(new TypeData(typeSystem, annotationValue, objectType, objectType));
-
-        return types;
-    }
-
-    private static void verifyTypeOrder(List<TypeData> types) {
-        Map<String, List<String>> invalidTypes = new HashMap<>();
-
-        for (int i = types.size() - 1; i >= 0; i--) {
-            TypeData typeData = types.get(i);
-            TypeMirror type = typeData.getBoxedType();
-            if (invalidTypes.containsKey(Utils.getQualifiedName(type))) {
-                typeData.addError("Invalid type order. The type(s) %s are inherited from a earlier defined type %s.", invalidTypes.get(Utils.getQualifiedName(type)), Utils.getQualifiedName(type));
-            }
-            List<String> nextInvalidTypes = Utils.getQualifiedSuperTypeNames(Utils.fromTypeMirror(type));
-            nextInvalidTypes.add(getQualifiedName(type));
-
-            for (String qualifiedName : nextInvalidTypes) {
-                List<String> inheritedTypes = invalidTypes.get(qualifiedName);
-                if (inheritedTypes == null) {
-                    inheritedTypes = new ArrayList<>();
-                    invalidTypes.put(qualifiedName, inheritedTypes);
-                }
-                inheritedTypes.add(Utils.getQualifiedName(typeData.getBoxedType()));
-            }
-        }
-    }
-
-    private boolean isPrimitiveWrapper(TypeMirror type) {
-        Types types = context.getEnvironment().getTypeUtils();
-        for (TypeKind kind : TypeKind.values()) {
-            if (!kind.isPrimitive()) {
-                continue;
-            }
-            if (Utils.typeEquals(type, types.boxedClass(types.getPrimitiveType(kind)).asType())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private void verifyMethodSignatures(TypeSystemData typeSystem) {
-        Set<String> generatedIsMethodNames = new HashSet<>();
-        Set<String> generatedAsMethodNames = new HashSet<>();
-        Set<String> generatedExpectMethodNames = new HashSet<>();
-
-        for (TypeData typeData : typeSystem.getTypes()) {
-            generatedIsMethodNames.add(TypeSystemCodeGenerator.isTypeMethodName(typeData));
-            generatedAsMethodNames.add(TypeSystemCodeGenerator.asTypeMethodName(typeData));
-            generatedExpectMethodNames.add(TypeSystemCodeGenerator.expectTypeMethodName(typeData));
-        }
-
-        List<ExecutableElement> methods = ElementFilter.methodsIn(typeSystem.getTemplateType().getEnclosedElements());
-        for (ExecutableElement method : methods) {
-            if (method.getModifiers().contains(Modifier.PRIVATE)) {
-                // will not conflict overridden methods
-                continue;
-            } else if (method.getParameters().size() != 1) {
-                continue;
-            }
-            String methodName = method.getSimpleName().toString();
-            if (generatedIsMethodNames.contains(methodName)) {
-                verifyIsMethod(typeSystem, method);
-            } else if (generatedAsMethodNames.contains(methodName)) {
-                verifyAsMethod(typeSystem, method);
-            } else if (generatedExpectMethodNames.contains(methodName)) {
-                verifyExpectMethod(typeSystem);
-            }
-        }
-    }
-
-    private boolean verifyIsMethod(TypeSystemData typeSystem, ExecutableElement method) {
-        AnnotationMirror mirror = Utils.findAnnotationMirror(processingEnv, method, TypeCheck.class);
-        if (mirror == null) {
-            typeSystem.addError("Method starting with the pattern is${typeName} must be annotated with @%s.", TypeCheck.class.getSimpleName());
-            return false;
-        }
-        return true;
-    }
-
-    private boolean verifyAsMethod(TypeSystemData typeSystem, ExecutableElement method) {
-        AnnotationMirror mirror = Utils.findAnnotationMirror(processingEnv, method, TypeCast.class);
-        if (mirror == null) {
-            typeSystem.addError("Method starting with the pattern as${typeName} must be annotated with @%s.", TypeCast.class.getSimpleName());
-            return false;
-        }
-        return true;
-    }
-
-    private static boolean verifyExpectMethod(TypeSystemData typeSystem) {
-        typeSystem.addError("Method starting with the pattern expect${typeName} must not be declared manually.");
-        return false;
-    }
-
-    private static void verifyNamesUnique(TypeSystemData typeSystem) {
-        List<TypeData> types = typeSystem.getTypes();
-        for (int i = 0; i < types.size(); i++) {
-            for (int j = i + 1; j < types.size(); j++) {
-                String name1 = Utils.getSimpleName(types.get(i).getBoxedType());
-                String name2 = Utils.getSimpleName(types.get(j).getBoxedType());
-                if (name1.equalsIgnoreCase(name2)) {
-                    typeSystem.addError("Two types result in the same name: %s, %s.", name1, name2);
-                }
-            }
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/META-INF/services/javax.annotation.processing.Processor	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,1 @@
+com.oracle.truffle.dsl.processor.TruffleProcessor
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/AbstractParser.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor;
+
+import java.lang.annotation.*;
+import java.util.*;
+
+import javax.annotation.processing.*;
+import javax.lang.model.element.*;
+import javax.tools.Diagnostic.Kind;
+
+import com.oracle.truffle.dsl.processor.template.*;
+
+/**
+ * THIS IS NOT PUBLIC API.
+ */
+public abstract class AbstractParser<M extends Template> {
+
+    protected final ProcessorContext context;
+    protected final ProcessingEnvironment processingEnv;
+    protected RoundEnvironment roundEnv;
+
+    protected final Log log;
+
+    public AbstractParser(ProcessorContext c) {
+        this.context = c;
+        this.processingEnv = c.getEnvironment();
+        this.log = c.getLog();
+    }
+
+    public final M parse(RoundEnvironment env, Element element) {
+        this.roundEnv = env;
+        M model = null;
+        try {
+            AnnotationMirror mirror = null;
+            if (getAnnotationType() != null) {
+                mirror = Utils.findAnnotationMirror(processingEnv, element.getAnnotationMirrors(), getAnnotationType());
+            }
+
+            if (!context.getTruffleTypes().verify(context, element, mirror)) {
+                return null;
+            }
+            model = parse(element, mirror);
+            if (model == null) {
+                return null;
+            }
+
+            model.emitMessages((TypeElement) element, log);
+            return filterErrorElements(model);
+        } catch (CompileErrorException e) {
+            log.message(Kind.WARNING, element, null, null, "The truffle processor could not parse class due to error: %s", e.getMessage());
+            return null;
+        } finally {
+            this.roundEnv = null;
+        }
+    }
+
+    protected M filterErrorElements(M model) {
+        return model.hasErrors() ? null : model;
+    }
+
+    protected abstract M parse(Element element, AnnotationMirror mirror);
+
+    public abstract Class<? extends Annotation> getAnnotationType();
+
+    public boolean isDelegateToRootDeclaredType() {
+        return false;
+    }
+
+    public List<Class<? extends Annotation>> getAllAnnotationTypes() {
+        List<Class<? extends Annotation>> list = new ArrayList<>();
+        if (getAnnotationType() != null) {
+            list.add(getAnnotationType());
+        }
+        list.addAll(getTypeDelegatedAnnotationTypes());
+        return list;
+    }
+
+    public List<Class<? extends Annotation>> getTypeDelegatedAnnotationTypes() {
+        return Collections.emptyList();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/AnnotationProcessor.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor;
+
+import java.io.*;
+import java.util.*;
+
+import javax.annotation.processing.*;
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+import javax.tools.*;
+
+import com.oracle.truffle.dsl.processor.ast.*;
+import com.oracle.truffle.dsl.processor.codewriter.*;
+import com.oracle.truffle.dsl.processor.compiler.*;
+import com.oracle.truffle.dsl.processor.template.*;
+
+/**
+ * THIS IS NOT PUBLIC API.
+ */
+class AnnotationProcessor<M extends Template> {
+
+    private final AbstractParser<M> parser;
+    private final CompilationUnitFactory<M> factory;
+    private final ProcessorContext context;
+
+    private final Set<String> processedElements = new HashSet<>();
+
+    public AnnotationProcessor(ProcessorContext context, AbstractParser<M> parser, CompilationUnitFactory<M> factory) {
+        this.context = context;
+        this.parser = parser;
+        this.factory = factory;
+    }
+
+    public AbstractParser<M> getParser() {
+        return parser;
+    }
+
+    public ProcessorContext getContext() {
+        return context;
+    }
+
+    @SuppressWarnings({"unchecked"})
+    public void process(RoundEnvironment env, Element element, boolean callback) {
+
+        // since it is not guaranteed to be called only once by the compiler
+        // we check for already processed elements to avoid errors when writing files.
+        if (!callback && element instanceof TypeElement) {
+            String qualifiedName = Utils.getQualifiedName((TypeElement) element);
+            if (processedElements.contains(qualifiedName)) {
+                return;
+            }
+            processedElements.add(qualifiedName);
+        }
+
+        TypeElement type = (TypeElement) element;
+
+        M model = (M) context.getTemplate(type.asType(), false);
+        boolean firstRun = !context.containsTemplate(type);
+
+        if (firstRun || !callback) {
+            context.registerTemplate(type, null);
+            model = parser.parse(env, element);
+            context.registerTemplate(type, model);
+
+            if (model != null) {
+                CodeCompilationUnit unit = factory.process(null, model);
+                unit.setGeneratorAnnotationMirror(model.getTemplateTypeAnnotation());
+                unit.setGeneratorElement(model.getTemplateType());
+
+                DeclaredType overrideType = (DeclaredType) context.getType(Override.class);
+                DeclaredType unusedType = (DeclaredType) context.getType(SuppressWarnings.class);
+                unit.accept(new GenerateOverrideVisitor(overrideType), null);
+                unit.accept(new FixWarningsVisitor(context, unusedType, overrideType), null);
+
+                if (!callback) {
+                    unit.accept(new CodeWriter(context.getEnvironment(), element), null);
+                }
+            }
+        }
+    }
+
+    private static class CodeWriter extends AbstractCodeWriter {
+
+        private final Element orignalElement;
+        private final ProcessingEnvironment env;
+
+        public CodeWriter(ProcessingEnvironment env, Element originalElement) {
+            this.env = env;
+            this.orignalElement = originalElement;
+        }
+
+        @Override
+        protected Writer createWriter(CodeTypeElement clazz) throws IOException {
+            JavaFileObject jfo = env.getFiler().createSourceFile(clazz.getQualifiedName(), orignalElement);
+            return jfo.openWriter();
+        }
+
+        @Override
+        protected void writeHeader() {
+            if (env == null) {
+                return;
+            }
+            String comment = CompilerFactory.getCompiler(orignalElement).getHeaderComment(env, orignalElement);
+            if (comment != null) {
+                writeLn(comment);
+            }
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/CompileErrorException.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor;
+
+public class CompileErrorException extends RuntimeException {
+
+    private static final long serialVersionUID = 1L;
+
+    public CompileErrorException(String message) {
+        super(message);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/Log.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor;
+
+import javax.annotation.processing.*;
+import javax.lang.model.element.*;
+import javax.tools.Diagnostic.Kind;
+
+import com.oracle.truffle.dsl.processor.ast.*;
+
+/**
+ * THIS IS NOT PUBLIC API.
+ */
+public class Log {
+
+    public static final boolean DEBUG = false;
+
+    private final ProcessingEnvironment processingEnv;
+
+    public Log(ProcessingEnvironment env) {
+        this.processingEnv = env;
+    }
+
+    public void message(Kind kind, Element element, AnnotationMirror mirror, AnnotationValue value, String format, Object... args) {
+        AnnotationMirror usedMirror = mirror;
+        Element usedElement = element;
+        AnnotationValue usedValue = value;
+        String message = String.format(format, args);
+
+        if (element instanceof GeneratedElement) {
+            usedMirror = ((GeneratedElement) element).getGeneratorAnnotationMirror();
+            usedElement = ((GeneratedElement) element).getGeneratorElement();
+            usedValue = null;
+            if (usedElement != null) {
+                message = String.format("Element %s: %s", element, message);
+            }
+        }
+        processingEnv.getMessager().printMessage(kind, message, usedElement, usedMirror, usedValue);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ProcessorContext.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor;
+
+import static com.oracle.truffle.dsl.processor.Utils.*;
+
+import java.util.*;
+
+import javax.annotation.processing.*;
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+import javax.lang.model.util.*;
+
+import com.oracle.truffle.dsl.processor.ast.*;
+import com.oracle.truffle.dsl.processor.ast.CodeTypeMirror.*;
+import com.oracle.truffle.dsl.processor.template.*;
+
+/**
+ * THIS IS NOT PUBLIC API.
+ */
+public class ProcessorContext {
+
+    private final ProcessingEnvironment environment;
+
+    private final Map<String, Template> models = new HashMap<>();
+    private final Map<String, Map<String, TypeMirror>> generatedClasses = new HashMap<>();
+
+    private final ProcessCallback callback;
+    private final Log log;
+    private final TruffleTypes truffleTypes;
+
+    public ProcessorContext(ProcessingEnvironment env, ProcessCallback callback) {
+        this.environment = env;
+        this.callback = callback;
+        this.log = new Log(environment);
+        this.truffleTypes = new TruffleTypes(this);
+    }
+
+    public TruffleTypes getTruffleTypes() {
+        return truffleTypes;
+    }
+
+    public Log getLog() {
+        return log;
+    }
+
+    public ProcessingEnvironment getEnvironment() {
+        return environment;
+    }
+
+    public boolean containsTemplate(TypeElement element) {
+        return models.containsKey(Utils.getQualifiedName(element));
+    }
+
+    public void registerTemplate(TypeElement element, Template model) {
+        models.put(Utils.getQualifiedName(element), model);
+    }
+
+    public void registerType(TypeElement templateType, TypeMirror generatedTypeMirror) {
+        String templateQualifiedName = getQualifiedName(templateType);
+        Map<String, TypeMirror> simpleNameToType = generatedClasses.get(templateQualifiedName);
+        if (simpleNameToType == null) {
+            simpleNameToType = new HashMap<>();
+            generatedClasses.put(templateQualifiedName, simpleNameToType);
+        }
+        String generatedSimpleName = getSimpleName(generatedTypeMirror);
+        simpleNameToType.put(generatedSimpleName, generatedTypeMirror);
+    }
+
+    public Template getTemplate(TypeMirror templateTypeMirror, boolean invokeCallback) {
+        String qualifiedName = Utils.getQualifiedName(templateTypeMirror);
+        Template model = models.get(qualifiedName);
+        if (model == null && invokeCallback) {
+            callback.callback(Utils.fromTypeMirror(templateTypeMirror));
+            model = models.get(qualifiedName);
+        }
+        return model;
+    }
+
+    public TypeMirror resolveNotYetCompiledType(TypeMirror mirror, Template templateHint) {
+        TypeMirror resolvedType = null;
+        if (mirror.getKind() == TypeKind.ARRAY) {
+            TypeMirror originalComponentType = ((ArrayType) mirror).getComponentType();
+            TypeMirror resolvedComponent = resolveNotYetCompiledType(originalComponentType, templateHint);
+            if (resolvedComponent != originalComponentType) {
+                return new ArrayCodeTypeMirror(resolvedComponent);
+            }
+        }
+
+        if (mirror.getKind() == TypeKind.ERROR) {
+            Element element = ((ErrorType) mirror).asElement();
+            ElementKind kind = element.getKind();
+            if (kind == ElementKind.CLASS || kind == ElementKind.PARAMETER || kind == ElementKind.ENUM) {
+                String simpleName = element.getSimpleName().toString();
+                resolvedType = findGeneratedClassBySimpleName(simpleName, templateHint);
+            }
+        } else {
+            resolvedType = mirror;
+        }
+
+        return resolvedType;
+    }
+
+    public TypeMirror findGeneratedClassBySimpleName(String simpleName, Template templateHint) {
+        if (templateHint == null) {
+            // search all
+            for (String qualifiedTemplateName : generatedClasses.keySet()) {
+                Map<String, TypeMirror> mirrors = generatedClasses.get(qualifiedTemplateName);
+                if (mirrors.get(simpleName) != null) {
+                    return mirrors.get(simpleName);
+                }
+            }
+            return null;
+        } else {
+            String templateQualifiedName = getQualifiedName(templateHint.getTemplateType());
+            Map<String, TypeMirror> simpleNameToType = generatedClasses.get(templateQualifiedName);
+            if (simpleNameToType == null) {
+                return null;
+            }
+            return simpleNameToType.get(simpleName);
+        }
+    }
+
+    public TypeMirror getType(String className) {
+        TypeElement element = environment.getElementUtils().getTypeElement(className);
+        if (element != null) {
+            return element.asType();
+        }
+        return null;
+    }
+
+    public TypeMirror getType(Class<?> element) {
+        TypeMirror mirror;
+        if (element.isPrimitive()) {
+            if (element == boolean.class) {
+                mirror = environment.getTypeUtils().getPrimitiveType(TypeKind.BOOLEAN);
+            } else if (element == byte.class) {
+                mirror = environment.getTypeUtils().getPrimitiveType(TypeKind.BYTE);
+            } else if (element == short.class) {
+                mirror = environment.getTypeUtils().getPrimitiveType(TypeKind.SHORT);
+            } else if (element == char.class) {
+                mirror = environment.getTypeUtils().getPrimitiveType(TypeKind.CHAR);
+            } else if (element == int.class) {
+                mirror = environment.getTypeUtils().getPrimitiveType(TypeKind.INT);
+            } else if (element == long.class) {
+                mirror = environment.getTypeUtils().getPrimitiveType(TypeKind.LONG);
+            } else if (element == float.class) {
+                mirror = environment.getTypeUtils().getPrimitiveType(TypeKind.FLOAT);
+            } else if (element == double.class) {
+                mirror = environment.getTypeUtils().getPrimitiveType(TypeKind.DOUBLE);
+            } else if (element == void.class) {
+                mirror = environment.getTypeUtils().getNoType(TypeKind.VOID);
+            } else {
+                assert false;
+                return null;
+            }
+        } else {
+            TypeElement typeElement = environment.getElementUtils().getTypeElement(element.getCanonicalName());
+            mirror = typeElement.asType();
+        }
+        return mirror;
+    }
+
+    public interface ProcessCallback {
+
+        void callback(TypeElement template);
+
+    }
+
+    public TypeMirror reloadTypeElement(TypeElement type) {
+        return getType(type.getQualifiedName().toString());
+    }
+
+    public TypeMirror reloadType(TypeMirror type) {
+        if (type instanceof CodeTypeMirror) {
+            return type;
+        } else if (type.getKind().isPrimitive()) {
+            return type;
+        }
+        Types types = getEnvironment().getTypeUtils();
+
+        switch (type.getKind()) {
+            case ARRAY:
+                return types.getArrayType(reloadType(((ArrayType) type).getComponentType()));
+            case WILDCARD:
+                return types.getWildcardType(((WildcardType) type).getExtendsBound(), ((WildcardType) type).getSuperBound());
+            case DECLARED:
+                return reloadTypeElement((TypeElement) (((DeclaredType) type).asElement()));
+        }
+        return type;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleProcessor.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor;
+
+import java.lang.annotation.*;
+import java.util.*;
+
+import javax.annotation.processing.*;
+import javax.lang.model.*;
+import javax.lang.model.element.*;
+import javax.tools.Diagnostic.*;
+
+import com.oracle.truffle.dsl.processor.ProcessorContext.*;
+import com.oracle.truffle.dsl.processor.node.*;
+import com.oracle.truffle.dsl.processor.typesystem.*;
+
+/**
+ * THIS IS NOT PUBLIC API.
+ */
+// @SupportedAnnotationTypes({"com.oracle.truffle.codegen.Operation",
+// "com.oracle.truffle.codegen.TypeLattice"})
+@SupportedSourceVersion(SourceVersion.RELEASE_7)
+public class TruffleProcessor extends AbstractProcessor implements ProcessCallback {
+
+    private ProcessorContext context;
+    private List<AnnotationProcessor<?>> generators;
+
+    private RoundEnvironment round;
+
+    @Override
+    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+        if (!roundEnv.processingOver()) {
+            processImpl(roundEnv);
+        }
+        return false;
+    }
+
+    private void processImpl(RoundEnvironment env) {
+        this.round = env;
+        // TODO run verifications that other annotations are not processed out of scope of the
+        // operation or typelattice.
+        try {
+            for (AnnotationProcessor generator : getGenerators()) {
+                AbstractParser<?> parser = generator.getParser();
+                if (parser.getAnnotationType() != null) {
+                    for (Element e : env.getElementsAnnotatedWith(parser.getAnnotationType())) {
+                        processElement(env, generator, e, false);
+                    }
+                }
+
+                for (Class<? extends Annotation> annotationType : parser.getTypeDelegatedAnnotationTypes()) {
+                    for (Element e : env.getElementsAnnotatedWith(annotationType)) {
+                        TypeElement processedType;
+                        if (parser.isDelegateToRootDeclaredType()) {
+                            processedType = Utils.findRootEnclosingType(e);
+                        } else {
+                            processedType = Utils.findNearestEnclosingType(e);
+                        }
+                        processElement(env, generator, processedType, false);
+                    }
+                }
+
+            }
+        } finally {
+            this.round = null;
+        }
+    }
+
+    private static void processElement(RoundEnvironment env, AnnotationProcessor generator, Element e, boolean callback) {
+        try {
+            generator.process(env, e, callback);
+        } catch (Throwable e1) {
+            handleThrowable(generator, e1, e);
+        }
+    }
+
+    private static void handleThrowable(AnnotationProcessor generator, Throwable t, Element e) {
+        String message = "Uncaught error in " + generator.getClass().getSimpleName() + " while processing " + e;
+        generator.getContext().getLog().message(Kind.ERROR, e, null, null, message + ": " + Utils.printException(t));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void callback(TypeElement template) {
+        for (AnnotationProcessor generator : generators) {
+            Class annotationType = generator.getParser().getAnnotationType();
+            if (annotationType != null) {
+                Annotation annotation = template.getAnnotation(annotationType);
+                if (annotation != null) {
+                    processElement(round, generator, template, true);
+                }
+            }
+        }
+    }
+
+    @Override
+    public Set<String> getSupportedAnnotationTypes() {
+        Set<String> annotations = new HashSet<>();
+        List<Class<? extends Annotation>> annotationsTypes = new ArrayList<>();
+        annotationsTypes.addAll(NodeParser.ANNOTATIONS);
+        annotationsTypes.addAll(TypeSystemParser.ANNOTATIONS);
+        for (Class<? extends Annotation> type : annotationsTypes) {
+            annotations.add(type.getCanonicalName());
+        }
+        return annotations;
+    }
+
+    private List<AnnotationProcessor<?>> getGenerators() {
+        if (generators == null && processingEnv != null) {
+            generators = new ArrayList<>();
+            generators.add(new AnnotationProcessor<>(getContext(), new TypeSystemParser(getContext()), new TypeSystemCodeGenerator(getContext())));
+            generators.add(new AnnotationProcessor<>(getContext(), new NodeParser(getContext()), new NodeCodeGenerator(getContext())));
+        }
+        return generators;
+    }
+
+    private ProcessorContext getContext() {
+        if (context == null) {
+            context = new ProcessorContext(processingEnv, this);
+        }
+        return context;
+    }
+
+    @Override
+    public synchronized void init(ProcessingEnvironment env) {
+        this.processingEnv = env;
+        super.init(env);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleTypes.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor;
+
+import java.util.*;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+import javax.tools.Diagnostic.Kind;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.api.nodes.Node.Child;
+import com.oracle.truffle.api.nodes.Node.Children;
+
+/**
+ * THIS IS NOT PUBLIC API.
+ */
+public final class TruffleTypes {
+
+    private final TypeMirror node;
+    private final TypeMirror nodeArray;
+    private final TypeMirror unexpectedValueException;
+    private final TypeMirror frame;
+    private final TypeMirror assumption;
+    private final TypeMirror invalidAssumption;
+    private final DeclaredType childAnnotation;
+    private final DeclaredType childrenAnnotation;
+    private final DeclaredType nodeInfoAnnotation;
+    private final DeclaredType nodeInfoKind;
+    private final TypeMirror compilerDirectives;
+    private final TypeMirror compilerAsserts;
+
+    private final List<String> errors = new ArrayList<>();
+
+    public TruffleTypes(ProcessorContext context) {
+        node = getRequired(context, Node.class);
+        nodeArray = context.getEnvironment().getTypeUtils().getArrayType(node);
+        unexpectedValueException = getRequired(context, UnexpectedResultException.class);
+        frame = getRequired(context, VirtualFrame.class);
+        childAnnotation = getRequired(context, Child.class);
+        childrenAnnotation = getRequired(context, Children.class);
+        compilerDirectives = getRequired(context, CompilerDirectives.class);
+        compilerAsserts = getRequired(context, CompilerAsserts.class);
+        assumption = getRequired(context, Assumption.class);
+        invalidAssumption = getRequired(context, InvalidAssumptionException.class);
+        nodeInfoAnnotation = getRequired(context, NodeInfo.class);
+        nodeInfoKind = getRequired(context, NodeInfo.Kind.class);
+    }
+
+    public DeclaredType getNodeInfoAnnotation() {
+        return nodeInfoAnnotation;
+    }
+
+    public boolean verify(ProcessorContext context, Element element, AnnotationMirror mirror) {
+        if (errors.isEmpty()) {
+            return true;
+        }
+
+        for (String error : errors) {
+            context.getLog().message(Kind.ERROR, element, mirror, null, error);
+        }
+
+        return false;
+    }
+
+    public DeclaredType getNodeInfoKind() {
+        return nodeInfoKind;
+    }
+
+    private DeclaredType getRequired(ProcessorContext context, Class clazz) {
+        TypeMirror type = context.getType(clazz);
+        if (type == null) {
+            errors.add(String.format("Could not find required type: %s", clazz.getSimpleName()));
+        }
+        return (DeclaredType) type;
+    }
+
+    public TypeMirror getInvalidAssumption() {
+        return invalidAssumption;
+    }
+
+    public TypeMirror getAssumption() {
+        return assumption;
+    }
+
+    public TypeMirror getCompilerDirectives() {
+        return compilerDirectives;
+    }
+
+    public TypeMirror getNode() {
+        return node;
+    }
+
+    public TypeMirror getNodeArray() {
+        return nodeArray;
+    }
+
+    public TypeMirror getFrame() {
+        return frame;
+    }
+
+    public TypeMirror getUnexpectedValueException() {
+        return unexpectedValueException;
+    }
+
+    public DeclaredType getChildAnnotation() {
+        return childAnnotation;
+    }
+
+    public DeclaredType getChildrenAnnotation() {
+        return childrenAnnotation;
+    }
+
+    public TypeMirror getCompilerAsserts() {
+        return compilerAsserts;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/Utils.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,930 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor;
+
+import java.io.*;
+import java.lang.annotation.*;
+import java.util.*;
+
+import javax.annotation.processing.*;
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+import javax.lang.model.util.*;
+
+import com.oracle.truffle.dsl.processor.ast.*;
+import com.oracle.truffle.dsl.processor.ast.CodeTypeMirror.*;
+import com.oracle.truffle.dsl.processor.compiler.*;
+
+/**
+ * THIS IS NOT PUBLIC API.
+ */
+public class Utils {
+
+    public static ExecutableElement findExecutableElement(DeclaredType type, String name) {
+        List<? extends ExecutableElement> elements = ElementFilter.methodsIn(type.asElement().getEnclosedElements());
+        for (ExecutableElement executableElement : elements) {
+            if (executableElement.getSimpleName().toString().equals(name)) {
+                return executableElement;
+            }
+        }
+        return null;
+    }
+
+    public static VariableElement findVariableElement(DeclaredType type, String name) {
+        List<? extends VariableElement> elements = ElementFilter.fieldsIn(type.asElement().getEnclosedElements());
+        for (VariableElement variableElement : elements) {
+            if (variableElement.getSimpleName().toString().equals(name)) {
+                return variableElement;
+            }
+        }
+        return null;
+    }
+
+    public static String getMethodBody(ProcessingEnvironment env, ExecutableElement method) {
+        if (method instanceof CodeExecutableElement) {
+            return ((CodeExecutableElement) method).getBody();
+        } else {
+            return CompilerFactory.getCompiler(method).getMethodBody(env, method);
+        }
+    }
+
+    public static TypeMirror boxType(ProcessorContext context, TypeMirror primitiveType) {
+        TypeMirror boxedType = primitiveType;
+        if (boxedType.getKind().isPrimitive()) {
+            boxedType = context.getEnvironment().getTypeUtils().boxedClass((PrimitiveType) boxedType).asType();
+        }
+        return boxedType;
+    }
+
+    public static List<TypeMirror> asTypeMirrors(List<? extends Element> elements) {
+        List<TypeMirror> types = new ArrayList<>(elements.size());
+        for (Element element : elements) {
+            types.add(element.asType());
+        }
+        return types;
+    }
+
+    public static DeclaredType getDeclaredType(TypeElement typeElem, TypeMirror... typeArgs) {
+        return new DeclaredCodeTypeMirror(typeElem, Arrays.asList(typeArgs));
+    }
+
+    public static List<AnnotationMirror> collectAnnotations(ProcessorContext context, AnnotationMirror markerAnnotation, String elementName, Element element,
+                    Class<? extends Annotation> annotationClass) {
+        List<AnnotationMirror> result = new ArrayList<>();
+        if (markerAnnotation != null) {
+            result.addAll(Utils.getAnnotationValueList(AnnotationMirror.class, markerAnnotation, elementName));
+        }
+        AnnotationMirror explicit = Utils.findAnnotationMirror(context.getEnvironment(), element, annotationClass);
+        if (explicit != null) {
+            result.add(explicit);
+        }
+        return result;
+    }
+
+    public static TypeMirror getCommonSuperType(ProcessorContext context, TypeMirror[] types) {
+        if (types.length == 0) {
+            return context.getType(Object.class);
+        }
+        TypeMirror prev = types[0];
+        for (int i = 1; i < types.length; i++) {
+            prev = getCommonSuperType(context, prev, types[i]);
+        }
+        return prev;
+    }
+
+    public static TypeMirror getCommonSuperType(ProcessorContext context, TypeMirror type1, TypeMirror type2) {
+        if (typeEquals(type1, type2)) {
+            return type1;
+        }
+        TypeElement element1 = fromTypeMirror(type1);
+        TypeElement element2 = fromTypeMirror(type2);
+        if (element1 == null || element2 == null) {
+            return context.getType(Object.class);
+        }
+
+        List<TypeElement> element1Types = getDirectSuperTypes(element1);
+        element1Types.add(0, element1);
+        List<TypeElement> element2Types = getDirectSuperTypes(element2);
+        element2Types.add(0, element2);
+
+        for (TypeElement superType1 : element1Types) {
+            for (TypeElement superType2 : element2Types) {
+                if (typeEquals(superType1.asType(), superType2.asType())) {
+                    return superType2.asType();
+                }
+            }
+        }
+        return context.getType(Object.class);
+    }
+
+    public static String getReadableSignature(ExecutableElement method) {
+        // TODO toString does not guarantee a good signature
+        return method.toString();
+    }
+
+    public static boolean hasError(TypeMirror mirror) {
+        switch (mirror.getKind()) {
+            case BOOLEAN:
+            case BYTE:
+            case CHAR:
+            case DOUBLE:
+            case FLOAT:
+            case INT:
+            case SHORT:
+            case LONG:
+            case DECLARED:
+            case VOID:
+            case TYPEVAR:
+                return false;
+            case ARRAY:
+                return hasError(((ArrayType) mirror).getComponentType());
+            case ERROR:
+                return true;
+            default:
+                throw new RuntimeException("Unknown type specified " + mirror.getKind() + " mirror: " + mirror);
+        }
+    }
+
+    public static boolean isAssignable(ProcessorContext context, TypeMirror from, TypeMirror to) {
+        if (!(from instanceof CodeTypeMirror) && !(to instanceof CodeTypeMirror)) {
+            return context.getEnvironment().getTypeUtils().isAssignable(context.reloadType(from), context.reloadType(to));
+        } else {
+            return isAssignableImpl(context, from, to);
+        }
+    }
+
+    private static boolean isAssignableImpl(ProcessorContext context, TypeMirror from, TypeMirror to) {
+        // JLS 5.1.1 identity conversion
+        if (Utils.typeEquals(from, to)) {
+            return true;
+        }
+
+        // JLS 5.1.2 widening primitives
+        if (Utils.isPrimitive(from) && Utils.isPrimitive(to)) {
+            TypeKind fromKind = from.getKind();
+            TypeKind toKind = to.getKind();
+            switch (fromKind) {
+                case BYTE:
+                    switch (toKind) {
+                        case SHORT:
+                        case INT:
+                        case LONG:
+                        case FLOAT:
+                        case DOUBLE:
+                            return true;
+                    }
+                    break;
+                case SHORT:
+                    switch (toKind) {
+                        case INT:
+                        case LONG:
+                        case FLOAT:
+                        case DOUBLE:
+                            return true;
+                    }
+                    break;
+                case CHAR:
+                    switch (toKind) {
+                        case INT:
+                        case LONG:
+                        case FLOAT:
+                        case DOUBLE:
+                            return true;
+                    }
+                    break;
+                case INT:
+                    switch (toKind) {
+                        case LONG:
+                        case FLOAT:
+                        case DOUBLE:
+                            return true;
+                    }
+                    break;
+                case LONG:
+                    switch (toKind) {
+                        case FLOAT:
+                        case DOUBLE:
+                            return true;
+                    }
+                    break;
+                case FLOAT:
+                    switch (toKind) {
+                        case DOUBLE:
+                            return true;
+                    }
+                    break;
+
+            }
+            return false;
+        } else if (Utils.isPrimitive(from) || Utils.isPrimitive(to)) {
+            return false;
+        }
+
+        if (from instanceof ArrayType && to instanceof ArrayType) {
+            return isAssignable(context, ((ArrayType) from).getComponentType(), ((ArrayType) to).getComponentType());
+        }
+
+        TypeElement fromType = Utils.fromTypeMirror(from);
+        TypeElement toType = Utils.fromTypeMirror(to);
+        if (fromType == null || toType == null) {
+            return false;
+        }
+        // JLS 5.1.6 narrowing reference conversion
+
+        List<TypeElement> superTypes = Utils.getSuperTypes(fromType);
+        for (TypeElement superType : superTypes) {
+            if (Utils.typeEquals(superType.asType(), to)) {
+                return true;
+            }
+        }
+
+        // TODO more spec
+        return false;
+    }
+
+    public static Set<Modifier> modifiers(Modifier... modifier) {
+        return new LinkedHashSet<>(Arrays.asList(modifier));
+    }
+
+    public static String getTypeId(TypeMirror mirror) {
+        switch (mirror.getKind()) {
+            case BOOLEAN:
+                return "Boolean";
+            case BYTE:
+                return "Byte";
+            case CHAR:
+                return "Char";
+            case DOUBLE:
+                return "Double";
+            case FLOAT:
+                return "Float";
+            case SHORT:
+                return "Short";
+            case INT:
+                return "Int";
+            case LONG:
+                return "Long";
+            case DECLARED:
+                return ((DeclaredType) mirror).asElement().getSimpleName().toString();
+            case ARRAY:
+                return getTypeId(((ArrayType) mirror).getComponentType()) + "Array";
+            case VOID:
+                return "Void";
+            case WILDCARD:
+                StringBuilder b = new StringBuilder();
+                WildcardType type = (WildcardType) mirror;
+                if (type.getExtendsBound() != null) {
+                    b.append("Extends").append(getTypeId(type.getExtendsBound()));
+                } else if (type.getSuperBound() != null) {
+                    b.append("Super").append(getTypeId(type.getExtendsBound()));
+                }
+                return b.toString();
+            case TYPEVAR:
+                return "Any";
+            case ERROR:
+                throw new CompileErrorException("Type error " + mirror);
+            default:
+                throw new RuntimeException("Unknown type specified " + mirror.getKind() + " mirror: " + mirror);
+        }
+    }
+
+    public static String getSimpleName(TypeElement element) {
+        return getSimpleName(element.asType());
+    }
+
+    public static String getSimpleName(TypeMirror mirror) {
+        switch (mirror.getKind()) {
+            case BOOLEAN:
+                return "boolean";
+            case BYTE:
+                return "byte";
+            case CHAR:
+                return "char";
+            case DOUBLE:
+                return "double";
+            case FLOAT:
+                return "float";
+            case SHORT:
+                return "short";
+            case INT:
+                return "int";
+            case LONG:
+                return "long";
+            case DECLARED:
+                return getDeclaredName((DeclaredType) mirror);
+            case ARRAY:
+                return getSimpleName(((ArrayType) mirror).getComponentType()) + "[]";
+            case VOID:
+                return "void";
+            case WILDCARD:
+                return getWildcardName((WildcardType) mirror);
+            case TYPEVAR:
+                return "?";
+            case ERROR:
+                throw new CompileErrorException("Type error " + mirror);
+            default:
+                throw new RuntimeException("Unknown type specified " + mirror.getKind() + " mirror: " + mirror);
+        }
+    }
+
+    private static String getWildcardName(WildcardType type) {
+        StringBuilder b = new StringBuilder();
+        if (type.getExtendsBound() != null) {
+            b.append("? extends ").append(getSimpleName(type.getExtendsBound()));
+        } else if (type.getSuperBound() != null) {
+            b.append("? super ").append(getSimpleName(type.getExtendsBound()));
+        }
+        return b.toString();
+    }
+
+    private static String getDeclaredName(DeclaredType element) {
+        String simpleName = element.asElement().getSimpleName().toString();
+
+        if (element.getTypeArguments().size() == 0) {
+            return simpleName;
+        }
+
+        StringBuilder b = new StringBuilder(simpleName);
+        b.append("<");
+        if (element.getTypeArguments().size() > 0) {
+            for (int i = 0; i < element.getTypeArguments().size(); i++) {
+                b.append(getSimpleName(element.getTypeArguments().get(i)));
+                if (i < element.getTypeArguments().size() - 1) {
+                    b.append(", ");
+                }
+            }
+        }
+        b.append(">");
+        return b.toString();
+    }
+
+    public static String getQualifiedName(TypeElement element) {
+        return element.getQualifiedName().toString();
+    }
+
+    public static String getQualifiedName(TypeMirror mirror) {
+        switch (mirror.getKind()) {
+            case BOOLEAN:
+                return "boolean";
+            case BYTE:
+                return "byte";
+            case CHAR:
+                return "char";
+            case DOUBLE:
+                return "double";
+            case SHORT:
+                return "short";
+            case FLOAT:
+                return "float";
+            case INT:
+                return "int";
+            case LONG:
+                return "long";
+            case DECLARED:
+                return getQualifiedName(fromTypeMirror(mirror));
+            case ARRAY:
+                return getQualifiedName(((ArrayType) mirror).getComponentType());
+            case VOID:
+                return "void";
+            case TYPEVAR:
+                return getSimpleName(mirror);
+            case ERROR:
+                throw new CompileErrorException("Type error " + mirror);
+            case NONE:
+                return "$none";
+            default:
+                throw new RuntimeException("Unknown type specified " + mirror + " mirror: " + mirror);
+        }
+    }
+
+    public static boolean isVoid(TypeMirror mirror) {
+        return mirror.getKind() == TypeKind.VOID;
+    }
+
+    public static boolean isPrimitive(TypeMirror mirror) {
+        return mirror.getKind().isPrimitive();
+    }
+
+    public static boolean isPrimitiveOrVoid(TypeMirror mirror) {
+        return isPrimitive(mirror) || isVoid(mirror);
+    }
+
+    public static List<String> getQualifiedSuperTypeNames(TypeElement element) {
+        List<TypeElement> types = getSuperTypes(element);
+        List<String> qualifiedNames = new ArrayList<>();
+        for (TypeElement type : types) {
+            qualifiedNames.add(getQualifiedName(type));
+        }
+        return qualifiedNames;
+    }
+
+    public static List<TypeElement> getDeclaredTypes(TypeElement element) {
+        return ElementFilter.typesIn(element.getEnclosedElements());
+    }
+
+    public static VariableElement findDeclaredField(TypeMirror type, String singletonName) {
+        List<VariableElement> elements = ElementFilter.fieldsIn(fromTypeMirror(type).getEnclosedElements());
+        for (VariableElement var : elements) {
+            if (var.getSimpleName().toString().equals(singletonName)) {
+                return var;
+            }
+        }
+        return null;
+    }
+
+    public static TypeElement findRootEnclosingType(Element element) {
+        List<Element> elements = getElementHierarchy(element);
+
+        for (int i = elements.size() - 1; i >= 0; i--) {
+            if (elements.get(i).getKind().isClass()) {
+                return (TypeElement) elements.get(i);
+            }
+        }
+
+        return null;
+    }
+
+    public static List<Element> getElementHierarchy(Element e) {
+        List<Element> elements = new ArrayList<>();
+        elements.add(e);
+
+        Element enclosing = e.getEnclosingElement();
+        while (enclosing != null && enclosing.getKind() != ElementKind.PACKAGE) {
+            elements.add(enclosing);
+            enclosing = enclosing.getEnclosingElement();
+        }
+        if (enclosing != null) {
+            elements.add(enclosing);
+        }
+        return elements;
+    }
+
+    public static TypeElement findNearestEnclosingType(Element element) {
+        List<Element> elements = getElementHierarchy(element);
+        for (Element e : elements) {
+            if (e.getKind().isClass()) {
+                return (TypeElement) e;
+            }
+        }
+        return null;
+    }
+
+    public static List<TypeElement> getDirectSuperTypes(TypeElement element) {
+        List<TypeElement> types = new ArrayList<>();
+        if (element.getSuperclass() != null) {
+            TypeElement superElement = fromTypeMirror(element.getSuperclass());
+            if (superElement != null) {
+                types.add(superElement);
+                types.addAll(getDirectSuperTypes(superElement));
+            }
+        }
+
+        return types;
+    }
+
+    public static List<TypeElement> getSuperTypes(TypeElement element) {
+        List<TypeElement> types = new ArrayList<>();
+        List<TypeElement> superTypes = null;
+        List<TypeElement> superInterfaces = null;
+        if (element.getSuperclass() != null) {
+            TypeElement superElement = fromTypeMirror(element.getSuperclass());
+            if (superElement != null) {
+                types.add(superElement);
+                superTypes = getSuperTypes(superElement);
+            }
+        }
+        for (TypeMirror interfaceMirror : element.getInterfaces()) {
+            TypeElement interfaceElement = fromTypeMirror(interfaceMirror);
+            if (interfaceElement != null) {
+                types.add(interfaceElement);
+                superInterfaces = getSuperTypes(interfaceElement);
+            }
+        }
+
+        if (superTypes != null) {
+            types.addAll(superTypes);
+        }
+
+        if (superInterfaces != null) {
+            types.addAll(superInterfaces);
+        }
+
+        return types;
+    }
+
+    public static String getPackageName(TypeElement element) {
+        return findPackageElement(element).getQualifiedName().toString();
+    }
+
+    public static String getPackageName(TypeMirror mirror) {
+        switch (mirror.getKind()) {
+            case BOOLEAN:
+            case BYTE:
+            case CHAR:
+            case DOUBLE:
+            case FLOAT:
+            case SHORT:
+            case INT:
+            case LONG:
+            case VOID:
+            case TYPEVAR:
+                return null;
+            case DECLARED:
+                PackageElement pack = findPackageElement(fromTypeMirror(mirror));
+                if (pack == null) {
+                    throw new IllegalArgumentException("No package element found for declared type " + getSimpleName(mirror));
+                }
+                return pack.getQualifiedName().toString();
+            case ARRAY:
+                return getSimpleName(((ArrayType) mirror).getComponentType());
+            default:
+                throw new RuntimeException("Unknown type specified " + mirror.getKind());
+        }
+    }
+
+    public static String createConstantName(String simpleName) {
+        // TODO use camel case to produce underscores.
+        return simpleName.toString().toUpperCase();
+    }
+
+    public static TypeElement fromTypeMirror(TypeMirror mirror) {
+        switch (mirror.getKind()) {
+            case DECLARED:
+                return (TypeElement) ((DeclaredType) mirror).asElement();
+            case ARRAY:
+                return fromTypeMirror(((ArrayType) mirror).getComponentType());
+            default:
+                return null;
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> List<T> getAnnotationValueList(Class<T> expectedListType, AnnotationMirror mirror, String name) {
+        List<? extends AnnotationValue> values = getAnnotationValue(List.class, mirror, name);
+        List<T> result = new ArrayList<>();
+
+        if (values != null) {
+            for (AnnotationValue value : values) {
+                T annotationValue = resolveAnnotationValue(expectedListType, value);
+                if (annotationValue != null) {
+                    result.add(annotationValue);
+                }
+            }
+        }
+        return result;
+    }
+
+    public static <T> T getAnnotationValue(Class<T> expectedType, AnnotationMirror mirror, String name) {
+        return resolveAnnotationValue(expectedType, getAnnotationValue(mirror, name));
+    }
+
+    @SuppressWarnings({"unchecked"})
+    private static <T> T resolveAnnotationValue(Class<T> expectedType, AnnotationValue value) {
+        if (value == null) {
+            return null;
+        }
+
+        Object unboxedValue = value.accept(new AnnotationValueVisitorImpl(), null);
+        if (unboxedValue != null) {
+            if (expectedType == TypeMirror.class && unboxedValue instanceof String) {
+                return null;
+            }
+            if (!expectedType.isAssignableFrom(unboxedValue.getClass())) {
+                throw new ClassCastException(unboxedValue.getClass().getName() + " not assignable from " + expectedType.getName());
+            }
+        }
+        return (T) unboxedValue;
+    }
+
+    public static AnnotationValue getAnnotationValue(AnnotationMirror mirror, String name) {
+        ExecutableElement valueMethod = null;
+        for (ExecutableElement method : ElementFilter.methodsIn(mirror.getAnnotationType().asElement().getEnclosedElements())) {
+            if (method.getSimpleName().toString().equals(name)) {
+                valueMethod = method;
+                break;
+            }
+        }
+
+        if (valueMethod == null) {
+            return null;
+        }
+
+        AnnotationValue value = mirror.getElementValues().get(valueMethod);
+        if (value == null) {
+            value = valueMethod.getDefaultValue();
+        }
+
+        return value;
+    }
+
+    private static class AnnotationValueVisitorImpl extends AbstractAnnotationValueVisitor7<Object, Void> {
+
+        @Override
+        public Object visitBoolean(boolean b, Void p) {
+            return Boolean.valueOf(b);
+        }
+
+        @Override
+        public Object visitByte(byte b, Void p) {
+            return Byte.valueOf(b);
+        }
+
+        @Override
+        public Object visitChar(char c, Void p) {
+            return c;
+        }
+
+        @Override
+        public Object visitDouble(double d, Void p) {
+            return d;
+        }
+
+        @Override
+        public Object visitFloat(float f, Void p) {
+            return f;
+        }
+
+        @Override
+        public Object visitInt(int i, Void p) {
+            return i;
+        }
+
+        @Override
+        public Object visitLong(long i, Void p) {
+            return i;
+        }
+
+        @Override
+        public Object visitShort(short s, Void p) {
+            return s;
+        }
+
+        @Override
+        public Object visitString(String s, Void p) {
+            return s;
+        }
+
+        @Override
+        public Object visitType(TypeMirror t, Void p) {
+            return t;
+        }
+
+        @Override
+        public Object visitEnumConstant(VariableElement c, Void p) {
+            return c;
+        }
+
+        @Override
+        public Object visitAnnotation(AnnotationMirror a, Void p) {
+            return a;
+        }
+
+        @Override
+        public Object visitArray(List<? extends AnnotationValue> vals, Void p) {
+            return vals;
+        }
+
+    }
+
+    public static boolean getAnnotationValueBoolean(AnnotationMirror mirror, String name) {
+        return (Boolean) getAnnotationValue(mirror, name).getValue();
+    }
+
+    public static String printException(Throwable e) {
+        StringWriter string = new StringWriter();
+        PrintWriter writer = new PrintWriter(string);
+        e.printStackTrace(writer);
+        writer.flush();
+        return e.getMessage() + "\r\n" + string.toString();
+    }
+
+    public static AnnotationMirror findAnnotationMirror(ProcessingEnvironment processingEnv, Element element, Class<?> annotationClass) {
+        return findAnnotationMirror(processingEnv, element.getAnnotationMirrors(), annotationClass);
+    }
+
+    public static AnnotationMirror findAnnotationMirror(ProcessingEnvironment processingEnv, List<? extends AnnotationMirror> mirrors, Class<?> annotationClass) {
+        TypeElement expectedAnnotationType = processingEnv.getElementUtils().getTypeElement(annotationClass.getCanonicalName());
+        for (AnnotationMirror mirror : mirrors) {
+            DeclaredType annotationType = mirror.getAnnotationType();
+            TypeElement actualAnnotationType = (TypeElement) annotationType.asElement();
+            if (actualAnnotationType.equals(expectedAnnotationType)) {
+                return mirror;
+            }
+        }
+        return null;
+    }
+
+    private static PackageElement findPackageElement(Element type) {
+        List<Element> hierarchy = getElementHierarchy(type);
+        for (Element element : hierarchy) {
+            if (element.getKind() == ElementKind.PACKAGE) {
+                return (PackageElement) element;
+            }
+        }
+        return null;
+    }
+
+    public static String firstLetterUpperCase(String name) {
+        if (name == null || name.isEmpty()) {
+            return name;
+        }
+        return Character.toUpperCase(name.charAt(0)) + name.substring(1, name.length());
+    }
+
+    public static String firstLetterLowerCase(String name) {
+        if (name == null || name.isEmpty()) {
+            return name;
+        }
+        return Character.toLowerCase(name.charAt(0)) + name.substring(1, name.length());
+    }
+
+    private static ExecutableElement getDeclaredMethod(TypeElement element, String name, TypeMirror[] params) {
+        List<ExecutableElement> methods = ElementFilter.methodsIn(element.getEnclosedElements());
+        method: for (ExecutableElement method : methods) {
+            if (!method.getSimpleName().toString().equals(name)) {
+                continue;
+            }
+            if (method.getParameters().size() != params.length) {
+                continue;
+            }
+            for (int i = 0; i < params.length; i++) {
+                TypeMirror param1 = params[i];
+                TypeMirror param2 = method.getParameters().get(i).asType();
+                if (param1.getKind() != TypeKind.TYPEVAR && param2.getKind() != TypeKind.TYPEVAR) {
+                    if (!getQualifiedName(param1).equals(getQualifiedName(param2))) {
+                        continue method;
+                    }
+                }
+            }
+            return method;
+        }
+        return null;
+    }
+
+    private static boolean isDeclaredMethod(TypeElement element, String name, TypeMirror[] params) {
+        return getDeclaredMethod(element, name, params) != null;
+    }
+
+    public static boolean isDeclaredMethodInSuperType(TypeElement element, String name, TypeMirror[] params) {
+        List<TypeElement> superElements = getSuperTypes(element);
+
+        for (TypeElement typeElement : superElements) {
+            if (isDeclaredMethod(typeElement, name, params)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static ExecutableElement getDeclaredMethodInSuperType(TypeElement element, String name, TypeMirror[] params) {
+        List<TypeElement> superElements = getSuperTypes(element);
+
+        for (TypeElement typeElement : superElements) {
+            ExecutableElement declared = getDeclaredMethod(typeElement, name, params);
+            if (declared != null) {
+                return declared;
+            }
+        }
+        return null;
+    }
+
+    public static ExecutableElement getDeclaredMethodRecursive(TypeElement element, String name, TypeMirror[] params) {
+        ExecutableElement declared = getDeclaredMethod(element, name, params);
+        if (declared != null) {
+            return declared;
+        }
+        return getDeclaredMethodInSuperType(element, name, params);
+    }
+
+    public static boolean typeEquals(TypeMirror type1, TypeMirror type2) {
+        if (type1 == null && type2 == null) {
+            return true;
+        } else if (type1 == null || type2 == null) {
+            return false;
+        }
+        String qualified1 = getQualifiedName(type1);
+        String qualified2 = getQualifiedName(type2);
+
+        if (type1.getKind() == TypeKind.ARRAY || type2.getKind() == TypeKind.ARRAY) {
+            if (type1.getKind() == TypeKind.ARRAY && type2.getKind() == TypeKind.ARRAY) {
+                return typeEquals(((ArrayType) type1).getComponentType(), ((ArrayType) type2).getComponentType());
+            } else {
+                return false;
+            }
+        }
+        return qualified1.equals(qualified2);
+    }
+
+    public static int compareByTypeHierarchy(TypeMirror t1, TypeMirror t2) {
+        if (typeEquals(t1, t2)) {
+            return 0;
+        }
+        Set<String> t1SuperSet = new HashSet<>(getQualifiedSuperTypeNames(fromTypeMirror(t1)));
+        if (t1SuperSet.contains(getQualifiedName(t2))) {
+            return -1;
+        }
+
+        Set<String> t2SuperSet = new HashSet<>(getQualifiedSuperTypeNames(fromTypeMirror(t2)));
+        if (t2SuperSet.contains(getQualifiedName(t1))) {
+            return 1;
+        }
+        return 0;
+    }
+
+    public static boolean canThrowType(List<? extends TypeMirror> thrownTypes, TypeMirror exceptionType) {
+        if (Utils.containsType(thrownTypes, exceptionType)) {
+            return true;
+        }
+
+        if (isRuntimeException(exceptionType)) {
+            return true;
+        }
+
+        // search for any super types
+        TypeElement exceptionTypeElement = fromTypeMirror(exceptionType);
+        List<TypeElement> superTypes = getSuperTypes(exceptionTypeElement);
+        for (TypeElement typeElement : superTypes) {
+            if (Utils.containsType(thrownTypes, typeElement.asType())) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    public static Modifier getVisibility(Set<Modifier> modifier) {
+        for (Modifier mod : modifier) {
+            if (mod == Modifier.PUBLIC || mod == Modifier.PRIVATE || mod == Modifier.PROTECTED) {
+                return mod;
+            }
+        }
+        return null;
+    }
+
+    private static boolean isRuntimeException(TypeMirror type) {
+        Set<String> typeSuperSet = new HashSet<>(getQualifiedSuperTypeNames(fromTypeMirror(type)));
+        String typeName = getQualifiedName(type);
+        if (!typeSuperSet.contains(Throwable.class.getCanonicalName()) && !typeName.equals(Throwable.class.getCanonicalName())) {
+            throw new IllegalArgumentException("Given type does not extend Throwable.");
+        }
+        return typeSuperSet.contains(RuntimeException.class.getCanonicalName()) || typeName.equals(RuntimeException.class.getCanonicalName());
+    }
+
+    private static boolean containsType(Collection<? extends TypeMirror> collection, TypeMirror type) {
+        for (TypeMirror otherTypeMirror : collection) {
+            if (typeEquals(otherTypeMirror, type)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public static boolean isTopLevelClass(TypeMirror importType) {
+        TypeElement type = fromTypeMirror(importType);
+        if (type != null && type.getEnclosingElement() != null) {
+            return !type.getEnclosingElement().getKind().isClass();
+        }
+        return true;
+    }
+
+    public static boolean isObject(TypeMirror actualType) {
+        return getQualifiedName(actualType).equals("java.lang.Object");
+    }
+
+    public static boolean isFieldAccessible(Element element, VariableElement variable) {
+        TypeElement type = Utils.findNearestEnclosingType(element);
+        TypeElement varType = Utils.findNearestEnclosingType(variable);
+
+        while (type != null) {
+            if (typeEquals(type.asType(), varType.asType())) {
+                return true;
+            }
+            if (type.getSuperclass() != null) {
+                type = Utils.fromTypeMirror(type.getSuperclass());
+            } else {
+                type = null;
+            }
+        }
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/ExtensionContext.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.api;
+
+import javax.annotation.processing.*;
+
+import com.oracle.truffle.dsl.processor.api.element.*;
+
+public interface ExtensionContext {
+
+    ProcessingEnvironment getProcessingEnvironment();
+
+    RoundEnvironment getRoundEnvironment();
+
+    WritableElementFactory getElementFactory();
+
+    void addGeneratedElement(WritableElement element);
+
+    void removeGeneratedElement(WritableElement element);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/ExtensionProcessor.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.api;
+
+import javax.lang.model.element.*;
+
+public interface ExtensionProcessor {
+
+    void process(ExtensionContext context, AnnotationMirror mirror, Element element);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/element/WritableAnnotationMirror.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.api.element;
+
+import javax.lang.model.element.*;
+
+public interface WritableAnnotationMirror extends AnnotationMirror {
+
+    void setElementValue(ExecutableElement valueName, AnnotationValue value);
+
+    AnnotationValue getElementValue(ExecutableElement valueName);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/element/WritableElement.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.api.element;
+
+import javax.lang.model.element.*;
+
+public interface WritableElement extends Element {
+
+    void addAnnotationMirror(AnnotationMirror annotationMirror);
+
+    void removeAnnotationMirror(AnnotationMirror annotationMirror);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/element/WritableElementFactory.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.api.element;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+public interface WritableElementFactory {
+
+    WritableExecutableElement cloneExecutableElement(ExecutableElement method);
+
+    WritableVariableElement cloneVariableElement(VariableElement parameter);
+
+    WritableAnnotationMirror cloneAnnotationMirror(AnnotationMirror mirror);
+
+    WritableVariableElement createParameter(TypeMirror type, String simpleName);
+
+    WritableExecutableElement createExecutableElement(TypeMirror returnType, String methodName);
+
+    WritableAnnotationMirror createAnnotationMirror(DeclaredType annotationClass);
+
+    Name createName(String name);
+
+    AnnotationValue createAnnotationValue(Object value);
+
+    TypeMirror createTypeMirror(Class<?> javaClass);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/element/WritableExecutableElement.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.api.element;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+public interface WritableExecutableElement extends ExecutableElement, WritableElement {
+
+    void setReturnType(TypeMirror type);
+
+    void setDefaultValue(AnnotationValue defaultValue);
+
+    void addParameter(VariableElement parameter);
+
+    void removeParameter(VariableElement parameter);
+
+    void addThrownType(TypeMirror thrownType);
+
+    void removeThrownType(TypeMirror thrownType);
+
+    void setSimpleName(Name name);
+
+    void setVarArgs(boolean varargs);
+
+    void setBody(String body);
+
+    String getBody();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/element/WritableVariableElement.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.api.element;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+public interface WritableVariableElement extends VariableElement, WritableElement {
+
+    void setSimpleName(Name name);
+
+    void setType(TypeMirror type);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeAnnotationMirror.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.ast;
+
+import java.util.*;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.api.element.*;
+
+public class CodeAnnotationMirror implements WritableAnnotationMirror {
+
+    private final DeclaredType annotationType;
+    private final Map<ExecutableElement, AnnotationValue> values = new LinkedHashMap<>();
+
+    public CodeAnnotationMirror(DeclaredType annotationType) {
+        this.annotationType = annotationType;
+    }
+
+    @Override
+    public DeclaredType getAnnotationType() {
+        return annotationType;
+    }
+
+    @Override
+    public Map<? extends ExecutableElement, ? extends AnnotationValue> getElementValues() {
+        return values;
+    }
+
+    @Override
+    public AnnotationValue getElementValue(ExecutableElement method) {
+        return values.get(method);
+    }
+
+    @Override
+    public void setElementValue(ExecutableElement method, AnnotationValue value) {
+        values.put(method, value);
+    }
+
+    public ExecutableElement findExecutableElement(String name) {
+        return Utils.findExecutableElement(annotationType, name);
+    }
+
+    public static CodeAnnotationMirror clone(AnnotationMirror mirror) {
+        CodeAnnotationMirror copy = new CodeAnnotationMirror(mirror.getAnnotationType());
+        for (ExecutableElement key : mirror.getElementValues().keySet()) {
+            copy.setElementValue(key, mirror.getElementValues().get(key));
+        }
+        return copy;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeAnnotationValue.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.ast;
+
+import java.util.*;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+public class CodeAnnotationValue implements AnnotationValue {
+
+    private final Object value;
+
+    public CodeAnnotationValue(Object value) {
+        Objects.requireNonNull(value);
+        if ((value instanceof AnnotationMirror) || (value instanceof List<?>) || (value instanceof Boolean) || (value instanceof Byte) || (value instanceof Character) || (value instanceof Double) ||
+                        (value instanceof VariableElement) || (value instanceof Float) || (value instanceof Integer) || (value instanceof Long) || (value instanceof Short) ||
+                        (value instanceof String) || (value instanceof TypeMirror)) {
+            this.value = value;
+        } else {
+            throw new IllegalArgumentException("Invalid annotation value type " + value.getClass().getName());
+        }
+    }
+
+    @Override
+    public Object getValue() {
+        return value;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <R, P> R accept(AnnotationValueVisitor<R, P> v, P p) {
+        if (value instanceof AnnotationMirror) {
+            return v.visitAnnotation((AnnotationMirror) value, p);
+        } else if (value instanceof List<?>) {
+            return v.visitArray((List<? extends AnnotationValue>) value, p);
+        } else if (value instanceof Boolean) {
+            return v.visitBoolean((boolean) value, p);
+        } else if (value instanceof Byte) {
+            return v.visitByte((byte) value, p);
+        } else if (value instanceof Character) {
+            return v.visitChar((char) value, p);
+        } else if (value instanceof Double) {
+            return v.visitDouble((double) value, p);
+        } else if (value instanceof VariableElement) {
+            return v.visitEnumConstant((VariableElement) value, p);
+        } else if (value instanceof Float) {
+            return v.visitFloat((float) value, p);
+        } else if (value instanceof Integer) {
+            return v.visitInt((int) value, p);
+        } else if (value instanceof Long) {
+            return v.visitLong((long) value, p);
+        } else if (value instanceof Short) {
+            return v.visitShort((short) value, p);
+        } else if (value instanceof String) {
+            return v.visitString((String) value, p);
+        } else if (value instanceof TypeMirror) {
+            return v.visitType((TypeMirror) value, p);
+        } else {
+            return v.visitUnknown(this, p);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeCompilationUnit.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.ast;
+
+import java.util.*;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+public class CodeCompilationUnit extends CodeElement<TypeElement> {
+
+    public CodeCompilationUnit() {
+        super(Collections.<Modifier> emptySet());
+    }
+
+    @Override
+    public TypeMirror asType() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ElementKind getKind() {
+        return ElementKind.OTHER;
+    }
+
+    @Override
+    public Name getSimpleName() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public <R, P> R accept(ElementVisitor<R, P> v, P p) {
+        for (Element type : getEnclosedElements()) {
+            if (type.getKind().isClass()) {
+                type.accept(v, p);
+            } else {
+                throw new ClassCastException(type.getClass().getName());
+            }
+        }
+        return null;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeElement.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,360 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.ast;
+
+import java.io.*;
+import java.lang.annotation.*;
+import java.util.*;
+
+import javax.lang.model.element.*;
+
+import com.oracle.truffle.dsl.processor.api.element.*;
+import com.oracle.truffle.dsl.processor.codewriter.*;
+
+public abstract class CodeElement<E extends Element> implements WritableElement, GeneratedElement {
+
+    private final Set<Modifier> modifiers;
+    private List<AnnotationMirror> annotations;
+    private List<E> enclosedElements;
+
+    private Element enclosingElement;
+
+    private Element generatorElement;
+    private AnnotationMirror generatorAnnotationMirror;
+
+    public CodeElement() {
+        this.modifiers = new LinkedHashSet<>();
+    }
+
+    @Override
+    public void setGeneratorAnnotationMirror(AnnotationMirror mirror) {
+        this.generatorAnnotationMirror = mirror;
+    }
+
+    @Override
+    public void setGeneratorElement(Element element) {
+        this.generatorElement = element;
+    }
+
+    @Override
+    public AnnotationMirror getGeneratorAnnotationMirror() {
+        return generatorAnnotationMirror;
+    }
+
+    @Override
+    public Element getGeneratorElement() {
+        return generatorElement;
+    }
+
+    public CodeElement(Set<Modifier> modifiers) {
+        this.modifiers = new LinkedHashSet<>(modifiers);
+    }
+
+    public E add(E element) {
+        if (element == null) {
+            throw new NullPointerException();
+        }
+        getEnclosedElements().add(element);
+        return element;
+    }
+
+    public void remove(E element) {
+        getEnclosedElements().remove(element);
+    }
+
+    @Override
+    public Set<Modifier> getModifiers() {
+        return modifiers;
+    }
+
+    @Override
+    public List<E> getEnclosedElements() {
+        if (enclosedElements == null) {
+            enclosedElements = parentableList(this, new ArrayList<E>());
+        }
+        return enclosedElements;
+    }
+
+    @Override
+    public List<AnnotationMirror> getAnnotationMirrors() {
+        if (annotations == null) {
+            annotations = parentableList(this, new ArrayList<AnnotationMirror>());
+        }
+        return annotations;
+    }
+
+    /**
+     * Support JDK8 langtools.
+     * 
+     * @param annotationType
+     */
+    public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Support for some JDK8 builds. (remove after jdk8 is released)
+     * 
+     * @param annotationType
+     */
+    public <A extends Annotation> A[] getAnnotations(Class<A> annotationType) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Support for some JDK8 builds. (remove after jdk8 is released)
+     * 
+     * @param annotationType
+     */
+    public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void addAnnotationMirror(AnnotationMirror annotationMirror) {
+        getAnnotationMirrors().add(annotationMirror);
+    }
+
+    public void removeAnnotationMirror(AnnotationMirror annotationMirror) {
+        getAnnotationMirrors().remove(annotationMirror);
+    }
+
+    void setEnclosingElement(Element parent) {
+        this.enclosingElement = parent;
+    }
+
+    public Element getEnclosingElement() {
+        return enclosingElement;
+    }
+
+    public CodeTypeElement getEnclosingClass() {
+        Element p = enclosingElement;
+        while (p != null && p.getKind() != ElementKind.CLASS && p.getKind() != ElementKind.ENUM) {
+            p = p.getEnclosingElement();
+        }
+        return (CodeTypeElement) p;
+    }
+
+    <T> List<T> parentableList(Element parent, List<T> list) {
+        return new ParentableList<>(parent, list);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilderCodeWriter codeWriter = new StringBuilderCodeWriter();
+        accept(codeWriter, null);
+        return codeWriter.getString();
+    }
+
+    private static class StringBuilderCodeWriter extends AbstractCodeWriter {
+
+        public StringBuilderCodeWriter() {
+            this.writer = new CharArrayWriter();
+        }
+
+        @Override
+        protected Writer createWriter(CodeTypeElement clazz) throws IOException {
+            return writer;
+        }
+
+        public String getString() {
+            return new String(((CharArrayWriter) writer).toCharArray()).trim();
+        }
+
+    }
+
+    private static class ParentableList<T> implements List<T> {
+
+        private final Element parent;
+        private final List<T> delegate;
+
+        public ParentableList(Element parent, List<T> delegate) {
+            this.parent = parent;
+            this.delegate = delegate;
+        }
+
+        private void addImpl(T element) {
+            if (element != null) {
+                if (element instanceof CodeElement<?>) {
+                    ((CodeElement<?>) element).setEnclosingElement(parent);
+                }
+            }
+        }
+
+        private static void removeImpl(Object element) {
+            if (element instanceof CodeElement<?>) {
+                ((CodeElement<?>) element).setEnclosingElement(null);
+            }
+        }
+
+        @Override
+        public int size() {
+            return delegate.size();
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return delegate.isEmpty();
+        }
+
+        @Override
+        public boolean contains(Object o) {
+            return delegate.contains(o);
+        }
+
+        @Override
+        public Iterator<T> iterator() {
+            return delegate.iterator();
+        }
+
+        @Override
+        public Object[] toArray() {
+            return delegate.toArray();
+        }
+
+        @Override
+        public <E> E[] toArray(E[] a) {
+            return delegate.toArray(a);
+        }
+
+        @Override
+        public boolean add(T e) {
+            addImpl(e);
+            return delegate.add(e);
+        }
+
+        @Override
+        public boolean remove(Object o) {
+            boolean removed = delegate.remove(o);
+            if (removed) {
+                removeImpl(o);
+            }
+            return removed;
+        }
+
+        @Override
+        public boolean containsAll(Collection<?> c) {
+            return delegate.containsAll(c);
+        }
+
+        @Override
+        public boolean addAll(Collection<? extends T> c) {
+            if (c != null) {
+                for (T t : c) {
+                    addImpl(t);
+                }
+            }
+            return delegate.addAll(c);
+        }
+
+        @Override
+        public boolean addAll(int index, Collection<? extends T> c) {
+            if (c != null) {
+                for (T t : c) {
+                    addImpl(t);
+                }
+            }
+            return delegate.addAll(index, c);
+        }
+
+        @Override
+        public boolean removeAll(Collection<?> c) {
+            if (c != null) {
+                for (Object t : c) {
+                    removeImpl(t);
+                }
+            }
+            return delegate.removeAll(c);
+        }
+
+        @Override
+        public String toString() {
+            return delegate.toString();
+        }
+
+        @Override
+        public boolean retainAll(Collection<?> c) {
+            throw new UnsupportedOperationException("Not supported by parentable list");
+        }
+
+        @Override
+        public void clear() {
+            for (Object e : this) {
+                removeImpl(e);
+            }
+            delegate.clear();
+        }
+
+        @Override
+        public T get(int index) {
+            return delegate.get(index);
+        }
+
+        @Override
+        public T set(int index, T element) {
+            removeImpl(delegate.get(index));
+            addImpl(element);
+            return delegate.set(index, element);
+        }
+
+        @Override
+        public void add(int index, T element) {
+            addImpl(element);
+            delegate.add(index, element);
+        }
+
+        @Override
+        public T remove(int index) {
+            T element = delegate.remove(index);
+            removeImpl(element);
+            return element;
+        }
+
+        @Override
+        public int indexOf(Object o) {
+            return delegate.indexOf(o);
+        }
+
+        @Override
+        public int lastIndexOf(Object o) {
+            return delegate.lastIndexOf(o);
+        }
+
+        @Override
+        public ListIterator<T> listIterator() {
+            return delegate.listIterator();
+        }
+
+        @Override
+        public ListIterator<T> listIterator(int index) {
+            return delegate.listIterator(index);
+        }
+
+        @Override
+        public List<T> subList(int fromIndex, int toIndex) {
+            return new ParentableList<>(parent, delegate.subList(fromIndex, toIndex));
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeElementScanner.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.ast;
+
+import javax.lang.model.element.*;
+import javax.lang.model.util.*;
+
+public abstract class CodeElementScanner<R, P> extends ElementScanner7<R, P> {
+
+    @Override
+    public final R visitExecutable(ExecutableElement e, P p) {
+        return visitExecutable(cast(e, CodeExecutableElement.class), p);
+    }
+
+    public R visitExecutable(CodeExecutableElement e, P p) {
+        R ret = super.visitExecutable(e, p);
+        if (e.getBodyTree() != null) {
+            visitTree(e.getBodyTree(), p);
+        }
+        return ret;
+    }
+
+    @Override
+    public R visitPackage(PackageElement e, P p) {
+        return super.visitPackage(e, p);
+    }
+
+    @Override
+    public final R visitType(TypeElement e, P p) {
+        return visitType(cast(e, CodeTypeElement.class), p);
+    }
+
+    public R visitType(CodeTypeElement e, P p) {
+        return super.visitType(e, p);
+    }
+
+    @Override
+    public R visitTypeParameter(TypeParameterElement e, P p) {
+        return super.visitTypeParameter(e, p);
+    }
+
+    private static <E> E cast(Element element, Class<E> clazz) {
+        return clazz.cast(element);
+    }
+
+    public void visitTree(CodeTree e, P p) {
+        for (CodeTree tree : e.getEnclosedElements()) {
+            tree.acceptCodeElementScanner(this, p);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public void visitImport(CodeImport e, P p) {
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeExecutableElement.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.ast;
+
+import java.util.*;
+
+import javax.annotation.processing.*;
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.api.element.*;
+
+public class CodeExecutableElement extends CodeElement<Element> implements WritableExecutableElement {
+
+    private final List<TypeMirror> throwables = new ArrayList<>();
+    private final List<VariableElement> parameters = parentableList(this, new ArrayList<VariableElement>());
+
+    private TypeMirror returnType;
+    private Name name;
+
+    private CodeTree bodyTree;
+    private String body;
+    private AnnotationValue defaultValue;
+    private boolean varArgs;
+
+    public CodeExecutableElement(TypeMirror returnType, String name) {
+        super(Utils.modifiers());
+        this.returnType = returnType;
+        this.name = CodeNames.of(name);
+    }
+
+    public CodeExecutableElement(Set<Modifier> modifiers, TypeMirror returnType, String name, CodeVariableElement... parameters) {
+        super(modifiers);
+        this.returnType = returnType;
+        this.name = CodeNames.of(name);
+        for (CodeVariableElement codeParameter : parameters) {
+            addParameter(codeParameter);
+        }
+    }
+
+    /* Support JDK8 langtools. */
+    public boolean isDefault() {
+        return false;
+    }
+
+    @Override
+    public List<TypeMirror> getThrownTypes() {
+        return throwables;
+    }
+
+    @Override
+    public TypeMirror asType() {
+        return returnType;
+    }
+
+    @Override
+    public ElementKind getKind() {
+        if (getReturnType() == null) {
+            return ElementKind.CONSTRUCTOR;
+        } else {
+            return ElementKind.METHOD;
+        }
+    }
+
+    @Override
+    public List<? extends TypeParameterElement> getTypeParameters() {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public void setVarArgs(boolean varargs) {
+        this.varArgs = varargs;
+    }
+
+    @Override
+    public boolean isVarArgs() {
+        return varArgs;
+    }
+
+    @Override
+    public void setDefaultValue(AnnotationValue defaultValue) {
+        this.defaultValue = defaultValue;
+    }
+
+    @Override
+    public AnnotationValue getDefaultValue() {
+        return defaultValue;
+    }
+
+    @Override
+    public Name getSimpleName() {
+        return name;
+    }
+
+    public CodeTreeBuilder createBuilder() {
+        CodeTreeBuilder builder = new CodeTreeBuilder(null);
+        this.bodyTree = builder.getTree();
+        this.bodyTree.setEnclosingElement(this);
+        this.body = null;
+        return builder;
+    }
+
+    public void setBodyTree(CodeTree body) {
+        this.bodyTree = body;
+    }
+
+    public CodeTree getBodyTree() {
+        return bodyTree;
+    }
+
+    public TypeMirror getReturnType() {
+        return returnType;
+    }
+
+    @Override
+    public List<VariableElement> getParameters() {
+        return parameters;
+    }
+
+    public TypeMirror[] getParameterTypes() {
+        TypeMirror[] types = new TypeMirror[getParameters().size()];
+        for (int i = 0; i < types.length; i++) {
+            types[i] = parameters.get(i).asType();
+        }
+        return types;
+    }
+
+    @Override
+    public void setReturnType(TypeMirror type) {
+        returnType = type;
+    }
+
+    @Override
+    public void addParameter(VariableElement parameter) {
+        parameters.add(parameter);
+    }
+
+    @Override
+    public void removeParameter(VariableElement parameter) {
+        parameters.remove(parameter);
+    }
+
+    public void removeParameter(String varName) {
+        VariableElement remove = null;
+        for (VariableElement var : getParameters()) {
+            if (var.getSimpleName().toString().equals(varName)) {
+                remove = var;
+                break;
+            }
+        }
+        if (remove != null) {
+            parameters.remove(remove);
+        }
+    }
+
+    @Override
+    public void addThrownType(TypeMirror thrownType) {
+        throwables.add(thrownType);
+    }
+
+    @Override
+    public void removeThrownType(TypeMirror thrownType) {
+        throwables.remove(thrownType);
+    }
+
+    @Override
+    public void setSimpleName(Name name) {
+        this.name = name;
+    }
+
+    @Override
+    public void setBody(String body) {
+        this.body = body;
+    }
+
+    @Override
+    public String getBody() {
+        return body;
+    }
+
+    @Override
+    public <R, P> R accept(ElementVisitor<R, P> v, P p) {
+        return v.visitExecutable(this, p);
+    }
+
+    public static CodeExecutableElement clone(@SuppressWarnings("unused") ProcessingEnvironment env, ExecutableElement method) {
+        CodeExecutableElement copy = new CodeExecutableElement(method.getReturnType(), method.getSimpleName().toString());
+        for (TypeMirror thrownType : method.getThrownTypes()) {
+            copy.addThrownType(thrownType);
+        }
+        copy.setDefaultValue(method.getDefaultValue());
+
+        for (AnnotationMirror mirror : method.getAnnotationMirrors()) {
+            copy.addAnnotationMirror(mirror);
+        }
+        for (VariableElement var : method.getParameters()) {
+            copy.addParameter(CodeVariableElement.clone(var));
+        }
+        for (Element element : method.getEnclosedElements()) {
+            copy.add(element);
+        }
+        copy.getModifiers().addAll(method.getModifiers());
+        copy.setVarArgs(method.isVarArgs());
+        return copy;
+    }
+
+    public TypeMirror getReceiverType() {
+        throw new UnsupportedOperationException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeImport.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.ast;
+
+import javax.lang.model.type.*;
+
+public class CodeImport implements Comparable<CodeImport> {
+
+    private final TypeMirror importType;
+    private final String importString;
+    private final boolean staticImport;
+
+    public CodeImport(TypeMirror importedType, String importString, boolean staticImport) {
+        this.importType = importedType;
+        this.importString = importString;
+        this.staticImport = staticImport;
+    }
+
+    public TypeMirror getImportType() {
+        return importType;
+    }
+
+    public boolean isStaticImport() {
+        return staticImport;
+    }
+
+    public String getImportString() {
+        return importString;
+    }
+
+    @Override
+    public int compareTo(CodeImport o) {
+        if (staticImport && !o.staticImport) {
+            return 1;
+        } else if (!staticImport && o.staticImport) {
+            return -1;
+        } else {
+            return importString.compareTo(o.getImportString());
+        }
+    }
+
+    public <P> void accept(CodeElementScanner<?, P> s, P p) {
+        s.visitImport(this, p);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((importString == null) ? 0 : importString.hashCode());
+        result = prime * result + (staticImport ? 1231 : 1237);
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        CodeImport other = (CodeImport) obj;
+        if (importString == null) {
+            if (other.importString != null) {
+                return false;
+            }
+        } else if (!importString.equals(other.importString)) {
+            return false;
+        }
+        if (staticImport != other.staticImport) {
+            return false;
+        }
+        return true;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeNames.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.ast;
+
+import java.util.*;
+
+import javax.lang.model.element.*;
+
+public abstract class CodeNames {
+
+    private static Map<String, Name> names = new HashMap<>();
+
+    public static Name of(String value) {
+        Name name = names.get(value);
+        if (name == null) {
+            name = new NameImpl(value);
+            names.put(value, name);
+        }
+        return name;
+    }
+
+    private static class NameImpl implements Name {
+
+        private final String name;
+
+        public NameImpl(String name) {
+            this.name = name;
+        }
+
+        @Override
+        public int length() {
+            return name.length();
+        }
+
+        @Override
+        public char charAt(int index) {
+            return name.charAt(index);
+        }
+
+        @Override
+        public CharSequence subSequence(int start, int end) {
+            return name.subSequence(start, end);
+        }
+
+        @Override
+        public boolean contentEquals(CharSequence cs) {
+            return name.contentEquals(cs);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof Name) {
+                return ((Name) obj).contentEquals(name);
+            }
+            return super.equals(obj);
+        }
+
+        @Override
+        public int hashCode() {
+            return name.hashCode();
+        }
+
+        @Override
+        public String toString() {
+            return name;
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTree.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.ast;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+public class CodeTree extends CodeElement<CodeTree> {
+
+    private final CodeTreeKind kind;
+
+    private final TypeMirror type;
+    private final String string;
+
+    public CodeTree(CodeTreeKind kind, TypeMirror type, String string) {
+        this.kind = kind;
+        this.type = type;
+        this.string = string;
+    }
+
+    public TypeMirror getType() {
+        return type;
+    }
+
+    public CodeTreeKind getCodeKind() {
+        return kind;
+    }
+
+    public String getString() {
+        return string;
+    }
+
+    public <P> void acceptCodeElementScanner(CodeElementScanner<?, P> s, P p) {
+        s.visitTree(this, p);
+    }
+
+    @Override
+    public TypeMirror asType() {
+        return type;
+    }
+
+    @Override
+    public ElementKind getKind() {
+        return ElementKind.OTHER;
+    }
+
+    @Override
+    public Name getSimpleName() {
+        return CodeNames.of(getString());
+    }
+
+    @Override
+    public <R, P> R accept(ElementVisitor<R, P> v, P p) {
+        if (v instanceof CodeElementScanner<?, ?>) {
+            acceptCodeElementScanner((CodeElementScanner<?, P>) v, p);
+            return null;
+        } else {
+            throw new UnsupportedOperationException();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTreeBuilder.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,818 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.ast;
+
+import static com.oracle.truffle.dsl.processor.ast.CodeTreeKind.*;
+
+import java.util.*;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+import com.oracle.truffle.dsl.processor.*;
+
+public class CodeTreeBuilder {
+
+    private final CodeTreeBuilder parent;
+
+    private BuilderCodeTree currentElement;
+    private final BuilderCodeTree root;
+
+    private int treeCount;
+
+    public CodeTreeBuilder(CodeTreeBuilder parent) {
+        this.root = new BuilderCodeTree(GROUP, null, null);
+        this.currentElement = root;
+        this.parent = parent;
+    }
+
+    @Override
+    public String toString() {
+        return root.toString();
+    }
+
+    public int getTreeCount() {
+        return treeCount;
+    }
+
+    public boolean isEmpty() {
+        return treeCount == 0;
+    }
+
+    public CodeTreeBuilder statement(String statement) {
+        return startStatement().string(statement).end();
+    }
+
+    public CodeTreeBuilder statement(CodeTree statement) {
+        return startStatement().tree(statement).end();
+    }
+
+    public static CodeTreeBuilder createBuilder() {
+        return new CodeTreeBuilder(null);
+    }
+
+    public static CodeTree singleString(String s) {
+        return new CodeTreeBuilder(null).string(s).getTree();
+    }
+
+    public static CodeTree singleType(TypeMirror s) {
+        return new CodeTreeBuilder(null).type(s).getTree();
+    }
+
+    private CodeTreeBuilder push(CodeTreeKind kind) {
+        return push(new BuilderCodeTree(kind, null, null));
+    }
+
+    private CodeTreeBuilder push(String string) {
+        return push(new BuilderCodeTree(CodeTreeKind.STRING, null, string));
+    }
+
+    private CodeTreeBuilder push(TypeMirror type) {
+        return push(new BuilderCodeTree(CodeTreeKind.TYPE, type, null));
+    }
+
+    private CodeTreeBuilder push(CodeTreeKind kind, TypeMirror type, String string) {
+        return push(new BuilderCodeTree(kind, type, string));
+    }
+
+    private CodeTreeBuilder push(BuilderCodeTree tree) {
+        if (currentElement != null) {
+            currentElement.add(tree);
+        }
+        switch (tree.getCodeKind()) {
+            case COMMA_GROUP:
+            case GROUP:
+            case INDENT:
+                currentElement = tree;
+                break;
+        }
+        treeCount++;
+        return this;
+    }
+
+    private void clearLast(CodeTreeKind kind) {
+        if (clearLastRec(kind, currentElement.getEnclosedElements())) {
+            treeCount--;
+        }
+    }
+
+    public CodeTreeBuilder startStatement() {
+        startGroup();
+        registerCallBack(new EndCallback() {
+
+            @Override
+            public void beforeEnd() {
+                string(";").newLine();
+            }
+
+            @Override
+            public void afterEnd() {
+            }
+        });
+        return this;
+    }
+
+    public CodeTreeBuilder startGroup() {
+        return push(CodeTreeKind.GROUP);
+    }
+
+    public CodeTreeBuilder startCommaGroup() {
+        return push(CodeTreeKind.COMMA_GROUP);
+    }
+
+    public CodeTreeBuilder startCall(String callSite) {
+        return startCall(null, callSite);
+    }
+
+    public CodeTreeBuilder startCall(String receiver, String callSite) {
+        if (receiver == null) {
+            return startGroup().string(callSite).startParanthesesCommaGroup().endAfter();
+        } else {
+            return startGroup().string(receiver).string(".").string(callSite).startParanthesesCommaGroup().endAfter();
+        }
+    }
+
+    public CodeTreeBuilder startStaticCall(TypeMirror type, String methodName) {
+        return startGroup().push(CodeTreeKind.STATIC_METHOD_REFERENCE, type, methodName).startParanthesesCommaGroup().endAfter();
+    }
+
+    public CodeTreeBuilder startStaticCall(ExecutableElement method) {
+        return startStaticCall(Utils.findNearestEnclosingType(method).asType(), method.getSimpleName().toString());
+    }
+
+    public CodeTreeBuilder staticReference(TypeMirror type, String fieldName) {
+        return push(CodeTreeKind.STATIC_FIELD_REFERENCE, type, fieldName);
+    }
+
+    private CodeTreeBuilder endAndWhitespaceAfter() {
+        registerCallBack(new EndCallback() {
+
+            @Override
+            public void beforeEnd() {
+            }
+
+            @Override
+            public void afterEnd() {
+                string(" ");
+                end();
+            }
+        });
+        return this;
+    }
+
+    private CodeTreeBuilder endAfter() {
+        registerCallBack(new EndCallback() {
+
+            @Override
+            public void beforeEnd() {
+            }
+
+            @Override
+            public void afterEnd() {
+                end();
+            }
+        });
+        return this;
+    }
+
+    private CodeTreeBuilder startParanthesesCommaGroup() {
+        startGroup();
+        string("(").startCommaGroup();
+        registerCallBack(new EndCallback() {
+
+            @Override
+            public void beforeEnd() {
+            }
+
+            @Override
+            public void afterEnd() {
+                string(")");
+            }
+        });
+        endAfter();
+        return this;
+    }
+
+    private CodeTreeBuilder startCurlyBracesCommaGroup() {
+        startGroup();
+        string("{").startCommaGroup();
+        registerCallBack(new EndCallback() {
+
+            @Override
+            public void beforeEnd() {
+            }
+
+            @Override
+            public void afterEnd() {
+                string("}");
+            }
+        });
+        endAfter();
+        return this;
+    }
+
+    public CodeTreeBuilder startParantheses() {
+        startGroup();
+        string("(").startGroup();
+        registerCallBack(new EndCallback() {
+
+            @Override
+            public void beforeEnd() {
+            }
+
+            @Override
+            public void afterEnd() {
+                string(")");
+            }
+        });
+        endAfter();
+        return this;
+    }
+
+    public CodeTreeBuilder doubleQuote(String s) {
+        return startGroup().string("\"" + s + "\"").end();
+    }
+
+    public CodeTreeBuilder string(String chunk1) {
+        return push(chunk1);
+    }
+
+    public CodeTreeBuilder string(String chunk1, String chunk2) {
+        return push(GROUP).string(chunk1).string(chunk2).end();
+    }
+
+    public CodeTreeBuilder string(String chunk1, String chunk2, String chunk3) {
+        return push(GROUP).string(chunk1).string(chunk2).string(chunk3).end();
+    }
+
+    public CodeTreeBuilder string(String chunk1, String chunk2, String chunk3, String chunk4) {
+        return push(GROUP).string(chunk1).string(chunk2).string(chunk3).string(chunk4).end();
+    }
+
+    public CodeTreeBuilder tree(CodeTree treeToAdd) {
+        if (treeToAdd instanceof BuilderCodeTree) {
+            return push((BuilderCodeTree) treeToAdd).end();
+        } else {
+            BuilderCodeTree tree = new BuilderCodeTree(GROUP, null, null);
+            tree.add(treeToAdd);
+            return push(tree).end();
+        }
+    }
+
+    public CodeTreeBuilder string(String chunk1, String chunk2, String chunk3, String chunk4, String... chunks) {
+        push(GROUP).string(chunk1).string(chunk2).string(chunk3).string(chunk4);
+        for (int i = 0; i < chunks.length; i++) {
+            string(chunks[i]);
+        }
+        return end();
+    }
+
+    public CodeTreeBuilder dot() {
+        return string(".");
+    }
+
+    public CodeTreeBuilder newLine() {
+        return push(NEW_LINE);
+    }
+
+    public CodeTreeBuilder startWhile() {
+        return startGroup().string("while ").startParanthesesCommaGroup().endAndWhitespaceAfter().startGroup().endAfter();
+    }
+
+    public CodeTreeBuilder startIf() {
+        return startGroup().string("if ").startParanthesesCommaGroup().endAndWhitespaceAfter().startGroup().endAfter();
+    }
+
+    public boolean startIf(boolean elseIf) {
+        if (elseIf) {
+            startElseIf();
+        } else {
+            startIf();
+        }
+        return true;
+    }
+
+    public CodeTreeBuilder startElseIf() {
+        clearLast(CodeTreeKind.NEW_LINE);
+        return startGroup().string(" else if ").startParanthesesCommaGroup().endAndWhitespaceAfter().startGroup().endAfter();
+    }
+
+    public CodeTreeBuilder startElseBlock() {
+        clearLast(CodeTreeKind.NEW_LINE);
+        return startGroup().string(" else ").startBlock().endAfter();
+    }
+
+    private boolean clearLastRec(CodeTreeKind kind, List<CodeTree> children) {
+        for (int i = children.size() - 1; i >= 0; i--) {
+            CodeTree child = children.get(i);
+            if (child.getCodeKind() == kind) {
+                children.remove(children.get(i));
+                return true;
+            } else {
+                if (clearLastRec(kind, child.getEnclosedElements())) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    public CodeTreeBuilder startCase() {
+        startGroup().string("case ");
+        registerCallBack(new EndCallback() {
+
+            @Override
+            public void beforeEnd() {
+                string(" :").newLine();
+            }
+
+            @Override
+            public void afterEnd() {
+            }
+        });
+        return this;
+    }
+
+    public CodeTreeBuilder caseDefault() {
+        return startGroup().string("default :").newLine().end();
+    }
+
+    public CodeTreeBuilder startSwitch() {
+        return startGroup().string("switch ").startParanthesesCommaGroup().endAndWhitespaceAfter();
+    }
+
+    public CodeTreeBuilder startReturn() {
+        ExecutableElement method = findMethod();
+        if (method != null && Utils.isVoid(method.getReturnType())) {
+            startGroup();
+            registerCallBack(new EndCallback() {
+
+                @Override
+                public void beforeEnd() {
+                    string(";").newLine(); // complete statement to execute
+                }
+
+                @Override
+                public void afterEnd() {
+                    string("return").string(";").newLine(); // emit a return;
+                }
+            });
+            return this;
+        } else {
+            return startStatement().string("return ");
+        }
+    }
+
+    public CodeTreeBuilder startAssert() {
+        return startStatement().string("assert ");
+    }
+
+    public CodeTreeBuilder startNewArray(ArrayType arrayType, CodeTree size) {
+        startGroup().string("new ").type(arrayType.getComponentType()).string("[");
+        if (size != null) {
+            tree(size);
+        }
+        string("]");
+        if (size == null) {
+            string(" ");
+            startCurlyBracesCommaGroup().endAfter();
+        }
+        return this;
+    }
+
+    public CodeTreeBuilder startNew(TypeMirror uninializedNodeClass) {
+        return startGroup().string("new ").type(uninializedNodeClass).startParanthesesCommaGroup().endAfter();
+    }
+
+    public CodeTreeBuilder startNew(String typeName) {
+        return startGroup().string("new ").string(typeName).startParanthesesCommaGroup().endAfter();
+    }
+
+    public CodeTreeBuilder startIndention() {
+        return push(CodeTreeKind.INDENT);
+    }
+
+    public CodeTreeBuilder end(int times) {
+        for (int i = 0; i < times; i++) {
+            end();
+        }
+        return this;
+    }
+
+    public CodeTreeBuilder end() {
+        BuilderCodeTree tree = currentElement;
+        EndCallback callback = tree.getAtEndListener();
+        if (callback != null) {
+            callback.beforeEnd();
+            toParent();
+            callback.afterEnd();
+        } else {
+            toParent();
+        }
+        return this;
+    }
+
+    private void toParent() {
+        Element parentElement = currentElement.getEnclosingElement();
+        if (currentElement != root) {
+            this.currentElement = (BuilderCodeTree) parentElement;
+        } else {
+            this.currentElement = root;
+        }
+    }
+
+    public CodeTreeBuilder startBlock() {
+        startGroup();
+        string("{").newLine().startIndention();
+        registerCallBack(new EndCallback() {
+
+            @Override
+            public void beforeEnd() {
+            }
+
+            @Override
+            public void afterEnd() {
+                string("}").newLine();
+            }
+        });
+        endAfter();
+        return this;
+    }
+
+    private void registerCallBack(EndCallback callback) {
+        currentElement.registerAtEnd(callback);
+    }
+
+    public CodeTreeBuilder defaultDeclaration(TypeMirror type, String name) {
+        if (!Utils.isVoid(type)) {
+            startStatement();
+            type(type);
+            string(" ");
+            string(name);
+            string(" = ");
+            defaultValue(type);
+            end(); // statement
+        }
+        return this;
+    }
+
+    public CodeTreeBuilder declaration(TypeMirror type, String name, String init) {
+        return declaration(type, name, singleString(init));
+    }
+
+    public CodeTreeBuilder declaration(TypeMirror type, String name, CodeTree init) {
+        if (Utils.isVoid(type)) {
+            startStatement();
+            tree(init);
+            end();
+        } else {
+            startStatement();
+            type(type);
+            string(" ");
+            string(name);
+            if (init != null) {
+                string(" = ");
+                tree(init);
+            }
+            end(); // statement
+        }
+        return this;
+    }
+
+    public CodeTreeBuilder declaration(TypeMirror type, String name, CodeTreeBuilder init) {
+        if (init == this) {
+            throw new IllegalArgumentException("Recursive builder usage.");
+        }
+        return declaration(type, name, init.getTree());
+    }
+
+    public CodeTreeBuilder declaration(TypeMirror type, String name) {
+        return declaration(type, name, (CodeTree) null);
+    }
+
+    public CodeTreeBuilder create() {
+        return new CodeTreeBuilder(this);
+    }
+
+    public CodeTreeBuilder type(TypeMirror type) {
+        return push(type);
+    }
+
+    public CodeTreeBuilder typeLiteral(TypeMirror type) {
+        return startGroup().type(type).string(".class").end();
+    }
+
+    private void assertRoot() {
+        if (currentElement != root) {
+            throw new IllegalStateException("CodeTreeBuilder was not ended properly.");
+        }
+    }
+
+    public CodeTreeBuilder startCaseBlock() {
+        return startIndention();
+    }
+
+    public CodeTreeBuilder startThrow() {
+        return startStatement().string("throw ");
+    }
+
+    public CodeTree getTree() {
+        assertRoot();
+        return root;
+    }
+
+    public CodeTree getRoot() {
+        return root;
+    }
+
+    public CodeTreeBuilder cast(String baseClassName) {
+        string("(").string(baseClassName).string(") ");
+        return this;
+    }
+
+    public CodeTreeBuilder cast(TypeMirror type, CodeTree content) {
+        if (Utils.isVoid(type)) {
+            tree(content);
+            return this;
+        } else if (type.getKind() == TypeKind.DECLARED && Utils.getQualifiedName(type).equals("java.lang.Object")) {
+            tree(content);
+            return this;
+        } else {
+            return startGroup().string("(").type(type).string(")").string(" ").tree(content).end();
+        }
+    }
+
+    public CodeTreeBuilder startSuperCall() {
+        return string("super").startParanthesesCommaGroup();
+    }
+
+    public CodeTreeBuilder returnFalse() {
+        return startReturn().string("false").end();
+    }
+
+    public CodeTreeBuilder returnStatement() {
+        return statement("return");
+    }
+
+    public ExecutableElement findMethod() {
+        Element element = currentElement;
+        while (element != null && (element.getKind() != ElementKind.METHOD && (element.getKind() != ElementKind.CONSTRUCTOR))) {
+            element = element.getEnclosingElement();
+        }
+        ExecutableElement found = element != null ? (ExecutableElement) element : null;
+        if (found == null && parent != null) {
+            found = parent.findMethod();
+        }
+        return found;
+    }
+
+    public CodeTreeBuilder returnTrue() {
+        return startReturn().string("true").end();
+    }
+
+    public CodeTreeBuilder instanceOf(CodeTree var, CodeTree type) {
+        tree(var).string(" instanceof ").tree(type);
+        return this;
+    }
+
+    public CodeTreeBuilder instanceOf(String var, String type) {
+        return instanceOf(singleString(var), singleString(type));
+    }
+
+    public CodeTreeBuilder instanceOf(String var, TypeMirror type) {
+        TypeElement element = Utils.fromTypeMirror(type);
+        if (element == null) {
+            throw new IllegalArgumentException("Cannot call instanceof for a non supported type: " + type.getKind());
+        }
+        return instanceOf(singleString(var), singleType(type));
+    }
+
+    public CodeTreeBuilder defaultValue(TypeMirror mirror) {
+        switch (mirror.getKind()) {
+            case VOID:
+                return string("");
+            case ARRAY:
+            case DECLARED:
+            case PACKAGE:
+            case NULL:
+                return string("null");
+            case BOOLEAN:
+                return string("false");
+            case BYTE:
+                return string("(byte) 0");
+            case CHAR:
+                return string("(char) 0");
+            case DOUBLE:
+                return string("0.0D");
+            case LONG:
+                return string("0L");
+            case INT:
+                return string("0");
+            case FLOAT:
+                return string("0.0F");
+            case SHORT:
+                return string("(short) 0");
+            default:
+                throw new AssertionError();
+        }
+    }
+
+    public CodeTreeBuilder assertFalse() {
+        return startAssert().string("false").end();
+    }
+
+    public CodeTreeBuilder breakStatement() {
+        return statement("break");
+    }
+
+    public CodeTreeBuilder isNull() {
+        return string(" == null");
+    }
+
+    public CodeTreeBuilder isNotNull() {
+        return string(" != null");
+    }
+
+    public CodeTreeBuilder is(CodeTree tree) {
+        return string(" == ").tree(tree);
+    }
+
+    public CodeTreeBuilder startTryBlock() {
+        return string("try ").startBlock();
+    }
+
+    public CodeTreeBuilder startCatchBlock(TypeMirror exceptionType, String localVarName) {
+        clearLast(CodeTreeKind.NEW_LINE);
+        string(" catch (").type(exceptionType).string(" ").string(localVarName).string(") ");
+        return startBlock();
+    }
+
+    public CodeTreeBuilder startFinallyBlock() {
+        clearLast(CodeTreeKind.NEW_LINE);
+        string(" finally ");
+        return startBlock();
+    }
+
+    public CodeTreeBuilder nullLiteral() {
+        return string("null");
+    }
+
+    private static class BuilderCodeTree extends CodeTree {
+
+        private EndCallback atEndListener;
+
+        public BuilderCodeTree(CodeTreeKind kind, TypeMirror type, String string) {
+            super(kind, type, string);
+        }
+
+        public void registerAtEnd(EndCallback atEnd) {
+            if (this.atEndListener != null) {
+                this.atEndListener = new CompoundCallback(this.atEndListener, atEnd);
+            } else {
+                this.atEndListener = atEnd;
+            }
+        }
+
+        public EndCallback getAtEndListener() {
+            return atEndListener;
+        }
+
+        @Override
+        public String toString() {
+            final StringBuilder b = new StringBuilder();
+            acceptCodeElementScanner(new Printer(b), null);
+            return b.toString();
+        }
+
+        private static class CompoundCallback implements EndCallback {
+
+            private final EndCallback callback1;
+            private final EndCallback callback2;
+
+            public CompoundCallback(EndCallback callback1, EndCallback callback2) {
+                this.callback1 = callback1;
+                this.callback2 = callback2;
+            }
+
+            @Override
+            public void afterEnd() {
+                callback1.afterEnd();
+                callback2.afterEnd();
+            }
+
+            @Override
+            public void beforeEnd() {
+                callback1.beforeEnd();
+                callback1.beforeEnd();
+            }
+        }
+
+    }
+
+    private interface EndCallback {
+
+        void beforeEnd();
+
+        void afterEnd();
+    }
+
+    private static class Printer extends CodeElementScanner<Void, Void> {
+
+        private int indent;
+        private boolean newLine;
+        private final String ln = "\n";
+
+        private final StringBuilder b;
+
+        Printer(StringBuilder b) {
+            this.b = b;
+        }
+
+        @Override
+        public void visitTree(CodeTree e, Void p) {
+            switch (e.getCodeKind()) {
+                case COMMA_GROUP:
+                    List<CodeTree> children = e.getEnclosedElements();
+                    for (int i = 0; i < children.size(); i++) {
+                        children.get(i).acceptCodeElementScanner(this, p);
+                        if (i < e.getEnclosedElements().size() - 1) {
+                            b.append(", ");
+                        }
+                    }
+                    break;
+                case GROUP:
+                    super.visitTree(e, p);
+                    break;
+                case INDENT:
+                    indent();
+                    super.visitTree(e, p);
+                    dedent();
+                    break;
+                case NEW_LINE:
+                    writeLn();
+                    break;
+                case STRING:
+                    if (e.getString() != null) {
+                        write(e.getString());
+                    } else {
+                        write("null");
+                    }
+                    break;
+                case TYPE:
+                    write(Utils.getSimpleName(e.getType()));
+                    break;
+                default:
+                    assert false;
+                    return;
+            }
+        }
+
+        private void indent() {
+            indent++;
+        }
+
+        private void dedent() {
+            indent--;
+        }
+
+        private void writeLn() {
+            write(ln);
+            newLine = true;
+        }
+
+        private void write(String m) {
+            if (newLine && m != ln) {
+                writeIndent();
+                newLine = false;
+            }
+            b.append(m);
+        }
+
+        private void writeIndent() {
+            for (int i = 0; i < indent; i++) {
+                b.append("    ");
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTreeKind.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.ast;
+
+public enum CodeTreeKind {
+    STATIC_FIELD_REFERENCE, STATIC_METHOD_REFERENCE, GROUP, COMMA_GROUP, INDENT, STRING, NEW_LINE, TYPE;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTreeVariable.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.ast;
+
+public class CodeTreeVariable extends CodeTree {
+
+    private final String name;
+
+    private CodeTree value;
+
+    public CodeTreeVariable() {
+        super(CodeTreeKind.GROUP, null, null);
+        this.name = "";
+    }
+
+    public CodeTreeVariable(String name) {
+        super(CodeTreeKind.GROUP, null, null);
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void set(CodeTree tree) {
+        if (value == tree) {
+            return;
+        }
+        if (this.value != null) {
+            remove(this.value);
+        }
+        this.value = tree;
+        add(tree);
+    }
+
+    public CodeTree get() {
+        return value;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTypeElement.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.ast;
+
+import java.util.*;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+import javax.lang.model.util.*;
+
+import com.oracle.truffle.dsl.processor.ast.CodeTypeMirror.*;
+
+public class CodeTypeElement extends CodeElement<Element> implements TypeElement {
+
+    private final List<? extends CodeImport> imports = parentableList(this, new ArrayList<CodeImport>());
+
+    private final PackageElement packageElement;
+
+    private final Name simpleName;
+    private final Name packageName;
+    private Name qualifiedName;
+
+    private final List<TypeMirror> implementsInterfaces = new ArrayList<>();
+    private final ElementKind kind;
+    private TypeMirror superClass;
+
+    private final DeclaredCodeTypeMirror mirror = new DeclaredCodeTypeMirror(this);
+
+    public CodeTypeElement(Set<Modifier> modifiers, ElementKind kind, PackageElement packageElement, String simpleName) {
+        super(modifiers);
+        this.kind = kind;
+        this.packageElement = packageElement;
+        this.simpleName = CodeNames.of(simpleName);
+        if (this.packageElement != null) {
+            this.packageName = packageElement.getQualifiedName();
+        } else {
+            this.packageName = CodeNames.of("default");
+        }
+        this.qualifiedName = createQualifiedName();
+    }
+
+    @Override
+    public TypeMirror asType() {
+        return mirror;
+    }
+
+    @Override
+    public ElementKind getKind() {
+        return kind;
+    }
+
+    public boolean containsField(String name) {
+        for (VariableElement field : getFields()) {
+            if (field.getSimpleName().toString().equals(name)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public NestingKind getNestingKind() {
+        return isTopLevelClass() ? NestingKind.TOP_LEVEL : NestingKind.LOCAL;
+    }
+
+    @Override
+    public Element getEnclosingElement() {
+        if (isTopLevelClass()) {
+            return packageElement;
+        } else {
+            return super.getEnclosingElement();
+        }
+    }
+
+    @Override
+    public TypeMirror getSuperclass() {
+        return superClass;
+    }
+
+    @Override
+    public List<TypeMirror> getInterfaces() {
+        return implementsInterfaces;
+    }
+
+    @Override
+    public List<? extends TypeParameterElement> getTypeParameters() {
+        return Collections.emptyList();
+    }
+
+    public boolean isTopLevelClass() {
+        return super.getEnclosingElement() instanceof CodeCompilationUnit;
+    }
+
+    public CodeVariableElement getField(String name) {
+        for (VariableElement field : ElementFilter.fieldsIn(getEnclosedElements())) {
+            if (field.getSimpleName().toString().equals(name)) {
+                return (CodeVariableElement) field;
+            }
+        }
+        return null;
+    }
+
+    private Name createQualifiedName() {
+        TypeElement enclosingType = getEnclosingClass();
+        if (enclosingType == null) {
+            return CodeNames.of(packageName + "." + simpleName);
+        } else {
+            return CodeNames.of(enclosingType.getQualifiedName() + "." + simpleName);
+        }
+    }
+
+    @Override
+    void setEnclosingElement(Element element) {
+        super.setEnclosingElement(element);
+
+        // update qualified name on container change
+        this.qualifiedName = createQualifiedName();
+    }
+
+    public Name getPackageName() {
+        return packageName;
+    }
+
+    @Override
+    public Name getQualifiedName() {
+        return qualifiedName;
+    }
+
+    @Override
+    public Name getSimpleName() {
+        return simpleName;
+    }
+
+    public void setSuperClass(TypeMirror superType) {
+        this.superClass = superType;
+    }
+
+    public List<? extends CodeImport> getImports() {
+        return imports;
+    }
+
+    public List<TypeMirror> getImplements() {
+        return implementsInterfaces;
+    }
+
+    @Override
+    public int hashCode() {
+        return getQualifiedName().hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        } else if (obj instanceof TypeElement) {
+            return getQualifiedName().equals(((TypeElement) obj).getQualifiedName());
+        }
+        return false;
+    }
+
+    public List<VariableElement> getFields() {
+        return ElementFilter.fieldsIn(getEnclosedElements());
+    }
+
+    public ExecutableElement getMethod(String name) {
+        for (Element element : getEnclosedElements()) {
+            if (element.getKind() == ElementKind.METHOD && element.getSimpleName().toString().equals(name)) {
+                return (ExecutableElement) element;
+            }
+        }
+        return null;
+    }
+
+    public List<ExecutableElement> getMethods() {
+        return ElementFilter.methodsIn(getEnclosedElements());
+    }
+
+    public List<TypeElement> getInnerClasses() {
+        return ElementFilter.typesIn(getEnclosedElements());
+    }
+
+    @Override
+    public String toString() {
+        return getQualifiedName().toString();
+    }
+
+    @Override
+    public <R, P> R accept(ElementVisitor<R, P> v, P p) {
+        return v.visitType(this, p);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTypeMirror.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.ast;
+
+import java.lang.annotation.*;
+import java.util.*;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+public class CodeTypeMirror implements TypeMirror {
+
+    private final TypeKind kind;
+
+    public CodeTypeMirror(TypeKind kind) {
+        this.kind = kind;
+    }
+
+    @Override
+    public TypeKind getKind() {
+        return kind;
+    }
+
+    @Override
+    public <R, P> R accept(TypeVisitor<R, P> v, P p) {
+        throw new UnsupportedOperationException();
+    }
+
+    public static class ArrayCodeTypeMirror extends CodeTypeMirror implements ArrayType {
+
+        private final TypeMirror component;
+
+        public ArrayCodeTypeMirror(TypeMirror component) {
+            super(TypeKind.ARRAY);
+            this.component = component;
+        }
+
+        @Override
+        public TypeMirror getComponentType() {
+            return component;
+        }
+
+    }
+
+    public static class DeclaredCodeTypeMirror extends CodeTypeMirror implements DeclaredType {
+
+        private final TypeElement clazz;
+        private final List<? extends TypeMirror> typeArguments;
+
+        public DeclaredCodeTypeMirror(TypeElement clazz) {
+            this(clazz, Collections.<TypeMirror> emptyList());
+        }
+
+        public DeclaredCodeTypeMirror(TypeElement clazz, List<? extends TypeMirror> typeArguments) {
+            super(TypeKind.DECLARED);
+            this.clazz = clazz;
+            this.typeArguments = typeArguments;
+        }
+
+        @Override
+        public Element asElement() {
+            return clazz;
+        }
+
+        @Override
+        public TypeMirror getEnclosingType() {
+            return clazz.getEnclosingElement().asType();
+        }
+
+        @Override
+        public List<? extends TypeMirror> getTypeArguments() {
+            return typeArguments;
+        }
+
+        @Override
+        public String toString() {
+            return clazz.getQualifiedName().toString();
+        }
+
+    }
+
+    public List<? extends AnnotationMirror> getAnnotationMirrors() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @param annotationType
+     */
+    public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @param annotationType
+     */
+    public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType) {
+        throw new UnsupportedOperationException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeVariableElement.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.ast;
+
+import java.util.*;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.api.element.*;
+
+public final class CodeVariableElement extends CodeElement<Element> implements WritableVariableElement {
+
+    private Name name;
+    private TypeMirror type;
+    private Object constantValue;
+
+    private CodeTree init;
+
+    public CodeVariableElement(TypeMirror type, String name) {
+        super(Utils.modifiers());
+        this.type = type;
+        this.name = CodeNames.of(name);
+    }
+
+    public CodeVariableElement(Set<Modifier> modifiers, TypeMirror type, String name) {
+        super(modifiers);
+        this.type = type;
+        this.name = CodeNames.of(name);
+    }
+
+    public CodeVariableElement(Set<Modifier> modifiers, TypeMirror type, String name, String init) {
+        this(modifiers, type, name);
+        if (init != null) {
+            this.init = new CodeTree(CodeTreeKind.STRING, null, init);
+        }
+    }
+
+    public CodeTreeBuilder createInitBuilder() {
+        CodeTreeBuilder builder = new CodeTreeBuilder(null);
+        init = builder.getTree();
+        init.setEnclosingElement(this);
+        return builder;
+    }
+
+    public void setInit(CodeTree init) {
+        this.init = init;
+    }
+
+    public CodeTree getInit() {
+        return init;
+    }
+
+    public Name getSimpleName() {
+        return name;
+    }
+
+    public TypeMirror getType() {
+        return type;
+    }
+
+    @Override
+    public TypeMirror asType() {
+        return type;
+    }
+
+    @Override
+    public ElementKind getKind() {
+        if (getEnclosingElement() instanceof ExecutableElement) {
+            return ElementKind.PARAMETER;
+        } else if (getEnclosingElement() instanceof TypeElement) {
+            return ElementKind.FIELD;
+        } else {
+            return ElementKind.PARAMETER;
+        }
+    }
+
+    public void setConstantValue(Object constantValue) {
+        this.constantValue = constantValue;
+    }
+
+    @Override
+    public Object getConstantValue() {
+        return constantValue;
+    }
+
+    public String getName() {
+        return getSimpleName().toString();
+    }
+
+    @Override
+    public void setSimpleName(Name name) {
+        this.name = name;
+    }
+
+    public void setName(String name) {
+        this.name = CodeNames.of(name);
+    }
+
+    @Override
+    public void setType(TypeMirror type) {
+        this.type = type;
+    }
+
+    @Override
+    public <R, P> R accept(ElementVisitor<R, P> v, P p) {
+        return v.visitVariable(this, p);
+    }
+
+    public static CodeVariableElement clone(VariableElement var) {
+        CodeVariableElement copy = new CodeVariableElement(var.getModifiers(), var.asType(), var.getSimpleName().toString());
+        copy.setConstantValue(var.getConstantValue());
+        for (AnnotationMirror mirror : var.getAnnotationMirrors()) {
+            copy.addAnnotationMirror(mirror);
+        }
+        for (Element element : var.getEnclosedElements()) {
+            copy.add(element);
+        }
+        return copy;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/GeneratedElement.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.ast;
+
+import javax.lang.model.element.*;
+
+public interface GeneratedElement {
+
+    AnnotationMirror getGeneratorAnnotationMirror();
+
+    void setGeneratorAnnotationMirror(AnnotationMirror mirror);
+
+    Element getGeneratorElement();
+
+    void setGeneratorElement(Element element);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/codewriter/AbstractCodeWriter.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,705 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.codewriter;
+
+import static com.oracle.truffle.dsl.processor.Utils.*;
+
+import java.io.*;
+import java.util.*;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+import javax.lang.model.util.*;
+
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.ast.*;
+
+public abstract class AbstractCodeWriter extends CodeElementScanner<Void, Void> {
+
+    private static final int LINE_LENGTH = 200;
+    private static final int LINE_WRAP_INDENTS = 3;
+    private static final String IDENT_STRING = "    ";
+    private static final String LN = "\n"; /* unix style */
+
+    protected Writer writer;
+    private int indent;
+    private boolean newLine;
+    private int lineLength;
+    private boolean lineWrapping = false;
+
+    private OrganizedImports imports;
+
+    public void visitCompilationUnit(CodeCompilationUnit e) {
+        for (TypeElement clazz : e.getEnclosedElements()) {
+            clazz.accept(this, null);
+        }
+    }
+
+    protected abstract Writer createWriter(CodeTypeElement clazz) throws IOException;
+
+    @Override
+    public Void visitType(CodeTypeElement e, Void p) {
+        if (e.isTopLevelClass()) {
+            Writer w = null;
+            try {
+                imports = OrganizedImports.organize(e);
+                w = new TrimTrailingSpaceWriter(createWriter(e));
+                writer = w;
+                writeRootClass(e);
+            } catch (IOException ex) {
+                throw new RuntimeException(ex);
+            } finally {
+                if (w != null) {
+                    try {
+                        w.close();
+                    } catch (Throwable e1) {
+                        // see eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=361378
+                        // TODO temporary suppress errors on close.
+                    }
+                }
+                writer = null;
+            }
+        } else {
+            writeClassImpl(e);
+        }
+        return null;
+    }
+
+    private void writeRootClass(CodeTypeElement e) {
+        writeHeader();
+        write("package ").write(e.getPackageName()).write(";").writeLn();
+        writeEmptyLn();
+
+        Set<CodeImport> generateImports = imports.generateImports();
+        List<CodeImport> typeImports = new ArrayList<>();
+        List<CodeImport> staticImports = new ArrayList<>();
+
+        for (CodeImport codeImport : generateImports) {
+            if (codeImport.isStaticImport()) {
+                staticImports.add(codeImport);
+            } else {
+                typeImports.add(codeImport);
+            }
+        }
+        Collections.sort(typeImports);
+        Collections.sort(staticImports);
+
+        for (CodeImport imp : staticImports) {
+            imp.accept(this, null);
+            writeLn();
+        }
+        if (!staticImports.isEmpty()) {
+            writeEmptyLn();
+        }
+
+        for (CodeImport imp : typeImports) {
+            imp.accept(this, null);
+            writeLn();
+        }
+        if (!typeImports.isEmpty()) {
+            writeEmptyLn();
+        }
+
+        writeClassImpl(e);
+    }
+
+    private String useImport(Element enclosedType, TypeMirror type) {
+        if (imports != null) {
+            return imports.createTypeReference(enclosedType, type);
+        } else {
+            return Utils.getSimpleName(type);
+        }
+    }
+
+    private void writeClassImpl(CodeTypeElement e) {
+        for (AnnotationMirror annotation : e.getAnnotationMirrors()) {
+            visitAnnotation(e, annotation);
+            writeLn();
+        }
+
+        writeModifiers(e.getModifiers());
+        if (e.getKind() == ElementKind.ENUM) {
+            write("enum ");
+        } else {
+            write("class ");
+        }
+        write(e.getSimpleName());
+        if (e.getSuperclass() != null && !getQualifiedName(e.getSuperclass()).equals("java.lang.Object")) {
+            write(" extends ").write(useImport(e, e.getSuperclass()));
+        }
+        if (e.getImplements().size() > 0) {
+            write(" implements ");
+            for (int i = 0; i < e.getImplements().size(); i++) {
+                write(useImport(e, e.getImplements().get(i)));
+                if (i < e.getImplements().size() - 1) {
+                    write(", ");
+                }
+            }
+        }
+
+        write(" {").writeLn();
+        writeEmptyLn();
+        indent(1);
+
+        List<VariableElement> staticFields = getStaticFields(e);
+        List<VariableElement> instanceFields = getInstanceFields(e);
+
+        for (int i = 0; i < staticFields.size(); i++) {
+            VariableElement field = staticFields.get(i);
+            field.accept(this, null);
+            if (e.getKind() == ElementKind.ENUM && i < staticFields.size() - 1) {
+                write(",");
+                writeLn();
+            } else {
+                write(";");
+                writeLn();
+            }
+        }
+
+        if (staticFields.size() > 0) {
+            writeEmptyLn();
+        }
+
+        for (VariableElement field : instanceFields) {
+            field.accept(this, null);
+            write(";");
+            writeLn();
+        }
+        if (instanceFields.size() > 0) {
+            writeEmptyLn();
+        }
+
+        for (ExecutableElement method : ElementFilter.constructorsIn(e.getEnclosedElements())) {
+            method.accept(this, null);
+        }
+
+        for (ExecutableElement method : getInstanceMethods(e)) {
+            method.accept(this, null);
+        }
+
+        for (ExecutableElement method : getStaticMethods(e)) {
+            method.accept(this, null);
+        }
+
+        for (TypeElement clazz : e.getInnerClasses()) {
+            clazz.accept(this, null);
+        }
+
+        dedent(1);
+        write("}");
+        writeEmptyLn();
+    }
+
+    private static List<VariableElement> getStaticFields(CodeTypeElement clazz) {
+        List<VariableElement> staticFields = new ArrayList<>();
+        for (VariableElement field : clazz.getFields()) {
+            if (field.getModifiers().contains(Modifier.STATIC)) {
+                staticFields.add(field);
+            }
+        }
+        return staticFields;
+    }
+
+    private static List<VariableElement> getInstanceFields(CodeTypeElement clazz) {
+        List<VariableElement> instanceFields = new ArrayList<>();
+        for (VariableElement field : clazz.getFields()) {
+            if (!field.getModifiers().contains(Modifier.STATIC)) {
+                instanceFields.add(field);
+            }
+        }
+        return instanceFields;
+    }
+
+    private static List<ExecutableElement> getStaticMethods(CodeTypeElement clazz) {
+        List<ExecutableElement> staticMethods = new ArrayList<>();
+        for (ExecutableElement method : clazz.getMethods()) {
+            if (method.getModifiers().contains(Modifier.STATIC)) {
+                staticMethods.add(method);
+            }
+        }
+        return staticMethods;
+    }
+
+    private static List<ExecutableElement> getInstanceMethods(CodeTypeElement clazz) {
+        List<ExecutableElement> instanceMethods = new ArrayList<>();
+        for (ExecutableElement method : clazz.getMethods()) {
+            if (!method.getModifiers().contains(Modifier.STATIC)) {
+                instanceMethods.add(method);
+            }
+        }
+        return instanceMethods;
+    }
+
+    @Override
+    public Void visitVariable(VariableElement f, Void p) {
+        Element parent = f.getEnclosingElement();
+
+        for (AnnotationMirror annotation : f.getAnnotationMirrors()) {
+            visitAnnotation(f, annotation);
+            write(" ");
+        }
+
+        CodeTree init = null;
+        if (f instanceof CodeVariableElement) {
+            init = ((CodeVariableElement) f).getInit();
+        }
+
+        if (parent.getKind() == ElementKind.ENUM && f.getModifiers().contains(Modifier.STATIC)) {
+            write(f.getSimpleName());
+            if (init != null) {
+                if (init != null) {
+                    write("(");
+                    init.acceptCodeElementScanner(this, p);
+                    write(")");
+                }
+            }
+        } else {
+            writeModifiers(f.getModifiers());
+            write(useImport(f, f.asType()));
+
+            if (f.getEnclosingElement().getKind() == ElementKind.METHOD) {
+                ExecutableElement method = (ExecutableElement) f.getEnclosingElement();
+                if (method.isVarArgs() && method.getParameters().indexOf(f) == method.getParameters().size() - 1) {
+                    write("...");
+                }
+            }
+
+            write(" ");
+            write(f.getSimpleName());
+            if (init != null) {
+                write(" = ");
+                init.acceptCodeElementScanner(this, p);
+            }
+        }
+        return null;
+    }
+
+    public void visitAnnotation(Element enclosedElement, AnnotationMirror e) {
+        write("@").write(useImport(enclosedElement, e.getAnnotationType()));
+
+        if (!e.getElementValues().isEmpty()) {
+            write("(");
+            final ExecutableElement defaultElement = findExecutableElement(e.getAnnotationType(), "value");
+
+            Map<? extends ExecutableElement, ? extends AnnotationValue> values = e.getElementValues();
+            if (defaultElement != null && values.size() == 1 && values.get(defaultElement) != null) {
+                visitAnnotationValue(enclosedElement, values.get(defaultElement));
+            } else {
+                Set<? extends ExecutableElement> methodsSet = values.keySet();
+                List<ExecutableElement> methodsList = new ArrayList<>();
+                for (ExecutableElement method : methodsSet) {
+                    if (values.get(method) == null) {
+                        continue;
+                    }
+                    methodsList.add(method);
+                }
+
+                Collections.sort(methodsList, new Comparator<ExecutableElement>() {
+
+                    @Override
+                    public int compare(ExecutableElement o1, ExecutableElement o2) {
+                        return o1.getSimpleName().toString().compareTo(o2.getSimpleName().toString());
+                    }
+                });
+
+                for (int i = 0; i < methodsList.size(); i++) {
+                    ExecutableElement method = methodsList.get(i);
+                    AnnotationValue value = values.get(method);
+                    write(method.getSimpleName().toString());
+                    write(" = ");
+                    visitAnnotationValue(enclosedElement, value);
+
+                    if (i < methodsList.size() - 1) {
+                        write(", ");
+                    }
+                }
+            }
+
+            write(")");
+        }
+    }
+
+    public void visitAnnotationValue(Element enclosedElement, AnnotationValue e) {
+        e.accept(new AnnotationValueWriterVisitor(enclosedElement), null);
+    }
+
+    private class AnnotationValueWriterVisitor extends AbstractAnnotationValueVisitor7<Void, Void> {
+
+        private final Element enclosedElement;
+
+        public AnnotationValueWriterVisitor(Element enclosedElement) {
+            this.enclosedElement = enclosedElement;
+        }
+
+        @Override
+        public Void visitBoolean(boolean b, Void p) {
+            write(Boolean.toString(b));
+            return null;
+        }
+
+        @Override
+        public Void visitByte(byte b, Void p) {
+            write(Byte.toString(b));
+            return null;
+        }
+
+        @Override
+        public Void visitChar(char c, Void p) {
+            write(Character.toString(c));
+            return null;
+        }
+
+        @Override
+        public Void visitDouble(double d, Void p) {
+            write(Double.toString(d));
+            return null;
+        }
+
+        @Override
+        public Void visitFloat(float f, Void p) {
+            write(Float.toString(f));
+            return null;
+        }
+
+        @Override
+        public Void visitInt(int i, Void p) {
+            write(Integer.toString(i));
+            return null;
+        }
+
+        @Override
+        public Void visitLong(long i, Void p) {
+            write(Long.toString(i));
+            return null;
+        }
+
+        @Override
+        public Void visitShort(short s, Void p) {
+            write(Short.toString(s));
+            return null;
+        }
+
+        @Override
+        public Void visitString(String s, Void p) {
+            write("\"");
+            write(s);
+            write("\"");
+            return null;
+        }
+
+        @Override
+        public Void visitType(TypeMirror t, Void p) {
+            write(useImport(enclosedElement, t));
+            write(".class");
+            return null;
+        }
+
+        @Override
+        public Void visitEnumConstant(VariableElement c, Void p) {
+            write(useImport(enclosedElement, c.asType()));
+            write(".");
+            write(c.getSimpleName().toString());
+            return null;
+        }
+
+        @Override
+        public Void visitAnnotation(AnnotationMirror a, Void p) {
+            AbstractCodeWriter.this.visitAnnotation(enclosedElement, a);
+            return null;
+        }
+
+        @Override
+        public Void visitArray(List<? extends AnnotationValue> vals, Void p) {
+            write("{");
+            for (int i = 0; i < vals.size(); i++) {
+                AnnotationValue value = vals.get(i);
+                AbstractCodeWriter.this.visitAnnotationValue(enclosedElement, value);
+                if (i < vals.size() - 1) {
+                    write(", ");
+                }
+            }
+            write("}");
+            return null;
+        }
+    }
+
+    public ExecutableElement findExecutableElement(DeclaredType type, String name) {
+        List<? extends ExecutableElement> elements = ElementFilter.methodsIn(type.asElement().getEnclosedElements());
+        for (ExecutableElement executableElement : elements) {
+            if (executableElement.getSimpleName().toString().equals(name)) {
+                return executableElement;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public void visitImport(CodeImport e, Void p) {
+        if (e.isStaticImport()) {
+            write("import static ").write(e.getImportString()).write(";");
+        } else {
+            write("import ").write(e.getImportString()).write(";");
+        }
+    }
+
+    @Override
+    public Void visitExecutable(CodeExecutableElement e, Void p) {
+        for (AnnotationMirror annotation : e.getAnnotationMirrors()) {
+            visitAnnotation(e, annotation);
+            writeLn();
+        }
+
+        writeModifiers(e.getModifiers());
+
+        if (e.getReturnType() != null) {
+            write(useImport(e, e.getReturnType()));
+            write(" ");
+        }
+        write(e.getSimpleName());
+        write("(");
+
+        for (int i = 0; i < e.getParameters().size(); i++) {
+            VariableElement param = e.getParameters().get(i);
+            param.accept(this, p);
+            if (i < e.getParameters().size() - 1) {
+                write(", ");
+            }
+        }
+        write(")");
+
+        List<TypeMirror> throwables = e.getThrownTypes();
+        if (throwables.size() > 0) {
+            write(" throws ");
+            for (int i = 0; i < throwables.size(); i++) {
+                write(useImport(e, throwables.get(i)));
+                if (i < throwables.size() - 1) {
+                    write(", ");
+                }
+            }
+        }
+
+        if (e.getModifiers().contains(Modifier.ABSTRACT)) {
+            writeLn(";");
+        } else if (e.getBodyTree() != null) {
+            writeLn(" {");
+            indent(1);
+            e.getBodyTree().acceptCodeElementScanner(this, p);
+            dedent(1);
+            writeLn("}");
+        } else if (e.getBody() != null) {
+            write(" {");
+            write(e.getBody());
+            writeLn("}");
+        } else {
+            writeLn("{ }");
+        }
+        writeEmptyLn();
+        return null;
+    }
+
+    @Override
+    public void visitTree(CodeTree e, Void p) {
+        CodeTreeKind kind = e.getCodeKind();
+
+        switch (kind) {
+            case COMMA_GROUP:
+                List<CodeTree> children = e.getEnclosedElements();
+                for (int i = 0; i < children.size(); i++) {
+                    children.get(i).acceptCodeElementScanner(this, p);
+                    if (i < e.getEnclosedElements().size() - 1) {
+                        write(", ");
+                    }
+                }
+                break;
+            case GROUP:
+                for (CodeTree tree : e.getEnclosedElements()) {
+                    tree.acceptCodeElementScanner(this, p);
+                }
+                break;
+            case INDENT:
+                indent(1);
+                for (CodeTree tree : e.getEnclosedElements()) {
+                    tree.acceptCodeElementScanner(this, p);
+                }
+                dedent(1);
+                break;
+            case NEW_LINE:
+                writeLn();
+                break;
+            case STRING:
+                if (e.getString() != null) {
+                    write(e.getString());
+                } else {
+                    write("null");
+                }
+                break;
+            case STATIC_FIELD_REFERENCE:
+                if (e.getString() != null) {
+                    write(imports.createStaticFieldReference(e, e.getType(), e.getString()));
+                } else {
+                    write("null");
+                }
+                break;
+            case STATIC_METHOD_REFERENCE:
+                if (e.getString() != null) {
+                    write(imports.createStaticMethodReference(e, e.getType(), e.getString()));
+                } else {
+                    write("null");
+                }
+                break;
+            case TYPE:
+                write(useImport(e, e.getType()));
+                break;
+            default:
+                assert false;
+                return;
+        }
+    }
+
+    protected void writeHeader() {
+        // default implementation does nothing
+    }
+
+    private void writeModifiers(Set<Modifier> modifiers) {
+        if (modifiers != null) {
+            for (Modifier modifier : modifiers) {
+                write(modifier.toString());
+                write(" ");
+            }
+        }
+    }
+
+    protected void indent(int count) {
+        indent += count;
+    }
+
+    protected void dedent(int count) {
+        indent -= count;
+    }
+
+    protected void writeLn() {
+        writeLn("");
+    }
+
+    protected void writeLn(String text) {
+        write(text);
+        write(LN);
+        lineLength = 0;
+        newLine = true;
+        if (lineWrapping) {
+            dedent(LINE_WRAP_INDENTS);
+            lineWrapping = false;
+        }
+        lineWrapping = false;
+    }
+
+    protected void writeEmptyLn() {
+        writeLn();
+    }
+
+    private AbstractCodeWriter write(Name name) {
+        return write(name.toString());
+    }
+
+    private AbstractCodeWriter write(String m) {
+        try {
+            lineLength += m.length();
+            if (newLine && m != LN) {
+                writeIndent();
+                newLine = false;
+            }
+            if (lineLength > LINE_LENGTH && m.length() > 0) {
+                char firstChar = m.charAt(0);
+                if (Character.isAlphabetic(firstChar)) {
+                    if (!lineWrapping) {
+                        indent(LINE_WRAP_INDENTS);
+                    }
+                    lineWrapping = true;
+                    lineLength = 0;
+                    write(LN);
+                    writeIndent();
+                }
+            }
+            writer.write(m);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        return this;
+    }
+
+    private void writeIndent() throws IOException {
+        for (int i = 0; i < indent; i++) {
+            lineLength += IDENT_STRING.length();
+            writer.write(IDENT_STRING);
+        }
+    }
+
+    private static class TrimTrailingSpaceWriter extends Writer {
+
+        private final Writer delegate;
+        private final StringBuilder buffer = new StringBuilder();
+
+        public TrimTrailingSpaceWriter(Writer delegate) {
+            this.delegate = delegate;
+        }
+
+        @Override
+        public void close() throws IOException {
+            this.delegate.close();
+        }
+
+        @Override
+        public void flush() throws IOException {
+            this.delegate.flush();
+        }
+
+        @Override
+        public void write(char[] cbuf, int off, int len) throws IOException {
+            buffer.append(cbuf, off, len);
+            int newLinePoint = buffer.indexOf(LN);
+
+            if (newLinePoint != -1) {
+                String lhs = trimTrailing(buffer.substring(0, newLinePoint));
+                delegate.write(lhs);
+                delegate.write(LN);
+                buffer.delete(0, newLinePoint + 1);
+            }
+        }
+
+        private static String trimTrailing(String s) {
+            int cut = 0;
+            for (int i = s.length() - 1; i >= 0; i--) {
+                if (Character.isWhitespace(s.charAt(i))) {
+                    cut++;
+                } else {
+                    break;
+                }
+            }
+            if (cut > 0) {
+                return s.substring(0, s.length() - cut);
+            }
+            return s;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/codewriter/FixWarningsVisitor.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.codewriter;
+
+import static com.oracle.truffle.dsl.processor.Utils.*;
+import static javax.lang.model.element.Modifier.*;
+
+import java.io.*;
+import java.util.*;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.ast.*;
+
+public class FixWarningsVisitor extends CodeElementScanner<Void, Void> {
+
+    private final Set<String> symbolsUsed = new HashSet<>();
+
+    private final ProcessorContext context;
+    private final DeclaredType unusedAnnotation;
+    private final DeclaredType overrideType;
+
+    public FixWarningsVisitor(ProcessorContext context, DeclaredType unusedAnnotation, DeclaredType overrideType) {
+        this.context = context;
+        this.unusedAnnotation = unusedAnnotation;
+        this.overrideType = overrideType;
+    }
+
+    @Override
+    public Void visitType(CodeTypeElement e, Void p) {
+        List<TypeElement> superTypes = Utils.getSuperTypes(e);
+        for (TypeElement type : superTypes) {
+            String qualifiedName = Utils.getQualifiedName(type);
+            if (qualifiedName.equals(Serializable.class.getCanonicalName())) {
+                if (!e.containsField("serialVersionUID")) {
+                    e.add(new CodeVariableElement(modifiers(PRIVATE, STATIC, FINAL), context.getType(long.class), "serialVersionUID", "1L"));
+                }
+                break;
+            }
+        }
+
+        return super.visitType(e, p);
+    }
+
+    @Override
+    public Void visitExecutable(CodeExecutableElement e, Void p) {
+        if (e.getParameters().isEmpty()) {
+            return null;
+        } else if (e.getModifiers().contains(Modifier.ABSTRACT)) {
+            return null;
+        } else if (containsOverride(e)) {
+            return null;
+        }
+
+        symbolsUsed.clear();
+        super.visitExecutable(e, p);
+        if (e.getBodyTree() == null && e.getBody() != null) {
+            computeSymbols(e.getBody());
+        }
+
+        for (VariableElement parameter : e.getParameters()) {
+            if (!symbolsUsed.contains(parameter.getSimpleName().toString())) {
+                e.getAnnotationMirrors().add(createUnusedAnnotationMirror());
+                break;
+            }
+        }
+        return null;
+    }
+
+    private boolean containsOverride(CodeExecutableElement e) {
+        for (AnnotationMirror mirror : e.getAnnotationMirrors()) {
+            if (Utils.typeEquals(overrideType, mirror.getAnnotationType())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private CodeAnnotationMirror createUnusedAnnotationMirror() {
+        CodeAnnotationMirror mirror = new CodeAnnotationMirror(unusedAnnotation);
+        mirror.setElementValue(mirror.findExecutableElement("value"), new CodeAnnotationValue("unused"));
+        return mirror;
+    }
+
+    @Override
+    public void visitTree(CodeTree e, Void p) {
+        if (e.getString() != null) {
+            computeSymbols(e.getString());
+        }
+        super.visitTree(e, p);
+    }
+
+    private void computeSymbols(String s) {
+        // TODO there should not be any need for a StringTokenizer if we have a real AST for
+        // method bodies. Also the current solution is not perfect. What if one token
+        // is spread across multiple CodeTree instances? But for now that works.
+        StringTokenizer tokenizer = new StringTokenizer(s, ".= :,()[];{}\"\"'' ", false);
+        while (tokenizer.hasMoreElements()) {
+            String token = tokenizer.nextToken().trim();
+            if (token.length() > 0) {
+                symbolsUsed.add(token);
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/codewriter/GenerateOverrideVisitor.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.codewriter;
+
+import static com.oracle.truffle.dsl.processor.Utils.*;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.ast.*;
+
+public class GenerateOverrideVisitor extends CodeElementScanner<Void, Void> {
+
+    private final DeclaredType overrideType;
+
+    public GenerateOverrideVisitor(DeclaredType overrideType) {
+        this.overrideType = overrideType;
+    }
+
+    @Override
+    public Void visitExecutable(CodeExecutableElement e, Void p) {
+        if (!e.getModifiers().contains(Modifier.STATIC) && !e.getModifiers().contains(Modifier.PRIVATE)) {
+            String name = e.getSimpleName().toString();
+            TypeMirror[] params = e.getParameterTypes();
+
+            for (AnnotationMirror mirror : e.getAnnotationMirrors()) {
+                if (Utils.typeEquals(overrideType, mirror.getAnnotationType())) {
+                    // already declared (may happen if method copied from super class)
+                    return super.visitExecutable(e, p);
+                }
+            }
+
+            if (isDeclaredMethodInSuperType(e.getEnclosingClass(), name, params)) {
+                e.addAnnotationMirror(new CodeAnnotationMirror(overrideType));
+            }
+        }
+        return super.visitExecutable(e, p);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/codewriter/OrganizedImports.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,491 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.codewriter;
+
+import static com.oracle.truffle.dsl.processor.Utils.*;
+
+import java.util.*;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+import javax.lang.model.util.*;
+
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.ast.*;
+
+public final class OrganizedImports {
+
+    private final Set<TypeMirror> staticImportUsage = new HashSet<>();
+
+    private final Map<String, TypeMirror> simpleNamesUsed = new HashMap<>();
+
+    private final Set<String> declaredStaticMethods = new HashSet<>();
+    private final Set<String> declaredStaticFields = new HashSet<>();
+    private final Set<String> ambiguousStaticMethods = new HashSet<>();
+    private final Set<String> ambiguousStaticFields = new HashSet<>();
+
+    private final CodeTypeElement topLevelClass;
+
+    private OrganizedImports(CodeTypeElement topLevelClass) {
+        this.topLevelClass = topLevelClass;
+    }
+
+    public static OrganizedImports organize(CodeTypeElement topLevelClass) {
+        OrganizedImports organized = new OrganizedImports(topLevelClass);
+        organized.organizeImpl();
+        return organized;
+    }
+
+    private void organizeImpl() {
+        ImportTypeReferenceVisitor reference = new ImportTypeReferenceVisitor();
+        topLevelClass.accept(reference, null);
+
+        processStaticImports(topLevelClass);
+        List<TypeElement> types = Utils.getSuperTypes(topLevelClass);
+        for (TypeElement typeElement : types) {
+            processStaticImports(typeElement);
+        }
+
+        for (TypeMirror type : staticImportUsage) {
+            TypeElement element = fromTypeMirror(type);
+            if (element != null) {
+                // already processed by supertype
+                if (types.contains(element)) {
+                    continue;
+                }
+                processStaticImports(element);
+            }
+        }
+    }
+
+    public String createTypeReference(Element enclosedElement, TypeMirror type) {
+        switch (type.getKind()) {
+            case BOOLEAN:
+            case BYTE:
+            case CHAR:
+            case DOUBLE:
+            case FLOAT:
+            case SHORT:
+            case INT:
+            case LONG:
+            case VOID:
+                return Utils.getSimpleName(type);
+            case DECLARED:
+                return createDeclaredTypeName(enclosedElement, (DeclaredType) type);
+            case ARRAY:
+                return createTypeReference(enclosedElement, ((ArrayType) type).getComponentType()) + "[]";
+            case WILDCARD:
+                return createWildcardName(enclosedElement, (WildcardType) type);
+            case TYPEVAR:
+                return "?";
+            default:
+                throw new RuntimeException("Unknown type specified " + type.getKind() + " mirror: " + type);
+        }
+    }
+
+    public String createStaticFieldReference(Element enclosedElement, TypeMirror type, String fieldName) {
+        return createStaticReference(enclosedElement, type, fieldName, ambiguousStaticFields, declaredStaticFields);
+    }
+
+    public String createStaticMethodReference(Element enclosedElement, TypeMirror type, String methodName) {
+        return createStaticReference(enclosedElement, type, methodName, ambiguousStaticMethods, declaredStaticMethods);
+    }
+
+    private String createStaticReference(Element enclosedElement, TypeMirror type, String name, Set<String> ambiguousSymbols, Set<String> declaredSymbols) {
+        if (ambiguousSymbols.contains(name)) {
+            // ambiguous import
+            return createTypeReference(enclosedElement, type) + "." + name;
+        } else if (!declaredSymbols.contains(name)) {
+            // not imported at all
+            return createTypeReference(enclosedElement, type) + "." + name;
+        } else {
+            // import declared and not ambiguous
+            return name;
+        }
+    }
+
+    private String createWildcardName(Element enclosedElement, WildcardType type) {
+        StringBuilder b = new StringBuilder();
+        if (type.getExtendsBound() != null) {
+            b.append("? extends ").append(createTypeReference(enclosedElement, type.getExtendsBound()));
+        } else if (type.getSuperBound() != null) {
+            b.append("? super ").append(createTypeReference(enclosedElement, type.getExtendsBound()));
+        }
+        return b.toString();
+    }
+
+    private String createDeclaredTypeName(Element enclosedElement, DeclaredType type) {
+        String name = type.asElement().getSimpleName().toString();
+
+        if (needsImport(enclosedElement, type)) {
+            TypeMirror usedByType = simpleNamesUsed.get(name);
+            if (usedByType == null) {
+                simpleNamesUsed.put(name, type);
+                usedByType = type;
+            }
+
+            if (!typeEquals(type, usedByType)) {
+                name = getQualifiedName(type);
+            }
+        }
+
+        if (type.getTypeArguments().size() == 0) {
+            return name;
+        }
+
+        StringBuilder b = new StringBuilder(name);
+        b.append("<");
+        if (type.getTypeArguments().size() > 0) {
+            for (int i = 0; i < type.getTypeArguments().size(); i++) {
+                b.append(createTypeReference(enclosedElement, type.getTypeArguments().get(i)));
+                if (i < type.getTypeArguments().size() - 1) {
+                    b.append(", ");
+                }
+            }
+        }
+        b.append(">");
+        return b.toString();
+    }
+
+    public Set<CodeImport> generateImports() {
+        Set<CodeImport> imports = new HashSet<>();
+
+        imports.addAll(generateImports(simpleNamesUsed.values()));
+        imports.addAll(generateStaticImports(staticImportUsage));
+
+        return imports;
+    }
+
+    boolean processStaticImports(TypeElement element) {
+        Set<String> importedMethods = new HashSet<>();
+        List<ExecutableElement> methods = ElementFilter.methodsIn(element.getEnclosedElements());
+        for (ExecutableElement method : methods) {
+            if (method.getModifiers().contains(Modifier.STATIC)) {
+                importedMethods.add(method.getSimpleName().toString());
+            }
+        }
+
+        boolean allMethodsAmbiguous = processStaticImportElements(importedMethods, this.ambiguousStaticMethods, this.declaredStaticMethods);
+
+        Set<String> importedFields = new HashSet<>();
+        List<VariableElement> fields = ElementFilter.fieldsIn(element.getEnclosedElements());
+        for (VariableElement field : fields) {
+            if (field.getModifiers().contains(Modifier.STATIC)) {
+                importedFields.add(field.getSimpleName().toString());
+            }
+        }
+
+        boolean allFieldsAmbiguous = processStaticImportElements(importedFields, this.ambiguousStaticFields, this.declaredStaticFields);
+
+        return allMethodsAmbiguous && allFieldsAmbiguous;
+    }
+
+    private static boolean processStaticImportElements(Set<String> newElements, Set<String> ambiguousElements, Set<String> declaredElements) {
+        boolean allAmbiguous = false;
+        if (declaredElements.containsAll(newElements)) {
+            // all types already declared -> we can remove the import completely -> they will all
+            // get ambiguous
+            allAmbiguous = true;
+        }
+        Set<String> newAmbiguous = new HashSet<>();
+        Set<String> newDeclared = new HashSet<>();
+
+        for (String newElement : newElements) {
+            if (declaredElements.contains(newElement)) {
+                newAmbiguous.add(newElement);
+            } else if (ambiguousElements.contains(newElement)) {
+                // nothing to do
+            } else {
+                newDeclared.add(newElement);
+            }
+        }
+
+        ambiguousElements.addAll(newAmbiguous);
+        declaredElements.addAll(newDeclared);
+        return allAmbiguous;
+    }
+
+    private boolean needsImport(Element enclosedElement, TypeMirror importType) {
+        String importPackagName = getPackageName(importType);
+        if (importPackagName == null) {
+            return false;
+        } else if (importPackagName.equals("java.lang")) {
+            return false;
+        } else if (importPackagName.equals(getPackageName(topLevelClass)) && Utils.isTopLevelClass(importType)) {
+            return false; // same package name -> no import
+        }
+
+        List<Element> elements = Utils.getElementHierarchy(enclosedElement);
+
+        Set<String> autoImportedTypes = new HashSet<>();
+        for (Element element : elements) {
+            if (element.getKind().isClass()) {
+                collectSuperTypeImports((TypeElement) element, autoImportedTypes);
+                collectInnerTypeImports((TypeElement) element, autoImportedTypes);
+            }
+        }
+
+        String qualifiedName = getQualifiedName(importType);
+        if (autoImportedTypes.contains(qualifiedName)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    private static Set<CodeImport> generateImports(Collection<TypeMirror> toGenerate) {
+        TreeSet<CodeImport> importObjects = new TreeSet<>();
+        for (TypeMirror importType : toGenerate) {
+            importObjects.add(new CodeImport(importType, getQualifiedName(importType), false));
+        }
+        return importObjects;
+    }
+
+    private static void collectInnerTypeImports(TypeElement e, Set<String> autoImportedTypes) {
+        autoImportedTypes.add(getQualifiedName(e));
+        for (TypeElement innerClass : ElementFilter.typesIn(e.getEnclosedElements())) {
+            collectInnerTypeImports(innerClass, autoImportedTypes);
+        }
+    }
+
+    private static void collectSuperTypeImports(TypeElement e, Set<String> autoImportedTypes) {
+        List<TypeElement> superTypes = getSuperTypes(e);
+        for (TypeElement superType : superTypes) {
+            List<TypeElement> declaredTypes = getDeclaredTypes(superType);
+            for (TypeElement declaredType : declaredTypes) {
+                autoImportedTypes.add(getQualifiedName(declaredType));
+            }
+        }
+    }
+
+    private Set<CodeImport> generateStaticImports(Set<TypeMirror> toGenerate) {
+        Set<String> autoImportedStaticTypes = new HashSet<>();
+
+        // if type is declared inside a super type of this class -> no import
+        autoImportedStaticTypes.add(getQualifiedName(topLevelClass));
+        autoImportedStaticTypes.addAll(getQualifiedSuperTypeNames(topLevelClass));
+
+        TreeSet<CodeImport> importObjects = new TreeSet<>();
+        for (TypeMirror importType : toGenerate) {
+            if (getPackageName(importType) == null) {
+                continue; // no package name -> no import
+            }
+
+            String qualifiedName = getQualifiedName(importType);
+            if (autoImportedStaticTypes.contains(qualifiedName)) {
+                continue;
+            }
+
+            importObjects.add(new CodeImport(importType, qualifiedName + ".*", true));
+        }
+
+        return importObjects;
+    }
+
+    private abstract static class TypeReferenceVisitor extends CodeElementScanner<Void, Void> {
+
+        @Override
+        public void visitTree(CodeTree e, Void p) {
+            if (e.getCodeKind() == CodeTreeKind.STATIC_FIELD_REFERENCE) {
+                visitStaticFieldReference(e, e.getType(), e.getString());
+            } else if (e.getCodeKind() == CodeTreeKind.STATIC_METHOD_REFERENCE) {
+                visitStaticMethodReference(e, e.getType(), e.getString());
+            } else if (e.getType() != null) {
+                visitTypeReference(e, e.getType());
+            }
+            super.visitTree(e, p);
+        }
+
+        @Override
+        public Void visitExecutable(CodeExecutableElement e, Void p) {
+            visitAnnotations(e, e.getAnnotationMirrors());
+            if (e.getReturnType() != null) {
+                visitTypeReference(e, e.getReturnType());
+            }
+            for (TypeMirror type : e.getThrownTypes()) {
+                visitTypeReference(e, type);
+            }
+            return super.visitExecutable(e, p);
+        }
+
+        @Override
+        public Void visitType(CodeTypeElement e, Void p) {
+            visitAnnotations(e, e.getAnnotationMirrors());
+
+            visitTypeReference(e, e.getSuperclass());
+            for (TypeMirror type : e.getImplements()) {
+                visitTypeReference(e, type);
+            }
+
+            return super.visitType(e, p);
+        }
+
+        private void visitAnnotations(Element enclosingElement, List<? extends AnnotationMirror> mirrors) {
+            for (AnnotationMirror mirror : mirrors) {
+                visitAnnotation(enclosingElement, mirror);
+            }
+        }
+
+        public void visitAnnotation(Element enclosingElement, AnnotationMirror e) {
+            visitTypeReference(enclosingElement, e.getAnnotationType());
+            if (!e.getElementValues().isEmpty()) {
+                Map<? extends ExecutableElement, ? extends AnnotationValue> values = e.getElementValues();
+                Set<? extends ExecutableElement> methodsSet = values.keySet();
+                List<ExecutableElement> methodsList = new ArrayList<>();
+                for (ExecutableElement method : methodsSet) {
+                    if (values.get(method) == null) {
+                        continue;
+                    }
+                    methodsList.add(method);
+                }
+
+                for (int i = 0; i < methodsList.size(); i++) {
+                    AnnotationValue value = values.get(methodsList.get(i));
+                    visitAnnotationValue(enclosingElement, value);
+                }
+            }
+        }
+
+        public void visitAnnotationValue(Element enclosingElement, AnnotationValue e) {
+            e.accept(new AnnotationValueReferenceVisitor(enclosingElement), null);
+        }
+
+        private class AnnotationValueReferenceVisitor extends AbstractAnnotationValueVisitor7<Void, Void> {
+
+            private final Element enclosingElement;
+
+            public AnnotationValueReferenceVisitor(Element enclosedElement) {
+                this.enclosingElement = enclosedElement;
+            }
+
+            @Override
+            public Void visitBoolean(boolean b, Void p) {
+                return null;
+            }
+
+            @Override
+            public Void visitByte(byte b, Void p) {
+                return null;
+            }
+
+            @Override
+            public Void visitChar(char c, Void p) {
+                return null;
+            }
+
+            @Override
+            public Void visitDouble(double d, Void p) {
+                return null;
+            }
+
+            @Override
+            public Void visitFloat(float f, Void p) {
+                return null;
+            }
+
+            @Override
+            public Void visitInt(int i, Void p) {
+                return null;
+            }
+
+            @Override
+            public Void visitLong(long i, Void p) {
+                return null;
+            }
+
+            @Override
+            public Void visitShort(short s, Void p) {
+                return null;
+            }
+
+            @Override
+            public Void visitString(String s, Void p) {
+                return null;
+            }
+
+            @Override
+            public Void visitType(TypeMirror t, Void p) {
+                visitTypeReference(enclosingElement, t);
+                return null;
+            }
+
+            @Override
+            public Void visitEnumConstant(VariableElement c, Void p) {
+                visitTypeReference(enclosingElement, c.asType());
+                return null;
+            }
+
+            @Override
+            public Void visitAnnotation(AnnotationMirror a, Void p) {
+                TypeReferenceVisitor.this.visitAnnotation(enclosingElement, a);
+                return null;
+            }
+
+            @Override
+            public Void visitArray(List<? extends AnnotationValue> vals, Void p) {
+                for (int i = 0; i < vals.size(); i++) {
+                    TypeReferenceVisitor.this.visitAnnotationValue(enclosingElement, vals.get(i));
+                }
+                return null;
+            }
+        }
+
+        @Override
+        public Void visitVariable(VariableElement f, Void p) {
+            visitAnnotations(f, f.getAnnotationMirrors());
+            visitTypeReference(f, f.asType());
+            return super.visitVariable(f, p);
+        }
+
+        @Override
+        public void visitImport(CodeImport e, Void p) {
+        }
+
+        public abstract void visitTypeReference(Element enclosedType, TypeMirror type);
+
+        public abstract void visitStaticMethodReference(Element enclosedType, TypeMirror type, String elementName);
+
+        public abstract void visitStaticFieldReference(Element enclosedType, TypeMirror type, String elementName);
+
+    }
+
+    private class ImportTypeReferenceVisitor extends TypeReferenceVisitor {
+
+        @Override
+        public void visitStaticFieldReference(Element enclosedType, TypeMirror type, String elementName) {
+            staticImportUsage.add(type);
+        }
+
+        @Override
+        public void visitStaticMethodReference(Element enclosedType, TypeMirror type, String elementName) {
+            staticImportUsage.add(type);
+        }
+
+        @Override
+        public void visitTypeReference(Element enclosedType, TypeMirror type) {
+            createTypeReference(enclosedType, type);
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/AbstractCompiler.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.compiler;
+
+import java.lang.reflect.*;
+
+public abstract class AbstractCompiler implements Compiler {
+
+    protected static Object method(Object o, String methodName) throws Exception {
+        Method method = o.getClass().getMethod(methodName);
+        method.setAccessible(true);
+        return method.invoke(o);
+    }
+
+    protected static Object method(Object o, String methodName, Class[] paramTypes, Object... values) throws Exception {
+        Method method = o.getClass().getMethod(methodName, paramTypes);
+        method.setAccessible(true);
+        return method.invoke(o, values);
+    }
+
+    protected static Object field(Object o, String fieldName) throws Exception {
+        if (o == null) {
+            return null;
+        }
+        Field field = o.getClass().getField(fieldName);
+        field.setAccessible(true);
+        return field.get(o);
+    }
+
+    protected static String parseHeader(String content) {
+        int index = content.indexOf("/*");
+        if (index == -1) {
+            return null;
+        }
+        if (!content.substring(0, index).trim().equals("")) {
+            // just whitespace before
+            return null;
+        }
+
+        int endIndex = content.indexOf("*/", index);
+        if (endIndex == -1) {
+            return null;
+        }
+        return content.substring(index, endIndex + 2);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/Compiler.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.compiler;
+
+import javax.annotation.processing.*;
+import javax.lang.model.element.*;
+
+public interface Compiler {
+
+    String getMethodBody(ProcessingEnvironment env, ExecutableElement method);
+
+    String getHeaderComment(ProcessingEnvironment env, Element type);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/CompilerFactory.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.compiler;
+
+import javax.lang.model.element.*;
+
+public class CompilerFactory {
+
+    private static Compiler javac;
+    private static Compiler jdt;
+
+    public static Compiler getCompiler(Element currentElement) {
+        if (JavaCCompiler.isValidElement(currentElement)) {
+            if (javac == null) {
+                javac = new JavaCCompiler();
+            }
+            return javac;
+        } else if (JDTCompiler.isValidElement(currentElement)) {
+            if (jdt == null) {
+                jdt = new JDTCompiler();
+            }
+            return jdt;
+        } else {
+            throw new UnsupportedOperationException("Unsupported compiler for element " + currentElement.getClass().getName() + ".");
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/JDTCompiler.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.compiler;
+
+import javax.annotation.processing.*;
+import javax.lang.model.element.*;
+
+import com.oracle.truffle.dsl.processor.*;
+
+public class JDTCompiler extends AbstractCompiler {
+
+    public static boolean isValidElement(Element currentElement) {
+        try {
+            Class<?> elementClass = Class.forName("org.eclipse.jdt.internal.compiler.apt.model.ElementImpl");
+            return elementClass.isAssignableFrom(currentElement.getClass());
+        } catch (ClassNotFoundException e) {
+            return false;
+        }
+    }
+
+    @Override
+    public String getMethodBody(ProcessingEnvironment env, ExecutableElement method) {
+        try {
+
+            char[] source = getSource(method);
+            if (source == null) {
+                return null;
+            }
+
+            /*
+             * AbstractMethodDeclaration decl =
+             * ((MethodBinding)(((ElementImpl)method)._binding)).sourceMethod(); int bodyStart =
+             * decl.bodyStart; int bodyEnd = decl.bodyEnd;
+             */
+            Object decl = method(field(method, "_binding"), "sourceMethod");
+            int bodyStart = (int) field(decl, "bodyStart");
+            int bodyEnd = (int) field(decl, "bodyEnd");
+
+            int length = bodyEnd - bodyStart;
+            char[] target = new char[length];
+            System.arraycopy(source, bodyStart, target, 0, length);
+
+            return new String(target);
+        } catch (Exception e) {
+            return Utils.printException(e);
+        }
+    }
+
+    private static char[] getSource(Element element) throws Exception {
+        /*
+         * Binding binding = ((ElementImpl)element)._binding; char[] source = null; if (binding
+         * instanceof MethodBinding) { source = ((MethodBinding)
+         * binding).sourceMethod().compilationResult.getCompilationUnit().getContents(); } else if
+         * (binding instanceof SourceTypeBinding) { source =
+         * ((SourceTypeBinding)binding).scope.referenceContext
+         * .compilationResult.compilationUnit.getContents(); } return source;
+         */
+
+        Object binding = field(element, "_binding");
+        Class<?> methodBindingClass = Class.forName("org.eclipse.jdt.internal.compiler.lookup.MethodBinding");
+        Class<?> referenceBindingClass = Class.forName("org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding");
+
+        char[] source = null;
+        if (methodBindingClass.isAssignableFrom(binding.getClass())) {
+            Object sourceMethod = method(binding, "sourceMethod");
+            if (sourceMethod == null) {
+                return null;
+            }
+            source = (char[]) method(method(field(sourceMethod, "compilationResult"), "getCompilationUnit"), "getContents");
+        } else if (referenceBindingClass.isAssignableFrom(binding.getClass())) {
+            source = (char[]) method(field(field(field(field(binding, "scope"), "referenceContext"), "compilationResult"), "compilationUnit"), "getContents");
+        }
+        return source;
+    }
+
+    @Override
+    public String getHeaderComment(ProcessingEnvironment env, Element type) {
+        try {
+            char[] source = getSource(type);
+            if (source == null) {
+                return null;
+            }
+            return parseHeader(new String(source));
+        } catch (Exception e) {
+            return Utils.printException(e);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/JavaCCompiler.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.compiler;
+
+import javax.annotation.processing.*;
+import javax.lang.model.element.*;
+
+import com.oracle.truffle.dsl.processor.*;
+
+public class JavaCCompiler extends AbstractCompiler {
+
+    public static boolean isValidElement(Element currentElement) {
+        try {
+            Class<?> elementClass = Class.forName("com.sun.tools.javac.code.Symbol");
+            return elementClass.isAssignableFrom(currentElement.getClass());
+        } catch (ClassNotFoundException e) {
+            return false;
+        }
+    }
+
+    private static final Class[] getTreeAndTopLevelSignature = new Class[]{Element.class, AnnotationMirror.class, AnnotationValue.class};
+    private static final Class[] getCharContentSignature = new Class[]{boolean.class};
+
+    @Override
+    public String getMethodBody(ProcessingEnvironment env, ExecutableElement method) {
+        try {
+            /*
+             * if (false) { Pair<JCTree, JCCompilationUnit> treeAndTopLevel = ((JavacElements)
+             * env.getElementUtils()).getTreeAndTopLevel(method, null, null); JCBlock block =
+             * ((JCMethodDecl) treeAndTopLevel.fst).getBody(); int startPos = block.pos; int endPos
+             * = block.endpos; String methodBody =
+             * treeAndTopLevel.snd.getSourceFile().getCharContent(true).subSequence(startPos + 1,
+             * endPos).toString(); return methodBody; }
+             */
+
+            Object treeAndTopLevel = getTreeAndTopLevel(env, method);
+            Object block = method(field(treeAndTopLevel, "fst"), "getBody");
+            int startPos = (int) field(block, "pos");
+            int endPos = (int) field(block, "endpos");
+            return getContent(treeAndTopLevel).subSequence(startPos + 1, endPos).toString();
+        } catch (Exception e) {
+            return Utils.printException(e);
+        }
+    }
+
+    private static CharSequence getContent(Object treeAndTopLevel) throws Exception {
+        /*
+         * CharSequence content = treeAndTopLevel.snd.getSourceFile().getCharContent(true);
+         */
+        return (CharSequence) method(method(field(treeAndTopLevel, "snd"), "getSourceFile"), "getCharContent", getCharContentSignature, true);
+    }
+
+    private static Object getTreeAndTopLevel(ProcessingEnvironment env, Element element) throws Exception {
+        /*
+         * Pair<JCTree, JCCompilationUnit> treeAndTopLevel = ((JavacElements)
+         * env.getElementUtils()).getTreeAndTopLevel(method, null, null);
+         */
+        return method(method(env, "getElementUtils"), "getTreeAndTopLevel", getTreeAndTopLevelSignature, element, null, null);
+    }
+
+    @Override
+    public String getHeaderComment(ProcessingEnvironment env, Element type) {
+        try {
+            String content = getContent(getTreeAndTopLevel(env, type)).toString();
+            return parseHeader(content);
+        } catch (Exception e) {
+            return Utils.printException(e);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/CreateCastData.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.node;
+
+import java.util.*;
+
+import com.oracle.truffle.dsl.processor.template.*;
+
+public class CreateCastData extends TemplateMethod {
+
+    private final List<String> childNames;
+
+    public CreateCastData(TemplateMethod method, List<String> childNames) {
+        super(method);
+        this.childNames = childNames;
+    }
+
+    public List<String> getChildNames() {
+        return childNames;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/CreateCastParser.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.node;
+
+import java.lang.annotation.*;
+import java.util.*;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.template.*;
+
+public class CreateCastParser extends NodeMethodParser<CreateCastData> {
+
+    public CreateCastParser(ProcessorContext context, NodeData operation) {
+        super(context, operation);
+    }
+
+    @Override
+    public Class<? extends Annotation> getAnnotationType() {
+        return CreateCast.class;
+    }
+
+    @Override
+    public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
+        List<String> childNames = Utils.getAnnotationValueList(String.class, mirror, "value");
+        TypeMirror baseType = getContext().getTruffleTypes().getNode();
+        for (String childName : childNames) {
+            NodeChildData child = getNode().findChild(childName);
+            if (child != null) {
+                baseType = child.getOriginalType();
+                break;
+            }
+        }
+        MethodSpec spec = new MethodSpec(new InheritsParameterSpec(getContext(), "child", baseType));
+        addDefaultFieldMethodSpec(method, spec);
+        spec.addRequired(new ParameterSpec("castedChild", baseType)).setSignature(true);
+        return spec;
+    }
+
+    @Override
+    public CreateCastData create(TemplateMethod method) {
+        AnnotationMirror mirror = method.getMarkerAnnotation();
+        List<String> childNames = Utils.getAnnotationValueList(String.class, mirror, "value");
+        CreateCastData cast = new CreateCastData(method, childNames);
+        AnnotationValue value = Utils.getAnnotationValue(mirror, "value");
+        TypeMirror type = null;
+        if (childNames == null || childNames.isEmpty()) {
+            cast.addError(value, "No value specified but required.");
+            return cast;
+        }
+
+        for (String childName : childNames) {
+            NodeChildData child = getNode().findChild(childName);
+            if (child == null) {
+                // error
+                cast.addError(value, "Specified child '%s' not found.", childName);
+                continue;
+            }
+            if (type == null) {
+                type = child.getNodeType();
+            } else if (!Utils.typeEquals(type, child.getNodeType())) {
+                cast.addError(value, "All child nodes for a cast must have the same node type.");
+                continue;
+            }
+        }
+        return cast;
+    }
+
+    private static class InheritsParameterSpec extends ParameterSpec {
+
+        private final ProcessorContext context;
+
+        public InheritsParameterSpec(ProcessorContext context, String name, TypeMirror... allowedTypes) {
+            super(name, Arrays.asList(allowedTypes));
+            this.context = context;
+        }
+
+        @Override
+        public boolean matches(TypeMirror actualType) {
+            boolean found = false;
+            for (TypeMirror specType : getAllowedTypes()) {
+                if (Utils.isAssignable(context, actualType, specType)) {
+                    found = true;
+                    break;
+                }
+            }
+            return found;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ExecutableTypeData.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.node;
+
+import javax.lang.model.element.*;
+
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.template.*;
+import com.oracle.truffle.dsl.processor.typesystem.*;
+
+public class ExecutableTypeData extends TemplateMethod {
+
+    private final TypeSystemData typeSystem;
+    private final TypeData type;
+
+    public ExecutableTypeData(TemplateMethod method, ExecutableElement executable, TypeSystemData typeSystem, TypeData type) {
+        super(method, executable);
+        this.typeSystem = typeSystem;
+        this.type = type;
+    }
+
+    public TypeData getType() {
+        return type;
+    }
+
+    public TypeSystemData getTypeSystem() {
+        return typeSystem;
+    }
+
+    public boolean hasFrame() {
+        return getMethod().getParameters().size() > 0;
+    }
+
+    public boolean hasUnexpectedValue(ProcessorContext context) {
+        return Utils.canThrowType(getMethod().getThrownTypes(), context.getTruffleTypes().getUnexpectedValueException());
+    }
+
+    public boolean isFinal() {
+        return getMethod().getModifiers().contains(Modifier.FINAL);
+    }
+
+    public boolean isAbstract() {
+        return getMethod().getModifiers().contains(Modifier.ABSTRACT);
+    }
+
+    public int getEvaluatedCount() {
+        int count = 0;
+        for (ActualParameter parameter : getParameters()) {
+            if (parameter.getSpecification().isSignature()) {
+                count++;
+            }
+        }
+        return count;
+    }
+
+    @Override
+    public int hashCode() {
+        return type.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof ExecutableTypeData) {
+            return type.equals(((ExecutableTypeData) obj).type);
+        }
+        return super.equals(obj);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ExecutableTypeMethodParser.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.node;
+
+import java.lang.annotation.*;
+import java.util.*;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.node.NodeChildData.*;
+import com.oracle.truffle.dsl.processor.template.*;
+import com.oracle.truffle.dsl.processor.typesystem.*;
+
+public class ExecutableTypeMethodParser extends NodeMethodParser<ExecutableTypeData> {
+
+    public ExecutableTypeMethodParser(ProcessorContext context, NodeData node) {
+        super(context, node);
+        setEmitErrors(false);
+        setParseNullOnError(false);
+    }
+
+    @Override
+    public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
+        MethodSpec spec = createDefaultMethodSpec(method, mirror, false, null);
+        List<ParameterSpec> requiredSpecs = new ArrayList<>(spec.getRequired());
+        spec.getRequired().clear();
+
+        for (ParameterSpec originalSpec : requiredSpecs) {
+            spec.addRequired(new ParameterSpec(originalSpec, Arrays.asList(getNode().getTypeSystem().getGenericType())));
+        }
+
+        spec.setVariableRequiredArguments(true);
+        ParameterSpec other = new ParameterSpec("other", Arrays.asList(getNode().getTypeSystem().getGenericType()));
+        other.setCardinality(Cardinality.MANY);
+        other.setSignature(true);
+        other.setIndexed(true);
+        spec.addRequired(other);
+        return spec;
+    }
+
+    @Override
+    public final boolean isParsable(ExecutableElement method) {
+        if (method.getModifiers().contains(Modifier.STATIC)) {
+            return false;
+        } else if (method.getModifiers().contains(Modifier.NATIVE)) {
+            return false;
+        }
+        return method.getSimpleName().toString().startsWith("execute");
+    }
+
+    @Override
+    protected List<TypeMirror> nodeTypeMirrors(NodeData nodeData) {
+        // executable types not yet available
+        List<TypeMirror> types = new ArrayList<>(nodeData.getTypeSystem().getPrimitiveTypeMirrors());
+        types.add(nodeData.getTypeSystem().getVoidType().getPrimitiveType());
+        return types;
+    }
+
+    @Override
+    public ExecutableTypeData create(TemplateMethod method) {
+        TypeData resolvedType = method.getReturnType().getTypeSystemType();
+        return new ExecutableTypeData(method, method.getMethod(), getNode().getTypeSystem(), resolvedType);
+    }
+
+    @Override
+    public Class<? extends Annotation> getAnnotationType() {
+        return null;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/GenericParser.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.node;
+
+import java.lang.annotation.*;
+import java.util.*;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.template.*;
+
+public class GenericParser extends NodeMethodParser<SpecializationData> {
+
+    public GenericParser(ProcessorContext context, NodeData node) {
+        super(context, node);
+    }
+
+    @Override
+    public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
+        return createDefaultMethodSpec(method, mirror, true, null);
+    }
+
+    @Override
+    protected ParameterSpec createValueParameterSpec(String valueName, NodeData nodeData, int evaluatedCount) {
+        List<ExecutableTypeData> execTypes = nodeData.findGenericExecutableTypes(getContext(), evaluatedCount);
+        List<TypeMirror> types = new ArrayList<>();
+        for (ExecutableTypeData type : execTypes) {
+            types.add(type.getType().getPrimitiveType());
+        }
+        ParameterSpec spec = new ParameterSpec(valueName, types);
+        spec.setSignature(true);
+        return spec;
+    }
+
+    @Override
+    protected ParameterSpec createReturnParameterSpec() {
+        return super.createValueParameterSpec("returnValue", getNode(), 0);
+    }
+
+    @Override
+    public SpecializationData create(TemplateMethod method) {
+        SpecializationData data = new SpecializationData(method, true, false, false);
+        return data;
+    }
+
+    @Override
+    public Class<? extends Annotation> getAnnotationType() {
+        return Generic.class;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeChildData.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.node;
+
+import java.util.*;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.template.*;
+import com.oracle.truffle.dsl.processor.typesystem.*;
+
+public class NodeChildData extends MessageContainer {
+
+    public enum Cardinality {
+        ONE, MANY;
+
+        public boolean isMany() {
+            return this == MANY;
+        }
+
+        public boolean isOne() {
+            return this == ONE;
+        }
+    }
+
+    public enum ExecutionKind {
+        DEFAULT, SHORT_CIRCUIT
+    }
+
+    private final Element sourceElement;
+    private final AnnotationMirror sourceAnnotationMirror;
+
+    private final String name;
+    private final TypeMirror type;
+    private final TypeMirror originalType;
+    private final Element accessElement;
+
+    private final Cardinality cardinality;
+    private final ExecutionKind executionKind;
+
+    private List<NodeChildData> executeWith = Collections.emptyList();
+
+    private NodeData nodeData;
+
+    public NodeChildData(Element sourceElement, AnnotationMirror sourceMirror, String name, TypeMirror nodeType, TypeMirror originalNodeType, Element accessElement, Cardinality cardinality,
+                    ExecutionKind executionKind) {
+        this.sourceElement = sourceElement;
+        this.sourceAnnotationMirror = sourceMirror;
+        this.name = name;
+        this.type = nodeType;
+        this.originalType = originalNodeType;
+        this.accessElement = accessElement;
+        this.cardinality = cardinality;
+        this.executionKind = executionKind;
+    }
+
+    public List<NodeChildData> getExecuteWith() {
+        return executeWith;
+    }
+
+    void setExecuteWith(List<NodeChildData> executeWith) {
+        this.executeWith = executeWith;
+    }
+
+    public ExecutableTypeData findExecutableType(ProcessorContext context, TypeData targetType) {
+        ExecutableTypeData executableType = nodeData.findExecutableType(targetType, getExecuteWith().size());
+        if (executableType == null) {
+            executableType = findAnyGenericExecutableType(context);
+        }
+        return executableType;
+    }
+
+    public List<ExecutableTypeData> findGenericExecutableTypes(ProcessorContext context) {
+        return nodeData.findGenericExecutableTypes(context, getExecuteWith().size());
+    }
+
+    public ExecutableTypeData findAnyGenericExecutableType(ProcessorContext context) {
+        return nodeData.findAnyGenericExecutableType(context, getExecuteWith().size());
+    }
+
+    public List<ExecutableTypeData> findExecutableTypes() {
+        return nodeData.getExecutableTypes(getExecuteWith().size());
+    }
+
+    public TypeMirror getOriginalType() {
+        return originalType;
+    }
+
+    @Override
+    public Element getMessageElement() {
+        return sourceElement;
+    }
+
+    @Override
+    public AnnotationMirror getMessageAnnotation() {
+        return sourceAnnotationMirror;
+    }
+
+    public boolean isShortCircuit() {
+        return executionKind == ExecutionKind.SHORT_CIRCUIT;
+    }
+
+    void setNode(NodeData nodeData) {
+        this.nodeData = nodeData;
+        if (nodeData != null) {
+            getMessages().addAll(nodeData.collectMessages());
+        }
+    }
+
+    public Element getAccessElement() {
+        return accessElement;
+    }
+
+    public TypeMirror getNodeType() {
+        return type;
+    }
+
+    public Cardinality getCardinality() {
+        return cardinality;
+    }
+
+    public ExecutionKind getExecutionKind() {
+        return executionKind;
+    }
+
+    public NodeData getNodeData() {
+        return nodeData;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String toString() {
+        return "NodeFieldData[name=" + getName() + ", kind=" + cardinality + ", execution=" + executionKind + ", node=" + getNodeData() + "]";
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,2437 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.node;
+
+import static com.oracle.truffle.dsl.processor.Utils.*;
+import static javax.lang.model.element.Modifier.*;
+
+import java.util.*;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+import javax.lang.model.util.*;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.nodes.NodeInfo.Kind;
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.ast.*;
+import com.oracle.truffle.dsl.processor.node.NodeChildData.*;
+import com.oracle.truffle.dsl.processor.template.*;
+import com.oracle.truffle.dsl.processor.typesystem.*;
+
+public class NodeCodeGenerator extends CompilationUnitFactory<NodeData> {
+
+    private static final String THIS_NODE_LOCAL_VAR_NAME = "thisNode";
+
+    private static final String EXECUTE_GENERIC_NAME = "executeGeneric0";
+    private static final String EXECUTE_SPECIALIZE_NAME = "executeAndSpecialize0";
+
+    public NodeCodeGenerator(ProcessorContext context) {
+        super(context);
+    }
+
+    private TypeMirror getUnexpectedValueException() {
+        return getContext().getTruffleTypes().getUnexpectedValueException();
+    }
+
+    private static String factoryClassName(NodeData node) {
+        return node.getNodeId() + "Factory";
+    }
+
+    private static String nodeSpecializationClassName(SpecializationData specialization) {
+        String nodeid = specialization.getNode().getNodeId();
+        if (nodeid.endsWith("Node") && !nodeid.equals("Node")) {
+            nodeid = nodeid.substring(0, nodeid.length() - 4);
+        }
+
+        String name = Utils.firstLetterUpperCase(nodeid);
+        name += Utils.firstLetterUpperCase(specialization.getId());
+        name += "Node";
+        return name;
+    }
+
+    private static String nodePolymorphicClassName(NodeData node, SpecializationData specialization) {
+        String nodeid = node.getNodeId();
+        if (nodeid.endsWith("Node") && !nodeid.equals("Node")) {
+            nodeid = nodeid.substring(0, nodeid.length() - 4);
+        }
+
+        String name = Utils.firstLetterUpperCase(nodeid);
+        int index = specialization == null ? 0 : node.getPolymorphicSpecializations().indexOf(specialization);
+        if (index == 0) {
+            name += "PolymorphicNode";
+        } else {
+            name += "Polymorphic" + index + "Node";
+        }
+        return name;
+    }
+
+    private static String valueNameEvaluated(ActualParameter targetParameter) {
+        return valueName(targetParameter) + "Evaluated";
+    }
+
+    private static String valueName(ActualParameter param) {
+        return param.getLocalName();
+    }
+
+    private static String castValueName(ActualParameter parameter) {
+        return valueName(parameter) + "Cast";
+    }
+
+    private void addInternalValueParameters(CodeExecutableElement method, TemplateMethod specialization, boolean forceFrame, boolean evaluated) {
+        if (forceFrame && specialization.getSpecification().findParameterSpec("frame") != null) {
+            method.addParameter(new CodeVariableElement(getContext().getTruffleTypes().getFrame(), "frameValue"));
+        }
+        for (ActualParameter parameter : specialization.getParameters()) {
+            ParameterSpec spec = parameter.getSpecification();
+            if (forceFrame && spec.getName().equals("frame")) {
+                continue;
+            }
+            if (spec.isLocal()) {
+                continue;
+            }
+
+            String name = valueName(parameter);
+            if (evaluated && spec.isSignature()) {
+                name = valueNameEvaluated(parameter);
+            }
+
+            method.addParameter(new CodeVariableElement(parameter.getType(), name));
+        }
+    }
+
+    private void addInternalValueParameterNames(CodeTreeBuilder builder, TemplateMethod source, TemplateMethod specialization, String unexpectedValueName, boolean forceFrame, boolean includeImplicit) {
+        if (forceFrame && specialization.getSpecification().findParameterSpec("frame") != null) {
+            builder.string("frameValue");
+        }
+        for (ActualParameter parameter : specialization.getParameters()) {
+            ParameterSpec spec = parameter.getSpecification();
+            if (forceFrame && spec.getName().equals("frame")) {
+                continue;
+            }
+
+            if (!includeImplicit && (parameter.isImplicit())) {
+                continue;
+            }
+            if (parameter.getSpecification().isLocal()) {
+                continue;
+            }
+
+            ActualParameter sourceParameter = source.findParameter(parameter.getLocalName());
+
+            if (unexpectedValueName != null && parameter.getLocalName().equals(unexpectedValueName)) {
+                builder.cast(parameter.getType(), CodeTreeBuilder.singleString("ex.getResult()"));
+            } else if (sourceParameter != null) {
+                builder.string(valueName(sourceParameter, parameter));
+            } else {
+                builder.string(valueName(parameter));
+            }
+        }
+    }
+
+    private String valueName(ActualParameter sourceParameter, ActualParameter targetParameter) {
+        if (sourceParameter != null) {
+            if (!sourceParameter.getSpecification().isSignature()) {
+                return valueName(targetParameter);
+            } else if (sourceParameter.getTypeSystemType() != null && targetParameter.getTypeSystemType() != null) {
+                if (sourceParameter.getTypeSystemType().needsCastTo(getContext(), targetParameter.getTypeSystemType())) {
+                    return castValueName(targetParameter);
+                }
+            }
+            return valueName(targetParameter);
+        } else {
+            return valueName(targetParameter);
+        }
+    }
+
+    private CodeTree createTemplateMethodCall(CodeTreeBuilder parent, CodeTree target, TemplateMethod sourceMethod, TemplateMethod targetMethod, String unexpectedValueName,
+                    String... customSignatureValueNames) {
+        CodeTreeBuilder builder = parent.create();
+
+        boolean castedValues = sourceMethod != targetMethod;
+
+        builder.startGroup();
+        ExecutableElement method = targetMethod.getMethod();
+        if (method == null) {
+            throw new UnsupportedOperationException();
+        }
+        TypeElement targetClass = Utils.findNearestEnclosingType(method.getEnclosingElement());
+        NodeData node = (NodeData) targetMethod.getTemplate();
+
+        if (target == null) {
+            boolean accessible = targetMethod.canBeAccessedByInstanceOf(getContext(), node.getNodeType());
+            if (accessible) {
+                if (builder.findMethod().getModifiers().contains(STATIC)) {
+                    if (method.getModifiers().contains(STATIC)) {
+                        builder.type(targetClass.asType());
+                    } else {
+                        builder.string(THIS_NODE_LOCAL_VAR_NAME);
+                    }
+                } else {
+                    if (targetMethod instanceof ExecutableTypeData) {
+                        builder.string("this");
+                    } else {
+                        builder.string("super");
+                    }
+                }
+            } else {
+                if (method.getModifiers().contains(STATIC)) {
+                    builder.type(targetClass.asType());
+                } else {
+                    ActualParameter parameter = null;
+                    for (ActualParameter searchParameter : targetMethod.getParameters()) {
+                        if (searchParameter.getSpecification().isSignature()) {
+                            parameter = searchParameter;
+                            break;
+                        }
+                    }
+                    ActualParameter sourceParameter = sourceMethod.findParameter(parameter.getLocalName());
+                    assert parameter != null;
+
+                    if (castedValues && sourceParameter != null) {
+                        builder.string(valueName(sourceParameter, parameter));
+                    } else {
+                        builder.string(valueName(parameter));
+                    }
+                }
+            }
+            builder.string(".");
+        } else {
+            builder.tree(target);
+        }
+        builder.startCall(method.getSimpleName().toString());
+
+        int signatureIndex = 0;
+
+        for (ActualParameter targetParameter : targetMethod.getParameters()) {
+            ActualParameter valueParameter = null;
+            if (sourceMethod != null) {
+                valueParameter = sourceMethod.findParameter(targetParameter.getLocalName());
+            }
+            if (valueParameter == null) {
+                valueParameter = targetParameter;
+            }
+            TypeData targetType = targetParameter.getTypeSystemType();
+
+            if (targetParameter.isImplicit() || valueParameter.isImplicit()) {
+                continue;
+            }
+
+            TypeData valueType = null;
+            if (valueParameter != null) {
+                valueType = valueParameter.getTypeSystemType();
+            }
+
+            if (signatureIndex < customSignatureValueNames.length && targetParameter.getSpecification().isSignature()) {
+                builder.string(customSignatureValueNames[signatureIndex]);
+                signatureIndex++;
+            } else if (targetParameter.getSpecification().isLocal()) {
+                builder.startGroup();
+                if (builder.findMethod().getModifiers().contains(Modifier.STATIC)) {
+                    builder.string(THIS_NODE_LOCAL_VAR_NAME).string(".");
+                } else {
+                    builder.string("this.");
+                }
+                builder.string(targetParameter.getSpecification().getName());
+                builder.end();
+            } else if (unexpectedValueName != null && targetParameter.getLocalName().equals(unexpectedValueName)) {
+                builder.string("ex.getResult()");
+            } else if (targetType == null || targetType.isGeneric() || (valueType != null && valueType.equalsType(targetType))) {
+                builder.startGroup();
+
+                if (valueType != null && sourceMethod.getMethodName().equals(targetMethod.getMethodName()) && !valueType.isGeneric() && targetType.isGeneric()) {
+                    builder.string("(");
+                    builder.type(targetType.getPrimitiveType());
+                    builder.string(") ");
+                }
+                builder.string(valueName(targetParameter));
+                builder.end();
+            } else {
+                builder.string(castValueName(targetParameter));
+            }
+        }
+
+        builder.end().end();
+
+        return builder.getRoot();
+    }
+
+    private static String baseClassName(NodeData node) {
+        String nodeid = node.getNodeId();
+        if (nodeid.endsWith("Node") && !nodeid.equals("Node")) {
+            nodeid = nodeid.substring(0, nodeid.length() - 4);
+        }
+        String name = Utils.firstLetterUpperCase(nodeid);
+        name += "BaseNode";
+        return name;
+    }
+
+    private static CodeTree createCallTypeSystemMethod(ProcessorContext context, CodeTreeBuilder parent, NodeData node, String methodName, CodeTree value) {
+        CodeTreeBuilder builder = new CodeTreeBuilder(parent);
+        startCallTypeSystemMethod(context, builder, node, methodName);
+        builder.tree(value);
+        builder.end().end();
+        return builder.getRoot();
+    }
+
+    private static void startCallTypeSystemMethod(ProcessorContext context, CodeTreeBuilder body, NodeData node, String methodName) {
+        VariableElement singleton = TypeSystemCodeGenerator.findSingleton(context, node.getTypeSystem());
+        assert singleton != null;
+
+        body.startGroup();
+        body.staticReference(singleton.getEnclosingElement().asType(), singleton.getSimpleName().toString());
+        body.string(".").startCall(methodName);
+    }
+
+    private CodeTree createGuardAndCast(CodeTreeBuilder parent, String conditionPrefix, SpecializationData sourceSpecialization, SpecializationData targetSpecialization, boolean castValues,
+                    CodeTree guardedStatements, CodeTree elseStatements, boolean emitAssumptions, boolean forceElse) {
+
+        NodeData node = targetSpecialization.getNode();
+        CodeTreeBuilder builder = new CodeTreeBuilder(parent);
+        CodeTree implicitGuards = createImplicitGuards(parent, conditionPrefix, sourceSpecialization, targetSpecialization, emitAssumptions);
+        CodeTree explicitGuards = createExplicitGuards(parent, implicitGuards == null ? conditionPrefix : null, sourceSpecialization, targetSpecialization);
+
+        Set<String> valuesNeedsCast;
+        if (castValues) {
+            // cast all
+            valuesNeedsCast = null;
+        } else {
+            // find out which values needs a cast
+            valuesNeedsCast = new HashSet<>();
+            for (GuardData guard : targetSpecialization.getGuards()) {
+                for (ActualParameter targetParameter : guard.getParameters()) {
+                    NodeChildData field = node.findChild(targetParameter.getSpecification().getName());
+                    if (field == null) {
+                        continue;
+                    }
+                    TypeData targetType = targetParameter.getTypeSystemType();
+                    ActualParameter sourceParameter = sourceSpecialization.findParameter(targetParameter.getLocalName());
+                    if (sourceParameter == null) {
+                        sourceParameter = targetParameter;
+                    }
+                    TypeData sourceType = sourceParameter.getTypeSystemType();
+
+                    if (sourceType.needsCastTo(getContext(), targetType)) {
+                        valuesNeedsCast.add(targetParameter.getLocalName());
+                    }
+                }
+            }
+        }
+
+        int ifCount = 0;
+
+        if (implicitGuards != null) {
+            builder.startIf();
+            builder.tree(implicitGuards);
+            builder.end();
+            builder.startBlock();
+            ifCount++;
+        }
+
+        builder.tree(createCasts(parent, valuesNeedsCast, sourceSpecialization, targetSpecialization));
+
+        if (explicitGuards != null) {
+            builder.startIf();
+            builder.tree(explicitGuards);
+            builder.end();
+            builder.startBlock();
+            ifCount++;
+        }
+
+        if (implicitGuards == null && explicitGuards == null && conditionPrefix != null && !conditionPrefix.isEmpty()) {
+            builder.startIf();
+            builder.string(conditionPrefix);
+            builder.end().startBlock();
+            ifCount++;
+        }
+
+        builder.tree(guardedStatements);
+
+        builder.end(ifCount);
+        if (elseStatements != null && (forceElse || ifCount > 0)) {
+            builder.tree(elseStatements);
+        }
+        return builder.getRoot();
+    }
+
+    private CodeTree createExplicitGuards(CodeTreeBuilder parent, String conditionPrefix, TemplateMethod valueSpecialization, SpecializationData guardedSpecialization) {
+        CodeTreeBuilder builder = new CodeTreeBuilder(parent);
+        String andOperator = conditionPrefix != null ? conditionPrefix + " && " : "";
+        if (guardedSpecialization.getGuards().size() > 0) {
+            // Explicitly specified guards
+            for (GuardData guard : guardedSpecialization.getGuards()) {
+                builder.string(andOperator);
+                builder.tree(createTemplateMethodCall(parent, null, valueSpecialization, guard, null));
+                andOperator = " && ";
+            }
+        }
+
+        return builder.isEmpty() ? null : builder.getRoot();
+    }
+
+    private CodeTree createCasts(CodeTreeBuilder parent, Set<String> castWhiteList, TemplateMethod valueSpecialization, SpecializationData guardedSpecialization) {
+        CodeTreeBuilder builder = new CodeTreeBuilder(parent);
+        // Implict guards based on method signature
+        for (ActualParameter guardedParam : guardedSpecialization.getParameters()) {
+            NodeChildData field = guardedSpecialization.getNode().findChild(guardedParam.getSpecification().getName());
+            if (field == null) {
+                continue;
+            }
+            ActualParameter valueParam = valueSpecialization.findParameter(guardedParam.getLocalName());
+
+            if (valueParam == null) {
+                /*
+                 * If used inside a function execute method. The value param may not exist. In that
+                 * case it assumes that the value is already converted.
+                 */
+                valueParam = guardedParam;
+            }
+
+            if (castWhiteList != null && !castWhiteList.contains(guardedParam.getLocalName())) {
+                continue;
+            }
+
+            CodeTree cast = createCast(parent, field, valueParam, guardedParam);
+            if (cast == null) {
+                continue;
+            }
+            builder.tree(cast);
+        }
+
+        return builder.getRoot();
+    }
+
+    private CodeTree createImplicitGuards(CodeTreeBuilder parent, String conditionPrefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization, boolean emitAssumptions) {
+        CodeTreeBuilder builder = new CodeTreeBuilder(parent);
+        // Implict guards based on method signature
+        String andOperator = conditionPrefix != null ? conditionPrefix + " && " : "";
+
+        if (emitAssumptions) {
+            for (String assumption : guardedSpecialization.getAssumptions()) {
+                builder.string(andOperator);
+                builder.string("this");
+                builder.string(".").string(assumption).string(".isValid()");
+                andOperator = " && ";
+            }
+        }
+
+        for (ActualParameter guardedParam : guardedSpecialization.getParameters()) {
+            NodeChildData field = guardedSpecialization.getNode().findChild(guardedParam.getSpecification().getName());
+            if (field == null) {
+                continue;
+            }
+            ActualParameter valueParam = valueSpecialization.findParameter(guardedParam.getLocalName());
+
+            if (valueParam == null) {
+                /*
+                 * If used inside a function execute method. The value param may not exist. In that
+                 * case it assumes that the value is already converted.
+                 */
+                valueParam = guardedParam;
+            }
+
+            CodeTree implicitGuard = createImplicitGuard(builder, field, valueParam, guardedParam);
+            if (implicitGuard == null) {
+                continue;
+            }
+
+            builder.string(andOperator);
+            builder.tree(implicitGuard);
+            andOperator = " && ";
+        }
+
+        return builder.isEmpty() ? null : builder.getRoot();
+    }
+
+    private CodeTree createImplicitGuard(CodeTreeBuilder parent, NodeChildData field, ActualParameter source, ActualParameter target) {
+        NodeData node = field.getNodeData();
+        CodeTreeBuilder builder = new CodeTreeBuilder(parent);
+
+        TypeData targetType = target.getTypeSystemType();
+        TypeData sourceType = source.getTypeSystemType();
+
+        if (!sourceType.needsCastTo(getContext(), targetType)) {
+            return null;
+        }
+
+        builder.startGroup();
+
+        if (field.isShortCircuit()) {
+            ActualParameter shortCircuit = target.getPreviousParameter();
+            assert shortCircuit != null;
+            builder.string("(");
+            builder.string("!").string(valueName(shortCircuit));
+            builder.string(" || ");
+        }
+
+        startCallTypeSystemMethod(getContext(), builder, node, TypeSystemCodeGenerator.isTypeMethodName(target.getTypeSystemType()));
+        builder.string(valueName(source));
+        builder.end().end(); // call
+
+        if (field.isShortCircuit()) {
+            builder.string(")");
+        }
+
+        builder.end(); // group
+
+        return builder.getRoot();
+    }
+
+    private CodeTree createCast(CodeTreeBuilder parent, NodeChildData field, ActualParameter source, ActualParameter target) {
+        NodeData node = field.getNodeData();
+        TypeData sourceType = source.getTypeSystemType();
+        TypeData targetType = target.getTypeSystemType();
+
+        if (!sourceType.needsCastTo(getContext(), targetType)) {
+            return null;
+        }
+
+        CodeTree condition = null;
+        if (field.isShortCircuit()) {
+            ActualParameter shortCircuit = target.getPreviousParameter();
+            assert shortCircuit != null;
+            condition = CodeTreeBuilder.singleString(valueName(shortCircuit));
+        }
+
+        CodeTree value = createCallTypeSystemMethod(context, parent, node, TypeSystemCodeGenerator.asTypeMethodName(targetType), CodeTreeBuilder.singleString(valueName(target)));
+
+        return createLazyAssignment(parent, castValueName(target), target.getType(), condition, value);
+    }
+
+    /**
+     * <pre>
+     * variant1 $condition != null
+     * 
+     * $type $name = defaultValue($type);
+     * if ($condition) {
+     *     $name = $value;
+     * }
+     * 
+     * variant2 $condition != null
+     * $type $name = $value;
+     * </pre>
+     * 
+     * .
+     */
+    private static CodeTree createLazyAssignment(CodeTreeBuilder parent, String name, TypeMirror type, CodeTree condition, CodeTree value) {
+        CodeTreeBuilder builder = new CodeTreeBuilder(parent);
+        if (condition == null) {
+            builder.declaration(type, name, value);
+        } else {
+            builder.declaration(type, name, new CodeTreeBuilder(parent).defaultValue(type).getRoot());
+
+            builder.startIf().tree(condition).end();
+            builder.startBlock();
+            builder.startStatement();
+            builder.string(name);
+            builder.string(" = ");
+            builder.tree(value);
+            builder.end(); // statement
+            builder.end(); // block
+        }
+        return builder.getRoot();
+    }
+
+    protected void emitEncounteredSynthetic(CodeTreeBuilder builder, TemplateMethod current) {
+        builder.startThrow().startNew(getContext().getType(UnsupportedOperationException.class));
+        builder.startCall("createInfo0");
+        builder.doubleQuote("Unsupported values");
+        addInternalValueParameterNames(builder, current, current, null, false, true);
+        builder.end().end().end();
+    }
+
+    private static List<ExecutableElement> findUserConstructors(TypeMirror nodeType) {
+        List<ExecutableElement> constructors = new ArrayList<>();
+        for (ExecutableElement constructor : ElementFilter.constructorsIn(Utils.fromTypeMirror(nodeType).getEnclosedElements())) {
+            if (constructor.getModifiers().contains(PRIVATE)) {
+                continue;
+            }
+            if (isCopyConstructor(constructor)) {
+                continue;
+            }
+            constructors.add(constructor);
+        }
+
+        if (constructors.isEmpty()) {
+            constructors.add(new CodeExecutableElement(null, Utils.getSimpleName(nodeType)));
+        }
+
+        return constructors;
+    }
+
+    private static ExecutableElement findCopyConstructor(TypeMirror type) {
+        for (ExecutableElement constructor : ElementFilter.constructorsIn(Utils.fromTypeMirror(type).getEnclosedElements())) {
+            if (constructor.getModifiers().contains(PRIVATE)) {
+                continue;
+            }
+            if (isCopyConstructor(constructor)) {
+                return constructor;
+            }
+        }
+
+        return null;
+    }
+
+    private static boolean isCopyConstructor(ExecutableElement element) {
+        if (element.getParameters().size() != 1) {
+            return false;
+        }
+        VariableElement var = element.getParameters().get(0);
+        TypeElement type = Utils.findNearestEnclosingType(var);
+
+        if (!Utils.typeEquals(var.asType(), type.asType())) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    protected void createChildren(NodeData node) {
+        Map<NodeData, List<TypeElement>> childTypes = new LinkedHashMap<>();
+        if (node.getDeclaredNodes() != null && !node.getDeclaredNodes().isEmpty()) {
+            for (NodeData nodeChild : node.getDeclaredNodes()) {
+                NodeCodeGenerator generator = new NodeCodeGenerator(getContext());
+                childTypes.put(nodeChild, generator.process(null, nodeChild).getEnclosedElements());
+            }
+        }
+
+        if (node.needsFactory() || node.getNodeDeclaringChildren().size() > 0) {
+            add(new NodeFactoryFactory(context, childTypes), node);
+        }
+    }
+
+    private class NodeFactoryFactory extends ClassElementFactory<NodeData> {
+
+        private final Map<NodeData, List<TypeElement>> childTypes;
+
+        private CodeTypeElement generatedNode;
+
+        public NodeFactoryFactory(ProcessorContext context, Map<NodeData, List<TypeElement>> childElements) {
+            super(context);
+            this.childTypes = childElements;
+        }
+
+        @Override
+        protected CodeTypeElement create(NodeData node) {
+            Modifier visibility = Utils.getVisibility(node.getTemplateType().getModifiers());
+            CodeTypeElement clazz = createClass(node, modifiers(), factoryClassName(node), null, false);
+            if (visibility != null) {
+                clazz.getModifiers().add(visibility);
+            }
+            clazz.getModifiers().add(Modifier.FINAL);
+            clazz.add(createConstructorUsingFields(modifiers(PRIVATE), clazz));
+            return clazz;
+        }
+
+        @Override
+        protected void createChildren(NodeData node) {
+            CodeTypeElement clazz = getElement();
+
+            Modifier createVisibility = Utils.getVisibility(clazz.getModifiers());
+
+            if (node.needsFactory()) {
+                NodeBaseFactory factory = new NodeBaseFactory(context);
+                add(factory, node.getGenericSpecialization() == null ? node.getSpecializations().get(0) : node.getGenericSpecialization());
+                generatedNode = factory.getElement();
+
+                if (node.needsRewrites(context)) {
+                    clazz.add(createCreateGenericMethod(node, createVisibility));
+                }
+
+                createFactoryMethods(node, clazz, createVisibility);
+
+                PolymorphicNodeFactory generic = null;
+                for (SpecializationData specialization : node.getPolymorphicSpecializations()) {
+                    PolymorphicNodeFactory polymorphicFactory = new PolymorphicNodeFactory(context, generic == null ? generatedNode : generic.getElement(), generic == null);
+                    add(polymorphicFactory, specialization);
+                    if (generic == null) {
+                        generic = polymorphicFactory;
+                    }
+                }
+
+                for (SpecializationData specialization : node.getSpecializations()) {
+                    if (!specialization.isReachable()) {
+                        continue;
+                    }
+                    add(new SpecializedNodeFactory(context, generatedNode), specialization);
+                }
+
+                TypeMirror nodeFactory = Utils.getDeclaredType(Utils.fromTypeMirror(getContext().getType(NodeFactory.class)), node.getNodeType());
+                clazz.getImplements().add(nodeFactory);
+                clazz.add(createCreateNodeMethod(node));
+                clazz.add(createCreateNodeGenericMethod(node));
+                clazz.add(createGetNodeClassMethod(node));
+                clazz.add(createGetNodeSignaturesMethod());
+                clazz.add(createGetChildrenSignatureMethod(node));
+                clazz.add(createGetInstanceMethod(node, createVisibility));
+                clazz.add(createInstanceConstant(node, clazz.asType()));
+            }
+
+            for (NodeData childNode : childTypes.keySet()) {
+                if (childNode.getTemplateType().getModifiers().contains(Modifier.PRIVATE)) {
+                    continue;
+                }
+
+                for (TypeElement type : childTypes.get(childNode)) {
+                    Set<Modifier> typeModifiers = ((CodeTypeElement) type).getModifiers();
+                    Modifier visibility = Utils.getVisibility(type.getModifiers());
+                    typeModifiers.clear();
+                    if (visibility != null) {
+                        typeModifiers.add(visibility);
+                    }
+
+                    typeModifiers.add(Modifier.STATIC);
+                    typeModifiers.add(Modifier.FINAL);
+                    clazz.add(type);
+                }
+            }
+
+            List<NodeData> children = node.getNodeDeclaringChildren();
+            if (node.getParent() == null && children.size() > 0) {
+                clazz.add(createGetFactories(node));
+            }
+
+        }
+
+        private CodeExecutableElement createGetNodeClassMethod(NodeData node) {
+            TypeMirror returnType = Utils.getDeclaredType(Utils.fromTypeMirror(getContext().getType(Class.class)), node.getNodeType());
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), returnType, "getNodeClass");
+            CodeTreeBuilder builder = method.createBuilder();
+            builder.startReturn().typeLiteral(node.getNodeType()).end();
+            return method;
+        }
+
+        private CodeExecutableElement createGetNodeSignaturesMethod() {
+            TypeElement listType = Utils.fromTypeMirror(getContext().getType(List.class));
+            TypeMirror classType = getContext().getType(Class.class);
+            TypeMirror returnType = Utils.getDeclaredType(listType, Utils.getDeclaredType(listType, classType));
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), returnType, "getNodeSignatures");
+            CodeTreeBuilder builder = method.createBuilder();
+            builder.startReturn();
+            builder.startStaticCall(getContext().getType(Arrays.class), "asList");
+            List<ExecutableElement> constructors = findUserConstructors(generatedNode.asType());
+            for (ExecutableElement constructor : constructors) {
+                builder.tree(createAsList(builder, Utils.asTypeMirrors(constructor.getParameters()), classType));
+            }
+            builder.end();
+            builder.end();
+            return method;
+        }
+
+        private CodeExecutableElement createGetChildrenSignatureMethod(NodeData node) {
+            Types types = getContext().getEnvironment().getTypeUtils();
+            TypeElement listType = Utils.fromTypeMirror(getContext().getType(List.class));
+            TypeMirror classType = getContext().getType(Class.class);
+            TypeMirror nodeType = getContext().getTruffleTypes().getNode();
+            TypeMirror wildcardNodeType = types.getWildcardType(nodeType, null);
+            classType = Utils.getDeclaredType(Utils.fromTypeMirror(classType), wildcardNodeType);
+            TypeMirror returnType = Utils.getDeclaredType(listType, classType);
+
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), returnType, "getExecutionSignature");
+            CodeTreeBuilder builder = method.createBuilder();
+
+            List<TypeMirror> signatureTypes = new ArrayList<>();
+            assert !node.getSpecializations().isEmpty();
+            SpecializationData data = node.getSpecializations().get(0);
+            for (ActualParameter parameter : data.getParameters()) {
+                ParameterSpec spec = parameter.getSpecification();
+                NodeChildData field = node.findChild(spec.getName());
+                if (field == null) {
+                    continue;
+                }
+
+                TypeMirror type;
+                if (field.getCardinality() == Cardinality.MANY && field.getNodeType().getKind() == TypeKind.ARRAY) {
+                    type = ((ArrayType) field.getNodeType()).getComponentType();
+                } else {
+                    type = field.getNodeType();
+                }
+
+                signatureTypes.add(type);
+            }
+
+            builder.startReturn().tree(createAsList(builder, signatureTypes, classType)).end();
+            return method;
+        }
+
+        private CodeTree createAsList(CodeTreeBuilder parent, List<TypeMirror> types, TypeMirror elementClass) {
+            CodeTreeBuilder builder = parent.create();
+            builder.startGroup();
+            builder.type(getContext().getType(Arrays.class));
+            builder.string(".<").type(elementClass).string(">");
+            builder.startCall("asList");
+            for (TypeMirror typeMirror : types) {
+                builder.typeLiteral(typeMirror);
+            }
+            builder.end().end();
+            return builder.getRoot();
+        }
+
+        private CodeExecutableElement createCreateNodeMethod(NodeData node) {
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), node.getNodeType(), "createNode");
+            CodeVariableElement arguments = new CodeVariableElement(getContext().getType(Object.class), "arguments");
+            method.setVarArgs(true);
+            method.addParameter(arguments);
+
+            CodeTreeBuilder builder = method.createBuilder();
+            List<ExecutableElement> signatures = findUserConstructors(generatedNode.asType());
+            boolean ifStarted = false;
+
+            for (ExecutableElement element : signatures) {
+                ifStarted = builder.startIf(ifStarted);
+                builder.string("arguments.length == " + element.getParameters().size());
+
+                int index = 0;
+                for (VariableElement param : element.getParameters()) {
+                    builder.string(" && ");
+                    if (!param.asType().getKind().isPrimitive()) {
+                        builder.string("(arguments[" + index + "] == null || ");
+                    }
+                    builder.string("arguments[" + index + "] instanceof ");
+                    builder.type(Utils.boxType(getContext(), param.asType()));
+                    if (!param.asType().getKind().isPrimitive()) {
+                        builder.string(")");
+                    }
+                    index++;
+                }
+                builder.end();
+                builder.startBlock();
+
+                builder.startReturn().startCall("create");
+                index = 0;
+                for (VariableElement param : element.getParameters()) {
+                    builder.startGroup();
+                    builder.string("(").type(param.asType()).string(") ");
+                    builder.string("arguments[").string(String.valueOf(index)).string("]");
+                    builder.end();
+                    index++;
+                }
+                builder.end().end();
+
+                builder.end(); // block
+            }
+
+            builder.startElseBlock();
+            builder.startThrow().startNew(getContext().getType(IllegalArgumentException.class));
+            builder.doubleQuote("Invalid create signature.");
+            builder.end().end();
+            builder.end(); // else block
+            return method;
+        }
+
+        private CodeExecutableElement createCreateNodeGenericMethod(NodeData node) {
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), node.getNodeType(), "createNodeGeneric");
+            CodeVariableElement nodeParam = new CodeVariableElement(node.getNodeType(), THIS_NODE_LOCAL_VAR_NAME);
+            method.addParameter(nodeParam);
+
+            CodeTreeBuilder builder = method.createBuilder();
+            if (!node.needsRewrites(getContext())) {
+                builder.startThrow().startNew(getContext().getType(UnsupportedOperationException.class)).doubleQuote("No specialized version.").end().end();
+            } else {
+                builder.startReturn().startCall("createGeneric");
+                builder.string(THIS_NODE_LOCAL_VAR_NAME);
+                builder.end().end();
+            }
+            return method;
+        }
+
+        private ExecutableElement createGetInstanceMethod(NodeData node, Modifier visibility) {
+            TypeElement nodeFactoryType = Utils.fromTypeMirror(getContext().getType(NodeFactory.class));
+            TypeMirror returnType = Utils.getDeclaredType(nodeFactoryType, node.getNodeType());
+
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(), returnType, "getInstance");
+            if (visibility != null) {
+                method.getModifiers().add(visibility);
+            }
+            method.getModifiers().add(Modifier.STATIC);
+
+            String varName = instanceVarName(node);
+
+            CodeTreeBuilder builder = method.createBuilder();
+            builder.startIf();
+            builder.string(varName).string(" == null");
+            builder.end().startBlock();
+
+            builder.startStatement();
+            builder.string(varName);
+            builder.string(" = ");
+            builder.startNew(factoryClassName(node)).end();
+            builder.end();
+
+            builder.end();
+            builder.startReturn().string(varName).end();
+            return method;
+        }
+
+        private String instanceVarName(NodeData node) {
+            if (node.getParent() != null) {
+                return Utils.firstLetterLowerCase(factoryClassName(node)) + "Instance";
+            } else {
+                return "instance";
+            }
+        }
+
+        private CodeVariableElement createInstanceConstant(NodeData node, TypeMirror factoryType) {
+            String varName = instanceVarName(node);
+            CodeVariableElement var = new CodeVariableElement(modifiers(), factoryType, varName);
+            var.getModifiers().add(Modifier.PRIVATE);
+            var.getModifiers().add(Modifier.STATIC);
+            return var;
+        }
+
+        private ExecutableElement createGetFactories(NodeData node) {
+            List<NodeData> children = node.getNodeDeclaringChildren();
+            if (node.needsFactory()) {
+                children.add(node);
+            }
+
+            List<TypeMirror> nodeTypesList = new ArrayList<>();
+            TypeMirror prev = null;
+            boolean allSame = true;
+            for (NodeData child : children) {
+                nodeTypesList.add(child.getNodeType());
+                if (prev != null && !Utils.typeEquals(child.getNodeType(), prev)) {
+                    allSame = false;
+                }
+                prev = child.getNodeType();
+            }
+            TypeMirror commonNodeSuperType = Utils.getCommonSuperType(getContext(), nodeTypesList.toArray(new TypeMirror[nodeTypesList.size()]));
+
+            Types types = getContext().getEnvironment().getTypeUtils();
+            TypeMirror factoryType = getContext().getType(NodeFactory.class);
+            TypeMirror baseType;
+            if (allSame) {
+                baseType = Utils.getDeclaredType(Utils.fromTypeMirror(factoryType), commonNodeSuperType);
+            } else {
+                baseType = Utils.getDeclaredType(Utils.fromTypeMirror(factoryType), types.getWildcardType(commonNodeSuperType, null));
+            }
+            TypeMirror listType = Utils.getDeclaredType(Utils.fromTypeMirror(getContext().getType(List.class)), baseType);
+
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, STATIC), listType, "getFactories");
+
+            CodeTreeBuilder builder = method.createBuilder();
+            builder.startReturn();
+            builder.startStaticCall(getContext().getType(Arrays.class), "asList");
+
+            for (NodeData child : children) {
+                builder.startGroup();
+                NodeData childNode = child;
+                List<NodeData> factories = new ArrayList<>();
+                while (childNode.getParent() != null) {
+                    factories.add(childNode);
+                    childNode = childNode.getParent();
+                }
+                Collections.reverse(factories);
+                for (NodeData nodeData : factories) {
+                    builder.string(factoryClassName(nodeData)).string(".");
+                }
+                builder.string("getInstance()");
+                builder.end();
+            }
+            builder.end();
+            builder.end();
+            return method;
+        }
+
+        private void createFactoryMethods(NodeData node, CodeTypeElement clazz, Modifier createVisibility) {
+            List<ExecutableElement> constructors = findUserConstructors(generatedNode.asType());
+            for (ExecutableElement constructor : constructors) {
+                clazz.add(createCreateMethod(node, createVisibility, constructor));
+            }
+        }
+
+        private CodeExecutableElement createCreateMethod(NodeData node, Modifier visibility, ExecutableElement constructor) {
+            CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), constructor);
+            method.setSimpleName(CodeNames.of("create"));
+            method.getModifiers().clear();
+            if (visibility != null) {
+                method.getModifiers().add(visibility);
+            }
+            method.getModifiers().add(Modifier.STATIC);
+            method.setReturnType(node.getNodeType());
+
+            CodeTreeBuilder body = method.createBuilder();
+            body.startReturn();
+            if (node.getSpecializations().isEmpty()) {
+                body.nullLiteral();
+            } else {
+                body.startNew(nodeSpecializationClassName(node.getSpecializations().get(0)));
+                for (VariableElement var : method.getParameters()) {
+                    body.string(var.getSimpleName().toString());
+                }
+                body.end();
+            }
+            body.end();
+            return method;
+        }
+
+        private CodeExecutableElement createCreateGenericMethod(NodeData node, Modifier visibility) {
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(), node.getNodeType(), "createGeneric");
+            if (visibility != null) {
+                method.getModifiers().add(visibility);
+            }
+            method.getModifiers().add(Modifier.STATIC);
+            method.addParameter(new CodeVariableElement(node.getNodeType(), THIS_NODE_LOCAL_VAR_NAME));
+
+            CodeTreeBuilder body = method.createBuilder();
+
+            SpecializationData found = null;
+            List<SpecializationData> specializations = node.getSpecializations();
+            for (int i = 0; i < specializations.size(); i++) {
+                if (specializations.get(i).isReachable()) {
+                    found = specializations.get(i);
+                }
+            }
+
+            if (found == null) {
+                body.startThrow().startNew(getContext().getType(UnsupportedOperationException.class)).end().end();
+            } else {
+                body.startReturn().startNew(nodeSpecializationClassName(found)).startGroup().cast(baseClassName(node)).string(THIS_NODE_LOCAL_VAR_NAME).end().end().end();
+            }
+            return method;
+        }
+    }
+
+    private class NodeBaseFactory extends ClassElementFactory<SpecializationData> {
+
+        public NodeBaseFactory(ProcessorContext context) {
+            super(context);
+        }
+
+        @Override
+        protected CodeTypeElement create(SpecializationData specialization) {
+            NodeData node = specialization.getNode();
+            CodeTypeElement clazz = createClass(node, modifiers(PRIVATE, ABSTRACT, STATIC), baseClassName(node), node.getNodeType(), false);
+
+            for (NodeChildData child : node.getChildren()) {
+                clazz.add(createChildField(child));
+
+                if (child.getAccessElement() != null && child.getAccessElement().getModifiers().contains(Modifier.ABSTRACT)) {
+                    ExecutableElement getter = (ExecutableElement) child.getAccessElement();
+                    CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), getter);
+                    method.getModifiers().remove(Modifier.ABSTRACT);
+                    method.createBuilder().startReturn().string("this.").string(child.getName()).end();
+                    clazz.add(method);
+                }
+            }
+
+            for (String assumption : node.getAssumptions()) {
+                clazz.add(createAssumptionField(assumption));
+            }
+
+            createConstructors(node, clazz);
+
+            return clazz;
+        }
+
+        protected String typeGetterName(ActualParameter parameter) {
+            return "get" + Utils.firstLetterUpperCase(parameter.getLocalName()) + "Type";
+        }
+
+        @Override
+        protected void createChildren(SpecializationData specialization) {
+            NodeData node = specialization.getNode();
+            CodeTypeElement clazz = getElement();
+
+            if (node.needsRewrites(context)) {
+
+                if (node.getPolymorphicDepth() > 1) {
+
+                    CodeVariableElement var = new CodeVariableElement(modifiers(PROTECTED), clazz.asType(), "next0");
+                    var.getAnnotationMirrors().add(new CodeAnnotationMirror(getContext().getTruffleTypes().getChildAnnotation()));
+                    clazz.add(var);
+
+                    CodeExecutableElement setter = new CodeExecutableElement(modifiers(PROTECTED), context.getType(void.class), "setNext0");
+                    setter.getParameters().add(new CodeVariableElement(clazz.asType(), "next0"));
+                    CodeTreeBuilder builder = setter.createBuilder();
+                    builder.statement("this.next0 = adoptChild(next0)");
+                    clazz.add(setter);
+
+                    createTypeGetters(clazz, node.getGenericSpecialization());
+
+                    clazz.add(createCreateSpecialization(node));
+
+                    CodeExecutableElement genericCachedExecute = null;
+                    for (SpecializationData polymorph : node.getPolymorphicSpecializations()) {
+                        CodeExecutableElement cachedExecute = createCachedExecute(node, polymorph, genericCachedExecute);
+                        clazz.add(cachedExecute);
+                        if (genericCachedExecute == null) {
+                            genericCachedExecute = cachedExecute;
+                        }
+                    }
+                }
+
+                clazz.add(createGenericExecuteAndSpecialize(node));
+                clazz.add(createInfoMessage(node));
+            }
+
+            if (node.getGenericSpecialization() != null && node.getGenericSpecialization().isReachable()) {
+                clazz.add(createGenericExecute(node));
+            }
+        }
+
+        private Element createInfoMessage(NodeData node) {
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, STATIC), getContext().getType(String.class), "createInfo0");
+            method.addParameter(new CodeVariableElement(getContext().getType(String.class), "message"));
+            addInternalValueParameters(method, node.getGenericSpecialization(), false, false);
+
+            CodeTreeBuilder builder = method.createBuilder();
+            builder.startStatement().string("StringBuilder builder = new StringBuilder(message)").end();
+            builder.startStatement().startCall("builder", "append").doubleQuote(" (").end().end();
+
+            String sep = null;
+            for (ActualParameter parameter : node.getGenericSpecialization().getParameters()) {
+                if (!parameter.getSpecification().isSignature()) {
+                    continue;
+                }
+
+                builder.startStatement();
+                builder.string("builder");
+                if (sep != null) {
+                    builder.startCall(".append").doubleQuote(sep).end();
+                }
+                builder.startCall(".append").doubleQuote(parameter.getLocalName()).end();
+                builder.startCall(".append").doubleQuote(" = ").end();
+                builder.startCall(".append").string(parameter.getLocalName()).end();
+                builder.end();
+
+                if (!Utils.isPrimitive(parameter.getType())) {
+                    builder.startIf().string(parameter.getLocalName() + " != null").end();
+                    builder.startBlock();
+                }
+                builder.startStatement();
+                if (Utils.isPrimitive(parameter.getType())) {
+                    builder.startCall("builder.append").doubleQuote(" (" + Utils.getSimpleName(parameter.getType()) + ")").end();
+                } else {
+                    builder.startCall("builder.append").doubleQuote(" (").end();
+                    builder.startCall(".append").string(parameter.getLocalName() + ".getClass().getSimpleName()").end();
+                    builder.startCall(".append").doubleQuote(")").end();
+                }
+                builder.end();
+                if (!Utils.isPrimitive(parameter.getType())) {
+                    builder.end();
+                }
+
+                sep = ", ";
+            }
+
+            builder.startStatement().startCall("builder", "append").doubleQuote(")").end().end();
+
+            builder.startReturn().string("builder.toString()").end();
+
+            return method;
+        }
+
+        protected void createTypeGetters(CodeTypeElement clazz, SpecializationData specialization) {
+            for (ActualParameter parameter : specialization.getReturnTypeAndParameters()) {
+                if (!parameter.getSpecification().isSignature()) {
+                    continue;
+                }
+                CodeExecutableElement typeGetter = new CodeExecutableElement(modifiers(PROTECTED), context.getType(Class.class), typeGetterName(parameter));
+                CodeTreeBuilder builder = typeGetter.createBuilder();
+                builder.startReturn().typeLiteral(parameter.getType()).end();
+                clazz.add(typeGetter);
+            }
+        }
+
+        private CodeExecutableElement createCachedExecute(NodeData node, SpecializationData polymorph, CodeExecutableElement genericPolymorphMethod) {
+            int index = node.getPolymorphicSpecializations().indexOf(polymorph);
+            assert index != -1;
+            boolean generic = index == 0;
+
+            String name = "executeCached" + index;
+            CodeExecutableElement cachedExecute = new CodeExecutableElement(modifiers(PROTECTED), polymorph.getReturnType().getType(), name);
+            addInternalValueParameters(cachedExecute, polymorph, true, true);
+
+            if (generic) {
+                cachedExecute.getModifiers().add(ABSTRACT);
+            } else {
+                SpecializationData genericPolymorph = node.getPolymorphicSpecializations().get(0);
+                CodeTreeBuilder builder = cachedExecute.createBuilder();
+                ExecutableTypeData genericExecutable = new ExecutableTypeData(genericPolymorph, genericPolymorphMethod, node.getTypeSystem(), genericPolymorph.getReturnType().getTypeSystemType());
+                ExecutableTypeData specificExecutable = new ExecutableTypeData(polymorph, cachedExecute, node.getTypeSystem(), polymorph.getReturnType().getTypeSystemType());
+                builder.tree(createCastingExecute(builder, polymorph, specificExecutable, genericExecutable));
+            }
+
+            return cachedExecute;
+
+        }
+
+        private CodeExecutableElement createCreateSpecialization(NodeData node) {
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE), getElement().asType(), "createSpezialization0");
+            method.getParameters().add(new CodeVariableElement(context.getType(Class.class), "clazz"));
+            CodeTreeBuilder builder = method.createBuilder();
+
+            builder.startStatement().type(getElement().asType()).string(" node").end();
+
+            boolean elseIf = false;
+            for (SpecializationData specialization : node.getSpecializations()) {
+                if (specialization.isGeneric() || specialization.isUninitialized()) {
+                    continue;
+                }
+
+                elseIf = builder.startIf(elseIf);
+                builder.startGroup().string("clazz == ").string(nodeSpecializationClassName(specialization)).string(".class").end();
+                builder.end();
+                builder.startBlock();
+                builder.startStatement();
+                builder.string("node = ");
+                builder.startNew(nodeSpecializationClassName(specialization)).string("this").end();
+                builder.end();
+                builder.end();
+            }
+
+            builder.startElseBlock();
+            builder.startThrow().startNew(context.getType(AssertionError.class)).end().end();
+            builder.end();
+
+            builder.startStatement().startCall("node", "setNext0");
+            builder.startNew(nodeSpecializationClassName(node.getUninitializedSpecialization())).string("this").end();
+            builder.end().end();
+
+            builder.startReturn().string("node").end();
+
+            return method;
+        }
+
+        private void createConstructors(NodeData node, CodeTypeElement clazz) {
+            List<ExecutableElement> constructors = findUserConstructors(node.getNodeType());
+            if (constructors.isEmpty()) {
+                clazz.add(createUserConstructor(clazz, null));
+            } else {
+                for (ExecutableElement constructor : constructors) {
+                    clazz.add(createUserConstructor(clazz, constructor));
+                }
+            }
+            if (node.needsRewrites(getContext())) {
+                clazz.add(createCopyConstructor(clazz, findCopyConstructor(node.getNodeType())));
+            }
+        }
+
+        private CodeExecutableElement createUserConstructor(CodeTypeElement type, ExecutableElement superConstructor) {
+            CodeExecutableElement method = new CodeExecutableElement(null, type.getSimpleName().toString());
+            CodeTreeBuilder builder = method.createBuilder();
+
+            NodeData node = getModel().getNode();
+
+            if (superConstructor != null) {
+                for (VariableElement param : superConstructor.getParameters()) {
+                    method.getParameters().add(CodeVariableElement.clone(param));
+                }
+            }
+
+            for (VariableElement var : type.getFields()) {
+                NodeChildData child = node.findChild(var.getSimpleName().toString());
+                if (child != null) {
+                    method.getParameters().add(new CodeVariableElement(child.getOriginalType(), child.getName()));
+                } else {
+                    method.getParameters().add(new CodeVariableElement(var.asType(), var.getSimpleName().toString()));
+                }
+            }
+
+            if (superConstructor != null) {
+                builder.startStatement().startSuperCall();
+                for (VariableElement param : superConstructor.getParameters()) {
+                    builder.string(param.getSimpleName().toString());
+                }
+                builder.end().end();
+            }
+
+            for (VariableElement var : type.getFields()) {
+                builder.startStatement();
+                String fieldName = var.getSimpleName().toString();
+
+                CodeTree fieldInit = CodeTreeBuilder.singleString(var.getSimpleName().toString());
+                builder.string("this.").string(var.getSimpleName().toString());
+
+                NodeChildData child = node.findChild(fieldName);
+                if (child != null) {
+                    CreateCastData createCast = node.findCast(child.getName());
+                    if (createCast != null) {
+                        fieldInit = createTemplateMethodCall(builder, null, node.getGenericSpecialization(), createCast, null, child.getName());
+                    }
+                }
+
+                if (Utils.isAssignable(getContext(), var.asType(), getContext().getTruffleTypes().getNode())) {
+                    builder.string(" = adoptChild(").tree(fieldInit).string(")");
+                } else if (Utils.isAssignable(getContext(), var.asType(), getContext().getTruffleTypes().getNodeArray())) {
+                    builder.string(" = adoptChildren(").tree(fieldInit).string(")");
+                } else {
+                    builder.string(" = ").tree(fieldInit);
+                }
+                builder.end();
+            }
+            return method;
+        }
+
+        private CodeExecutableElement createCopyConstructor(CodeTypeElement type, ExecutableElement superConstructor) {
+            CodeExecutableElement method = new CodeExecutableElement(null, type.getSimpleName().toString());
+            CodeTreeBuilder builder = method.createBuilder();
+            if (!(superConstructor == null && type.getFields().isEmpty())) {
+                method.getParameters().add(new CodeVariableElement(type.asType(), "copy"));
+            }
+
+            if (superConstructor != null) {
+                builder.startStatement().startSuperCall().string("copy").end().end();
+            }
+
+            for (VariableElement var : type.getFields()) {
+                builder.startStatement();
+                String varName = var.getSimpleName().toString();
+                builder.string("this.").string(varName);
+                if (Utils.isAssignable(getContext(), var.asType(), getContext().getTruffleTypes().getNode())) {
+                    builder.string(" = adoptChild(copy.").string(varName).string(")");
+                } else if (Utils.isAssignable(getContext(), var.asType(), getContext().getTruffleTypes().getNodeArray())) {
+                    builder.string(" = adoptChildren(copy.").string(varName).string(")");
+                } else {
+                    builder.string(" = copy.").string(varName);
+                }
+                builder.end();
+            }
+            if (getModel().getNode().getPolymorphicDepth() > 1) {
+                builder.statement("this.next0 = adoptChild(copy.next0)");
+            }
+
+            return method;
+        }
+
+        private CodeVariableElement createAssumptionField(String assumption) {
+            CodeVariableElement var = new CodeVariableElement(getContext().getTruffleTypes().getAssumption(), assumption);
+            var.getModifiers().add(Modifier.FINAL);
+            return var;
+        }
+
+        private CodeVariableElement createChildField(NodeChildData child) {
+            CodeVariableElement var = new CodeVariableElement(child.getNodeType(), child.getName());
+            var.getModifiers().add(Modifier.PROTECTED);
+
+            DeclaredType annotationType;
+            if (child.getCardinality() == Cardinality.MANY) {
+                annotationType = getContext().getTruffleTypes().getChildrenAnnotation();
+            } else {
+                annotationType = getContext().getTruffleTypes().getChildAnnotation();
+            }
+
+            var.getAnnotationMirrors().add(new CodeAnnotationMirror(annotationType));
+            return var;
+        }
+
+        private CodeExecutableElement createGenericExecuteAndSpecialize(NodeData node) {
+
+            TypeMirror genericReturnType = node.getGenericSpecialization().getReturnType().getType();
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED), genericReturnType, EXECUTE_SPECIALIZE_NAME);
+            method.addParameter(new CodeVariableElement(getContext().getType(Class.class), "minimumState"));
+            addInternalValueParameters(method, node.getGenericSpecialization(), true, false);
+            method.addParameter(new CodeVariableElement(getContext().getType(String.class), "reason"));
+
+            CodeTreeBuilder builder = method.createBuilder();
+            builder.startStatement();
+            builder.startStaticCall(getContext().getTruffleTypes().getCompilerAsserts(), "neverPartOfCompilation").end();
+            builder.end();
+
+            emitSpecializationListeners(builder, node);
+            builder.defaultDeclaration(node.getGenericSpecialization().getReturnType().getTypeSystemType().getPrimitiveType(), "result");
+
+            builder.defaultDeclaration(getContext().getType(Class.class), "resultClass");
+
+            builder.startStatement().string("boolean allowed = (minimumState == ").string(nodeSpecializationClassName(node.getSpecializations().get(0))).string(".class)").end();
+
+            builder.startStatement().string("String message = ").startCall("createInfo0").string("reason");
+            addInternalValueParameterNames(builder, node.getGenericSpecialization(), node.getGenericSpecialization(), null, false, true);
+            builder.end().end();
+
+            String prefix = null;
+
+            List<SpecializationData> specializations = node.getSpecializations();
+
+            for (SpecializationData current : specializations) {
+                if (current.isUninitialized() || !current.isReachable()) {
+                    continue;
+                }
+                CodeTreeBuilder execute = new CodeTreeBuilder(builder);
+
+                execute.tree(createGenericInvokeAndSpecialize(builder, node.getGenericSpecialization(), current));
+
+                if (!current.isGeneric()) {
+                    builder.startStatement().string("allowed = allowed || (minimumState == ").string(nodeSpecializationClassName(current)).string(".class)").end();
+                }
+
+                builder.tree(createGuardAndCast(builder, prefix, current.getNode().getGenericSpecialization(), current, true, execute.getRoot(), null, true, false));
+            }
+
+            for (SpecializationData current : specializations) {
+                if (current.isUninitialized() || current.isReachable()) {
+                    continue;
+                }
+                builder.string("// unreachable ").string(current.getId()).newLine();
+            }
+
+            return method;
+        }
+
+        private CodeExecutableElement createGenericExecute(NodeData node) {
+            TypeMirror genericReturnType = node.getGenericSpecialization().getReturnType().getType();
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED), genericReturnType, EXECUTE_GENERIC_NAME);
+            addInternalValueParameters(method, node.getGenericSpecialization(), true, false);
+            CodeTreeBuilder builder = method.createBuilder();
+
+            String prefix = null;
+            List<SpecializationData> specializations = node.getSpecializations();
+
+            for (SpecializationData current : specializations) {
+                if (current.isUninitialized() || !current.isReachable()) {
+                    continue;
+                }
+                CodeTreeBuilder execute = new CodeTreeBuilder(builder);
+                execute.tree(createGenericInvoke(builder, node.getGenericSpecialization(), current));
+                builder.tree(createGuardAndCast(builder, prefix, current.getNode().getGenericSpecialization(), current, true, execute.getRoot(), null, true, false));
+            }
+
+            for (SpecializationData current : specializations) {
+                if (current.isUninitialized() || current.isReachable()) {
+                    continue;
+                }
+                builder.string("// unreachable ").string(current.getId()).newLine();
+            }
+
+            return method;
+        }
+
+        protected CodeTree createGenericInvoke(CodeTreeBuilder parent, SpecializationData source, SpecializationData current) {
+            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
+
+            if (current.getMethod() == null) {
+                emitEncounteredSynthetic(builder, current);
+            } else {
+                builder.startReturn().tree(createTemplateMethodCall(builder, null, source, current, null)).end();
+            }
+
+            return encloseThrowsWithFallThrough(current, builder.getRoot());
+        }
+
+        protected CodeTree createGenericInvokeAndSpecialize(CodeTreeBuilder parent, SpecializationData source, SpecializationData current) {
+            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
+
+            NodeData node = current.getNode();
+
+            builder.startIf().string("resultClass == null").end().startBlock();
+            if (current.getMethod() != null) {
+                CodeTree executeCall = createTemplateMethodCall(builder, null, source, current, null);
+                if (current.getReturnType().getTypeSystemType().isVoid()) {
+                    builder.statement(executeCall);
+                } else {
+                    builder.startStatement().string("result = ").tree(executeCall).end();
+                }
+                builder.startStatement();
+                builder.string("resultClass = ").string(nodeSpecializationClassName(current)).string(".class");
+                builder.end();
+            } else {
+                emitEncounteredSynthetic(builder, current);
+            }
+            builder.end();
+
+            boolean ifAllowed = current.hasRewrite(getContext());
+            if (ifAllowed) {
+                builder.startIf().string("allowed").end().startBlock();
+            }
+
+            if (!current.isGeneric() || node.getPolymorphicDepth() <= 1) {
+                // generic rewrite
+                builder.tree(createRewriteGeneric(builder, current));
+            } else {
+                boolean rewriteableToGeneric = node.getGenericSpecialization().getMethod() != null && node.getGenericSpecialization().isReachable();
+                if (rewriteableToGeneric) {
+                    builder.startIf().string("resultClass == ").string(nodeSpecializationClassName(node.getGenericSpecialization())).string(".class").end();
+                    builder.startBlock();
+
+                    boolean maybePolymorphic = node.getPolymorphicDepth() > 1;
+                    if (maybePolymorphic) {
+                        builder.startIf().string("next0 == null").end();
+                        builder.startBlock();
+                    }
+                    builder.tree(createRewriteGeneric(builder, current));
+                    if (maybePolymorphic) {
+                        builder.end().startElseBlock();
+                        builder.statement("Node searchNode = super.getParent()");
+                        builder.startWhile().string("searchNode != null").end();
+                        builder.startBlock();
+                        builder.statement("searchNode = searchNode.getParent()");
+                        builder.startIf().instanceOf("searchNode", nodePolymorphicClassName(node, node.getPolymorphicSpecializations().get(0))).end();
+                        builder.startBlock().breakStatement().end();
+                        builder.end();
+                        builder.startStatement().startCall("searchNode", "replace");
+                        builder.startGroup().startNew(nodeSpecializationClassName(current)).startGroup().cast(baseClassName(node)).string("searchNode").end().end().end();
+                        builder.string("message");
+                        builder.end().end().end();
+                    }
+
+                    builder.end().startElseBlock();
+                }
+
+                // polymorphic rewrite
+                builder.tree(createRewritePolymorphic(builder, node));
+
+                if (rewriteableToGeneric) {
+                    builder.end();
+                }
+            }
+
+            if (current.getReturnType().getTypeSystemType().isVoid()) {
+                builder.returnStatement();
+            } else {
+                builder.startReturn().string("result").end();
+            }
+            if (ifAllowed) {
+                builder.end();
+            }
+
+            return encloseThrowsWithFallThrough(current, builder.getRoot());
+        }
+
+        private CodeTree encloseThrowsWithFallThrough(SpecializationData current, CodeTree tree) {
+            if (current.getExceptions().isEmpty()) {
+                return tree;
+            }
+            CodeTreeBuilder builder = new CodeTreeBuilder(null);
+
+            builder.startTryBlock();
+            builder.tree(tree);
+            for (SpecializationThrowsData exception : current.getExceptions()) {
+                builder.end().startCatchBlock(exception.getJavaClass(), "rewriteEx");
+                builder.string("// fall through").newLine();
+            }
+            builder.end();
+
+            return builder.getRoot();
+        }
+
+        private CodeTree createRewriteGeneric(CodeTreeBuilder parent, SpecializationData current) {
+            CodeTreeBuilder builder = parent.create();
+            builder.startStatement().startCall("super", "replace");
+            builder.startGroup().startNew(nodeSpecializationClassName(current)).string("this").end().end();
+            builder.string("message");
+            builder.end().end();
+            return builder.getRoot();
+        }
+
+        private CodeTree createRewritePolymorphic(CodeTreeBuilder parent, NodeData node) {
+            CodeTreeBuilder builder = parent.create();
+            builder.startStatement();
+            builder.string(nodePolymorphicClassName(node, null));
+            builder.string(" polymorphic = ");
+            builder.startNew(nodePolymorphicClassName(node, null)).string("this").end();
+            builder.end();
+            for (NodeChildData child : node.getChildren()) {
+                builder.startStatement().string("this.").string(child.getName()).string(" = null").end();
+            }
+            builder.startStatement().startCall("super", "replace");
+            builder.string("polymorphic");
+            builder.string("message");
+            builder.end().end();
+
+            builder.statement("polymorphic.setNext0(this)");
+            builder.statement("setNext0(createSpezialization0(resultClass))");
+
+            builder.statement("polymorphic.optimizeTypes()");
+            return builder.getRoot();
+        }
+
+        private void emitSpecializationListeners(CodeTreeBuilder builder, NodeData node) {
+            for (TemplateMethod listener : node.getSpecializationListeners()) {
+                builder.startStatement();
+                builder.tree(createTemplateMethodCall(builder, null, listener, listener, null));
+                builder.end(); // statement
+            }
+        }
+
+        protected CodeTree createCastingExecute(CodeTreeBuilder parent, SpecializationData specialization, ExecutableTypeData executable, ExecutableTypeData castExecutable) {
+            TypeData type = executable.getType();
+            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
+            NodeData node = specialization.getNode();
+
+            ExecutableTypeData castedType = node.findExecutableType(type, 0);
+            TypeData primaryType = castExecutable.getType();
+
+            boolean needsTry = castExecutable.hasUnexpectedValue(getContext());
+            boolean returnVoid = type.isVoid();
+
+            List<ActualParameter> executeParameters = new ArrayList<>();
+            for (ActualParameter sourceParameter : executable.getParameters()) {
+                if (!sourceParameter.getSpecification().isSignature()) {
+                    continue;
+                }
+
+                ActualParameter targetParameter = castExecutable.findParameter(sourceParameter.getLocalName());
+                if (targetParameter != null) {
+                    executeParameters.add(targetParameter);
+                }
+            }
+
+            builder.tree(createExecuteChildren(builder, executable, specialization, executeParameters, null, true));
+
+            CodeTree primaryExecuteCall = createTemplateMethodCall(builder, null, executable, castExecutable, null);
+            if (needsTry) {
+                if (!returnVoid) {
+                    builder.declaration(primaryType.getPrimitiveType(), "value");
+                }
+                builder.startTryBlock();
+
+                if (returnVoid) {
+                    builder.statement(primaryExecuteCall);
+                } else {
+                    builder.startStatement();
+                    builder.string("value = ");
+                    builder.tree(primaryExecuteCall);
+                    builder.end();
+                }
+
+                builder.end().startCatchBlock(getUnexpectedValueException(), "ex");
+                if (returnVoid) {
+                    builder.string("// ignore").newLine();
+                } else {
+                    builder.startReturn();
+                    builder.tree(createExpectExecutableType(node, specialization.getNode().getTypeSystem().getGenericTypeData(), castedType, CodeTreeBuilder.singleString("ex.getResult()")));
+                    builder.end();
+                }
+                builder.end();
+
+                if (!returnVoid) {
+                    builder.startReturn();
+                    builder.tree(createExpectExecutableType(node, castExecutable.getReturnType().getTypeSystemType(), executable, CodeTreeBuilder.singleString("value")));
+                    builder.end();
+                }
+            } else {
+                if (returnVoid) {
+                    builder.statement(primaryExecuteCall);
+                } else {
+                    builder.startReturn();
+                    builder.tree(createExpectExecutableType(node, castExecutable.getReturnType().getTypeSystemType(), executable, primaryExecuteCall));
+                    builder.end();
+                }
+            }
+
+            return builder.getRoot();
+        }
+
+        protected CodeTree createExpectExecutableType(NodeData node, TypeData sourceType, ExecutableTypeData castedType, CodeTree value) {
+            boolean hasUnexpected = castedType.hasUnexpectedValue(getContext());
+            return createCastType(node, sourceType, castedType.getType(), hasUnexpected, value);
+        }
+
+        protected CodeTree createCastType(NodeData node, TypeData sourceType, TypeData targetType, boolean expect, CodeTree value) {
+            if (targetType == null) {
+                return value;
+            } else if (!sourceType.needsCastTo(getContext(), targetType)) {
+                return value;
+            }
+
+            CodeTreeBuilder builder = CodeTreeBuilder.createBuilder();
+            String targetMethodName;
+            if (expect) {
+                targetMethodName = TypeSystemCodeGenerator.expectTypeMethodName(targetType);
+            } else {
+                targetMethodName = TypeSystemCodeGenerator.asTypeMethodName(targetType);
+            }
+            startCallTypeSystemMethod(getContext(), builder, node, targetMethodName);
+
+            builder.tree(value);
+            builder.end().end();
+            return builder.getRoot();
+        }
+
+        protected CodeTree createExecuteChildren(CodeTreeBuilder parent, ExecutableTypeData sourceExecutable, SpecializationData specialization, List<ActualParameter> targetParameters,
+                        ActualParameter unexpectedParameter, boolean cast) {
+            NodeData sourceNode = specialization.getNode();
+
+            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
+
+            for (ActualParameter targetParameter : targetParameters) {
+                NodeChildData field = sourceNode.findChild(targetParameter.getSpecification().getName());
+                if (!targetParameter.getSpecification().isSignature()) {
+                    continue;
+                }
+
+                TypeData targetType = targetParameter.getTypeSystemType();
+                ExecutableTypeData targetExecutable = null;
+                if (field != null) {
+                    targetExecutable = field.findExecutableType(getContext(), targetType);
+                }
+
+                ActualParameter sourceParameter = sourceExecutable.findParameter(targetParameter.getLocalName());
+
+                String targetVariableName = valueName(targetParameter);
+                CodeTree executionExpression = null;
+                if ((sourceParameter != null && cast) || sourceParameter != null) {
+                    TypeData sourceType = sourceParameter.getTypeSystemType();
+                    if (targetExecutable == null || !sourceType.needsCastTo(getContext(), targetType)) {
+                        if (field != null && field.isShortCircuit() && sourceParameter != null) {
+                            builder.tree(createShortCircuitValue(builder, specialization, field, targetParameter.getPreviousParameter(), unexpectedParameter));
+                        }
+                        builder.startStatement();
+                        builder.type(targetParameter.getType()).string(" ");
+                        builder.string(valueName(targetParameter)).string(" = ");
+                        builder.tree(CodeTreeBuilder.singleString(valueNameEvaluated(targetParameter)));
+                        builder.end();
+                        continue;
+                    } else {
+                        CodeTree valueTree = CodeTreeBuilder.singleString(valueNameEvaluated(targetParameter));
+                        executionExpression = createExpectExecutableType(sourceNode, sourceType, targetExecutable, valueTree);
+                    }
+                } else if (sourceParameter == null) {
+                    executionExpression = createExecuteChildExpression(builder, field, targetParameter, unexpectedParameter);
+                }
+
+                if (executionExpression != null) {
+                    CodeTreeVariable executionVar = new CodeTreeVariable();
+                    CodeTree shortCircuitTree = createShortCircuitTree(builder, executionVar, targetVariableName, specialization, targetParameter, unexpectedParameter);
+                    CodeTree unexpectedTree = createCatchUnexpectedTree(builder, executionExpression, targetVariableName, specialization, sourceExecutable, targetExecutable, targetParameter,
+                                    shortCircuitTree != executionVar);
+
+                    executionVar.set(unexpectedTree);
+                    builder.tree(shortCircuitTree);
+                }
+            }
+            return builder.getRoot();
+        }
+
+        private CodeTree createCatchUnexpectedTree(CodeTreeBuilder parent, CodeTree body, String targetVariableName, SpecializationData specialization, ExecutableTypeData currentExecutable,
+                        ExecutableTypeData targetExecutable, ActualParameter param, boolean shortCircuit) {
+            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
+            boolean unexpected = targetExecutable.hasUnexpectedValue(getContext());
+            boolean cast = false;
+            if (targetExecutable.getType().needsCastTo(getContext(), param.getTypeSystemType())) {
+                unexpected = true;
+                cast = true;
+            }
+
+            if (specialization.isGeneric() && unexpected) {
+                throw new AssertionError("Generic has unexpected parameters. " + specialization.toString());
+            }
+
+            builder.startStatement();
+
+            if (!shortCircuit) {
+                builder.type(param.getType()).string(" ").string(targetVariableName);
+            }
+
+            if (unexpected) {
+                if (!shortCircuit) {
+                    builder.end();
+                }
+                builder.startTryBlock();
+                builder.startStatement();
+                builder.string(targetVariableName);
+            } else if (shortCircuit) {
+                builder.startStatement();
+                builder.string(targetVariableName);
+            }
+            builder.string(" = ");
+            if (cast) {
+                builder.tree(createCastType(specialization.getNode(), targetExecutable.getType(), param.getTypeSystemType(), true, body));
+            } else {
+                builder.tree(body);
+            }
+            builder.end();
+
+            if (unexpected) {
+                builder.end().startCatchBlock(getUnexpectedValueException(), "ex");
+                SpecializationData generic = specialization.getNode().getGenericSpecialization();
+                ActualParameter genericParameter = generic.findParameter(param.getLocalName());
+
+                List<ActualParameter> genericParameters = generic.getParametersAfter(genericParameter);
+                builder.tree(createDeoptimize(builder));
+                builder.tree(createExecuteChildren(parent, currentExecutable, generic, genericParameters, genericParameter, false));
+                if (specialization.isPolymorphic()) {
+                    builder.tree(createReturnOptimizeTypes(builder, specialization, param));
+                } else {
+                    builder.tree(createReturnExecuteAndSpecialize(builder, currentExecutable, specialization.findNextSpecialization(), param, "Expected " + param.getLocalName() + " instanceof " +
+                                    Utils.getSimpleName(param.getType())));
+                }
+                builder.end(); // catch block
+            }
+
+            return builder.getRoot();
+        }
+
+        private CodeTree createReturnOptimizeTypes(CodeTreeBuilder parent, SpecializationData specialization, ActualParameter param) {
+            NodeData node = specialization.getNode();
+            assert !node.getPolymorphicSpecializations().isEmpty();
+            SpecializationData generic = node.getPolymorphicSpecializations().get(0);
+
+            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
+            builder.startReturn();
+
+            CodeTreeBuilder execute = new CodeTreeBuilder(builder);
+            execute.startCall("next0", "executeCached0");
+            addInternalValueParameterNames(execute, specialization, generic, param.getLocalName(), true, true);
+            execute.end();
+
+            TypeData sourceType = generic.getReturnType().getTypeSystemType();
+            TypeData targetType = specialization.getReturnType().getTypeSystemType();
+
+            builder.tree(createCastType(node, sourceType, targetType, true, execute.getRoot()));
+
+            builder.end();
+            return builder.getRoot();
+        }
+
+        private CodeTree createExecuteChildExpression(CodeTreeBuilder parent, NodeChildData targetField, ActualParameter sourceParameter, ActualParameter unexpectedParameter) {
+            TypeData type = sourceParameter.getTypeSystemType();
+            ExecutableTypeData execType = targetField.findExecutableType(getContext(), type);
+
+            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
+            if (targetField != null) {
+                Element accessElement = targetField.getAccessElement();
+                if (accessElement == null || accessElement.getKind() == ElementKind.METHOD) {
+                    builder.string("this.").string(targetField.getName());
+                } else if (accessElement.getKind() == ElementKind.FIELD) {
+                    builder.string("this.").string(accessElement.getSimpleName().toString());
+                } else {
+                    throw new AssertionError();
+                }
+                if (sourceParameter.getSpecification().isIndexed()) {
+                    builder.string("[" + sourceParameter.getIndex() + "]");
+                }
+                builder.string(".");
+            }
+
+            builder.startCall(execType.getMethodName());
+
+            int index = 0;
+            for (ActualParameter parameter : execType.getParameters()) {
+
+                if (!parameter.getSpecification().isSignature()) {
+                    builder.string(parameter.getLocalName());
+                } else {
+                    if (index < targetField.getExecuteWith().size()) {
+                        NodeChildData child = targetField.getExecuteWith().get(index);
+
+                        ParameterSpec spec = getModel().getSpecification().findParameterSpec(child.getName());
+                        List<ActualParameter> specializationParams = getModel().findParameters(spec);
+
+                        if (specializationParams.isEmpty()) {
+                            builder.defaultValue(parameter.getType());
+                            continue;
+                        }
+
+                        ActualParameter specializationParam = specializationParams.get(0);
+
+                        TypeData targetType = parameter.getTypeSystemType();
+                        TypeData sourceType = specializationParam.getTypeSystemType();
+                        String localName = specializationParam.getLocalName();
+
+                        if (unexpectedParameter != null && unexpectedParameter.getLocalName().equals(specializationParam.getLocalName())) {
+                            localName = "ex.getResult()";
+                            sourceType = getModel().getNode().getTypeSystem().getGenericTypeData();
+                        }
+
+                        CodeTree value = CodeTreeBuilder.singleString(localName);
+
+                        if (sourceType.needsCastTo(getContext(), targetType)) {
+                            value = createCallTypeSystemMethod(getContext(), builder, getModel().getNode(), TypeSystemCodeGenerator.asTypeMethodName(targetType), value);
+                        }
+                        builder.tree(value);
+                    } else {
+                        builder.defaultValue(parameter.getType());
+                    }
+                    index++;
+                }
+            }
+
+            builder.end();
+
+            return builder.getRoot();
+        }
+
+        private CodeTree createShortCircuitTree(CodeTreeBuilder parent, CodeTree body, String targetVariableName, SpecializationData specialization, ActualParameter parameter,
+                        ActualParameter exceptionParam) {
+            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
+
+            NodeChildData forField = specialization.getNode().findChild(parameter.getSpecification().getName());
+            if (forField == null) {
+                return body;
+            }
+
+            if (forField.getExecutionKind() != ExecutionKind.SHORT_CIRCUIT) {
+                return body;
+            }
+
+            ActualParameter shortCircuitParam = specialization.getPreviousParam(parameter);
+
+            builder.tree(createShortCircuitValue(builder, specialization, forField, shortCircuitParam, exceptionParam));
+
+            builder.declaration(parameter.getType(), targetVariableName, CodeTreeBuilder.createBuilder().defaultValue(parameter.getType()));
+            builder.startIf().string(shortCircuitParam.getLocalName()).end();
+            builder.startBlock();
+            builder.tree(body);
+            builder.end();
+
+            return builder.getRoot();
+        }
+
+        private CodeTree createShortCircuitValue(CodeTreeBuilder parent, SpecializationData specialization, NodeChildData forField, ActualParameter shortCircuitParam, ActualParameter exceptionParam) {
+            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
+            int shortCircuitIndex = 0;
+            for (NodeChildData field : specialization.getNode().getChildren()) {
+                if (field.getExecutionKind() == ExecutionKind.SHORT_CIRCUIT) {
+                    if (field == forField) {
+                        break;
+                    }
+                    shortCircuitIndex++;
+                }
+            }
+
+            builder.startStatement().type(shortCircuitParam.getType()).string(" ").string(valueName(shortCircuitParam)).string(" = ");
+            ShortCircuitData shortCircuitData = specialization.getShortCircuits().get(shortCircuitIndex);
+            builder.tree(createTemplateMethodCall(builder, null, specialization, shortCircuitData, exceptionParam != null ? exceptionParam.getLocalName() : null));
+            builder.end(); // statement
+
+            return builder.getRoot();
+        }
+
+        protected CodeTree createDeoptimize(CodeTreeBuilder parent) {
+            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
+            builder.startStatement();
+            builder.startStaticCall(getContext().getTruffleTypes().getCompilerDirectives(), "transferToInterpreter").end();
+            builder.end();
+            return builder.getRoot();
+        }
+
+        protected CodeTree createReturnExecuteAndSpecialize(CodeTreeBuilder parent, ExecutableTypeData executable, SpecializationData nextSpecialization, ActualParameter exceptionParam, String reason) {
+            SpecializationData generic = getModel().getNode().getGenericSpecialization();
+            CodeTreeBuilder specializeCall = new CodeTreeBuilder(parent);
+            specializeCall.startCall(EXECUTE_SPECIALIZE_NAME);
+            specializeCall.string(nodeSpecializationClassName(nextSpecialization) + ".class");
+            addInternalValueParameterNames(specializeCall, generic, nextSpecialization.getNode().getGenericSpecialization(), exceptionParam != null ? exceptionParam.getLocalName() : null, true, true);
+            specializeCall.doubleQuote(reason);
+            specializeCall.end().end();
+
+            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
+
+            builder.startReturn();
+            builder.tree(createExpectExecutableType(nextSpecialization.getNode(), generic.getReturnType().getTypeSystemType(), executable, specializeCall.getRoot()));
+            builder.end();
+
+            return builder.getRoot();
+        }
+    }
+
+    private class PolymorphicNodeFactory extends SpecializedNodeFactory {
+
+        private final boolean generic;
+
+        public PolymorphicNodeFactory(ProcessorContext context, CodeTypeElement nodeGen, boolean generic) {
+            super(context, nodeGen);
+            this.generic = generic;
+        }
+
+        @Override
+        public CodeTypeElement create(SpecializationData specialization) {
+            NodeData node = specialization.getNode();
+            TypeMirror baseType = node.getNodeType();
+            if (nodeGen != null) {
+                baseType = nodeGen.asType();
+            }
+            CodeTypeElement clazz = createClass(node, modifiers(PRIVATE, STATIC), nodePolymorphicClassName(node, specialization), baseType, false);
+
+            if (!generic) {
+                clazz.getModifiers().add(Modifier.FINAL);
+            }
+
+            clazz.getAnnotationMirrors().add(createNodeInfo(node, Kind.POLYMORPHIC));
+
+            return clazz;
+        }
+
+        @Override
+        protected void createChildren(SpecializationData specialization) {
+// super.createChildren(specialization);
+            CodeTypeElement clazz = getElement();
+
+            createConstructors(clazz);
+            createExecuteMethods(specialization);
+
+            if (generic) {
+                getElement().add(createOptimizeTypes());
+                createCachedExecuteMethods(specialization);
+            }
+        }
+
+        private CodeExecutableElement createOptimizeTypes() {
+            NodeData node = getModel().getNode();
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), getContext().getType(void.class), "optimizeTypes");
+            CodeTreeBuilder builder = method.createBuilder();
+            builder.startStatement().string(baseClassName(node)).string(" node = this.next0").end();
+            TypeMirror classType = getContext().getType(Class.class);
+
+            SpecializationData genericSpecialization = node.getGenericSpecialization();
+
+            CodeTreeBuilder whileBodyBuilder = builder.create();
+            for (ActualParameter parameter : node.getGenericSpecialization().getReturnTypeAndParameters()) {
+                if (!parameter.getSpecification().isSignature()) {
+                    continue;
+                }
+
+                ActualParameter genericParameter = genericSpecialization.findParameter(parameter.getLocalName());
+
+                String name = parameter.getLocalName() + "Type";
+
+                builder.declaration(classType, name, builder.create().startCall("node", typeGetterName(parameter)).end().getRoot());
+
+                whileBodyBuilder.startIf().string(name).string(" != ").startCall("node", typeGetterName(parameter)).end().end();
+                whileBodyBuilder.startBlock();
+                whileBodyBuilder.startStatement().string(name).string(" = ").typeLiteral(genericParameter.getType()).end();
+                whileBodyBuilder.end();
+            }
+
+            builder.startWhile().string("node != null && !(").instanceOf("node", nodeSpecializationClassName(node.getUninitializedSpecialization())).string(")").end();
+            builder.startBlock();
+            builder.tree(whileBodyBuilder.getRoot());
+            builder.statement("node = node.next0");
+            builder.end();
+
+            boolean elseIf = false;
+            for (SpecializationData polymorph : node.getPolymorphicSpecializations()) {
+                elseIf = builder.startIf(elseIf);
+                String and = "";
+                StringBuilder reason = new StringBuilder("Optimized polymorphic types for (");
+                for (ActualParameter parameter : polymorph.getReturnTypeAndParameters()) {
+                    if (!parameter.getSpecification().isSignature()) {
+                        continue;
+                    }
+                    String name = parameter.getLocalName() + "Type";
+                    builder.string(and).string(name).string(" == ").typeLiteral(parameter.getType());
+
+                    if (!and.isEmpty()) {
+                        reason.append(", ");
+                    }
+                    reason.append(Utils.getSimpleName(parameter.getType()));
+                    and = " && ";
+                }
+                reason.append(")");
+                builder.end();
+                builder.startBlock();
+
+                String className = nodePolymorphicClassName(node, polymorph);
+                builder.startIf().string("getClass() != ").string(className).string(".class").end();
+                builder.startBlock();
+                builder.startStatement().startCall("super", "replace");
+                builder.startNew(className).string("this").end();
+                builder.doubleQuote(reason.toString());
+                builder.end().end(); // call
+                builder.end(); // block
+                builder.end();
+            }
+            return method;
+        }
+    }
+
+    private class SpecializedNodeFactory extends NodeBaseFactory {
+
+        protected final CodeTypeElement nodeGen;
+
+        public SpecializedNodeFactory(ProcessorContext context, CodeTypeElement nodeGen) {
+            super(context);
+            this.nodeGen = nodeGen;
+        }
+
+        @Override
+        public CodeTypeElement create(SpecializationData specialization) {
+            NodeData node = specialization.getNode();
+            TypeMirror baseType = node.getNodeType();
+            if (nodeGen != null) {
+                baseType = nodeGen.asType();
+            }
+            CodeTypeElement clazz = createClass(node, modifiers(PRIVATE, STATIC, FINAL), nodeSpecializationClassName(specialization), baseType, false);
+
+            Kind kind;
+            if (specialization.isGeneric()) {
+                kind = Kind.GENERIC;
+            } else if (specialization.isUninitialized()) {
+                kind = Kind.UNINITIALIZED;
+            } else {
+                kind = Kind.SPECIALIZED;
+            }
+            clazz.getAnnotationMirrors().add(createNodeInfo(node, kind));
+
+            return clazz;
+        }
+
+        protected CodeAnnotationMirror createNodeInfo(NodeData node, Kind kind) {
+            String shortName = node.getShortName();
+            CodeAnnotationMirror nodeInfoMirror = new CodeAnnotationMirror(getContext().getTruffleTypes().getNodeInfoAnnotation());
+            if (shortName != null) {
+                nodeInfoMirror.setElementValue(nodeInfoMirror.findExecutableElement("shortName"), new CodeAnnotationValue(shortName));
+            }
+
+            DeclaredType nodeinfoKind = getContext().getTruffleTypes().getNodeInfoKind();
+            VariableElement varKind = Utils.findVariableElement(nodeinfoKind, kind.name());
+
+            nodeInfoMirror.setElementValue(nodeInfoMirror.findExecutableElement("kind"), new CodeAnnotationValue(varKind));
+            return nodeInfoMirror;
+        }
+
+        @Override
+        protected void createChildren(SpecializationData specialization) {
+            CodeTypeElement clazz = getElement();
+            createConstructors(clazz);
+
+            NodeData node = specialization.getNode();
+
+            if (!specialization.isGeneric() && !specialization.isUninitialized() && !specialization.isPolymorphic() && node.needsRewrites(getContext()) && node.getPolymorphicDepth() > 1) {
+
+                createTypeGetters(clazz, specialization);
+            }
+
+            createExecuteMethods(specialization);
+            createCachedExecuteMethods(specialization);
+        }
+
+        protected void createConstructors(CodeTypeElement clazz) {
+            TypeElement superTypeElement = Utils.fromTypeMirror(clazz.getSuperclass());
+            for (ExecutableElement constructor : ElementFilter.constructorsIn(superTypeElement.getEnclosedElements())) {
+                if (getModel().getNode().getUninitializedSpecialization() != null && !getModel().isUninitialized() &&
+                                (constructor.getParameters().size() != 1 || constructor.getParameters().get(0).getSimpleName().toString().equals(baseClassName(getModel().getNode())))) {
+                    continue;
+                }
+
+                CodeExecutableElement superConstructor = createSuperConstructor(clazz, constructor);
+                if (superConstructor != null) {
+                    if (getModel().isGeneric() && getModel().getNode().getPolymorphicDepth() > 1) {
+                        CodeTree body = superConstructor.getBodyTree();
+                        CodeTreeBuilder builder = superConstructor.createBuilder();
+                        builder.tree(body);
+                        builder.statement("this.next0 = null");
+                    }
+
+                    clazz.add(superConstructor);
+                }
+            }
+        }
+
+        protected void createExecuteMethods(SpecializationData specialization) {
+            NodeData node = specialization.getNode();
+            CodeTypeElement clazz = getElement();
+
+            for (ExecutableTypeData execType : node.getExecutableTypes()) {
+                if (execType.isFinal()) {
+                    continue;
+                }
+                CodeExecutableElement executeMethod = createExecutableTypeOverride(execType, true);
+                clazz.add(executeMethod);
+                CodeTreeBuilder builder = executeMethod.createBuilder();
+                CodeTree result = createExecuteBody(builder, specialization, execType);
+                if (result != null) {
+                    builder.tree(result);
+                } else {
+                    clazz.remove(executeMethod);
+                }
+            }
+        }
+
+        protected void createCachedExecuteMethods(SpecializationData specialization) {
+            NodeData node = specialization.getNode();
+            CodeTypeElement clazz = getElement();
+            int index = 0;
+            for (SpecializationData polymorphic : node.getPolymorphicSpecializations()) {
+                boolean matchFound = false;
+                if (!specialization.isGeneric() && !specialization.isUninitialized() && !specialization.isPolymorphic()) {
+                    matchFound = polymorphic.getSignature().hasAnyParameterMatch(specialization.getSignature());
+                }
+
+                if (matchFound || index == 0) {
+                    ExecutableElement executeCached = nodeGen.getMethod("executeCached" + index);
+                    ExecutableTypeData execType = new ExecutableTypeData(polymorphic, executeCached, node.getTypeSystem(), polymorphic.getReturnType().getTypeSystemType());
+
+                    CodeExecutableElement executeMethod = createExecutableTypeOverride(execType, false);
+                    CodeTreeBuilder builder = executeMethod.createBuilder();
+
+                    if (specialization.isGeneric() || specialization.isPolymorphic()) {
+                        builder.startThrow().startNew(getContext().getType(AssertionError.class));
+                        builder.doubleQuote("Should not be reached.");
+                        builder.end().end();
+                    } else if (specialization.isUninitialized()) {
+                        builder.tree(createAppendPolymorphic(builder, specialization));
+                    } else {
+                        CodeTreeBuilder elseBuilder = new CodeTreeBuilder(builder);
+                        elseBuilder.startReturn().startCall("this.next0", "executeCached" + index);
+                        addInternalValueParameterNames(elseBuilder, polymorphic, polymorphic, null, true, true);
+                        elseBuilder.end().end();
+                        CodeTreeBuilder execute = new CodeTreeBuilder(builder);
+                        execute.tree(createGenericInvoke(builder, polymorphic, specialization));
+                        boolean forceElse = !specialization.getExceptions().isEmpty();
+                        builder.tree(createGuardAndCast(builder, null, polymorphic, specialization, true, execute.getRoot(), elseBuilder.getRoot(), true, forceElse));
+                    }
+                    clazz.add(executeMethod);
+                }
+                index++;
+            }
+        }
+
+        private CodeTree createAppendPolymorphic(CodeTreeBuilder parent, SpecializationData specialization) {
+            NodeData node = specialization.getNode();
+            String genericClassName = nodePolymorphicClassName(node, null);
+
+            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
+            builder.startStatement().startStaticCall(getContext().getTruffleTypes().getCompilerDirectives(), "transferToInterpreter").end().end();
+
+            builder.declaration(getContext().getTruffleTypes().getNode(), "searchNode", "super.getParent()");
+            builder.declaration(getContext().getType(int.class), "depth", "0");
+            builder.startWhile().string("searchNode != null").end();
+            builder.startBlock();
+            builder.statement("depth++");
+            builder.statement("searchNode = searchNode.getParent()");
+
+            builder.startIf().instanceOf("searchNode", genericClassName).end();
+            builder.startBlock().breakStatement().end();
+            builder.end(); // if
+            builder.end(); // while
+
+            builder.startAssert().instanceOf("searchNode", genericClassName).end();
+
+            builder.startStatement();
+            builder.string(genericClassName).string(" ").string("polymorphic = ").string("(").string(genericClassName).string(") searchNode");
+            builder.end();
+
+            builder.startIf().string("depth >= ").string(String.valueOf(node.getPolymorphicDepth())).end();
+            builder.startBlock();
+            builder.startStatement();
+            builder.startCall("searchNode", "replace");
+            builder.startNew(nodeSpecializationClassName(node.getGenericSpecialization())).string("this").end();
+            builder.doubleQuote("Polymorphic limit reached (" + node.getPolymorphicDepth() + ")");
+            builder.end();
+            builder.end();
+
+            builder.startReturn().startCall("super", EXECUTE_GENERIC_NAME);
+            addInternalValueParameterNames(builder, specialization, node.getGenericSpecialization(), null, true, true);
+            builder.end().end();
+
+            builder.end().startElseBlock();
+            builder.startStatement().startCall("super", "setNext0");
+            builder.startNew(nodeSpecializationClassName(node.getUninitializedSpecialization())).string("this").end();
+            builder.end().end();
+
+            CodeTreeBuilder specializeCall = new CodeTreeBuilder(builder);
+            specializeCall.startCall(EXECUTE_SPECIALIZE_NAME);
+            specializeCall.string(nodeSpecializationClassName(node.getUninitializedSpecialization()) + ".class");
+            addInternalValueParameterNames(specializeCall, specialization, node.getGenericSpecialization(), null, true, true);
+            specializeCall.startGroup().doubleQuote("Uninitialized polymorphic (").string(" + depth + ").doubleQuote("/" + node.getPolymorphicDepth() + ")").end();
+            specializeCall.end().end();
+
+            builder.declaration(node.getGenericSpecialization().getReturnType().getType(), "result", specializeCall.getRoot());
+
+            builder.statement("polymorphic.optimizeTypes()");
+
+            if (Utils.isVoid(builder.findMethod().getReturnType())) {
+                builder.returnStatement();
+            } else {
+                builder.startReturn().string("result").end();
+            }
+
+            builder.end();
+
+            return builder.getRoot();
+        }
+
+        private CodeTree createExecuteBody(CodeTreeBuilder parent, SpecializationData specialization, ExecutableTypeData execType) {
+            TypeData primaryType = specialization.getReturnType().getTypeSystemType();
+
+            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
+
+            List<ExecutableTypeData> primaryExecutes = findFunctionalExecutableType(specialization, execType.getEvaluatedCount());
+
+            if (primaryExecutes.contains(execType) || primaryExecutes.isEmpty()) {
+                builder.tree(createFunctionalExecute(builder, specialization, execType));
+            } else if (needsCastingExecuteMethod(execType, primaryType)) {
+                assert !primaryExecutes.isEmpty();
+                builder.tree(createCastingExecute(builder, specialization, execType, primaryExecutes.get(0)));
+            } else {
+                return null;
+            }
+
+            return builder.getRoot();
+        }
+
+        private CodeExecutableElement createExecutableTypeOverride(ExecutableTypeData execType, boolean evaluated) {
+            CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), execType.getMethod());
+
+            int i = 0;
+            for (VariableElement param : method.getParameters()) {
+                CodeVariableElement var = CodeVariableElement.clone(param);
+                ActualParameter actualParameter = execType.getParameters().get(i);
+                if (evaluated && actualParameter.getSpecification().isSignature()) {
+                    var.setName(valueNameEvaluated(actualParameter));
+                } else {
+                    var.setName(valueName(actualParameter));
+                }
+                method.getParameters().set(i, var);
+                i++;
+            }
+
+            method.getAnnotationMirrors().clear();
+            method.getModifiers().remove(Modifier.ABSTRACT);
+            return method;
+        }
+
+        private boolean needsCastingExecuteMethod(ExecutableTypeData execType, TypeData primaryType) {
+            if (execType.isAbstract()) {
+                return true;
+            }
+            if (Utils.isPrimitiveOrVoid(primaryType.getPrimitiveType()) && Utils.isPrimitiveOrVoid(execType.getType().getPrimitiveType())) {
+                return true;
+            }
+            if (execType.getType().isGeneric()) {
+                return true;
+            }
+            return false;
+        }
+
+        private List<ExecutableTypeData> findFunctionalExecutableType(SpecializationData specialization, int evaluatedCount) {
+            TypeData primaryType = specialization.getReturnType().getTypeSystemType();
+            List<ExecutableTypeData> otherTypes = specialization.getNode().getExecutableTypes(evaluatedCount);
+
+            List<ExecutableTypeData> filteredTypes = new ArrayList<>();
+            for (ExecutableTypeData compareType : otherTypes) {
+                if (!Utils.typeEquals(compareType.getType().getPrimitiveType(), primaryType.getPrimitiveType())) {
+                    continue;
+                }
+                filteredTypes.add(compareType);
+            }
+
+            // no direct matches found use generic where the type is Object
+            if (filteredTypes.isEmpty()) {
+                for (ExecutableTypeData compareType : otherTypes) {
+                    if (compareType.getType().isGeneric() && !compareType.hasUnexpectedValue(getContext())) {
+                        filteredTypes.add(compareType);
+                    }
+                }
+            }
+
+            if (filteredTypes.isEmpty()) {
+                for (ExecutableTypeData compareType : otherTypes) {
+                    if (compareType.getType().isGeneric()) {
+                        filteredTypes.add(compareType);
+                    }
+                }
+            }
+
+            return filteredTypes;
+        }
+
+        private CodeTree createFunctionalExecute(CodeTreeBuilder parent, SpecializationData specialization, ExecutableTypeData executable) {
+            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
+            if (specialization.isUninitialized()) {
+                builder.tree(createDeoptimize(builder));
+            }
+
+            builder.tree(createExecuteChildren(builder, executable, specialization, specialization.getParameters(), null, false));
+
+            CodeTree executeNode = createExecute(builder, executable, specialization);
+
+            SpecializationData next = specialization.findNextSpecialization();
+            CodeTree returnSpecialized = null;
+            if (next != null) {
+                CodeTreeBuilder returnBuilder = new CodeTreeBuilder(builder);
+                returnBuilder.tree(createDeoptimize(builder));
+                returnBuilder.tree(createReturnExecuteAndSpecialize(builder, executable, next, null, "One of guards " + specialization.getGuards() + " failed"));
+                returnSpecialized = returnBuilder.getRoot();
+            }
+            builder.tree(createGuardAndCast(builder, null, specialization, specialization, true, executeNode, returnSpecialized, false, false));
+
+            return builder.getRoot();
+        }
+
+        private CodeTree createExecute(CodeTreeBuilder parent, ExecutableTypeData executable, SpecializationData specialization) {
+            NodeData node = specialization.getNode();
+            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
+            if (!specialization.getExceptions().isEmpty() || !specialization.getAssumptions().isEmpty()) {
+                builder.startTryBlock();
+            }
+
+            for (String assumption : specialization.getAssumptions()) {
+                builder.startStatement();
+                builder.string("this.").string(assumption).string(".check()");
+                builder.end();
+            }
+
+            CodeTreeBuilder returnBuilder = new CodeTreeBuilder(parent);
+            if (specialization.isPolymorphic()) {
+                int index = 0;
+                if (executable.hasUnexpectedValue(getContext())) {
+                    index = specialization.getNode().getPolymorphicSpecializations().indexOf(specialization);
+                }
+                returnBuilder.startCall("next0", "executeCached" + index);
+                addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, true);
+                returnBuilder.end();
+            } else if (specialization.isUninitialized()) {
+                returnBuilder.startCall("super", EXECUTE_SPECIALIZE_NAME);
+                returnBuilder.startGroup().string(nodeSpecializationClassName(specialization)).string(".class").end();
+                addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, true);
+                returnBuilder.doubleQuote("Uninitialized monomorphic");
+                returnBuilder.end();
+            } else if (specialization.getMethod() == null && !node.needsRewrites(context)) {
+                emitEncounteredSynthetic(builder, specialization);
+            } else if (specialization.isGeneric()) {
+                returnBuilder.startCall("super", EXECUTE_GENERIC_NAME);
+                addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, true);
+                returnBuilder.end();
+            } else {
+                returnBuilder.tree(createTemplateMethodCall(returnBuilder, null, specialization, specialization, null));
+            }
+
+            if (!returnBuilder.isEmpty()) {
+                builder.startReturn();
+
+                TypeData targetType = node.getTypeSystem().findTypeData(builder.findMethod().getReturnType());
+                TypeData sourceType = specialization.getReturnType().getTypeSystemType();
+
+                if (targetType == null || sourceType == null) {
+                    builder.tree(returnBuilder.getRoot());
+                } else if (sourceType.needsCastTo(getContext(), targetType)) {
+                    builder.tree(createCallTypeSystemMethod(context, parent, node, TypeSystemCodeGenerator.expectTypeMethodName(targetType), returnBuilder.getRoot()));
+                } else {
+                    builder.tree(returnBuilder.getRoot());
+                }
+                builder.end();
+            }
+
+            if (!specialization.getExceptions().isEmpty()) {
+                for (SpecializationThrowsData exception : specialization.getExceptions()) {
+                    builder.end().startCatchBlock(exception.getJavaClass(), "ex");
+                    builder.tree(createDeoptimize(builder));
+                    builder.tree(createReturnExecuteAndSpecialize(parent, executable, exception.getTransitionTo(), null, "Thrown " + Utils.getSimpleName(exception.getJavaClass())));
+                }
+                builder.end();
+            }
+            if (!specialization.getAssumptions().isEmpty()) {
+                builder.end().startCatchBlock(getContext().getTruffleTypes().getInvalidAssumption(), "ex");
+                builder.tree(createReturnExecuteAndSpecialize(parent, executable, specialization.findNextSpecialization(), null, "Assumption failed"));
+                builder.end();
+            }
+
+            return builder.getRoot();
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeData.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,552 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.node;
+
+import java.util.*;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.node.NodeChildData.*;
+import com.oracle.truffle.dsl.processor.template.*;
+import com.oracle.truffle.dsl.processor.typesystem.*;
+
+public class NodeData extends Template {
+
+    private final String nodeId;
+    private NodeData declaringNode;
+    private List<NodeData> declaredNodes = new ArrayList<>();
+    private boolean nodeContainer;
+
+    private TypeSystemData typeSystem;
+    private List<NodeChildData> children;
+    private List<NodeFieldData> fields;
+    private TypeMirror nodeType;
+    private ParameterSpec instanceParameterSpec;
+
+    private List<SpecializationData> specializations;
+    private List<SpecializationData> polymorphicSpecializations;
+    private List<SpecializationListenerData> specializationListeners;
+    private Map<Integer, List<ExecutableTypeData>> executableTypes;
+    private List<ShortCircuitData> shortCircuits;
+    private List<String> assumptions;
+    private List<CreateCastData> casts;
+
+    private int polymorphicDepth = -1;
+    private String shortName;
+
+    public NodeData(TypeElement type, String id) {
+        super(type, null, null);
+        this.nodeId = id;
+    }
+
+    public NodeData(NodeData splitSource, String templateMethodName, String nodeId) {
+        super(splitSource.getTemplateType(), templateMethodName, null);
+        this.nodeId = nodeId;
+        this.declaringNode = splitSource.declaringNode;
+        this.declaredNodes = splitSource.declaredNodes;
+        this.typeSystem = splitSource.typeSystem;
+        this.nodeType = splitSource.nodeType;
+        this.specializations = splitSource.specializations;
+        this.specializationListeners = splitSource.specializationListeners;
+        this.executableTypes = splitSource.executableTypes;
+        this.shortCircuits = splitSource.shortCircuits;
+        this.fields = splitSource.fields;
+        this.children = splitSource.children;
+        this.assumptions = splitSource.assumptions;
+    }
+
+    public int getPolymorphicDepth() {
+        return polymorphicDepth;
+    }
+
+    void setPolymorphicDepth(int polymorphicDepth) {
+        this.polymorphicDepth = polymorphicDepth;
+    }
+
+    public List<CreateCastData> getCasts() {
+        return casts;
+    }
+
+    void setCasts(List<CreateCastData> casts) {
+        this.casts = casts;
+    }
+
+    void setShortName(String shortName) {
+        this.shortName = shortName;
+    }
+
+    public String getShortName() {
+        return shortName;
+    }
+
+    public boolean isNodeContainer() {
+        return nodeContainer;
+    }
+
+    void setTypeSystem(TypeSystemData typeSystem) {
+        this.typeSystem = typeSystem;
+    }
+
+    void setFields(List<NodeFieldData> fields) {
+        this.fields = fields;
+    }
+
+    public List<NodeFieldData> getFields() {
+        return fields;
+    }
+
+    void setNodeContainer(boolean splitByMethodName) {
+        this.nodeContainer = splitByMethodName;
+    }
+
+    @Override
+    protected List<MessageContainer> findChildContainers() {
+        List<MessageContainer> containerChildren = new ArrayList<>();
+        if (declaredNodes != null) {
+            containerChildren.addAll(declaredNodes);
+        }
+        if (typeSystem != null) {
+            containerChildren.add(typeSystem);
+        }
+        if (specializations != null) {
+            for (MessageContainer specialization : specializations) {
+                if (specialization.getMessageElement() != null) {
+                    containerChildren.add(specialization);
+                }
+            }
+        }
+        if (specializationListeners != null) {
+            containerChildren.addAll(specializationListeners);
+        }
+        if (executableTypes != null) {
+            containerChildren.addAll(getExecutableTypes());
+        }
+        if (shortCircuits != null) {
+            containerChildren.addAll(shortCircuits);
+        }
+        if (children != null) {
+            containerChildren.addAll(children);
+        }
+        if (fields != null) {
+            containerChildren.addAll(fields);
+        }
+        if (casts != null) {
+            containerChildren.addAll(casts);
+        }
+        return containerChildren;
+    }
+
+    public ParameterSpec getInstanceParameterSpec() {
+        return instanceParameterSpec;
+    }
+
+    public void setInstanceParameterSpec(ParameterSpec instanceParameter) {
+        this.instanceParameterSpec = instanceParameter;
+    }
+
+    public String getNodeId() {
+        return nodeId;
+    }
+
+    public TypeMirror getNodeType() {
+        if (nodeType != null) {
+            return nodeType;
+        }
+        return getTemplateType().asType();
+    }
+
+    void setAssumptions(List<String> assumptions) {
+        this.assumptions = assumptions;
+    }
+
+    public List<String> getAssumptions() {
+        return assumptions;
+    }
+
+    public boolean needsFactory() {
+        if (specializations == null) {
+            return false;
+        }
+        if (getTemplateType().getModifiers().contains(Modifier.PRIVATE)) {
+            return false;
+        }
+
+        boolean noSpecialization = true;
+        for (SpecializationData specialization : specializations) {
+            noSpecialization = noSpecialization && specialization.isGeneric() || specialization.isUninitialized();
+        }
+        return !noSpecialization;
+    }
+
+    public boolean supportsFrame() {
+        if (executableTypes != null) {
+            for (ExecutableTypeData execType : getExecutableTypes(-1)) {
+                if (execType.findParameter("frameValue") == null) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    public List<NodeData> getNodeDeclaringChildren() {
+        List<NodeData> nodeChildren = new ArrayList<>();
+        for (NodeData child : getDeclaredNodes()) {
+            if (child.needsFactory()) {
+                nodeChildren.add(child);
+            }
+            nodeChildren.addAll(child.getNodeDeclaringChildren());
+        }
+        return nodeChildren;
+    }
+
+    void setDeclaredNodes(List<NodeData> declaredChildren) {
+        this.declaredNodes = declaredChildren;
+
+        for (NodeData child : declaredChildren) {
+            child.declaringNode = this;
+        }
+    }
+
+    public NodeData getParent() {
+        return declaringNode;
+    }
+
+    public List<NodeData> getDeclaredNodes() {
+        return declaredNodes;
+    }
+
+    public void setNodeType(TypeMirror nodeType) {
+        this.nodeType = nodeType;
+    }
+
+    public List<TemplateMethod> getAllTemplateMethods() {
+        List<TemplateMethod> methods = new ArrayList<>();
+
+        for (SpecializationData specialization : getSpecializations()) {
+            methods.add(specialization);
+        }
+
+        methods.addAll(getSpecializationListeners());
+        methods.addAll(getExecutableTypes());
+        methods.addAll(getShortCircuits());
+        if (getCasts() != null) {
+            methods.addAll(getCasts());
+        }
+
+        return methods;
+    }
+
+    public ExecutableTypeData findGenericExecutableType(ProcessorContext context, TypeData type, int evaluatedCount) {
+        List<ExecutableTypeData> types = findGenericExecutableTypes(context, evaluatedCount);
+        for (ExecutableTypeData availableType : types) {
+            if (Utils.typeEquals(availableType.getType().getBoxedType(), type.getBoxedType())) {
+                return availableType;
+            }
+        }
+        return null;
+    }
+
+    public ExecutableTypeData findAnyGenericExecutableType(ProcessorContext context, int evaluatedCount) {
+        List<ExecutableTypeData> types = findGenericExecutableTypes(context, evaluatedCount);
+        for (ExecutableTypeData type : types) {
+            if (type.getType().isGeneric()) {
+                return type;
+            }
+        }
+
+        for (ExecutableTypeData type : types) {
+            if (!type.getType().isVoid()) {
+                return type;
+            }
+        }
+
+        for (ExecutableTypeData type : types) {
+            return type;
+        }
+        return null;
+    }
+
+    public List<ExecutableTypeData> getExecutableTypes(int evaluatedCount) {
+        if (executableTypes == null) {
+            return Collections.emptyList();
+        }
+        if (evaluatedCount == -1) {
+            List<ExecutableTypeData> typeData = new ArrayList<>();
+            for (int currentEvaluationCount : executableTypes.keySet()) {
+                typeData.addAll(executableTypes.get(currentEvaluationCount));
+            }
+            return typeData;
+        } else {
+            List<ExecutableTypeData> types = executableTypes.get(evaluatedCount);
+            if (types == null) {
+                return Collections.emptyList();
+            }
+            return types;
+        }
+    }
+
+    public List<ExecutableTypeData> findGenericExecutableTypes(ProcessorContext context, int evaluatedCount) {
+        List<ExecutableTypeData> types = new ArrayList<>();
+        for (ExecutableTypeData type : getExecutableTypes(evaluatedCount)) {
+            if (!type.hasUnexpectedValue(context)) {
+                types.add(type);
+            }
+        }
+        return types;
+    }
+
+    public ExecutableTypeData findExecutableType(TypeData prmitiveType, int evaluatedCount) {
+        for (ExecutableTypeData type : getExecutableTypes(evaluatedCount)) {
+            if (Utils.typeEquals(type.getType().getPrimitiveType(), prmitiveType.getPrimitiveType())) {
+                return type;
+            }
+        }
+        return null;
+    }
+
+    public SpecializationData findUniqueSpecialization(TypeData type) {
+        SpecializationData result = null;
+        for (SpecializationData specialization : specializations) {
+            if (specialization.getReturnType().getTypeSystemType() == type) {
+                if (result != null) {
+                    // Result not unique;
+                    return null;
+                }
+                result = specialization;
+            }
+        }
+        return result;
+    }
+
+    public NodeChildData[] filterFields(ExecutionKind usage) {
+        List<NodeChildData> filteredFields = new ArrayList<>();
+        for (NodeChildData field : getChildren()) {
+            if (usage == null || field.getExecutionKind() == usage) {
+                filteredFields.add(field);
+            }
+        }
+        return filteredFields.toArray(new NodeChildData[filteredFields.size()]);
+    }
+
+    public boolean needsRewrites(ProcessorContext context) {
+        boolean needsRewrites = false;
+
+        for (SpecializationData specialization : getSpecializations()) {
+            if (specialization.hasRewrite(context)) {
+                needsRewrites = true;
+                break;
+            }
+        }
+        return needsRewrites || getSpecializations().size() > 1;
+    }
+
+    public SpecializationData getGenericSpecialization() {
+        for (SpecializationData specialization : specializations) {
+            if (specialization.isGeneric()) {
+                return specialization;
+            }
+        }
+        return null;
+    }
+
+    public SpecializationData getUninitializedSpecialization() {
+        for (SpecializationData specialization : specializations) {
+            if (specialization.isUninitialized()) {
+                return specialization;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public TypeSystemData getTypeSystem() {
+        return typeSystem;
+    }
+
+    public String dump() {
+        return dump(0);
+    }
+
+    private String dump(int level) {
+        String indent = "";
+        for (int i = 0; i < level; i++) {
+            indent += "    ";
+        }
+        StringBuilder builder = new StringBuilder();
+
+        builder.append(String.format("%s%s {", indent, toString()));
+
+        dumpProperty(builder, indent, "templateClass", Utils.getQualifiedName(getTemplateType()));
+        dumpProperty(builder, indent, "typeSystem", getTypeSystem());
+        dumpProperty(builder, indent, "fields", getChildren());
+        dumpProperty(builder, indent, "executableTypes", getExecutableTypes());
+        dumpProperty(builder, indent, "specializations", getSpecializations());
+        dumpProperty(builder, indent, "polymorphicDepth", getPolymorphicDepth());
+        dumpProperty(builder, indent, "polymorphic", getPolymorphicSpecializations());
+        dumpProperty(builder, indent, "assumptions", getAssumptions());
+        dumpProperty(builder, indent, "casts", getCasts());
+        dumpProperty(builder, indent, "messages", collectMessages());
+        if (getDeclaredNodes().size() > 0) {
+            builder.append(String.format("\n%s  children = [", indent));
+            for (NodeData node : getDeclaredNodes()) {
+                builder.append("\n");
+                builder.append(node.dump(level + 1));
+            }
+            builder.append(String.format("\n%s  ]", indent));
+        }
+        builder.append(String.format("%s}", indent));
+        return builder.toString();
+    }
+
+    private static void dumpProperty(StringBuilder b, String indent, String propertyName, Object value) {
+        if (value instanceof List) {
+            List<?> list = (List<?>) value;
+            if (!list.isEmpty()) {
+                b.append(String.format("\n%s  %s = %s", indent, propertyName, dumpList(indent, (List<?>) value)));
+            }
+        } else {
+            if (value != null) {
+                b.append(String.format("\n%s  %s = %s", indent, propertyName, value));
+            }
+        }
+    }
+
+    private static String dumpList(String indent, List<?> array) {
+        if (array == null) {
+            return "null";
+        }
+
+        if (array.isEmpty()) {
+            return "[]";
+        } else if (array.size() == 1) {
+            return "[" + array.get(0).toString() + "]";
+        }
+
+        StringBuilder b = new StringBuilder();
+        b.append("[");
+        for (Object object : array) {
+            b.append("\n        ");
+            b.append(indent);
+            b.append(object);
+            b.append(", ");
+        }
+        b.append("\n    ").append(indent).append("]");
+        return b.toString();
+    }
+
+    public NodeChildData findChild(String name) {
+        for (NodeChildData field : getChildren()) {
+            if (field.getName().equals(name)) {
+                return field;
+            }
+        }
+        return null;
+    }
+
+    public List<NodeChildData> getChildren() {
+        return children;
+    }
+
+    void setChildren(List<NodeChildData> fields) {
+        this.children = fields;
+    }
+
+    public List<SpecializationData> getSpecializations() {
+        return getSpecializations(false);
+    }
+
+    public List<SpecializationData> getSpecializations(boolean userDefinedOnly) {
+        if (userDefinedOnly) {
+            List<SpecializationData> specs = new ArrayList<>();
+            for (SpecializationData spec : specializations) {
+                if (spec.getMethod() != null) {
+                    specs.add(spec);
+                }
+            }
+            return specs;
+        } else {
+            return specializations;
+        }
+    }
+
+    public List<SpecializationListenerData> getSpecializationListeners() {
+        return specializationListeners;
+    }
+
+    public List<ExecutableTypeData> getExecutableTypes() {
+        return getExecutableTypes(-1);
+    }
+
+    public List<ShortCircuitData> getShortCircuits() {
+        return shortCircuits;
+    }
+
+    void setSpecializations(List<SpecializationData> specializations) {
+        this.specializations = specializations;
+        if (this.specializations != null) {
+            for (SpecializationData specialization : specializations) {
+                specialization.setNode(this);
+            }
+        }
+    }
+
+    void setPolymorphicSpecializations(List<SpecializationData> polymorphicSpecializations) {
+        this.polymorphicSpecializations = polymorphicSpecializations;
+    }
+
+    public List<SpecializationData> getPolymorphicSpecializations() {
+        return polymorphicSpecializations;
+    }
+
+    void setSpecializationListeners(List<SpecializationListenerData> specializationListeners) {
+        this.specializationListeners = specializationListeners;
+    }
+
+    void setExecutableTypes(Map<Integer, List<ExecutableTypeData>> executableTypes) {
+        this.executableTypes = executableTypes;
+    }
+
+    void setShortCircuits(List<ShortCircuitData> shortCircuits) {
+        this.shortCircuits = shortCircuits;
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + "[" + getNodeId() + "]";
+    }
+
+    public CreateCastData findCast(String name) {
+        if (getCasts() != null) {
+            for (CreateCastData cast : getCasts()) {
+                if (cast.getChildNames().contains(name)) {
+                    return cast;
+                }
+            }
+        }
+        return null;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeFieldData.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.node;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+import com.oracle.truffle.dsl.processor.template.*;
+
+public class NodeFieldData extends MessageContainer {
+
+    private VariableElement variable;
+
+    public NodeFieldData(VariableElement var) {
+        this.variable = var;
+    }
+
+    @Override
+    public Element getMessageElement() {
+        return variable;
+    }
+
+    public String getName() {
+        return variable.getSimpleName().toString();
+    }
+
+    public TypeMirror getType() {
+        return variable.asType();
+    }
+
+    public VariableElement getVariable() {
+        return variable;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeMethodParser.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.node;
+
+import java.util.*;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.node.NodeChildData.*;
+import com.oracle.truffle.dsl.processor.template.*;
+
+public abstract class NodeMethodParser<E extends TemplateMethod> extends TemplateMethodParser<NodeData, E> {
+
+    public NodeMethodParser(ProcessorContext context, NodeData node) {
+        super(context, node);
+    }
+
+    public NodeData getNode() {
+        return template;
+    }
+
+    @SuppressWarnings("unused")
+    protected ParameterSpec createValueParameterSpec(String valueName, NodeData nodeData, int evaluatedCount) {
+        ParameterSpec spec = new ParameterSpec(valueName, nodeTypeMirrors(nodeData));
+        spec.setSignature(true);
+        return spec;
+    }
+
+    protected List<TypeMirror> nodeTypeMirrors(NodeData nodeData) {
+        Set<TypeMirror> typeMirrors = new LinkedHashSet<>();
+
+        for (ExecutableTypeData typeData : nodeData.getExecutableTypes()) {
+            typeMirrors.add(typeData.getType().getPrimitiveType());
+        }
+
+        typeMirrors.add(nodeData.getTypeSystem().getGenericType());
+
+        return new ArrayList<>(typeMirrors);
+    }
+
+    protected ParameterSpec createReturnParameterSpec() {
+        return createValueParameterSpec("returnValue", getNode(), 0);
+    }
+
+    @Override
+    public boolean isParsable(ExecutableElement method) {
+        if (getAnnotationType() != null) {
+            return Utils.findAnnotationMirror(getContext().getEnvironment(), method, getAnnotationType()) != null;
+        }
+
+        return true;
+    }
+
+    @SuppressWarnings("unused")
+    protected final MethodSpec createDefaultMethodSpec(ExecutableElement method, AnnotationMirror mirror, boolean shortCircuitsEnabled, String shortCircuitName) {
+        MethodSpec methodSpec = new MethodSpec(createReturnParameterSpec());
+
+        addDefaultFrame(methodSpec);
+        addDefaultImplicitThis(method, methodSpec);
+        addDefaultFieldMethodSpec(method, methodSpec);
+        addDefaultChildren(shortCircuitsEnabled, shortCircuitName, methodSpec);
+
+        return methodSpec;
+    }
+
+    private void addDefaultChildren(boolean shortCircuitsEnabled, String shortCircuitName, MethodSpec methodSpec) {
+        // children are null when parsing executable types
+        if (getNode().getChildren() != null) {
+            for (NodeChildData child : getNode().getChildren()) {
+                if (child.getExecutionKind() == ExecutionKind.DEFAULT) {
+                    ParameterSpec spec = createValueParameterSpec(child.getName(), child.getNodeData(), child.getExecuteWith().size());
+                    if (child.getCardinality().isMany()) {
+                        spec.setCardinality(Cardinality.MANY);
+                        spec.setIndexed(true);
+                    }
+                    methodSpec.addRequired(spec);
+                } else if (child.getExecutionKind() == ExecutionKind.SHORT_CIRCUIT) {
+                    String valueName = child.getName();
+                    if (shortCircuitName != null && valueName.equals(shortCircuitName)) {
+                        break;
+                    }
+
+                    if (shortCircuitsEnabled) {
+                        methodSpec.addRequired(new ParameterSpec(shortCircuitValueName(valueName), getContext().getType(boolean.class)));
+                    }
+                    methodSpec.addRequired(createValueParameterSpec(valueName, child.getNodeData(), child.getExecuteWith().size()));
+                } else {
+                    assert false;
+                }
+            }
+        }
+    }
+
+    private void addDefaultFrame(MethodSpec methodSpec) {
+        if (getNode().supportsFrame()) {
+            methodSpec.addOptional(new ParameterSpec("frame", getContext().getTruffleTypes().getFrame()));
+        }
+    }
+
+    protected void addDefaultFieldMethodSpec(ExecutableElement method, MethodSpec methodSpec) {
+        for (NodeFieldData field : getNode().getFields()) {
+            if (!Utils.isFieldAccessible(method, field.getVariable())) {
+                ParameterSpec spec = new ParameterSpec(field.getName(), field.getType());
+                spec.setLocal(true);
+                methodSpec.addOptional(spec);
+            }
+        }
+    }
+
+    protected void addDefaultImplicitThis(ExecutableElement method, MethodSpec methodSpec) {
+        TypeMirror declaredType = Utils.findNearestEnclosingType(method).asType();
+
+        if (!method.getModifiers().contains(Modifier.STATIC) && !Utils.isAssignable(getContext(), declaredType, getContext().getTruffleTypes().getNode())) {
+            methodSpec.addImplicitRequiredType(getNode().getTemplateType().asType());
+        }
+    }
+
+    private static String shortCircuitValueName(String valueName) {
+        return "has" + Utils.firstLetterUpperCase(valueName);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeParser.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,1189 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.node;
+
+import java.lang.annotation.*;
+import java.util.*;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+import javax.lang.model.util.*;
+import javax.tools.Diagnostic.Kind;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.node.NodeChildData.*;
+import com.oracle.truffle.dsl.processor.template.*;
+import com.oracle.truffle.dsl.processor.template.TemplateMethod.*;
+import com.oracle.truffle.dsl.processor.typesystem.*;
+
+public class NodeParser extends TemplateParser<NodeData> {
+
+    public static final List<Class<? extends Annotation>> ANNOTATIONS = Arrays.asList(Generic.class, TypeSystemReference.class, ShortCircuit.class, Specialization.class, SpecializationListener.class,
+                    NodeContainer.class, NodeChild.class, NodeChildren.class, NodeId.class);
+
+    private Map<String, NodeData> parsedNodes;
+
+    public NodeParser(ProcessorContext c) {
+        super(c);
+    }
+
+    @Override
+    protected NodeData parse(Element element, AnnotationMirror mirror) {
+        assert element instanceof TypeElement;
+        NodeData node = null;
+        try {
+            parsedNodes = new HashMap<>();
+            node = resolveNode((TypeElement) element);
+            if (Log.DEBUG) {
+                NodeData parsed = parsedNodes.get(Utils.getQualifiedName((TypeElement) element));
+                if (node != null) {
+                    String dump = parsed.dump();
+                    log.message(Kind.ERROR, null, null, null, dump);
+                }
+            }
+        } finally {
+            parsedNodes = null;
+        }
+
+        return node;
+    }
+
+    @Override
+    protected NodeData filterErrorElements(NodeData model) {
+        for (Iterator<NodeData> iterator = model.getDeclaredNodes().iterator(); iterator.hasNext();) {
+            NodeData node = filterErrorElements(iterator.next());
+            if (node == null) {
+                iterator.remove();
+            }
+        }
+        if (model.hasErrors()) {
+            return null;
+        }
+        return model;
+    }
+
+    @Override
+    public boolean isDelegateToRootDeclaredType() {
+        return true;
+    }
+
+    @Override
+    public Class<? extends Annotation> getAnnotationType() {
+        return null;
+    }
+
+    @Override
+    public List<Class<? extends Annotation>> getTypeDelegatedAnnotationTypes() {
+        return ANNOTATIONS;
+    }
+
+    private NodeData resolveNode(TypeElement rootType) {
+        String typeName = Utils.getQualifiedName(rootType);
+        if (parsedNodes.containsKey(typeName)) {
+            return parsedNodes.get(typeName);
+        }
+
+        List<? extends TypeElement> types = ElementFilter.typesIn(rootType.getEnclosedElements());
+
+        List<NodeData> children = new ArrayList<>();
+        for (TypeElement childElement : types) {
+            NodeData childNode = resolveNode(childElement);
+            if (childNode != null) {
+                children.add(childNode);
+            }
+        }
+
+        NodeData rootNode = parseNode(rootType);
+        if (rootNode == null && children.size() > 0) {
+            rootNode = new NodeData(rootType, rootType.getSimpleName().toString());
+        }
+
+        parsedNodes.put(typeName, rootNode);
+
+        if (rootNode != null) {
+            children.addAll(rootNode.getDeclaredNodes());
+            rootNode.setDeclaredNodes(children);
+        }
+
+        return rootNode;
+    }
+
+    private NodeData parseNode(TypeElement originalTemplateType) {
+        // reloading the type elements is needed for ecj
+        TypeElement templateType = Utils.fromTypeMirror(context.reloadTypeElement(originalTemplateType));
+
+        if (Utils.findAnnotationMirror(processingEnv, originalTemplateType, GeneratedBy.class) != null) {
+            // generated nodes should not get called again.
+            return null;
+        }
+
+        List<TypeElement> lookupTypes = findSuperClasses(new ArrayList<TypeElement>(), templateType);
+        Collections.reverse(lookupTypes);
+
+        AnnotationMirror nodeClass = findFirstAnnotation(lookupTypes, NodeContainer.class);
+        TypeMirror nodeType = null;
+        if (Utils.isAssignable(context, templateType.asType(), context.getTruffleTypes().getNode())) {
+            nodeType = templateType.asType();
+        }
+        if (nodeClass != null) {
+            nodeType = inheritType(nodeClass, "value", nodeType);
+        }
+
+        if (nodeType == null) {
+            return null;
+        }
+
+        Elements elementUtil = context.getEnvironment().getElementUtils();
+        Set<Element> elementSet = new HashSet<>(elementUtil.getAllMembers(templateType));
+        if (!Utils.typeEquals(templateType.asType(), nodeType)) {
+            elementSet.addAll(elementUtil.getAllMembers(Utils.fromTypeMirror(nodeType)));
+
+            List<TypeElement> nodeLookupTypes = findSuperClasses(new ArrayList<TypeElement>(), Utils.fromTypeMirror(nodeType));
+            Collections.reverse(nodeLookupTypes);
+            lookupTypes.addAll(nodeLookupTypes);
+
+            Set<TypeElement> types = new HashSet<>();
+            for (ListIterator<TypeElement> iterator = lookupTypes.listIterator(); iterator.hasNext();) {
+                TypeElement typeElement = iterator.next();
+                if (types.contains(typeElement)) {
+                    iterator.remove();
+                } else {
+                    types.add(typeElement);
+                }
+            }
+        }
+        List<Element> elements = new ArrayList<>(elementSet);
+
+        NodeData node = parseNodeData(templateType, nodeType, elements, lookupTypes);
+
+        if (node.hasErrors()) {
+            return node; // error sync point
+        }
+
+        parseMethods(node, elements);
+
+        if (node.hasErrors()) {
+            return node;
+        }
+
+        List<NodeData> nodes;
+
+        if (node.isNodeContainer()) {
+            nodes = splitNodeData(node);
+        } else {
+            nodes = new ArrayList<>();
+            nodes.add(node);
+        }
+
+        for (NodeData splittedNode : nodes) {
+            finalizeSpecializations(elements, splittedNode);
+            verifyNode(splittedNode, elements);
+            splittedNode.setPolymorphicSpecializations(createPolymorphicSpecializations(splittedNode));
+            assignShortCircuitsToSpecializations(splittedNode);
+        }
+
+        if (node.isNodeContainer()) {
+            node.setDeclaredNodes(nodes);
+            node.setSpecializationListeners(new ArrayList<SpecializationListenerData>());
+            node.setSpecializations(new ArrayList<SpecializationData>());
+        }
+        return node;
+    }
+
+    private List<SpecializationData> createPolymorphicSpecializations(NodeData node) {
+        if (!node.needsRewrites(context) || node.getPolymorphicDepth() <= 1) {
+            return Collections.emptyList();
+        }
+
+        Signature genericSignature = node.getGenericSpecialization().getSignature();
+        Set<Signature> signatures = new HashSet<>();
+
+        for (SpecializationData specialization1 : node.getSpecializations()) {
+            Signature signature = specialization1.getSignature();
+
+            for (SpecializationData specialization2 : node.getSpecializations()) {
+                if (specialization1 == specialization2) {
+                    continue;
+                }
+                signatures.add(signature.combine(genericSignature, specialization2.getSignature()));
+            }
+        }
+
+        while (true) {
+            List<Signature> newSignatures = new ArrayList<>();
+            for (Signature signature1 : signatures) {
+                for (Signature signature2 : signatures) {
+                    if (signature1 == signature2) {
+                        continue;
+                    }
+                    newSignatures.add(signature1.combine(genericSignature, signature2));
+                }
+            }
+            if (!signatures.addAll(newSignatures)) {
+                break;
+            }
+        }
+
+        List<Signature> sortedSignatures = new ArrayList<>(signatures);
+        Collections.sort(sortedSignatures);
+
+        List<SpecializationData> specializations = new ArrayList<>();
+        SpecializationData generic = node.getGenericSpecialization();
+        for (Signature signature : sortedSignatures) {
+            SpecializationData specialization = new SpecializationData(generic, false, false, true);
+            specialization.forceFrame(context.getTruffleTypes().getFrame());
+            specialization.setNode(node);
+            specialization.updateSignature(signature);
+
+            if (specialization.isGenericSpecialization(context)) {
+                specializations.add(0, specialization);
+            } else {
+                specializations.add(specialization);
+            }
+        }
+
+        return specializations;
+    }
+
+    private NodeData parseNodeData(TypeElement templateType, TypeMirror nodeType, List<? extends Element> elements, List<TypeElement> lookupTypes) {
+        NodeData nodeData = new NodeData(templateType, templateType.getSimpleName().toString());
+
+        AnnotationMirror typeSystemMirror = findFirstAnnotation(lookupTypes, TypeSystemReference.class);
+        if (typeSystemMirror == null) {
+            nodeData.addError("No @%s annotation found in type hierarchy of %s.", TypeSystemReference.class.getSimpleName(), Utils.getQualifiedName(nodeType));
+            return nodeData;
+        }
+
+        TypeMirror typeSytemType = Utils.getAnnotationValue(TypeMirror.class, typeSystemMirror, "value");
+        final TypeSystemData typeSystem = (TypeSystemData) context.getTemplate(typeSytemType, true);
+        if (typeSystem == null) {
+            nodeData.addError("The used type system '%s' is invalid or not a Node.", Utils.getQualifiedName(typeSytemType));
+            return nodeData;
+        }
+
+        AnnotationMirror polymorphicMirror = findFirstAnnotation(lookupTypes, PolymorphicLimit.class);
+        if (polymorphicMirror != null) {
+            AnnotationValue limitValue = Utils.getAnnotationValue(polymorphicMirror, "value");
+            int polymorphicLimit = Utils.getAnnotationValue(Integer.class, polymorphicMirror, "value");
+            if (polymorphicLimit < 1) {
+                nodeData.addError(limitValue, "Invalid polymorphic limit %s.", polymorphicLimit);
+            }
+            nodeData.setPolymorphicDepth(polymorphicLimit);
+        }
+
+        List<String> assumptionsList = new ArrayList<>();
+        for (int i = lookupTypes.size() - 1; i >= 0; i--) {
+            TypeElement type = lookupTypes.get(i);
+            AnnotationMirror assumptions = Utils.findAnnotationMirror(context.getEnvironment(), type, NodeAssumptions.class);
+            if (assumptions != null) {
+                List<String> assumptionStrings = Utils.getAnnotationValueList(String.class, assumptions, "value");
+                for (String string : assumptionStrings) {
+                    if (assumptionsList.contains(string)) {
+                        assumptionsList.remove(string);
+                    }
+                    assumptionsList.add(string);
+                }
+            }
+        }
+        AnnotationMirror nodeInfoMirror = findFirstAnnotation(lookupTypes, NodeInfo.class);
+        if (nodeInfoMirror != null) {
+            nodeData.setShortName(Utils.getAnnotationValue(String.class, nodeInfoMirror, "shortName"));
+        }
+
+        nodeData.setAssumptions(new ArrayList<>(assumptionsList));
+        nodeData.setNodeType(nodeType);
+        AnnotationMirror nodeContainer = findFirstAnnotation(lookupTypes, NodeContainer.class);
+        nodeData.setNodeContainer(nodeContainer != null);
+        nodeData.setTypeSystem(typeSystem);
+        nodeData.setFields(parseFields(elements));
+        parsedNodes.put(Utils.getQualifiedName(templateType), nodeData);
+        // parseChildren invokes cyclic parsing.
+        nodeData.setChildren(parseChildren(elements, lookupTypes));
+        nodeData.setExecutableTypes(groupExecutableTypes(new ExecutableTypeMethodParser(context, nodeData).parse(elements)));
+
+        return nodeData;
+    }
+
+    private static List<NodeFieldData> parseFields(List<? extends Element> elements) {
+        List<NodeFieldData> fields = new ArrayList<>();
+        for (VariableElement field : ElementFilter.fieldsIn(elements)) {
+            if (field.getModifiers().contains(Modifier.STATIC)) {
+                continue;
+            }
+            if (field.getModifiers().contains(Modifier.PUBLIC) || field.getModifiers().contains(Modifier.PROTECTED)) {
+                fields.add(new NodeFieldData(field));
+            }
+        }
+        return fields;
+    }
+
+    private List<NodeChildData> parseChildren(List<? extends Element> elements, final List<TypeElement> typeHierarchy) {
+        Set<String> shortCircuits = new HashSet<>();
+        for (ExecutableElement method : ElementFilter.methodsIn(elements)) {
+            AnnotationMirror mirror = Utils.findAnnotationMirror(processingEnv, method, ShortCircuit.class);
+            if (mirror != null) {
+                shortCircuits.add(Utils.getAnnotationValue(String.class, mirror, "value"));
+            }
+        }
+        Map<String, TypeMirror> castNodeTypes = new HashMap<>();
+        for (ExecutableElement method : ElementFilter.methodsIn(elements)) {
+            AnnotationMirror mirror = Utils.findAnnotationMirror(processingEnv, method, CreateCast.class);
+            if (mirror != null) {
+                List<String> children = (Utils.getAnnotationValueList(String.class, mirror, "value"));
+                if (children != null) {
+                    for (String child : children) {
+                        castNodeTypes.put(child, method.getReturnType());
+                    }
+                }
+            }
+        }
+
+        List<NodeChildData> parsedChildren = new ArrayList<>();
+        List<TypeElement> typeHierarchyReversed = new ArrayList<>(typeHierarchy);
+        Collections.reverse(typeHierarchyReversed);
+        for (TypeElement type : typeHierarchyReversed) {
+            AnnotationMirror nodeClassMirror = Utils.findAnnotationMirror(processingEnv, type, NodeContainer.class);
+            AnnotationMirror nodeChildrenMirror = Utils.findAnnotationMirror(processingEnv, type, NodeChildren.class);
+
+            TypeMirror nodeClassType = type.getSuperclass();
+            if (!Utils.isAssignable(context, nodeClassType, context.getTruffleTypes().getNode())) {
+                nodeClassType = null;
+            }
+
+            if (nodeClassMirror != null) {
+                nodeClassType = inheritType(nodeClassMirror, "value", nodeClassType);
+            }
+
+            List<AnnotationMirror> children = Utils.collectAnnotations(context, nodeChildrenMirror, "value", type, NodeChild.class);
+            int index = 0;
+            for (AnnotationMirror childMirror : children) {
+                String name = Utils.getAnnotationValue(String.class, childMirror, "value");
+                if (name.equals("")) {
+                    name = "child" + index;
+                }
+
+                Cardinality cardinality = Cardinality.ONE;
+
+                TypeMirror childType = inheritType(childMirror, "type", nodeClassType);
+                if (childType.getKind() == TypeKind.ARRAY) {
+                    cardinality = Cardinality.MANY;
+                }
+
+                TypeMirror originalChildType = childType;
+                TypeMirror castNodeType = castNodeTypes.get(name);
+                if (castNodeType != null) {
+                    childType = castNodeType;
+                }
+
+                Element getter = findGetter(elements, name, childType);
+
+                ExecutionKind kind = ExecutionKind.DEFAULT;
+                if (shortCircuits.contains(name)) {
+                    kind = ExecutionKind.SHORT_CIRCUIT;
+                }
+
+                NodeChildData nodeChild = new NodeChildData(type, childMirror, name, childType, originalChildType, getter, cardinality, kind);
+
+                parsedChildren.add(nodeChild);
+
+                verifyNodeChild(nodeChild);
+                if (nodeChild.hasErrors()) {
+                    continue;
+                }
+
+                NodeData fieldNodeData = resolveNode(Utils.fromTypeMirror(childType));
+                nodeChild.setNode(fieldNodeData);
+                if (fieldNodeData == null) {
+                    nodeChild.addError("Node type '%s' is invalid or not a valid Node.", Utils.getQualifiedName(childType));
+                }
+
+            }
+            index++;
+        }
+
+        List<NodeChildData> filteredChildren = new ArrayList<>();
+        Set<String> encounteredNames = new HashSet<>();
+        for (int i = parsedChildren.size() - 1; i >= 0; i--) {
+            NodeChildData child = parsedChildren.get(i);
+            if (!encounteredNames.contains(child.getName())) {
+                filteredChildren.add(0, child);
+                encounteredNames.add(child.getName());
+            }
+        }
+
+        for (NodeChildData child : filteredChildren) {
+            List<String> executeWithStrings = Utils.getAnnotationValueList(String.class, child.getMessageAnnotation(), "executeWith");
+            AnnotationValue executeWithValue = Utils.getAnnotationValue(child.getMessageAnnotation(), "executeWith");
+            List<NodeChildData> executeWith = new ArrayList<>();
+            for (String executeWithString : executeWithStrings) {
+
+                if (child.getName().equals(executeWithString)) {
+                    child.addError(executeWithValue, "The child node '%s' cannot be executed with itself.", executeWithString);
+                    continue;
+                }
+
+                NodeChildData found = null;
+                boolean before = true;
+                for (NodeChildData resolveChild : filteredChildren) {
+                    if (resolveChild == child) {
+                        before = false;
+                        continue;
+                    }
+                    if (resolveChild.getName().equals(executeWithString)) {
+                        found = resolveChild;
+                        break;
+                    }
+                }
+
+                if (found == null) {
+                    child.addError(executeWithValue, "The child node '%s' cannot be executed with '%s'. The child node was not found.", child.getName(), executeWithString);
+                    continue;
+                } else if (!before) {
+                    child.addError(executeWithValue, "The child node '%s' cannot be executed with '%s'. The node %s is executed after the current node.", child.getName(), executeWithString,
+                                    executeWithString);
+                    continue;
+                }
+                executeWith.add(found);
+            }
+            child.setExecuteWith(executeWith);
+            if (child.getNodeData() == null) {
+                continue;
+            }
+
+            List<ExecutableTypeData> types = child.findGenericExecutableTypes(context);
+            if (types.isEmpty()) {
+                child.addError(executeWithValue, "No generic execute method found with %s evaluated arguments for node type %s.", executeWith.size(), Utils.getSimpleName(child.getNodeType()));
+                continue;
+            }
+        }
+
+        return filteredChildren;
+    }
+
+    private void parseMethods(final NodeData node, List<Element> elements) {
+        node.setShortCircuits(new ShortCircuitParser(context, node).parse(elements));
+        node.setSpecializationListeners(new SpecializationListenerParser(context, node).parse(elements));
+        List<SpecializationData> generics = new GenericParser(context, node).parse(elements);
+        List<SpecializationData> specializations = new SpecializationMethodParser(context, node).parse(elements);
+        node.setCasts(new CreateCastParser(context, node).parse(elements));
+
+        List<SpecializationData> allSpecializations = new ArrayList<>();
+        allSpecializations.addAll(generics);
+        allSpecializations.addAll(specializations);
+
+        node.setSpecializations(allSpecializations);
+    }
+
+    private static List<NodeData> splitNodeData(NodeData node) {
+        SortedMap<String, List<SpecializationData>> groupedSpecializations = groupByNodeId(node.getSpecializations());
+        SortedMap<String, List<SpecializationListenerData>> groupedListeners = groupByNodeId(node.getSpecializationListeners());
+        SortedMap<String, List<CreateCastData>> groupedCasts = groupByNodeId(node.getCasts());
+
+        Set<String> ids = new TreeSet<>();
+        ids.addAll(groupedSpecializations.keySet());
+        ids.addAll(groupedListeners.keySet());
+
+        List<NodeData> splitted = new ArrayList<>();
+        for (String id : ids) {
+            List<SpecializationData> specializations = groupedSpecializations.get(id);
+            List<SpecializationListenerData> listeners = groupedListeners.get(id);
+            List<CreateCastData> casts = groupedCasts.get(id);
+
+            if (specializations == null) {
+                specializations = new ArrayList<>();
+            }
+
+            if (listeners == null) {
+                listeners = new ArrayList<>();
+            }
+
+            String nodeId = node.getNodeId();
+            if (nodeId.endsWith("Node") && !nodeId.equals("Node")) {
+                nodeId = nodeId.substring(0, nodeId.length() - 4);
+            }
+            String newNodeId = nodeId + Utils.firstLetterUpperCase(id);
+            NodeData copy = new NodeData(node, id, newNodeId);
+
+            copy.setSpecializations(specializations);
+            copy.setSpecializationListeners(listeners);
+            copy.setCasts(casts);
+
+            splitted.add(copy);
+        }
+
+        node.setSpecializations(new ArrayList<SpecializationData>());
+        node.setSpecializationListeners(new ArrayList<SpecializationListenerData>());
+        node.setCasts(new ArrayList<CreateCastData>());
+
+        return splitted;
+    }
+
+    private void finalizeSpecializations(List<Element> elements, final NodeData node) {
+        List<SpecializationData> specializations = new ArrayList<>(node.getSpecializations());
+
+        if (specializations.isEmpty()) {
+            return;
+        }
+
+        for (SpecializationData specialization : specializations) {
+            matchGuards(elements, specialization);
+        }
+
+        List<SpecializationData> generics = new ArrayList<>();
+        for (SpecializationData spec : specializations) {
+            if (spec.isGeneric()) {
+                generics.add(spec);
+            }
+        }
+
+        if (generics.size() == 1 && specializations.size() == 1) {
+            for (SpecializationData generic : generics) {
+                generic.addError("@%s defined but no @%s.", Generic.class.getSimpleName(), Specialization.class.getSimpleName());
+            }
+        }
+
+        SpecializationData genericSpecialization = null;
+        if (generics.size() > 1) {
+            for (SpecializationData generic : generics) {
+                generic.addError("Only @%s is allowed per operation.", Generic.class.getSimpleName());
+            }
+            return;
+        } else if (generics.size() == 1) {
+            genericSpecialization = generics.get(0);
+        } else if (node.needsRewrites(context)) {
+            SpecializationData specialization = specializations.get(0);
+            GenericParser parser = new GenericParser(context, node);
+            MethodSpec specification = parser.createDefaultMethodSpec(specialization.getMethod(), null, true, null);
+
+            ExecutableTypeData anyGenericReturnType = node.findAnyGenericExecutableType(context, 0);
+            assert anyGenericReturnType != null;
+
+            ActualParameter returnType = new ActualParameter(specification.getReturnType(), anyGenericReturnType.getType(), 0, false);
+            List<ActualParameter> parameters = new ArrayList<>();
+            for (ActualParameter specializationParameter : specialization.getParameters()) {
+                ParameterSpec parameterSpec = specification.findParameterSpec(specializationParameter.getSpecification().getName());
+                NodeChildData child = node.findChild(parameterSpec.getName());
+                TypeData actualType;
+                if (child == null) {
+                    actualType = specializationParameter.getTypeSystemType();
+                } else {
+                    ExecutableTypeData paramType = child.findAnyGenericExecutableType(context);
+                    assert paramType != null;
+                    actualType = paramType.getType();
+                }
+
+                if (actualType != null) {
+                    parameters.add(new ActualParameter(parameterSpec, actualType, specializationParameter.getIndex(), specializationParameter.isImplicit()));
+                } else {
+                    parameters.add(new ActualParameter(parameterSpec, specializationParameter.getType(), specializationParameter.getIndex(), specializationParameter.isImplicit()));
+                }
+            }
+            TemplateMethod genericMethod = new TemplateMethod("Generic", node, specification, null, null, returnType, parameters);
+            genericSpecialization = new SpecializationData(genericMethod, true, false, false);
+
+            specializations.add(genericSpecialization);
+        }
+
+        if (genericSpecialization != null) {
+            for (ActualParameter parameter : genericSpecialization.getReturnTypeAndParameters()) {
+                if (Utils.isObject(parameter.getType())) {
+                    continue;
+                }
+                Set<String> types = new HashSet<>();
+                for (SpecializationData specialization : specializations) {
+                    ActualParameter actualParameter = specialization.findParameter(parameter.getLocalName());
+                    if (actualParameter != null) {
+                        types.add(Utils.getQualifiedName(actualParameter.getType()));
+                    }
+                }
+                if (types.size() > 1) {
+                    genericSpecialization.replaceParameter(parameter.getLocalName(), new ActualParameter(parameter, node.getTypeSystem().getGenericTypeData()));
+                }
+            }
+            TemplateMethod uninializedMethod = new TemplateMethod("Uninitialized", node, genericSpecialization.getSpecification(), null, null, genericSpecialization.getReturnType(),
+                            genericSpecialization.getParameters());
+            // should not use messages from generic specialization
+            uninializedMethod.getMessages().clear();
+            specializations.add(new SpecializationData(uninializedMethod, false, true, false));
+        }
+
+        Collections.sort(specializations);
+
+        node.setSpecializations(specializations);
+
+        List<SpecializationData> needsId = new ArrayList<>();
+        for (SpecializationData specialization : specializations) {
+            if (specialization.isGeneric()) {
+                specialization.setId("Generic");
+            } else if (specialization.isUninitialized()) {
+                specialization.setId("Uninitialized");
+            } else {
+                needsId.add(specialization);
+            }
+        }
+
+        // verify specialization parameter length
+        if (verifySpecializationParameters(node)) {
+            List<String> ids = calculateSpecializationIds(needsId);
+            for (int i = 0; i < ids.size(); i++) {
+                needsId.get(i).setId(ids.get(i));
+            }
+        }
+
+        // calculate reachability
+        int specializationCount = 0;
+        boolean reachable = true;
+        for (SpecializationData specialization : specializations) {
+            if (specialization.isUninitialized()) {
+                specialization.setReachable(true);
+                continue;
+            }
+            if (!reachable && specialization.getMethod() != null) {
+                specialization.addError("%s is not reachable.", specialization.isGeneric() ? "Generic" : "Specialization");
+            }
+            specialization.setReachable(reachable);
+            if (!specialization.hasRewrite(context)) {
+                reachable = false;
+            }
+            if (!specialization.isGeneric()) {
+                specializationCount++;
+            }
+        }
+
+        if (node.getPolymorphicDepth() < 0) {
+            node.setPolymorphicDepth(specializationCount - 1);
+        }
+
+        // reduce polymorphicness if generic is not reachable
+        if (node.getGenericSpecialization() != null && !node.getGenericSpecialization().isReachable()) {
+            node.setPolymorphicDepth(1);
+        }
+    }
+
+    private void assignShortCircuitsToSpecializations(NodeData node) {
+        Map<String, List<ShortCircuitData>> groupedShortCircuits = groupShortCircuits(node.getShortCircuits());
+
+        boolean valid = true;
+        for (NodeChildData field : node.filterFields(ExecutionKind.SHORT_CIRCUIT)) {
+            String valueName = field.getName();
+            List<ShortCircuitData> availableCircuits = groupedShortCircuits.get(valueName);
+
+            if (availableCircuits == null || availableCircuits.isEmpty()) {
+                node.addError("@%s method for short cut value '%s' required.", ShortCircuit.class.getSimpleName(), valueName);
+                valid = false;
+                continue;
+            }
+
+            boolean sameMethodName = true;
+            String methodName = availableCircuits.get(0).getMethodName();
+            for (ShortCircuitData circuit : availableCircuits) {
+                if (!circuit.getMethodName().equals(methodName)) {
+                    sameMethodName = false;
+                }
+            }
+
+            if (!sameMethodName) {
+                for (ShortCircuitData circuit : availableCircuits) {
+                    circuit.addError("All short circuits for short cut value '%s' must have the same method name.", valueName);
+                }
+                valid = false;
+                continue;
+            }
+
+            ShortCircuitData genericCircuit = null;
+            for (ShortCircuitData circuit : availableCircuits) {
+                if (isGenericShortCutMethod(node, circuit)) {
+                    genericCircuit = circuit;
+                    break;
+                }
+            }
+
+            if (genericCircuit == null) {
+                node.addError("No generic @%s method available for short cut value '%s'.", ShortCircuit.class.getSimpleName(), valueName);
+                valid = false;
+                continue;
+            }
+
+            for (ShortCircuitData circuit : availableCircuits) {
+                if (circuit != genericCircuit) {
+                    circuit.setGenericShortCircuitMethod(genericCircuit);
+                }
+            }
+        }
+
+        if (!valid) {
+            return;
+        }
+
+        NodeChildData[] fields = node.filterFields(ExecutionKind.SHORT_CIRCUIT);
+        List<SpecializationData> specializations = new ArrayList<>();
+        specializations.addAll(node.getSpecializations());
+        specializations.addAll(node.getPolymorphicSpecializations());
+
+        for (SpecializationData specialization : specializations) {
+            List<ShortCircuitData> assignedShortCuts = new ArrayList<>(fields.length);
+
+            for (int i = 0; i < fields.length; i++) {
+                List<ShortCircuitData> availableShortCuts = groupedShortCircuits.get(fields[i].getName());
+
+                ShortCircuitData genericShortCircuit = null;
+                ShortCircuitData compatibleShortCircuit = null;
+                for (ShortCircuitData circuit : availableShortCuts) {
+                    if (circuit.isGeneric()) {
+                        genericShortCircuit = circuit;
+                    } else if (circuit.isCompatibleTo(specialization)) {
+                        compatibleShortCircuit = circuit;
+                    }
+                }
+
+                if (compatibleShortCircuit == null) {
+                    compatibleShortCircuit = genericShortCircuit;
+                }
+                assignedShortCuts.add(compatibleShortCircuit);
+            }
+            specialization.setShortCircuits(assignedShortCuts);
+        }
+    }
+
+    private void matchGuards(List<Element> elements, SpecializationData specialization) {
+        if (specialization.getGuardDefinitions().isEmpty()) {
+            specialization.setGuards(Collections.<GuardData> emptyList());
+            return;
+        }
+
+        List<GuardData> foundGuards = new ArrayList<>();
+        List<ExecutableElement> methods = ElementFilter.methodsIn(elements);
+        for (String guardDefinition : specialization.getGuardDefinitions()) {
+            GuardParser parser = new GuardParser(context, specialization, guardDefinition);
+            List<GuardData> guards = parser.parse(methods);
+            if (!guards.isEmpty()) {
+                foundGuards.add(guards.get(0));
+            } else {
+                // error no guard found
+                MethodSpec spec = parser.createSpecification(specialization.getMethod(), null);
+                spec.applyTypeDefinitions("types");
+                specialization.addError("Guard with method name '%s' not found. Expected signature: %n%s", guardDefinition, spec.toSignatureString("guard"));
+            }
+        }
+
+        specialization.setGuards(foundGuards);
+
+    }
+
+    private static List<String> calculateSpecializationIds(List<SpecializationData> specializations) {
+        int lastSize = -1;
+        List<List<String>> signatureChunks = new ArrayList<>();
+        for (SpecializationData other : specializations) {
+            if (other.isUninitialized() || other.isGeneric()) {
+                continue;
+            }
+            List<String> paramIds = new LinkedList<>();
+            paramIds.add(Utils.getTypeId(other.getReturnType().getType()));
+            for (ActualParameter param : other.getParameters()) {
+                if (other.getNode().findChild(param.getSpecification().getName()) == null) {
+                    continue;
+                }
+                paramIds.add(Utils.getTypeId(param.getType()));
+            }
+            assert lastSize == -1 || lastSize == paramIds.size();
+            if (lastSize != -1 && lastSize != paramIds.size()) {
+                throw new AssertionError();
+            }
+            signatureChunks.add(paramIds);
+            lastSize = paramIds.size();
+        }
+
+        // reduce id vertically
+        for (int i = 0; i < lastSize; i++) {
+            String prev = null;
+            boolean allSame = true;
+            for (List<String> signature : signatureChunks) {
+                String arg = signature.get(i);
+                if (prev == null) {
+                    prev = arg;
+                    continue;
+                } else if (!prev.equals(arg)) {
+                    allSame = false;
+                    break;
+                }
+                prev = arg;
+            }
+
+            if (allSame) {
+                for (List<String> signature : signatureChunks) {
+                    signature.remove(i);
+                }
+                lastSize--;
+            }
+        }
+
+        // reduce id horizontally
+        for (List<String> signature : signatureChunks) {
+            if (signature.isEmpty()) {
+                continue;
+            }
+            String prev = null;
+            boolean allSame = true;
+            for (String arg : signature) {
+                if (prev == null) {
+                    prev = arg;
+                    continue;
+                } else if (!prev.equals(arg)) {
+                    allSame = false;
+                    break;
+                }
+                prev = arg;
+            }
+
+            if (allSame) {
+                signature.clear();
+                signature.add(prev);
+            }
+        }
+
+        // create signatures
+        List<String> signatures = new ArrayList<>();
+        for (List<String> signatureChunk : signatureChunks) {
+            StringBuilder b = new StringBuilder();
+            if (signatureChunk.isEmpty()) {
+                b.append("Default");
+            } else {
+                for (String s : signatureChunk) {
+                    b.append(s);
+                }
+            }
+            signatures.add(b.toString());
+        }
+
+        Map<String, Integer> counts = new HashMap<>();
+        for (String s1 : signatures) {
+            Integer count = counts.get(s1);
+            if (count == null) {
+                count = 0;
+            }
+            count++;
+            counts.put(s1, count);
+        }
+
+        for (String s : counts.keySet()) {
+            int count = counts.get(s);
+            if (count > 1) {
+                int number = 0;
+                for (ListIterator<String> iterator = signatures.listIterator(); iterator.hasNext();) {
+                    String s2 = iterator.next();
+                    if (s.equals(s2)) {
+                        iterator.set(s2 + number);
+                        number++;
+                    }
+                }
+            }
+        }
+
+        return signatures;
+    }
+
+    private void verifyNode(NodeData nodeData, List<? extends Element> elements) {
+        // verify order is not ambiguous
+        verifySpecializationOrder(nodeData);
+
+        verifyMissingAbstractMethods(nodeData, elements);
+
+        verifyConstructors(nodeData);
+
+        verifyNamingConvention(nodeData.getShortCircuits(), "needs");
+
+        verifySpecializationThrows(nodeData);
+    }
+
+    private static void verifyNodeChild(NodeChildData nodeChild) {
+        if (nodeChild.getNodeType() == null) {
+            nodeChild.addError("No valid node type could be resoleved.");
+        }
+        // FIXME verify node child
+        // FIXME verify node type set
+    }
+
+    private static void verifyMissingAbstractMethods(NodeData nodeData, List<? extends Element> originalElements) {
+        if (!nodeData.needsFactory()) {
+            // missing abstract methods only needs to be implemented
+            // if we need go generate factory for it.
+            return;
+        }
+
+        List<Element> elements = new ArrayList<>(originalElements);
+
+        Set<Element> unusedElements = new HashSet<>(elements);
+        for (TemplateMethod method : nodeData.getAllTemplateMethods()) {
+            unusedElements.remove(method.getMethod());
+        }
+        if (nodeData.getExtensionElements() != null) {
+            unusedElements.removeAll(nodeData.getExtensionElements());
+        }
+
+        for (NodeChildData child : nodeData.getChildren()) {
+            if (child.getAccessElement() != null) {
+                unusedElements.remove(child.getAccessElement());
+            }
+        }
+
+        for (ExecutableElement unusedMethod : ElementFilter.methodsIn(unusedElements)) {
+            if (unusedMethod.getModifiers().contains(Modifier.ABSTRACT)) {
+                nodeData.addError("The type %s must implement the inherited abstract method %s.", Utils.getSimpleName(nodeData.getTemplateType()), Utils.getReadableSignature(unusedMethod));
+            }
+        }
+    }
+
+    private void verifyConstructors(NodeData nodeData) {
+        if (!nodeData.needsRewrites(context)) {
+            // no specialization constructor is needed if the node never rewrites.
+            return;
+        }
+
+        TypeElement type = Utils.fromTypeMirror(nodeData.getNodeType());
+        List<ExecutableElement> constructors = ElementFilter.constructorsIn(type.getEnclosedElements());
+
+        boolean parametersFound = false;
+        for (ExecutableElement constructor : constructors) {
+            if (!constructor.getParameters().isEmpty()) {
+                parametersFound = true;
+            }
+        }
+        if (!parametersFound) {
+            return;
+        }
+        for (ExecutableElement e : constructors) {
+            if (e.getParameters().size() == 1) {
+                TypeMirror firstArg = e.getParameters().get(0).asType();
+                if (Utils.typeEquals(firstArg, nodeData.getNodeType())) {
+                    if (e.getModifiers().contains(Modifier.PRIVATE)) {
+                        nodeData.addError("The specialization constructor must not be private.");
+                    } else if (constructors.size() <= 1) {
+                        nodeData.addError("The specialization constructor must not be the only constructor. The definition of an alternative constructor is required.");
+                    }
+                    return;
+                }
+            }
+        }
+
+        // not found
+        nodeData.addError("Specialization constructor '%s(%s previousNode) { this(...); }' is required.", Utils.getSimpleName(type), Utils.getSimpleName(type));
+    }
+
+    private static boolean verifySpecializationParameters(NodeData nodeData) {
+        boolean valid = true;
+        int args = -1;
+        for (SpecializationData specializationData : nodeData.getSpecializations()) {
+            int signatureArgs = 0;
+            for (ActualParameter param : specializationData.getParameters()) {
+                if (param.getSpecification().isSignature()) {
+                    signatureArgs++;
+                }
+            }
+            if (args != -1 && args != signatureArgs) {
+                valid = false;
+                break;
+            }
+            args = signatureArgs;
+        }
+        if (!valid) {
+            for (SpecializationData specialization : nodeData.getSpecializations()) {
+                specialization.addError("All specializations must have the same number of arguments.");
+            }
+        }
+        return valid;
+    }
+
+    private static void verifySpecializationOrder(NodeData node) {
+        List<SpecializationData> specializations = node.getSpecializations();
+        for (int i = 0; i < specializations.size(); i++) {
+            SpecializationData m1 = specializations.get(i);
+            for (int j = i + 1; j < specializations.size(); j++) {
+                SpecializationData m2 = specializations.get(j);
+                int inferredOrder = m1.compareBySignature(m2);
+
+                if (m1.getOrder() != Specialization.DEFAULT_ORDER && m2.getOrder() != Specialization.DEFAULT_ORDER) {
+                    int specOrder = m1.getOrder() - m2.getOrder();
+                    if (specOrder == 0) {
+                        m1.addError("Order value %d used multiple times", m1.getOrder());
+                        m2.addError("Order value %d used multiple times", m1.getOrder());
+                        return;
+                    } else if ((specOrder < 0 && inferredOrder > 0) || (specOrder > 0 && inferredOrder < 0)) {
+                        m1.addError("Explicit order values %d and %d are inconsistent with type lattice ordering.", m1.getOrder(), m2.getOrder());
+                        m2.addError("Explicit order values %d and %d are inconsistent with type lattice ordering.", m1.getOrder(), m2.getOrder());
+                        return;
+                    }
+                } else if (inferredOrder == 0) {
+                    SpecializationData m = (m1.getOrder() == Specialization.DEFAULT_ORDER ? m1 : m2);
+                    m.addError("Cannot calculate a consistent order for this specialization. Define the order attribute to resolve this.");
+                    return;
+                }
+            }
+        }
+    }
+
+    private static void verifySpecializationThrows(NodeData node) {
+        Map<String, SpecializationData> specializationMap = new HashMap<>();
+        for (SpecializationData spec : node.getSpecializations()) {
+            specializationMap.put(spec.getMethodName(), spec);
+        }
+        for (SpecializationData sourceSpecialization : node.getSpecializations()) {
+            if (sourceSpecialization.getExceptions() != null) {
+                for (SpecializationThrowsData throwsData : sourceSpecialization.getExceptions()) {
+                    for (SpecializationThrowsData otherThrowsData : sourceSpecialization.getExceptions()) {
+                        if (otherThrowsData != throwsData && Utils.typeEquals(otherThrowsData.getJavaClass(), throwsData.getJavaClass())) {
+                            throwsData.addError("Duplicate exception type.");
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private static void verifyNamingConvention(List<? extends TemplateMethod> methods, String prefix) {
+        for (int i = 0; i < methods.size(); i++) {
+            TemplateMethod m1 = methods.get(i);
+            if (m1.getMethodName().length() < 3 || !m1.getMethodName().startsWith(prefix)) {
+                m1.addError("Naming convention: method name must start with '%s'.", prefix);
+            }
+        }
+    }
+
+    private static Map<Integer, List<ExecutableTypeData>> groupExecutableTypes(List<ExecutableTypeData> executableTypes) {
+        Map<Integer, List<ExecutableTypeData>> groupedTypes = new HashMap<>();
+        for (ExecutableTypeData type : executableTypes) {
+            int evaluatedCount = type.getEvaluatedCount();
+
+            List<ExecutableTypeData> types = groupedTypes.get(evaluatedCount);
+            if (types == null) {
+                types = new ArrayList<>();
+                groupedTypes.put(evaluatedCount, types);
+            }
+            types.add(type);
+        }
+
+        for (List<ExecutableTypeData> types : groupedTypes.values()) {
+            Collections.sort(types);
+        }
+        return groupedTypes;
+    }
+
+    private AnnotationMirror findFirstAnnotation(List<? extends Element> elements, Class<? extends Annotation> annotation) {
+        for (Element element : elements) {
+            AnnotationMirror mirror = Utils.findAnnotationMirror(processingEnv, element, annotation);
+            if (mirror != null) {
+                return mirror;
+            }
+        }
+        return null;
+    }
+
+    private TypeMirror inheritType(AnnotationMirror annotation, String valueName, TypeMirror parentType) {
+        TypeMirror inhertNodeType = context.getTruffleTypes().getNode();
+        TypeMirror value = Utils.getAnnotationValue(TypeMirror.class, annotation, valueName);
+        if (Utils.typeEquals(inhertNodeType, value)) {
+            return parentType;
+        } else {
+            return value;
+        }
+    }
+
+    private Element findGetter(List<? extends Element> elements, String variableName, TypeMirror type) {
+        if (type == null) {
+            return null;
+        }
+        String methodName;
+        if (Utils.typeEquals(type, context.getType(boolean.class))) {
+            methodName = "is" + Utils.firstLetterUpperCase(variableName);
+        } else {
+            methodName = "get" + Utils.firstLetterUpperCase(variableName);
+        }
+
+        for (ExecutableElement method : ElementFilter.methodsIn(elements)) {
+            if (method.getSimpleName().toString().equals(methodName) && method.getParameters().size() == 0 && Utils.isAssignable(context, type, method.getReturnType())) {
+                return method;
+            }
+        }
+        return null;
+    }
+
+    private boolean isGenericShortCutMethod(NodeData node, TemplateMethod method) {
+        for (ActualParameter parameter : method.getParameters()) {
+            NodeChildData field = node.findChild(parameter.getSpecification().getName());
+            if (field == null) {
+                continue;
+            }
+            ExecutableTypeData found = null;
+            List<ExecutableTypeData> executableElements = field.findGenericExecutableTypes(context);
+            for (ExecutableTypeData executable : executableElements) {
+                if (executable.getType().equalsType(parameter.getTypeSystemType())) {
+                    found = executable;
+                    break;
+                }
+            }
+            if (found == null) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private static Map<String, List<ShortCircuitData>> groupShortCircuits(List<ShortCircuitData> shortCircuits) {
+        Map<String, List<ShortCircuitData>> group = new HashMap<>();
+        for (ShortCircuitData shortCircuit : shortCircuits) {
+            List<ShortCircuitData> circuits = group.get(shortCircuit.getValueName());
+            if (circuits == null) {
+                circuits = new ArrayList<>();
+                group.put(shortCircuit.getValueName(), circuits);
+            }
+            circuits.add(shortCircuit);
+        }
+        return group;
+    }
+
+    private static <M extends TemplateMethod> SortedMap<String, List<M>> groupByNodeId(List<M> methods) {
+        SortedMap<String, List<M>> grouped = new TreeMap<>();
+        for (M m : methods) {
+            List<M> list = grouped.get(m.getId());
+            if (list == null) {
+                list = new ArrayList<>();
+                grouped.put(m.getId(), list);
+            }
+            list.add(m);
+        }
+        return grouped;
+    }
+
+    private static List<TypeElement> findSuperClasses(List<TypeElement> collection, TypeElement element) {
+        if (element.getSuperclass() != null) {
+            TypeElement superElement = Utils.fromTypeMirror(element.getSuperclass());
+            if (superElement != null) {
+                findSuperClasses(collection, superElement);
+            }
+        }
+        collection.add(element);
+        return collection;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ShortCircuitData.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.node;
+
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.template.*;
+
+public class ShortCircuitData extends TemplateMethod {
+
+    private ShortCircuitData genericShortCircuitMethod;
+    private final String valueName;
+
+    public ShortCircuitData(TemplateMethod template, String valueName) {
+        super(template);
+        this.valueName = valueName;
+    }
+
+    public String getValueName() {
+        return valueName;
+    }
+
+    public void setGenericShortCircuitMethod(ShortCircuitData genericShortCircuitMethod) {
+        this.genericShortCircuitMethod = genericShortCircuitMethod;
+    }
+
+    public boolean isGeneric() {
+        return genericShortCircuitMethod == null;
+    }
+
+    public ShortCircuitData getGeneric() {
+        if (isGeneric()) {
+            return this;
+        } else {
+            return genericShortCircuitMethod;
+        }
+    }
+
+    public boolean isCompatibleTo(SpecializationData specialization) {
+        if (isGeneric() && specialization.isGeneric()) {
+            return true;
+        }
+
+        for (ActualParameter param : getParameters()) {
+            ActualParameter specializationParam = specialization.findParameter(param.getLocalName());
+            if (!Utils.typeEquals(param.getType(), specializationParam.getType())) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ShortCircuitParser.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.node;
+
+import java.lang.annotation.*;
+import java.util.*;
+
+import javax.lang.model.element.*;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.node.NodeChildData.*;
+import com.oracle.truffle.dsl.processor.template.*;
+
+public class ShortCircuitParser extends NodeMethodParser<ShortCircuitData> {
+
+    private final Set<String> shortCircuitValues;
+
+    public ShortCircuitParser(ProcessorContext context, NodeData node) {
+        super(context, node);
+
+        shortCircuitValues = new HashSet<>();
+        NodeChildData[] shortCircuitFields = node.filterFields(ExecutionKind.SHORT_CIRCUIT);
+        for (NodeChildData field : shortCircuitFields) {
+            shortCircuitValues.add(field.getName());
+        }
+    }
+
+    @Override
+    public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
+        String shortCircuitValue = Utils.getAnnotationValue(String.class, mirror, "value");
+        return createDefaultMethodSpec(method, mirror, true, shortCircuitValue);
+    }
+
+    @Override
+    protected ParameterSpec createReturnParameterSpec() {
+        return new ParameterSpec("has", getContext().getType(boolean.class));
+    }
+
+    @Override
+    public ShortCircuitData create(TemplateMethod method) {
+        String shortCircuitValue = Utils.getAnnotationValue(String.class, method.getMarkerAnnotation(), "value");
+
+        if (!shortCircuitValues.contains(shortCircuitValue)) {
+            method.addError("Invalid short circuit value %s.", shortCircuitValue);
+        }
+
+        return new ShortCircuitData(method, shortCircuitValue);
+    }
+
+    @Override
+    public Class<? extends Annotation> getAnnotationType() {
+        return ShortCircuit.class;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationData.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.node;
+
+import java.util.*;
+
+import javax.lang.model.type.*;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.template.*;
+import com.oracle.truffle.dsl.processor.typesystem.*;
+
+public class SpecializationData extends TemplateMethod {
+
+    private final int order;
+    private final boolean generic;
+    private final boolean polymorphic;
+    private final boolean uninitialized;
+    private final List<SpecializationThrowsData> exceptions;
+    private List<String> guardDefinitions = Collections.emptyList();
+    private List<GuardData> guards = Collections.emptyList();
+    private List<ShortCircuitData> shortCircuits;
+    private List<String> assumptions = Collections.emptyList();
+    private NodeData node;
+    private boolean reachable;
+
+    public SpecializationData(TemplateMethod template, int order, List<SpecializationThrowsData> exceptions) {
+        super(template);
+        this.order = order;
+        this.generic = false;
+        this.uninitialized = false;
+        this.polymorphic = false;
+        this.exceptions = exceptions;
+
+        for (SpecializationThrowsData exception : exceptions) {
+            exception.setSpecialization(this);
+        }
+    }
+
+    public SpecializationData(TemplateMethod template, boolean generic, boolean uninitialized, boolean polymorphic) {
+        super(template);
+        this.order = Specialization.DEFAULT_ORDER;
+        this.generic = generic;
+        this.uninitialized = uninitialized;
+        this.polymorphic = polymorphic;
+        this.exceptions = Collections.emptyList();
+    }
+
+    public void setReachable(boolean reachable) {
+        this.reachable = reachable;
+    }
+
+    public boolean isReachable() {
+        return reachable;
+    }
+
+    public boolean isPolymorphic() {
+        return polymorphic;
+    }
+
+    @Override
+    protected List<MessageContainer> findChildContainers() {
+        List<MessageContainer> sinks = new ArrayList<>();
+        if (exceptions != null) {
+            sinks.addAll(exceptions);
+        }
+        if (guards != null) {
+            sinks.addAll(guards);
+        }
+        return sinks;
+    }
+
+    public boolean isGenericSpecialization(ProcessorContext context) {
+        if (isGeneric()) {
+            return true;
+        }
+        if (hasRewrite(context)) {
+            return false;
+        }
+
+        for (ActualParameter parameter : getParameters()) {
+            if (!parameter.getSpecification().isSignature()) {
+                continue;
+            }
+            NodeChildData child = getNode().findChild(parameter.getSpecification().getName());
+            if (child == null) {
+                continue;
+            }
+            if (!parameter.getTypeSystemType().isGeneric()) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    public boolean hasRewrite(ProcessorContext context) {
+        if (!getExceptions().isEmpty()) {
+            return true;
+        }
+        if (!getGuards().isEmpty()) {
+            return true;
+        }
+        if (!getAssumptions().isEmpty()) {
+            return true;
+        }
+        for (ActualParameter parameter : getParameters()) {
+            NodeChildData child = getNode().findChild(parameter.getSpecification().getName());
+            if (child == null) {
+                continue;
+            }
+            ExecutableTypeData type = child.findExecutableType(context, parameter.getTypeSystemType());
+            if (type.hasUnexpectedValue(context)) {
+                return true;
+            }
+            if (type.getReturnType().getTypeSystemType().needsCastTo(context, parameter.getTypeSystemType())) {
+                return true;
+            }
+
+        }
+        return false;
+    }
+
+    @Override
+    public int compareBySignature(TemplateMethod other) {
+        if (this == other) {
+            return 0;
+        } else if (!(other instanceof SpecializationData)) {
+            return super.compareBySignature(other);
+        }
+
+        SpecializationData m2 = (SpecializationData) other;
+
+        if (getOrder() != Specialization.DEFAULT_ORDER && m2.getOrder() != Specialization.DEFAULT_ORDER) {
+            return getOrder() - m2.getOrder();
+        } else if (isUninitialized() ^ m2.isUninitialized()) {
+            return isUninitialized() ? -1 : 1;
+        } else if (isGeneric() ^ m2.isGeneric()) {
+            return isGeneric() ? 1 : -1;
+        }
+
+        if (getTemplate() != m2.getTemplate()) {
+            throw new UnsupportedOperationException("Cannot compare two specializations with different templates.");
+        }
+
+        return super.compareBySignature(m2);
+    }
+
+    public NodeData getNode() {
+        return node;
+    }
+
+    public void setNode(NodeData node) {
+        this.node = node;
+    }
+
+    public void setGuards(List<GuardData> guards) {
+        this.guards = guards;
+    }
+
+    public void setGuardDefinitions(List<String> guardDefinitions) {
+        this.guardDefinitions = guardDefinitions;
+    }
+
+    public int getOrder() {
+        return order;
+    }
+
+    public boolean isGeneric() {
+        return generic;
+    }
+
+    public boolean isUninitialized() {
+        return uninitialized;
+    }
+
+    public List<SpecializationThrowsData> getExceptions() {
+        return exceptions;
+    }
+
+    public List<String> getGuardDefinitions() {
+        return guardDefinitions;
+    }
+
+    public List<GuardData> getGuards() {
+        return guards;
+    }
+
+    public void setShortCircuits(List<ShortCircuitData> shortCircuits) {
+        this.shortCircuits = shortCircuits;
+    }
+
+    public List<ShortCircuitData> getShortCircuits() {
+        return shortCircuits;
+    }
+
+    public List<String> getAssumptions() {
+        return assumptions;
+    }
+
+    void setAssumptions(List<String> assumptions) {
+        this.assumptions = assumptions;
+    }
+
+    public SpecializationData findNextSpecialization() {
+        List<SpecializationData> specializations = node.getSpecializations();
+        for (int i = 0; i < specializations.size() - 1; i++) {
+            if (specializations.get(i) == this) {
+                return specializations.get(i + 1);
+            }
+        }
+        return null;
+    }
+
+    public boolean hasDynamicGuards() {
+        return !getGuards().isEmpty();
+    }
+
+    @Override
+    public String toString() {
+        return String.format("%s [id = %s, method = %s, guards = %s, signature = %s]", getClass().getSimpleName(), getId(), getMethod(), getGuards(), getSignature());
+    }
+
+    public void forceFrame(TypeMirror frameType) {
+        if (getParameters().isEmpty() || !Utils.typeEquals(getParameters().get(0).getType(), frameType)) {
+            ParameterSpec frameSpec = getSpecification().findParameterSpec("frame");
+            getParameters().add(0, new ActualParameter(frameSpec, frameType, -1, false));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationGuardData.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.node;
+
+import javax.lang.model.element.*;
+
+import com.oracle.truffle.dsl.processor.template.*;
+import com.oracle.truffle.dsl.processor.typesystem.*;
+
+public class SpecializationGuardData extends MessageContainer {
+
+    private final SpecializationData specialization;
+    private final AnnotationValue value;
+    private final String guardMethod;
+    private final boolean onSpecialization;
+    private final boolean onExecution;
+
+    private GuardData guardDeclaration;
+
+    public SpecializationGuardData(SpecializationData specialization, AnnotationValue value, String guardMethod, boolean onSpecialization, boolean onExecution) {
+        this.specialization = specialization;
+        this.guardMethod = guardMethod;
+        this.onSpecialization = onSpecialization;
+        this.onExecution = onExecution;
+        this.value = value;
+    }
+
+    @Override
+    public Element getMessageElement() {
+        return specialization.getMessageElement();
+    }
+
+    @Override
+    public AnnotationMirror getMessageAnnotation() {
+        return specialization.getMessageAnnotation();
+    }
+
+    @Override
+    public AnnotationValue getMessageAnnotationValue() {
+        return value;
+    }
+
+    public String getGuardMethod() {
+        return guardMethod;
+    }
+
+    public boolean isOnExecution() {
+        return onExecution;
+    }
+
+    public boolean isOnSpecialization() {
+        return onSpecialization;
+    }
+
+    public void setGuardDeclaration(GuardData compatibleGuard) {
+        this.guardDeclaration = compatibleGuard;
+    }
+
+    public GuardData getGuardDeclaration() {
+        return guardDeclaration;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationListenerData.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.node;
+
+import com.oracle.truffle.dsl.processor.template.*;
+
+public class SpecializationListenerData extends TemplateMethod {
+
+    public SpecializationListenerData(TemplateMethod method) {
+        super(method);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationListenerParser.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.node;
+
+import java.lang.annotation.*;
+
+import javax.lang.model.element.*;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.template.*;
+
+public class SpecializationListenerParser extends NodeMethodParser<SpecializationListenerData> {
+
+    public SpecializationListenerParser(ProcessorContext context, NodeData node) {
+        super(context, node);
+    }
+
+    @Override
+    public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
+        return createDefaultMethodSpec(method, mirror, true, null);
+    }
+
+    @Override
+    protected ParameterSpec createReturnParameterSpec() {
+        return new ParameterSpec("void", getContext().getType(void.class));
+    }
+
+    @Override
+    public SpecializationListenerData create(TemplateMethod method) {
+        return new SpecializationListenerData(method);
+    }
+
+    @Override
+    public Class<? extends Annotation> getAnnotationType() {
+        return SpecializationListener.class;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationMethodParser.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.node;
+
+import java.lang.annotation.*;
+import java.util.*;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.template.*;
+
+public class SpecializationMethodParser extends NodeMethodParser<SpecializationData> {
+
+    public SpecializationMethodParser(ProcessorContext context, NodeData operation) {
+        super(context, operation);
+    }
+
+    @Override
+    public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
+        return createDefaultMethodSpec(method, mirror, true, null);
+    }
+
+    @Override
+    public SpecializationData create(TemplateMethod method) {
+        return parseSpecialization(method);
+    }
+
+    @Override
+    public Class<? extends Annotation> getAnnotationType() {
+        return Specialization.class;
+    }
+
+    private SpecializationData parseSpecialization(TemplateMethod method) {
+        int order = Utils.getAnnotationValue(Integer.class, method.getMarkerAnnotation(), "order");
+        if (order < 0 && order != Specialization.DEFAULT_ORDER) {
+            method.addError("Invalid order attribute %d. The value must be >= 0 or the default value.");
+            return null;
+        }
+
+        AnnotationValue rewriteValue = Utils.getAnnotationValue(method.getMarkerAnnotation(), "rewriteOn");
+        List<TypeMirror> exceptionTypes = Utils.getAnnotationValueList(TypeMirror.class, method.getMarkerAnnotation(), "rewriteOn");
+        List<SpecializationThrowsData> exceptionData = new ArrayList<>();
+        for (TypeMirror exceptionType : exceptionTypes) {
+            SpecializationThrowsData throwsData = new SpecializationThrowsData(method.getMarkerAnnotation(), rewriteValue, exceptionType);
+            if (!Utils.canThrowType(method.getMethod().getThrownTypes(), exceptionType)) {
+                throwsData.addError("Method must specify a throws clause with the exception type '%s'.", Utils.getQualifiedName(exceptionType));
+            }
+            exceptionData.add(throwsData);
+        }
+
+        Collections.sort(exceptionData, new Comparator<SpecializationThrowsData>() {
+
+            @Override
+            public int compare(SpecializationThrowsData o1, SpecializationThrowsData o2) {
+                return Utils.compareByTypeHierarchy(o1.getJavaClass(), o2.getJavaClass());
+            }
+        });
+        SpecializationData specialization = new SpecializationData(method, order, exceptionData);
+        List<String> guardDefs = Utils.getAnnotationValueList(String.class, specialization.getMarkerAnnotation(), "guards");
+        specialization.setGuardDefinitions(guardDefs);
+
+        List<String> assumptionDefs = Utils.getAnnotationValueList(String.class, specialization.getMarkerAnnotation(), "assumptions");
+        specialization.setAssumptions(assumptionDefs);
+
+        for (String assumption : assumptionDefs) {
+            if (!getNode().getAssumptions().contains(assumption)) {
+                specialization.addError("Undeclared assumption '%s' used. Use @NodeAssumptions to declare them.", assumption);
+            }
+        }
+
+        return specialization;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationThrowsData.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.node;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+import com.oracle.truffle.dsl.processor.template.*;
+
+public class SpecializationThrowsData extends MessageContainer {
+
+    private final AnnotationValue annotationValue;
+    private final AnnotationMirror annotationMirror;
+    private final TypeMirror javaClass;
+    private SpecializationData specialization;
+
+    public SpecializationThrowsData(AnnotationMirror annotationMirror, AnnotationValue value, TypeMirror javaClass) {
+        this.annotationMirror = annotationMirror;
+        this.annotationValue = value;
+        this.javaClass = javaClass;
+    }
+
+    void setSpecialization(SpecializationData specialization) {
+        this.specialization = specialization;
+    }
+
+    @Override
+    public Element getMessageElement() {
+        return specialization.getMessageElement();
+    }
+
+    @Override
+    public AnnotationMirror getMessageAnnotation() {
+        return annotationMirror;
+    }
+
+    @Override
+    public AnnotationValue getMessageAnnotationValue() {
+        return annotationValue;
+    }
+
+    public TypeMirror getJavaClass() {
+        return javaClass;
+    }
+
+    public SpecializationData getSpecialization() {
+        return specialization;
+    }
+
+    public AnnotationMirror getAnnotationMirror() {
+        return annotationMirror;
+    }
+
+    public SpecializationData getTransitionTo() {
+        return specialization.findNextSpecialization();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ActualParameter.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.template;
+
+import javax.lang.model.type.*;
+
+import com.oracle.truffle.dsl.processor.typesystem.*;
+
+public class ActualParameter {
+
+    private final ParameterSpec specification;
+    private TypeData typeSystemType;
+    private TemplateMethod method;
+    private final String localName;
+    private final int index;
+    private final boolean implicit;
+    private final TypeMirror type;
+
+    public ActualParameter(ParameterSpec specification, TypeMirror actualType, int index, boolean implicit) {
+        this.specification = specification;
+        this.type = actualType;
+        this.typeSystemType = null;
+
+        this.index = index;
+        this.implicit = implicit;
+        String valueName = specification.getName() + "Value";
+
+        if (specification.isIndexed()) {
+            valueName += index;
+        }
+        this.localName = valueName;
+    }
+
+    public ActualParameter(ParameterSpec specification, TypeData actualType, int index, boolean implicit) {
+        this(specification, actualType.getPrimitiveType(), index, implicit);
+        this.typeSystemType = actualType;
+    }
+
+    public ActualParameter(ActualParameter parameter, TypeData otherType) {
+        this(parameter.specification, otherType, parameter.index, parameter.implicit);
+    }
+
+    public ActualParameter(ActualParameter parameter) {
+        this.specification = parameter.specification;
+        this.type = parameter.type;
+        this.typeSystemType = parameter.typeSystemType;
+        this.index = parameter.index;
+        this.implicit = parameter.implicit;
+        this.localName = parameter.localName;
+    }
+
+    public boolean isImplicit() {
+        return implicit;
+    }
+
+    public int getIndex() {
+        return index;
+    }
+
+    public String getLocalName() {
+        return localName;
+    }
+
+    void setMethod(TemplateMethod method) {
+        this.method = method;
+    }
+
+    public ParameterSpec getSpecification() {
+        return specification;
+    }
+
+    public TemplateMethod getMethod() {
+        return method;
+    }
+
+    public TypeMirror getType() {
+        return type;
+    }
+
+    public TypeData getTypeSystemType() {
+        return typeSystemType;
+    }
+
+    public ActualParameter getPreviousParameter() {
+        return method.getPreviousParam(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ClassElementFactory.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.template;
+
+import static com.oracle.truffle.dsl.processor.Utils.*;
+import static javax.lang.model.element.Modifier.*;
+
+import java.util.*;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+import javax.lang.model.util.*;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.ast.*;
+
+public abstract class ClassElementFactory<M> extends CodeElementFactory<M> {
+
+    public ClassElementFactory(ProcessorContext context) {
+        super(context);
+    }
+
+    @Override
+    protected abstract CodeTypeElement create(M m);
+
+    @Override
+    public CodeTypeElement getElement() {
+        return (CodeTypeElement) super.getElement();
+    }
+
+    protected CodeExecutableElement createConstructorUsingFields(Set<Modifier> modifiers, CodeTypeElement clazz) {
+        CodeExecutableElement method = new CodeExecutableElement(modifiers, null, clazz.getSimpleName().toString());
+        CodeTreeBuilder builder = method.createBuilder();
+        TypeElement superClass = fromTypeMirror(clazz.getSuperclass());
+        ExecutableElement constructor = findConstructor(superClass);
+        if (constructor != null && constructor.getParameters().size() > 0) {
+            builder.startStatement();
+            builder.startSuperCall();
+            for (VariableElement parameter : constructor.getParameters()) {
+                method.addParameter(new CodeVariableElement(parameter.asType(), parameter.getSimpleName().toString()));
+                builder.string(parameter.getSimpleName().toString());
+            }
+            builder.end(); // super
+            builder.end(); // statement
+        }
+
+        for (VariableElement field : clazz.getFields()) {
+            if (field.getModifiers().contains(STATIC)) {
+                continue;
+            }
+            String fieldName = field.getSimpleName().toString();
+            method.addParameter(new CodeVariableElement(field.asType(), fieldName));
+            builder.startStatement();
+            builder.string("this.");
+            builder.string(fieldName);
+            builder.string(" = ");
+            if (isAssignable(getContext(), field.asType(), getContext().getTruffleTypes().getNode())) {
+                builder.string("adoptChild(").string(fieldName).string(")");
+            } else {
+                builder.string(fieldName);
+            }
+            builder.end(); // statement
+        }
+
+        return method;
+    }
+
+    private static ExecutableElement findConstructor(TypeElement clazz) {
+        List<ExecutableElement> constructors = ElementFilter.constructorsIn(clazz.getEnclosedElements());
+        if (constructors.isEmpty()) {
+            return null;
+        } else {
+            return constructors.get(0);
+        }
+    }
+
+    protected CodeExecutableElement createSuperConstructor(TypeElement type, ExecutableElement element) {
+        if (element.getModifiers().contains(Modifier.PRIVATE)) {
+            return null;
+        }
+        CodeExecutableElement executable = CodeExecutableElement.clone(getContext().getEnvironment(), element);
+        executable.setReturnType(null);
+        executable.setSimpleName(CodeNames.of(type.getSimpleName().toString()));
+        CodeTreeBuilder b = executable.createBuilder();
+        b.startStatement();
+        b.startSuperCall();
+        for (VariableElement v : element.getParameters()) {
+            b.string(v.getSimpleName().toString());
+        }
+        b.end();
+        b.end();
+
+        return executable;
+    }
+
+    protected CodeTypeElement createClass(Template model, Set<Modifier> modifiers, String simpleName, TypeMirror superType, boolean enumType) {
+        TypeElement templateType = model.getTemplateType();
+
+        PackageElement pack = getContext().getEnvironment().getElementUtils().getPackageOf(templateType);
+        CodeTypeElement clazz = new CodeTypeElement(modifiers, enumType ? ElementKind.ENUM : ElementKind.CLASS, pack, simpleName);
+        TypeMirror resolvedSuperType = superType;
+        if (resolvedSuperType == null) {
+            resolvedSuperType = getContext().getType(Object.class);
+        }
+        clazz.setSuperClass(resolvedSuperType);
+
+        CodeAnnotationMirror generatedByAnnotation = new CodeAnnotationMirror((DeclaredType) getContext().getType(GeneratedBy.class));
+        generatedByAnnotation.setElementValue(generatedByAnnotation.findExecutableElement("value"), new CodeAnnotationValue(templateType.asType()));
+        if (model.getTemplateMethodName() != null) {
+            generatedByAnnotation.setElementValue(generatedByAnnotation.findExecutableElement("methodName"), new CodeAnnotationValue(model.getTemplateMethodName()));
+        }
+
+        clazz.addAnnotationMirror(generatedByAnnotation);
+
+        context.registerType(model.getTemplateType(), clazz.asType());
+
+        return clazz;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/CodeElementFactory.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.template;
+
+import javax.lang.model.element.*;
+
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.ast.*;
+
+public abstract class CodeElementFactory<M> {
+
+    protected final ProcessorContext context;
+    private M model;
+
+    private CodeElement<? super Element> element;
+
+    public CodeElementFactory(ProcessorContext context) {
+        this.context = context;
+    }
+
+    protected abstract CodeElement<?> create(M m);
+
+    @SuppressWarnings("unused")
+    protected void createChildren(M m) {
+    }
+
+    @SuppressWarnings("unchecked")
+    public CodeElement<?> process(CodeElement parent, M m) {
+        model = m;
+        element = (CodeElement<? super Element>) create(model);
+        if (parent != null) {
+            parent.add(element);
+        }
+        if (element != null) {
+            createChildren(model);
+        }
+        return element;
+    }
+
+    public CodeElement getElement() {
+        return element;
+    }
+
+    protected <MO, K extends Element> void add(CodeElementFactory<MO> factory, MO m) {
+        factory.process(this.element, m);
+    }
+
+    public ProcessorContext getContext() {
+        return context;
+    }
+
+    public M getModel() {
+        return model;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/CompilationUnitFactory.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.template;
+
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.ast.*;
+
+public abstract class CompilationUnitFactory<M> extends CodeElementFactory<M> {
+
+    public CompilationUnitFactory(ProcessorContext context) {
+        super(context);
+    }
+
+    @Override
+    public final CodeCompilationUnit create(M m) {
+        return new CodeCompilationUnit();
+    }
+
+    @Override
+    public CodeCompilationUnit process(CodeElement parent, M m) {
+        return (CodeCompilationUnit) super.process(parent, m);
+    }
+
+    @Override
+    protected abstract void createChildren(M m);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/JavaName.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.template;
+
+import java.util.*;
+import java.util.regex.*;
+
+public final class JavaName {
+
+    private static final String[] RESERVED_NAMES = new String[]{"abstract", "continue", "for", "new", "switch", "assert", "default", "goto", "package", "synchronized", "boolean", "do", "if",
+                    "private", "this", "break", "double", "implements", "protected", "throw", "byte", "else", "import", "public", "throws", "case", "enum", "instanceof", "return", "transient",
+                    "catch", "extends", "int", "short", "try", "char", "final", "interface", "static", "void", "class", "finally", "long", "strictfp", "volatile", "const", "float", "native", "super",
+                    "while"};
+
+    private static final Set<String> RESERVED_NAMES_SET = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(RESERVED_NAMES)));
+
+    private static final Pattern VALID_JAVA_NAME_PATTERN = Pattern.compile("[_a-zA-z][_a-zA-Z0-9]*");
+
+    private JavaName() {
+        super();
+    }
+
+    public static boolean isReserved(String name) {
+        return RESERVED_NAMES_SET.contains(name);
+    }
+
+    public static boolean isValid(String typeName) {
+        return VALID_JAVA_NAME_PATTERN.matcher(typeName).matches();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MessageContainer.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.template;
+
+import java.util.*;
+
+import javax.lang.model.element.*;
+import javax.tools.Diagnostic.Kind;
+
+import com.oracle.truffle.dsl.processor.*;
+
+public abstract class MessageContainer {
+
+    private final List<Message> messages = new ArrayList<>();
+
+    public final void addWarning(String text, Object... params) {
+        getMessages().add(new Message(null, this, String.format(text, params), Kind.WARNING));
+    }
+
+    public final void addError(String text, Object... params) {
+        addError(null, text, params);
+    }
+
+    public final void addError(AnnotationValue value, String text, Object... params) {
+        getMessages().add(new Message(value, this, String.format(text, params), Kind.ERROR));
+    }
+
+    protected List<MessageContainer> findChildContainers() {
+        return Collections.emptyList();
+    }
+
+    public abstract Element getMessageElement();
+
+    public final void emitMessages(TypeElement baseElement, Log log) {
+        emitMessagesImpl(baseElement, log, new HashSet<MessageContainer>());
+    }
+
+    private void emitMessagesImpl(TypeElement baseElement, Log log, Set<MessageContainer> visitedSinks) {
+        for (Message message : getMessages()) {
+            emitDefault(baseElement, log, message);
+        }
+
+        for (MessageContainer sink : findChildContainers()) {
+            if (visitedSinks.contains(sink)) {
+                continue;
+            }
+
+            visitedSinks.add(sink);
+            sink.emitMessagesImpl(baseElement, log, visitedSinks);
+        }
+    }
+
+    private void emitDefault(TypeElement baseType, Log log, Message message) {
+        TypeElement rootEnclosing = Utils.findRootEnclosingType(getMessageElement());
+        if (rootEnclosing != null && Utils.typeEquals(baseType.asType(), rootEnclosing.asType()) && this == message.getOriginalContainer()) {
+            log.message(message.getKind(), getMessageElement(), getMessageAnnotation(), getMessageAnnotationValue(), message.getText());
+        } else {
+            MessageContainer original = message.getOriginalContainer();
+            log.message(message.getKind(), baseType, null, null, wrapText(original.getMessageElement(), original.getMessageAnnotation(), message.getText()));
+        }
+    }
+
+    private static String wrapText(Element element, AnnotationMirror mirror, String text) {
+        StringBuilder b = new StringBuilder();
+        if (element != null) {
+            b.append("Element " + element.toString());
+        }
+        if (mirror != null) {
+            b.append(" at annotation @" + Utils.getSimpleName(mirror.getAnnotationType()));
+        }
+
+        if (b.length() > 0) {
+            b.append(" is erroneous: ").append(text);
+            return b.toString();
+        } else {
+            return text;
+        }
+    }
+
+    public AnnotationMirror getMessageAnnotation() {
+        return null;
+    }
+
+    public AnnotationValue getMessageAnnotationValue() {
+        return null;
+    }
+
+    public final boolean hasErrors() {
+        return hasErrorsImpl(new HashSet<MessageContainer>());
+    }
+
+    public final List<Message> collectMessages() {
+        List<Message> collectedMessages = new ArrayList<>();
+        collectMessagesImpl(collectedMessages, new HashSet<MessageContainer>());
+        return collectedMessages;
+    }
+
+    private void collectMessagesImpl(List<Message> collectedMessages, Set<MessageContainer> visitedSinks) {
+        collectedMessages.addAll(getMessages());
+        for (MessageContainer sink : findChildContainers()) {
+            if (visitedSinks.contains(sink)) {
+                return;
+            }
+
+            visitedSinks.add(sink);
+            sink.collectMessagesImpl(collectedMessages, visitedSinks);
+        }
+    }
+
+    private boolean hasErrorsImpl(Set<MessageContainer> visitedSinks) {
+        for (Message msg : getMessages()) {
+            if (msg.getKind() == Kind.ERROR) {
+                return true;
+            }
+        }
+        for (MessageContainer sink : findChildContainers()) {
+            if (visitedSinks.contains(sink)) {
+                return false;
+            }
+
+            visitedSinks.add(sink);
+
+            if (sink.hasErrorsImpl(visitedSinks)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public List<Message> getMessages() {
+        return messages;
+    }
+
+    public static final class Message {
+
+        private final MessageContainer originalContainer;
+        private final AnnotationValue annotationValue;
+        private final String text;
+        private final Kind kind;
+
+        public Message(AnnotationValue annotationValue, MessageContainer originalContainer, String text, Kind kind) {
+            this.annotationValue = annotationValue;
+            this.originalContainer = originalContainer;
+            this.text = text;
+            this.kind = kind;
+        }
+
+        public AnnotationValue getAnnotationValue() {
+            return annotationValue;
+        }
+
+        public MessageContainer getOriginalContainer() {
+            return originalContainer;
+        }
+
+        public String getText() {
+            return text;
+        }
+
+        public Kind getKind() {
+            return kind;
+        }
+
+        @Override
+        public String toString() {
+            return kind + ": " + text;
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MethodSpec.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.template;
+
+import java.util.*;
+
+import javax.lang.model.type.*;
+
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.node.NodeChildData.*;
+
+public class MethodSpec {
+
+    private final List<TypeMirror> implicitRequiredTypes = new ArrayList<>();
+
+    private final ParameterSpec returnType;
+    private final List<ParameterSpec> optional = new ArrayList<>();
+    private final List<ParameterSpec> required = new ArrayList<>();
+
+    private boolean variableRequiredArguments;
+    private List<TypeDef> typeDefinitions;
+
+    public MethodSpec(ParameterSpec returnType) {
+        this.returnType = returnType;
+    }
+
+    public void setVariableRequiredArguments(boolean variableArguments) {
+        this.variableRequiredArguments = variableArguments;
+    }
+
+    public boolean isVariableRequiredArguments() {
+        return variableRequiredArguments;
+    }
+
+    public void addImplicitRequiredType(TypeMirror type) {
+        this.implicitRequiredTypes.add(type);
+    }
+
+    public void addOptional(ParameterSpec spec) {
+        optional.add(spec);
+    }
+
+    public ParameterSpec addRequired(ParameterSpec spec) {
+        required.add(spec);
+        return spec;
+    }
+
+    public List<TypeMirror> getImplicitRequiredTypes() {
+        return implicitRequiredTypes;
+    }
+
+    public ParameterSpec getReturnType() {
+        return returnType;
+    }
+
+    public List<ParameterSpec> getRequired() {
+        return required;
+    }
+
+    public List<ParameterSpec> getOptional() {
+        return optional;
+    }
+
+    public List<ParameterSpec> getAll() {
+        List<ParameterSpec> specs = new ArrayList<>();
+        specs.add(getReturnType());
+        specs.addAll(getOptional());
+        specs.addAll(getRequired());
+        return specs;
+    }
+
+    public ParameterSpec findParameterSpec(String name) {
+        for (ParameterSpec spec : getAll()) {
+            if (spec.getName().equals(name)) {
+                return spec;
+            }
+        }
+        return null;
+    }
+
+    public void applyTypeDefinitions(String prefix) {
+        this.typeDefinitions = createTypeDefinitions(prefix);
+    }
+
+    private List<TypeDef> createTypeDefinitions(String prefix) {
+        List<TypeDef> typeDefs = new ArrayList<>();
+
+        int defIndex = 0;
+        for (ParameterSpec spec : getAll()) {
+            List<TypeMirror> allowedTypes = spec.getAllowedTypes();
+            List<TypeMirror> types = spec.getAllowedTypes();
+            if (types != null && allowedTypes.size() > 1) {
+                TypeDef foundDef = null;
+                for (TypeDef def : typeDefs) {
+                    if (allowedTypes.equals(def.getTypes())) {
+                        foundDef = def;
+                        break;
+                    }
+                }
+                if (foundDef == null) {
+                    foundDef = new TypeDef(types, prefix + defIndex);
+                    typeDefs.add(foundDef);
+                    defIndex++;
+                }
+
+                spec.setTypeDefinition(foundDef);
+            }
+        }
+
+        return typeDefs;
+    }
+
+    public String toSignatureString(String methodName) {
+        StringBuilder b = new StringBuilder();
+        b.append("    ");
+        b.append(createTypeSignature(returnType, true));
+
+        b.append(" ");
+        b.append(methodName);
+        b.append("(");
+
+        String sep = "";
+
+        for (ParameterSpec optionalSpec : getOptional()) {
+            b.append(sep);
+            b.append("[");
+            b.append(createTypeSignature(optionalSpec, false));
+            b.append("]");
+            sep = ", ";
+        }
+
+        for (ParameterSpec requiredSpec : getRequired()) {
+            b.append(sep);
+            if (requiredSpec.getCardinality() == Cardinality.MANY) {
+                b.append("{");
+            }
+            b.append(createTypeSignature(requiredSpec, false));
+            if (requiredSpec.getCardinality() == Cardinality.MANY) {
+                b.append("}");
+            }
+            sep = ", ";
+        }
+
+        b.append(")");
+
+        if (typeDefinitions != null && !typeDefinitions.isEmpty()) {
+            b.append("\n\n");
+
+            String lineSep = "";
+            for (TypeDef def : typeDefinitions) {
+                b.append(lineSep);
+                b.append("    <").append(def.getName()).append(">");
+                b.append(" = {");
+                String separator = "";
+                for (TypeMirror type : def.getTypes()) {
+                    b.append(separator).append(Utils.getSimpleName(type));
+                    separator = ", ";
+                }
+                b.append("}");
+                lineSep = "\n";
+
+            }
+        }
+        return b.toString();
+    }
+
+    private static String createTypeSignature(ParameterSpec spec, boolean typeOnly) {
+        StringBuilder builder = new StringBuilder();
+        TypeDef foundTypeDef = spec.getTypeDefinition();
+        if (foundTypeDef != null) {
+            builder.append("<" + foundTypeDef.getName() + ">");
+        } else if (spec.getAllowedTypes().size() >= 1) {
+            builder.append(Utils.getSimpleName(spec.getAllowedTypes().get(0)));
+        } else {
+            builder.append("void");
+        }
+        if (!typeOnly) {
+            builder.append(" ");
+            builder.append(spec.getName());
+        }
+        return builder.toString();
+    }
+
+    @Override
+    public String toString() {
+        return toSignatureString("methodName");
+    }
+
+    static class TypeDef {
+
+        private final List<TypeMirror> types;
+        private final String name;
+
+        public TypeDef(List<TypeMirror> types, String name) {
+            this.types = types;
+            this.name = name;
+        }
+
+        public List<TypeMirror> getTypes() {
+            return types;
+        }
+
+        public String getName() {
+            return name;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ParameterSpec.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.template;
+
+import java.util.*;
+
+import javax.lang.model.type.*;
+
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.node.NodeChildData.*;
+import com.oracle.truffle.dsl.processor.template.MethodSpec.*;
+
+public class ParameterSpec {
+
+    private final String name;
+    private final List<TypeMirror> allowedTypes;
+
+    /** Cardinality one or multiple. */
+    private Cardinality cardinality = Cardinality.ONE;
+    /** Type is part of the method signature. Relevant for comparisons. */
+    private boolean signature;
+    /** Type must be indexed when parsing. */
+    private boolean indexed;
+    /** Type is bound to local final variable. */
+    private boolean local;
+
+    private TypeDef typeDefinition;
+
+    public ParameterSpec(String name, TypeMirror... allowedTypes) {
+        this(name, Arrays.asList(allowedTypes));
+    }
+
+    public ParameterSpec(String name, List<TypeMirror> allowedTypes) {
+        this.name = name;
+        this.allowedTypes = allowedTypes;
+    }
+
+    public ParameterSpec(ParameterSpec o, List<TypeMirror> allowedTypes) {
+        this.name = o.name;
+        this.cardinality = o.cardinality;
+        this.signature = o.signature;
+        this.indexed = o.indexed;
+        this.local = o.local;
+        this.typeDefinition = o.typeDefinition;
+        this.allowedTypes = allowedTypes;
+    }
+
+    void setTypeDefinition(TypeDef typeDefinition) {
+        this.typeDefinition = typeDefinition;
+    }
+
+    TypeDef getTypeDefinition() {
+        return typeDefinition;
+    }
+
+    public void setSignature(boolean signature) {
+        this.signature = signature;
+    }
+
+    public void setLocal(boolean local) {
+        this.local = local;
+    }
+
+    public boolean isSignature() {
+        return signature;
+    }
+
+    public boolean isLocal() {
+        return local;
+    }
+
+    public boolean isIndexed() {
+        return indexed;
+    }
+
+    public void setIndexed(boolean indexed) {
+        this.indexed = indexed;
+    }
+
+    public void setCardinality(Cardinality cardinality) {
+        this.cardinality = cardinality;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Cardinality getCardinality() {
+        return cardinality;
+    }
+
+    public List<TypeMirror> getAllowedTypes() {
+        return allowedTypes;
+    }
+
+    public boolean matches(TypeMirror actualType) {
+        for (TypeMirror mirror : allowedTypes) {
+            if (Utils.typeEquals(actualType, mirror)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toSignatureString(false);
+    }
+
+    public String toSignatureString(boolean typeOnly) {
+        StringBuilder builder = new StringBuilder();
+        if (typeDefinition != null) {
+            builder.append("<" + typeDefinition.getName() + ">");
+        } else if (getAllowedTypes().size() >= 1) {
+            builder.append(Utils.getSimpleName(getAllowedTypes().get(0)));
+        } else {
+            builder.append("void");
+        }
+        if (!typeOnly) {
+            builder.append(" ");
+            builder.append(getName());
+        }
+        return builder.toString();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/Template.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.template;
+
+import java.util.*;
+
+import javax.lang.model.element.*;
+
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.api.element.*;
+import com.oracle.truffle.dsl.processor.typesystem.*;
+
+public abstract class Template extends MessageContainer {
+
+    private final TypeElement templateType;
+    private final String templateMethodName;
+    private final AnnotationMirror annotation;
+
+    private List<? extends WritableElement> extensionElements;
+
+    public Template(TypeElement templateType, String templateMethodName, AnnotationMirror annotation) {
+        this.templateType = templateType;
+        this.templateMethodName = templateMethodName;
+        this.annotation = annotation;
+    }
+
+    public abstract TypeSystemData getTypeSystem();
+
+    @Override
+    public Element getMessageElement() {
+        return templateType;
+    }
+
+    @Override
+    protected List<MessageContainer> findChildContainers() {
+        return Collections.emptyList();
+    }
+
+    public String getTemplateMethodName() {
+        return templateMethodName;
+    }
+
+    public TypeElement getTemplateType() {
+        return templateType;
+    }
+
+    public AnnotationMirror getTemplateTypeAnnotation() {
+        return annotation;
+    }
+
+    public List<? extends WritableElement> getExtensionElements() {
+        return extensionElements;
+    }
+
+    public void setExtensionElements(List<? extends WritableElement> extensionMethods) {
+        this.extensionElements = extensionMethods;
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + "[" + Utils.getSimpleName(getTemplateType()) + "]";
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethod.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,393 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.template;
+
+import java.util.*;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.typesystem.*;
+
+/**
+ * Note: this class has a natural ordering that is inconsistent with equals.
+ */
+public class TemplateMethod extends MessageContainer implements Comparable<TemplateMethod> {
+
+    private String id;
+    private final Template template;
+    private final MethodSpec specification;
+    private final ExecutableElement method;
+    private final AnnotationMirror markerAnnotation;
+    private ActualParameter returnType;
+    private List<ActualParameter> parameters;
+
+    public TemplateMethod(String id, Template template, MethodSpec specification, ExecutableElement method, AnnotationMirror markerAnnotation, ActualParameter returnType,
+                    List<ActualParameter> parameters) {
+        this.template = template;
+        this.specification = specification;
+        this.method = method;
+        this.markerAnnotation = markerAnnotation;
+        this.returnType = returnType;
+        this.parameters = new ArrayList<>();
+        for (ActualParameter param : parameters) {
+            ActualParameter newParam = new ActualParameter(param);
+            this.parameters.add(newParam);
+            newParam.setMethod(this);
+        }
+        this.id = id;
+    }
+
+    public TemplateMethod(TemplateMethod method) {
+        this(method.id, method.template, method.specification, method.method, method.markerAnnotation, method.returnType, method.parameters);
+        getMessages().addAll(method.getMessages());
+    }
+
+    public TemplateMethod(TemplateMethod method, ExecutableElement executable) {
+        this(method.id, method.template, method.specification, executable, method.markerAnnotation, method.returnType, method.parameters);
+        getMessages().addAll(method.getMessages());
+    }
+
+    public void setParameters(List<ActualParameter> parameters) {
+        this.parameters = parameters;
+    }
+
+    @Override
+    public Element getMessageElement() {
+        return method;
+    }
+
+    @Override
+    public AnnotationMirror getMessageAnnotation() {
+        return markerAnnotation;
+    }
+
+    @Override
+    protected List<MessageContainer> findChildContainers() {
+        return Collections.emptyList();
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public Template getTemplate() {
+        return template;
+    }
+
+    public MethodSpec getSpecification() {
+        return specification;
+    }
+
+    public ActualParameter getReturnType() {
+        return returnType;
+    }
+
+    public void replaceParameter(String localName, ActualParameter newParameter) {
+        if (returnType.getLocalName().equals(localName)) {
+            returnType = newParameter;
+            returnType.setMethod(this);
+        }
+
+        for (ListIterator<ActualParameter> iterator = parameters.listIterator(); iterator.hasNext();) {
+            ActualParameter parameter = iterator.next();
+            if (parameter.getLocalName().equals(localName)) {
+                iterator.set(newParameter);
+                newParameter.setMethod(this);
+            }
+        }
+    }
+
+    public List<ActualParameter> getRequiredParameters() {
+        List<ActualParameter> requiredParameters = new ArrayList<>();
+        for (ActualParameter parameter : getParameters()) {
+            if (getSpecification().getRequired().contains(parameter.getSpecification())) {
+                requiredParameters.add(parameter);
+            }
+        }
+        return requiredParameters;
+    }
+
+    public List<ActualParameter> getParameters() {
+        return parameters;
+    }
+
+    public List<ActualParameter> findParameters(ParameterSpec spec) {
+        List<ActualParameter> foundParameters = new ArrayList<>();
+        for (ActualParameter param : getReturnTypeAndParameters()) {
+            if (param.getSpecification().equals(spec)) {
+                foundParameters.add(param);
+            }
+        }
+        return foundParameters;
+    }
+
+    public ActualParameter findParameter(String valueName) {
+        for (ActualParameter param : getReturnTypeAndParameters()) {
+            if (param.getLocalName().equals(valueName)) {
+                return param;
+            }
+        }
+        return null;
+    }
+
+    public List<ActualParameter> getReturnTypeAndParameters() {
+        List<ActualParameter> allParameters = new ArrayList<>(getParameters().size() + 1);
+        if (getReturnType() != null) {
+            allParameters.add(getReturnType());
+        }
+        allParameters.addAll(getParameters());
+        return Collections.unmodifiableList(allParameters);
+    }
+
+    public boolean canBeAccessedByInstanceOf(ProcessorContext context, TypeMirror type) {
+        TypeMirror methodType = Utils.findNearestEnclosingType(getMethod()).asType();
+        return Utils.isAssignable(context, type, methodType) || Utils.isAssignable(context, methodType, type);
+    }
+
+    public ExecutableElement getMethod() {
+        return method;
+    }
+
+    public String getMethodName() {
+        if (getMethod() != null) {
+            return getMethod().getSimpleName().toString();
+        } else {
+            return "$synthetic";
+        }
+    }
+
+    public AnnotationMirror getMarkerAnnotation() {
+        return markerAnnotation;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("%s [id = %s, method = %s]", getClass().getSimpleName(), getId(), getMethod());
+    }
+
+    public ActualParameter getPreviousParam(ActualParameter searchParam) {
+        ActualParameter prev = null;
+        for (ActualParameter param : getParameters()) {
+            if (param == searchParam) {
+                return prev;
+            }
+            prev = param;
+        }
+        return prev;
+    }
+
+    public Signature getSignature() {
+        Signature signature = new Signature();
+        for (ActualParameter parameter : getReturnTypeAndParameters()) {
+            if (!parameter.getSpecification().isSignature()) {
+                continue;
+            }
+            TypeData typeData = parameter.getTypeSystemType();
+            if (typeData != null) {
+                signature.types.add(typeData);
+            }
+        }
+        return signature;
+    }
+
+    public void updateSignature(Signature signature) {
+        assert signature.size() >= 1;
+        int signatureIndex = 0;
+        for (ActualParameter parameter : getReturnTypeAndParameters()) {
+            if (!parameter.getSpecification().isSignature()) {
+                continue;
+            }
+            TypeData newType = signature.get(signatureIndex++);
+            if (!parameter.getTypeSystemType().equals(newType)) {
+                replaceParameter(parameter.getLocalName(), new ActualParameter(parameter, newType));
+            }
+        }
+    }
+
+    @Override
+    public int compareTo(TemplateMethod o) {
+        if (this == o) {
+            return 0;
+        }
+
+        int compare = compareBySignature(o);
+        if (compare == 0) {
+            // if signature sorting failed sort by id
+            compare = getId().compareTo(o.getId());
+        }
+        if (compare == 0) {
+            // if still no difference sort by enclosing type name
+            TypeElement enclosingType1 = Utils.findNearestEnclosingType(getMethod());
+            TypeElement enclosingType2 = Utils.findNearestEnclosingType(o.getMethod());
+            compare = enclosingType1.getQualifiedName().toString().compareTo(enclosingType2.getQualifiedName().toString());
+        }
+        return compare;
+    }
+
+    public List<ActualParameter> getParametersAfter(ActualParameter genericParameter) {
+        boolean found = false;
+        List<ActualParameter> foundParameters = new ArrayList<>();
+        for (ActualParameter param : getParameters()) {
+            if (param.getLocalName().equals(genericParameter.getLocalName())) {
+                found = true;
+            } else if (found) {
+                foundParameters.add(param);
+            }
+        }
+        return foundParameters;
+    }
+
+    public int compareBySignature(TemplateMethod compareMethod) {
+        TypeSystemData typeSystem = getTemplate().getTypeSystem();
+        if (typeSystem != compareMethod.getTemplate().getTypeSystem()) {
+            throw new IllegalStateException("Cannot compare two methods with different type systems.");
+        }
+
+        Signature signature1 = getSignature();
+        Signature signature2 = compareMethod.getSignature();
+        if (signature1.size() != signature2.size()) {
+            return signature2.size() - signature1.size();
+        }
+
+        int result = 0;
+        for (int i = 1; i < signature1.size(); i++) {
+            int typeResult = compareActualParameter(typeSystem, signature1.get(i), signature2.get(i));
+            if (result == 0) {
+                result = typeResult;
+            } else if (typeResult != 0 && Math.signum(result) != Math.signum(typeResult)) {
+                // We cannot define an order.
+                return 0;
+            }
+        }
+        if (result == 0 && signature1.size() > 0) {
+            result = compareActualParameter(typeSystem, signature1.get(0), signature2.get(0));
+        }
+
+        return result;
+    }
+
+    private static int compareActualParameter(TypeSystemData typeSystem, TypeData t1, TypeData t2) {
+        int index1 = typeSystem.findType(t1);
+        int index2 = typeSystem.findType(t2);
+        return index1 - index2;
+    }
+
+    public static class Signature implements Iterable<TypeData>, Comparable<Signature> {
+
+        final List<TypeData> types;
+
+        public Signature() {
+            this.types = new ArrayList<>();
+        }
+
+        public Signature(List<TypeData> signature) {
+            this.types = signature;
+        }
+
+        @Override
+        public int hashCode() {
+            return types.hashCode();
+        }
+
+        public int compareTo(Signature o) {
+            if (o.size() != size()) {
+                return size() - o.size();
+            }
+
+            int typeSum = 0;
+            int otherTypeSum = 0;
+            for (int i = 0; i < types.size(); i++) {
+                TypeData type = types.get(i);
+                TypeData otherType = o.get(i);
+                typeSum += type.isGeneric() ? 1 : 0;
+                otherTypeSum += otherType.isGeneric() ? 1 : 0;
+            }
+
+            return typeSum - otherTypeSum;
+        }
+
+        public int size() {
+            return types.size();
+        }
+
+        public TypeData get(int index) {
+            return types.get(index);
+        }
+
+        public Signature combine(Signature genericSignature, Signature other) {
+            assert types.size() == other.types.size();
+            assert genericSignature.types.size() == other.types.size();
+
+            if (this.equals(other)) {
+                return this;
+            }
+
+            Signature signature = new Signature();
+            for (int i = 0; i < types.size(); i++) {
+                TypeData type1 = types.get(i);
+                TypeData type2 = other.types.get(i);
+                if (type1.equals(type2)) {
+                    signature.types.add(type1);
+                } else {
+                    signature.types.add(genericSignature.types.get(i));
+                }
+            }
+            return signature;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof Signature) {
+                return ((Signature) obj).types.equals(types);
+            }
+            return super.equals(obj);
+        }
+
+        public Iterator<TypeData> iterator() {
+            return types.iterator();
+        }
+
+        @Override
+        public String toString() {
+            return types.toString();
+        }
+
+        public boolean hasAnyParameterMatch(Signature other) {
+            for (int i = 1; i < types.size(); i++) {
+                TypeData type1 = types.get(i);
+                TypeData type2 = other.types.get(i);
+                if (type1.equals(type2)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethodParser.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,338 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.template;
+
+import static com.oracle.truffle.dsl.processor.Utils.*;
+
+import java.lang.annotation.*;
+import java.util.*;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+import javax.lang.model.util.*;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.node.NodeChildData.*;
+import com.oracle.truffle.dsl.processor.typesystem.*;
+
+public abstract class TemplateMethodParser<T extends Template, E extends TemplateMethod> {
+
+    private final ProcessorContext context;
+
+    protected final T template;
+
+    private boolean emitErrors = true;
+    private boolean parseNullOnError = true;
+
+    public TemplateMethodParser(ProcessorContext context, T template) {
+        this.template = template;
+        this.context = context;
+    }
+
+    public boolean isEmitErrors() {
+        return emitErrors;
+    }
+
+    public void setParseNullOnError(boolean nullOnError) {
+        this.parseNullOnError = nullOnError;
+    }
+
+    public boolean isParseNullOnError() {
+        return parseNullOnError;
+    }
+
+    public void setEmitErrors(boolean emitErrors) {
+        this.emitErrors = emitErrors;
+    }
+
+    public ProcessorContext getContext() {
+        return context;
+    }
+
+    public TypeSystemData getTypeSystem() {
+        return template.getTypeSystem();
+    }
+
+    public abstract MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror);
+
+    public abstract E create(TemplateMethod method);
+
+    public abstract boolean isParsable(ExecutableElement method);
+
+    public Class<? extends Annotation> getAnnotationType() {
+        return null;
+    }
+
+    public final List<E> parse(List<? extends Element> elements) {
+        List<ExecutableElement> methods = new ArrayList<>();
+        methods.addAll(ElementFilter.methodsIn(elements));
+
+        List<E> parsedMethods = new ArrayList<>();
+        boolean valid = true;
+        for (ExecutableElement method : methods) {
+            if (!isParsable(method)) {
+                continue;
+            }
+
+            Class<? extends Annotation> annotationType = getAnnotationType();
+            AnnotationMirror mirror = null;
+            if (annotationType != null) {
+                mirror = Utils.findAnnotationMirror(getContext().getEnvironment(), method, annotationType);
+            }
+
+            E parsedMethod = parse(method, mirror);
+
+            if (method.getModifiers().contains(Modifier.PRIVATE) && emitErrors) {
+                parsedMethod.addError("Method must not be private.");
+                valid = false;
+                continue;
+            }
+
+            if (parsedMethod != null) {
+                parsedMethods.add(parsedMethod);
+            } else {
+                valid = false;
+            }
+        }
+        Collections.sort(parsedMethods);
+
+        if (!valid && parseNullOnError) {
+            return null;
+        }
+        return parsedMethods;
+    }
+
+    private E parse(ExecutableElement method, AnnotationMirror annotation) {
+        MethodSpec methodSpecification = createSpecification(method, annotation);
+        if (methodSpecification == null) {
+            return null;
+        }
+
+        methodSpecification.applyTypeDefinitions("types");
+
+        String id = method.getSimpleName().toString();
+        AnnotationMirror idAnnotation = Utils.findAnnotationMirror(context.getEnvironment(), method, NodeId.class);
+        if (idAnnotation != null) {
+            id = Utils.getAnnotationValue(String.class, idAnnotation, "value");
+        }
+
+        ParameterSpec returnTypeSpec = methodSpecification.getReturnType();
+
+        ActualParameter returnTypeMirror = matchParameter(returnTypeSpec, method.getReturnType(), template, 0, false);
+        if (returnTypeMirror == null) {
+            if (emitErrors) {
+                E invalidMethod = create(new TemplateMethod(id, template, methodSpecification, method, annotation, returnTypeMirror, Collections.<ActualParameter> emptyList()));
+                String expectedReturnType = returnTypeSpec.toSignatureString(true);
+                String actualReturnType = Utils.getSimpleName(method.getReturnType());
+
+                String message = String.format("The provided return type \"%s\" does not match expected return type \"%s\".\nExpected signature: \n %s", actualReturnType, expectedReturnType,
+                                methodSpecification.toSignatureString(method.getSimpleName().toString()));
+                invalidMethod.addError(message);
+                return invalidMethod;
+            } else {
+                return null;
+            }
+        }
+
+        List<TypeMirror> parameterTypes = new ArrayList<>();
+        for (VariableElement var : method.getParameters()) {
+            parameterTypes.add(var.asType());
+        }
+
+        List<ActualParameter> parameters = parseParameters(methodSpecification, parameterTypes);
+        if (parameters == null) {
+            if (isEmitErrors()) {
+                E invalidMethod = create(new TemplateMethod(id, template, methodSpecification, method, annotation, returnTypeMirror, Collections.<ActualParameter> emptyList()));
+                String message = String.format("Method signature %s does not match to the expected signature: \n%s", createActualSignature(methodSpecification, method),
+                                methodSpecification.toSignatureString(method.getSimpleName().toString()));
+                invalidMethod.addError(message);
+                return invalidMethod;
+            } else {
+                return null;
+            }
+        }
+
+        return create(new TemplateMethod(id, template, methodSpecification, method, annotation, returnTypeMirror, parameters));
+    }
+
+    private static String createActualSignature(MethodSpec spec, ExecutableElement method) {
+        StringBuilder b = new StringBuilder("(");
+        String sep = "";
+        for (TypeMirror implicitType : spec.getImplicitRequiredTypes()) {
+            b.append(sep);
+            b.append("implicit " + Utils.getSimpleName(implicitType));
+            sep = ", ";
+        }
+        for (VariableElement var : method.getParameters()) {
+            b.append(sep);
+            b.append(Utils.getSimpleName(var.asType()));
+            sep = ", ";
+        }
+        b.append(")");
+        return b.toString();
+    }
+
+    private List<ActualParameter> parseParameters(MethodSpec spec, List<TypeMirror> parameterTypes) {
+        List<ActualParameter> parsedParams = new ArrayList<>();
+        ConsumableListIterator<TypeMirror> types = new ConsumableListIterator<>(parameterTypes);
+
+        // parse optional parameters
+        ConsumableListIterator<ParameterSpec> optionals = new ConsumableListIterator<>(spec.getOptional());
+        for (TypeMirror type : types) {
+            int oldIndex = types.getIndex();
+            int optionalCount = 1;
+            for (ParameterSpec paramspec : optionals) {
+                ActualParameter optionalParam = matchParameter(paramspec, type, template, 0, false);
+                if (optionalParam != null) {
+                    optionals.consume(optionalCount);
+                    types.consume();
+                    parsedParams.add(optionalParam);
+                    break;
+                }
+                optionalCount++;
+            }
+            if (oldIndex == types.getIndex()) {
+                // nothing found anymore skip optional
+                break;
+            }
+        }
+
+        List<TypeMirror> typesWithImplicit = new ArrayList<>(spec.getImplicitRequiredTypes());
+        typesWithImplicit.addAll(types.toList());
+        types = new ConsumableListIterator<>(typesWithImplicit);
+
+        int specificationParameterIndex = 0;
+        ConsumableListIterator<ParameterSpec> required = new ConsumableListIterator<>(spec.getRequired());
+        while (required.get() != null || types.get() != null) {
+            if (required.get() == null || types.get() == null) {
+                if (required.get() != null && required.get().getCardinality() == Cardinality.MANY) {
+                    required.consume();
+                    specificationParameterIndex = 0;
+                    continue;
+                }
+                break;
+            }
+            boolean implicit = types.getIndex() < spec.getImplicitRequiredTypes().size();
+            ActualParameter resolvedParameter = matchParameter(required.get(), types.get(), template, specificationParameterIndex, implicit);
+            if (resolvedParameter == null) {
+                if (required.get().getCardinality() == Cardinality.MANY) {
+                    required.consume();
+                    continue;
+                }
+                // direct mismatch but required -> error
+                return null;
+            } else {
+                parsedParams.add(resolvedParameter);
+                types.consume();
+                if (required.get().getCardinality() == Cardinality.ONE) {
+                    required.consume();
+                    specificationParameterIndex = 0;
+                } else if (required.get().getCardinality() == Cardinality.MANY) {
+                    specificationParameterIndex++;
+                }
+            }
+        }
+
+        if (!types.toList().isEmpty()) {
+            // additional types -> error
+            return null;
+        }
+
+        if (!required.toList().isEmpty() && !spec.isVariableRequiredArguments()) {
+            // additional specifications -> error
+            return null;
+        }
+
+        // success!
+        return parsedParams;
+    }
+
+    private ActualParameter matchParameter(ParameterSpec specification, TypeMirror mirror, Template originalTemplate, int index, boolean implicit) {
+        TypeMirror resolvedType = mirror;
+        if (hasError(resolvedType)) {
+            resolvedType = context.resolveNotYetCompiledType(mirror, originalTemplate);
+        }
+
+        if (!specification.matches(resolvedType)) {
+            return null;
+        }
+
+        TypeData resolvedTypeData = getTypeSystem().findTypeData(resolvedType);
+        if (resolvedTypeData != null) {
+            return new ActualParameter(specification, resolvedTypeData, index, implicit);
+        } else {
+            return new ActualParameter(specification, resolvedType, index, implicit);
+        }
+    }
+
+    /* Helper class for parsing. */
+    private static class ConsumableListIterator<E> implements Iterable<E> {
+
+        private final List<E> data;
+        private int index;
+
+        public ConsumableListIterator(List<E> data) {
+            this.data = data;
+        }
+
+        public E get() {
+            if (index >= data.size()) {
+                return null;
+            }
+            return data.get(index);
+        }
+
+        public E consume() {
+            return consume(1);
+        }
+
+        public E consume(int count) {
+            if (index + count <= data.size()) {
+                index += count;
+                return get();
+            } else {
+                throw new ArrayIndexOutOfBoundsException(count + 1);
+            }
+        }
+
+        public int getIndex() {
+            return index;
+        }
+
+        @Override
+        public Iterator<E> iterator() {
+            return toList().iterator();
+        }
+
+        public List<E> toList() {
+            if (index < data.size()) {
+                return data.subList(index, data.size());
+            } else {
+                return Collections.<E> emptyList();
+            }
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateParser.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.template;
+
+import java.util.*;
+
+import javax.lang.model.element.*;
+import javax.lang.model.util.*;
+
+import com.oracle.truffle.dsl.processor.*;
+
+public abstract class TemplateParser<M extends Template> extends AbstractParser<M> {
+
+    public TemplateParser(ProcessorContext c) {
+        super(c);
+    }
+
+    protected void verifyExclusiveMethodAnnotation(Template template, Class<?>... annotationTypes) {
+        List<ExecutableElement> methods = ElementFilter.methodsIn(template.getTemplateType().getEnclosedElements());
+        for (ExecutableElement method : methods) {
+            List<AnnotationMirror> foundAnnotations = new ArrayList<>();
+            for (int i = 0; i < annotationTypes.length; i++) {
+                Class<?> annotationType = annotationTypes[i];
+                AnnotationMirror mirror = Utils.findAnnotationMirror(context.getEnvironment(), method, annotationType);
+                if (mirror != null) {
+                    foundAnnotations.add(mirror);
+                }
+            }
+            if (foundAnnotations.size() > 1) {
+                List<String> annotationNames = new ArrayList<>();
+                for (AnnotationMirror mirror : foundAnnotations) {
+                    annotationNames.add("@" + Utils.getSimpleName(mirror.getAnnotationType()));
+                }
+
+                template.addError("Non exclusive usage of annotations %s.", annotationNames);
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardData.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.typesystem;
+
+import com.oracle.truffle.dsl.processor.node.*;
+import com.oracle.truffle.dsl.processor.template.*;
+
+public class GuardData extends TemplateMethod {
+
+    private final SpecializationData specialization;
+
+    public GuardData(TemplateMethod method, SpecializationData specialization) {
+        super(method);
+        this.specialization = specialization;
+    }
+
+    public SpecializationData getSpecialization() {
+        return specialization;
+    }
+
+    @Override
+    public String toString() {
+        return getMethodName();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardParser.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.typesystem;
+
+import java.lang.annotation.*;
+import java.util.*;
+
+import javax.lang.model.element.*;
+
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.node.*;
+import com.oracle.truffle.dsl.processor.template.*;
+
+public class GuardParser extends NodeMethodParser<GuardData> {
+
+    private final SpecializationData specialization;
+    private final String guardName;
+
+    public GuardParser(ProcessorContext context, SpecializationData specialization, String guardName) {
+        super(context, specialization.getNode());
+        this.specialization = specialization;
+        this.guardName = guardName;
+        setEmitErrors(false);
+        setParseNullOnError(false);
+    }
+
+    @Override
+    public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
+        MethodSpec spec = createDefaultMethodSpec(method, mirror, true, null);
+        spec.setVariableRequiredArguments(true);
+        spec.getRequired().clear();
+
+        for (ActualParameter parameter : specialization.getRequiredParameters()) {
+            ParameterSpec paramSpec = new ParameterSpec(parameter.getLocalName(), parameter.getType(), getNode().getTypeSystem().getGenericType());
+            paramSpec.setSignature(true);
+            spec.addRequired(paramSpec);
+        }
+
+        return spec;
+    }
+
+    @Override
+    protected ParameterSpec createReturnParameterSpec() {
+        return new ParameterSpec("returnType", getContext().getType(boolean.class));
+    }
+
+    @Override
+    public boolean isParsable(ExecutableElement method) {
+        return method.getSimpleName().toString().equals(guardName);
+    }
+
+    @Override
+    public GuardData create(TemplateMethod method) {
+        GuardData guard = new GuardData(method, specialization);
+        /*
+         * Update parameters in way that parameter specifications match again the node field names
+         * etc.
+         */
+        List<ActualParameter> newParameters = new ArrayList<>();
+        for (ActualParameter parameter : guard.getParameters()) {
+            ActualParameter specializationParameter = specialization.findParameter(parameter.getSpecification().getName());
+            if (specializationParameter == null) {
+                newParameters.add(parameter);
+            } else {
+                newParameters.add(new ActualParameter(specializationParameter.getSpecification(), parameter.getTypeSystemType(), specializationParameter.getIndex(), parameter.isImplicit()));
+            }
+        }
+        guard.setParameters(newParameters);
+
+        return guard;
+    }
+
+    @Override
+    public Class<? extends Annotation> getAnnotationType() {
+        return null;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeCastData.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.typesystem;
+
+import com.oracle.truffle.dsl.processor.template.*;
+
+public class TypeCastData extends TemplateMethod {
+
+    private final TypeData targetType;
+    private final TypeData sourceType;
+
+    public TypeCastData(TemplateMethod method, TypeData sourceType, TypeData targetType) {
+        super(method);
+        this.sourceType = sourceType;
+        this.targetType = targetType;
+    }
+
+    public boolean isGeneric() {
+        return sourceType.isGeneric();
+    }
+
+    public TypeData getSourceType() {
+        return sourceType;
+    }
+
+    public TypeData getTargetType() {
+        return targetType;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeCastParser.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.typesystem;
+
+import java.lang.annotation.*;
+
+import javax.lang.model.element.*;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.template.*;
+
+class TypeCastParser extends TypeSystemMethodParser<TypeCastData> {
+
+    public TypeCastParser(ProcessorContext context, TypeSystemData typeSystem) {
+        super(context, typeSystem);
+    }
+
+    @Override
+    public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
+        TypeData targetType = findTypeByMethodName(method.getSimpleName().toString(), "as");
+        if (targetType == null) {
+            return null;
+        }
+        MethodSpec spec = new MethodSpec(new ParameterSpec("returnType", targetType.getPrimitiveType()));
+        spec.addRequired(new ParameterSpec("value", getTypeSystem().getPrimitiveTypeMirrors()));
+        return spec;
+    }
+
+    @Override
+    public TypeCastData create(TemplateMethod method) {
+        TypeData targetType = findTypeByMethodName(method, "as");
+        ActualParameter parameter = method.findParameter("valueValue");
+        return new TypeCastData(method, parameter.getTypeSystemType(), targetType);
+    }
+
+    @Override
+    public Class<? extends Annotation> getAnnotationType() {
+        return TypeCast.class;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeCheckData.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.typesystem;
+
+import com.oracle.truffle.dsl.processor.template.*;
+
+public class TypeCheckData extends TemplateMethod {
+
+    private final TypeData checkedType;
+    private final TypeData valueType;
+
+    public TypeCheckData(TemplateMethod method, TypeData checkedType, TypeData valueType) {
+        super(method);
+        this.checkedType = checkedType;
+        this.valueType = valueType;
+    }
+
+    public boolean isGeneric() {
+        return valueType.isGeneric();
+    }
+
+    public TypeData getCheckedType() {
+        return checkedType;
+    }
+
+    public TypeData getValueType() {
+        return valueType;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeCheckParser.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.typesystem;
+
+import java.lang.annotation.*;
+
+import javax.lang.model.element.*;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.template.*;
+
+class TypeCheckParser extends TypeSystemMethodParser<TypeCheckData> {
+
+    public TypeCheckParser(ProcessorContext context, TypeSystemData typeSystem) {
+        super(context, typeSystem);
+    }
+
+    @Override
+    public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
+        TypeData targetType = findTypeByMethodName(method.getSimpleName().toString(), "is");
+        if (targetType == null) {
+            return null;
+        }
+        MethodSpec spec = new MethodSpec(new ParameterSpec("returnType", getContext().getType(boolean.class)));
+        spec.addRequired(new ParameterSpec("value", getTypeSystem().getPrimitiveTypeMirrors()));
+        return spec;
+    }
+
+    @Override
+    public TypeCheckData create(TemplateMethod method) {
+        TypeData checkedType = findTypeByMethodName(method, "is");
+        assert checkedType != null;
+        ActualParameter parameter = method.findParameter("valueValue");
+        assert parameter != null;
+        return new TypeCheckData(method, checkedType, parameter.getTypeSystemType());
+    }
+
+    @Override
+    public Class<? extends Annotation> getAnnotationType() {
+        return TypeCheck.class;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeData.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.typesystem;
+
+import java.util.*;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.template.*;
+
+public class TypeData extends MessageContainer {
+
+    private final TypeSystemData typeSystem;
+    private final AnnotationValue annotationValue;
+    private final TypeMirror primitiveType;
+    private final TypeMirror boxedType;
+
+    private final List<TypeCastData> typeCasts = new ArrayList<>();
+    private final List<TypeCheckData> typeChecks = new ArrayList<>();
+
+    public TypeData(TypeSystemData typeSystem, AnnotationValue value, TypeMirror primitiveType, TypeMirror boxedType) {
+        this.typeSystem = typeSystem;
+        this.annotationValue = value;
+        this.primitiveType = primitiveType;
+        this.boxedType = boxedType;
+    }
+
+    @Override
+    public Element getMessageElement() {
+        return typeSystem.getMessageElement();
+    }
+
+    @Override
+    public AnnotationMirror getMessageAnnotation() {
+        return typeSystem.getMessageAnnotation();
+    }
+
+    @Override
+    public AnnotationValue getMessageAnnotationValue() {
+        return annotationValue;
+    }
+
+    void addTypeCast(TypeCastData typeCast) {
+        this.typeCasts.add(typeCast);
+    }
+
+    void addTypeCheck(TypeCheckData typeCheck) {
+        this.typeChecks.add(typeCheck);
+    }
+
+    public List<TypeCastData> getTypeCasts() {
+        return typeCasts;
+    }
+
+    public List<TypeCheckData> getTypeChecks() {
+        return typeChecks;
+    }
+
+    public TypeSystemData getTypeSystem() {
+        return typeSystem;
+    }
+
+    public TypeMirror getPrimitiveType() {
+        return primitiveType;
+    }
+
+    public TypeMirror getBoxedType() {
+        return boxedType;
+    }
+
+    public boolean isGeneric() {
+        return Utils.typeEquals(boxedType, getTypeSystem().getGenericType());
+    }
+
+    public boolean isVoid() {
+        if (getTypeSystem().getVoidType() == null) {
+            return false;
+        }
+        return Utils.typeEquals(boxedType, getTypeSystem().getVoidType().getBoxedType());
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + "[" + Utils.getSimpleName(primitiveType) + "]";
+    }
+
+    public boolean equalsType(TypeData actualTypeData) {
+        return Utils.typeEquals(boxedType, actualTypeData.boxedType);
+    }
+
+    public boolean needsCastTo(ProcessorContext context, TypeData targetType) {
+        if (this.equals(targetType)) {
+            return false;
+        } else if (targetType.isGeneric()) {
+            return false;
+        } else if (targetType.isVoid()) {
+            return false;
+        } else if (Utils.isAssignable(context, getPrimitiveType(), targetType.getPrimitiveType())) {
+            return false;
+        }
+        return true;
+    }
+
+    public boolean isPrimitive() {
+        return Utils.isPrimitive(getPrimitiveType());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemCodeGenerator.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.typesystem;
+
+import static com.oracle.truffle.dsl.processor.Utils.*;
+import static javax.lang.model.element.Modifier.*;
+
+import java.util.*;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.ast.*;
+import com.oracle.truffle.dsl.processor.template.*;
+
+public class TypeSystemCodeGenerator extends CompilationUnitFactory<TypeSystemData> {
+
+    public TypeSystemCodeGenerator(ProcessorContext context) {
+        super(context);
+    }
+
+    public static String isTypeMethodName(TypeData type) {
+        return "is" + Utils.getTypeId(type.getBoxedType());
+    }
+
+    public static String asTypeMethodName(TypeData type) {
+        return "as" + Utils.getTypeId(type.getBoxedType());
+    }
+
+    public static String expectTypeMethodName(TypeData type) {
+        return "expect" + Utils.getTypeId(type.getBoxedType());
+    }
+
+    /**
+     * Finds the generated singleton field for a TypeSytemData instance. TypeSystemCodeGenerator
+     * must be applied to the TypeSystemData model before use.
+     */
+    public static VariableElement findSingleton(ProcessorContext context, TypeSystemData typeSystem) {
+        TypeMirror type = context.findGeneratedClassBySimpleName(TypeClassFactory.typeName(typeSystem), typeSystem);
+        return Utils.findDeclaredField(type, TypeClassFactory.singletonName(typeSystem.getTemplateType().asType()));
+    }
+
+    @Override
+    protected void createChildren(TypeSystemData m) {
+        add(new TypeClassFactory(context), m);
+    }
+
+    protected static class TypeClassFactory extends ClassElementFactory<TypeSystemData> {
+
+        private static final String LOCAL_VALUE = "value";
+
+        public TypeClassFactory(ProcessorContext context) {
+            super(context);
+        }
+
+        @Override
+        public CodeTypeElement create(TypeSystemData typeSystem) {
+            String name = typeName(typeSystem);
+            CodeTypeElement clazz = createClass(typeSystem, modifiers(PUBLIC), name, typeSystem.getTemplateType().asType(), false);
+
+            clazz.add(createConstructorUsingFields(modifiers(PROTECTED), clazz));
+            CodeVariableElement singleton = createSingleton(clazz);
+            clazz.add(singleton);
+
+            for (TypeData type : typeSystem.getTypes()) {
+                if (!type.isGeneric()) {
+                    CodeExecutableElement isType = createIsTypeMethod(type);
+                    if (isType != null) {
+                        clazz.add(isType);
+                    }
+                    CodeExecutableElement asType = createAsTypeMethod(type);
+                    if (asType != null) {
+                        clazz.add(asType);
+                    }
+
+                    for (TypeData sourceType : collectExpectSourceTypes(type)) {
+                        CodeExecutableElement expect = createExpectTypeMethod(type, sourceType);
+                        if (expect != null) {
+                            clazz.add(expect);
+                        }
+                    }
+                }
+            }
+
+            return clazz;
+        }
+
+        private static List<TypeData> collectExpectSourceTypes(TypeData type) {
+            Set<TypeData> sourceTypes = new HashSet<>();
+            sourceTypes.add(type.getTypeSystem().getGenericTypeData());
+            for (TypeCastData cast : type.getTypeCasts()) {
+                sourceTypes.add(cast.getSourceType());
+            }
+            for (TypeCheckData cast : type.getTypeChecks()) {
+                sourceTypes.add(cast.getCheckedType());
+            }
+            return new ArrayList<>(sourceTypes);
+        }
+
+        private static String typeName(TypeSystemData typeSystem) {
+            String name = getSimpleName(typeSystem.getTemplateType());
+            return name + "Gen";
+        }
+
+        private static String singletonName(TypeMirror type) {
+            return createConstantName(getSimpleName(type));
+        }
+
+        private CodeVariableElement createSingleton(CodeTypeElement clazz) {
+            CodeVariableElement field = new CodeVariableElement(modifiers(PUBLIC, STATIC, FINAL), clazz.asType(), singletonName(getModel().getTemplateType().asType()));
+            field.createInitBuilder().startNew(clazz.asType()).end();
+            return field;
+        }
+
+        private CodeExecutableElement createIsTypeMethod(TypeData type) {
+            if (!type.getTypeChecks().isEmpty()) {
+                return null;
+            }
+
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), getContext().getType(boolean.class), TypeSystemCodeGenerator.isTypeMethodName(type));
+            method.addParameter(new CodeVariableElement(getContext().getType(Object.class), LOCAL_VALUE));
+
+            CodeTreeBuilder body = method.createBuilder();
+            body.startReturn().instanceOf(LOCAL_VALUE, type.getBoxedType()).end();
+
+            return method;
+        }
+
+        private CodeExecutableElement createAsTypeMethod(TypeData type) {
+            if (!type.getTypeCasts().isEmpty()) {
+                return null;
+            }
+
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), type.getPrimitiveType(), TypeSystemCodeGenerator.asTypeMethodName(type));
+            method.addParameter(new CodeVariableElement(getContext().getType(Object.class), LOCAL_VALUE));
+
+            CodeTreeBuilder body = method.createBuilder();
+            body.startAssert().startCall(isTypeMethodName(type)).string(LOCAL_VALUE).end().end();
+            body.startReturn().cast(type.getPrimitiveType(), body.create().string(LOCAL_VALUE).getTree()).end();
+
+            return method;
+        }
+
+        private CodeExecutableElement createExpectTypeMethod(TypeData expectedType, TypeData sourceType) {
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), expectedType.getPrimitiveType(), TypeSystemCodeGenerator.expectTypeMethodName(expectedType));
+            method.addParameter(new CodeVariableElement(sourceType.getPrimitiveType(), LOCAL_VALUE));
+            method.addThrownType(getContext().getTruffleTypes().getUnexpectedValueException());
+
+            CodeTreeBuilder body = method.createBuilder();
+            body.startIf().startCall(null, TypeSystemCodeGenerator.isTypeMethodName(expectedType)).string(LOCAL_VALUE).end().end().startBlock();
+            body.startReturn().startCall(null, TypeSystemCodeGenerator.asTypeMethodName(expectedType)).string(LOCAL_VALUE).end().end();
+            body.end(); // if-block
+            body.startThrow().startNew(getContext().getTruffleTypes().getUnexpectedValueException()).string(LOCAL_VALUE).end().end();
+
+            return method;
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemData.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.typesystem;
+
+import java.util.*;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.template.*;
+
+public class TypeSystemData extends Template {
+
+    private List<TypeData> types;
+    private List<TypeMirror> primitiveTypeMirrors = new ArrayList<>();
+    private List<TypeMirror> boxedTypeMirrors = new ArrayList<>();
+
+    private TypeMirror genericType;
+    private TypeData voidType;
+
+    public TypeSystemData(TypeElement templateType, AnnotationMirror annotation) {
+        super(templateType, null, annotation);
+    }
+
+    @Override
+    public TypeSystemData getTypeSystem() {
+        return this;
+    }
+
+    void setTypes(List<TypeData> types) {
+        this.types = types;
+        if (types != null) {
+            for (TypeData typeData : types) {
+                primitiveTypeMirrors.add(typeData.getPrimitiveType());
+                boxedTypeMirrors.add(typeData.getBoxedType());
+            }
+        }
+    }
+
+    void setGenericType(TypeMirror genericType) {
+        this.genericType = genericType;
+    }
+
+    void setVoidType(TypeData voidType) {
+        this.voidType = voidType;
+    }
+
+    @Override
+    protected List<MessageContainer> findChildContainers() {
+        List<MessageContainer> sinks = new ArrayList<>();
+        if (types != null) {
+            sinks.addAll(types);
+        }
+        return sinks;
+    }
+
+    public boolean isGeneric(TypeMirror type) {
+        return Utils.typeEquals(getGenericType(), type);
+    }
+
+    public TypeData getVoidType() {
+        return voidType;
+    }
+
+    public List<TypeMirror> getBoxedTypeMirrors() {
+        return boxedTypeMirrors;
+    }
+
+    public List<TypeMirror> getPrimitiveTypeMirrors() {
+        return primitiveTypeMirrors;
+    }
+
+    public List<TypeData> getTypes() {
+        return types;
+    }
+
+    public TypeMirror getGenericType() {
+        return genericType;
+    }
+
+    public TypeData getGenericTypeData() {
+        TypeData result = types.get(types.size() - 1);
+        assert result.getBoxedType() == genericType;
+        return result;
+    }
+
+    public TypeData findType(String simpleName) {
+        for (TypeData type : types) {
+            if (Utils.getSimpleName(type.getBoxedType()).equals(simpleName)) {
+                return type;
+            }
+        }
+        return null;
+    }
+
+    public TypeData findTypeData(TypeMirror type) {
+        if (Utils.typeEquals(voidType.getPrimitiveType(), type)) {
+            return voidType;
+        }
+
+        int index = findType(type);
+        if (index == -1) {
+            return null;
+        }
+        return types.get(index);
+    }
+
+    public int findType(TypeData typeData) {
+        return findType(typeData.getPrimitiveType());
+    }
+
+    public int findType(TypeMirror type) {
+        for (int i = 0; i < types.size(); i++) {
+            if (Utils.typeEquals(types.get(i).getPrimitiveType(), type)) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + "[template = " + Utils.getSimpleName(getTemplateType()) + ", types = " + types + "]";
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemMethodParser.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.typesystem;
+
+import javax.lang.model.element.*;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.template.*;
+
+abstract class TypeSystemMethodParser<E extends TemplateMethod> extends TemplateMethodParser<TypeSystemData, E> {
+
+    public TypeSystemMethodParser(ProcessorContext context, TypeSystemData typeSystem) {
+        super(context, typeSystem);
+    }
+
+    @Override
+    public final boolean isParsable(ExecutableElement method) {
+        return Utils.findAnnotationMirror(getContext().getEnvironment(), method, getAnnotationType()) != null;
+    }
+
+    protected TypeData findTypeByMethodName(String methodName, String prefix) {
+        String typeName = methodName.substring(prefix.length(), methodName.length());
+        TypeData type = getTypeSystem().findType(typeName);
+        return type;
+    }
+
+    protected TypeData findTypeByMethodName(TemplateMethod method, String prefix) {
+        String methodName = method.getMethodName();
+        if (!methodName.startsWith(prefix)) {
+            String annotationName = Utils.getSimpleName(method.getMessageAnnotation().getAnnotationType());
+            method.addError("Methods annotated with %s must match the pattern '%s'.", annotationName, String.format("%s${typeName}", prefix));
+            return null;
+        }
+        String typeName = methodName.substring(prefix.length(), methodName.length());
+        TypeData type = getTypeSystem().findType(typeName);
+        if (type == null) {
+            String annotationName = TypeSystem.class.getSimpleName();
+            method.addError("Type '%s' is not declared in this @%s.", typeName, annotationName);
+            return null;
+        }
+
+        return type;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemParser.java	Mon Jul 01 20:58:32 2013 +0200
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.dsl.processor.typesystem;
+
+import static com.oracle.truffle.dsl.processor.Utils.*;
+
+import java.lang.annotation.*;
+import java.util.*;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+import javax.lang.model.util.*;
+
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.dsl.processor.*;
+import com.oracle.truffle.dsl.processor.template.*;
+
+public class TypeSystemParser extends TemplateParser<TypeSystemData> {
+
+    public static final List<Class<TypeSystem>> ANNOTATIONS = Arrays.asList(TypeSystem.class);
+
+    public TypeSystemParser(ProcessorContext c) {
+        super(c);
+    }
+
+    @Override
+    public Class<? extends Annotation> getAnnotationType() {
+        return TypeSystem.class;
+    }
+
+    @Override
+    protected TypeSystemData parse(Element element, AnnotationMirror mirror) {
+        TypeElement templateType = (TypeElement) element;
+        AnnotationMirror templateTypeAnnotation = mirror;
+        TypeSystemData typeSystem = new TypeSystemData(templateType, templateTypeAnnotation);
+
+        // annotation type on class path!?
+        TypeElement annotationTypeElement = processingEnv.getElementUtils().getTypeElement(getAnnotationType().getCanonicalName());
+        if (annotationTypeElement == null) {
+            typeSystem.addError("Required class %s is not on the classpath.", getAnnotationType().getName());
+        }
+        if (templateType.getModifiers().contains(Modifier.PRIVATE)) {
+            typeSystem.addError("A @%s must have at least package protected visibility.", getAnnotationType().getName());
+        }
+
+        if (templateType.getModifiers().contains(Modifier.FINAL)) {
+            typeSystem.addError("The @%s must not be final.", getAnnotationType().getName());
+        }
+        if (typeSystem.hasErrors()) {
+            return typeSystem;
+        }
+
+        typeSystem.setTypes(parseTypes(typeSystem));
+        if (typeSystem.getTypes() == null) {
+            return typeSystem;
+        }
+
+        TypeMirror genericType = context.getType(Object.class);
+        TypeData voidType = new TypeData(typeSystem, null, context.getType(void.class), context.getType(Void.class));
+
+        typeSystem.setGenericType(genericType);
+        typeSystem.setVoidType(voidType);
+
+        verifyExclusiveMethodAnnotation(typeSystem, TypeCast.class, TypeCheck.class);
+
+        List<Element> elements = new ArrayList<>(context.getEnvironment().getElementUtils().getAllMembers(templateType));
+
+        List<TypeCastData> casts = new TypeCastParser(context, typeSystem).parse(elements);
+        List<TypeCheckData> checks = new TypeCheckParser(context, typeSystem).parse(elements);
+
+        if (casts == null || checks == null) {
+            return typeSystem;
+        }
+
+        for (TypeCheckData check : checks) {
+            check.getCheckedType().addTypeCheck(check);
+        }
+
+        for (TypeCastData cast : casts) {
+            cast.getTargetType().addTypeCast(cast);
+        }
+
+        verifyGenericTypeChecksAndCasts(typeSystem);
+        verifyMethodSignatures(typeSystem);
+        verifyNamesUnique(typeSystem);
+
+        return typeSystem;
+    }
+
+    private static void verifyGenericTypeChecksAndCasts(TypeSystemData typeSystem) {
+        for (TypeData type : typeSystem.getTypes()) {
+            if (!type.getTypeChecks().isEmpty()) {
+                boolean hasGeneric = false;
+                for (TypeCheckData typeCheck : type.getTypeChecks()) {
+                    if (typeCheck.isGeneric()) {
+                        hasGeneric = true;
+                        break;
+                    }
+                }
+                if (!hasGeneric) {
+                    type.addError("No generic but specific @%s method %s for type %s specified. " + "Specify a generic @%s method with parameter type %s to resolve this.",
+                                    TypeCheck.class.getSimpleName(), TypeSystemCodeGenerator.isTypeMethodName(type), Utils.getSimpleName(type.getBoxedType()), TypeCheck.class.getSimpleName(),
+                                    Object.class.getSimpleName());
+                }
+            }
+            if (!type.getTypeCasts().isEmpty()) {
+                boolean hasGeneric = false;
+                for (TypeCastData typeCast : type.getTypeCasts()) {
+                    if (typeCast.isGeneric()) {
+                        hasGeneric = true;
+                        break;
+                    }
+                }
+                if (!hasGeneric) {
+                    type.addError("No generic but specific @%s method %s for type %s specified. " + "Specify a generic @%s method with parameter type %s to resolve this.",
+                                    TypeCast.class.getSimpleName(), TypeSystemCodeGenerator.asTypeMethodName(type), Utils.getSimpleName(type.getBoxedType()), TypeCast.class.getSimpleName(),
+                                    Object.class.getSimpleName());
+                }
+            }
+        }
+    }
+
+    private List<TypeData> parseTypes(TypeSystemData typeSystem) {
+        List<TypeData> types = new ArrayList<>();
+        List<TypeMirror> typeMirrors = Utils.getAnnotationValueList(TypeMirror.class, typeSystem.getTemplateTypeAnnotation(), "value");
+        if (typeMirrors.isEmpty()) {
+            typeSystem.addError("At least one type must be defined.");
+            return types;
+        }
+
+        final AnnotationValue annotationValue = Utils.getAnnotationValue(typeSystem.getTemplateTypeAnnotation(), "value");
+        final TypeMirror objectType = context.getType(Object.class);
+
+        for (TypeMirror primitiveType : typeMirrors) {
+            TypeMirror boxedType = Utils.boxType(context, primitiveType);
+            TypeData typeData = new TypeData(typeSystem, annotationValue, primitiveType, boxedType);
+
+            if (isPrimitiveWrapper(primitiveType)) {
+                typeData.addError("Types must not contain primitive wrapper types.");
+            }
+
+            if (Utils.typeEquals(boxedType, objectType)) {
+                typeData.addError("Types must not contain the generic type java.lang.Object.");
+            }
+
+            types.add(typeData);
+        }
+
+        verifyTypeOrder(types);
+
+        types.add(new TypeData(typeSystem, annotationValue, objectType, objectType));
+
+        return types;
+    }
+
+    private static void verifyTypeOrder(List<TypeData> types) {
+        Map<String, List<String>> invalidTypes = new HashMap<>();
+
+        for (int i = types.size() - 1; i >= 0; i--) {
+            TypeData typeData = types.get(i);
+            TypeMirror type = typeData.getBoxedType();
+            if (invalidTypes.containsKey(Utils.getQualifiedName(type))) {
+                typeData.addError("Invalid type order. The type(s) %s are inherited from a earlier defined type %s.", invalidTypes.get(Utils.getQualifiedName(type)), Utils.getQualifiedName(type));
+            }
+            List<String> nextInvalidTypes = Utils.getQualifiedSuperTypeNames(Utils.fromTypeMirror(type));
+            nextInvalidTypes.add(getQualifiedName(type));
+
+            for (String qualifiedName : nextInvalidTypes) {
+                List<String> inheritedTypes = invalidTypes.get(qualifiedName);
+                if (inheritedTypes == null) {
+                    inheritedTypes = new ArrayList<>();
+                    invalidTypes.put(qualifiedName, inheritedTypes);
+                }
+                inheritedTypes.add(Utils.getQualifiedName(typeData.getBoxedType()));
+            }
+        }
+    }
+
+    private boolean isPrimitiveWrapper(TypeMirror type) {
+        Types types = context.getEnvironment().getTypeUtils();
+        for (TypeKind kind : TypeKind.values()) {
+            if (!kind.isPrimitive()) {
+                continue;
+            }
+            if (Utils.typeEquals(type, types.boxedClass(types.getPrimitiveType(kind)).asType())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void verifyMethodSignatures(TypeSystemData typeSystem) {
+        Set<String> generatedIsMethodNames = new HashSet<>();
+        Set<String> generatedAsMethodNames = new HashSet<>();
+        Set<String> generatedExpectMethodNames = new HashSet<>();
+
+        for (TypeData typeData : typeSystem.getTypes()) {
+            generatedIsMethodNames.add(TypeSystemCodeGenerator.isTypeMethodName(typeData));
+            generatedAsMethodNames.add(TypeSystemCodeGenerator.asTypeMethodName(typeData));
+            generatedExpectMethodNames.add(TypeSystemCodeGenerator.expectTypeMethodName(typeData));
+        }
+
+        List<ExecutableElement> methods = ElementFilter.methodsIn(typeSystem.getTemplateType().getEnclosedElements());
+        for (ExecutableElement method : methods) {
+            if (method.getModifiers().contains(Modifier.PRIVATE)) {
+                // will not conflict overridden methods
+                continue;
+            } else if (method.getParameters().size() != 1) {
+                continue;
+            }
+            String methodName = method.getSimpleName().toString();
+            if (generatedIsMethodNames.contains(methodName)) {
+                verifyIsMethod(typeSystem, method);
+            } else if (generatedAsMethodNames.contains(methodName)) {
+                verifyAsMethod(typeSystem, method);
+            } else if (generatedExpectMethodNames.contains(methodName)) {
+                verifyExpectMethod(typeSystem);
+            }
+        }
+    }
+
+    private boolean verifyIsMethod(TypeSystemData typeSystem, ExecutableElement method) {
+        AnnotationMirror mirror = Utils.findAnnotationMirror(processingEnv, method, TypeCheck.class);
+        if (mirror == null) {
+            typeSystem.addError("Method starting with the pattern is${typeName} must be annotated with @%s.", TypeCheck.class.getSimpleName());
+            return false;
+        }
+        return true;
+    }
+
+    private boolean verifyAsMethod(TypeSystemData typeSystem, ExecutableElement method) {
+        AnnotationMirror mirror = Utils.findAnnotationMirror(processingEnv, method, TypeCast.class);
+        if (mirror == null) {
+            typeSystem.addError("Method starting with the pattern as${typeName} must be annotated with @%s.", TypeCast.class.getSimpleName());
+            return false;
+        }
+        return true;
+    }
+
+    private static boolean verifyExpectMethod(TypeSystemData typeSystem) {
+        typeSystem.addError("Method starting with the pattern expect${typeName} must not be declared manually.");
+        return false;
+    }
+
+    private static void verifyNamesUnique(TypeSystemData typeSystem) {
+        List<TypeData> types = typeSystem.getTypes();
+        for (int i = 0; i < types.size(); i++) {
+            for (int j = i + 1; j < types.size(); j++) {
+                String name1 = Utils.getSimpleName(types.get(i).getBoxedType());
+                String name2 = Utils.getSimpleName(types.get(j).getBoxedType());
+                if (name1.equalsIgnoreCase(name2)) {
+                    typeSystem.addError("Two types result in the same name: %s, %s.", name1, name2);
+                }
+            }
+        }
+    }
+}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLNode.java	Mon Jul 01 20:32:20 2013 +0200
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLNode.java	Mon Jul 01 20:58:32 2013 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.truffle.sl;
 
-import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.nodes.*;
 
 @TypeSystemReference(SLTypes.class)
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLTypes.java	Mon Jul 01 20:32:20 2013 +0200
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLTypes.java	Mon Jul 01 20:58:32 2013 +0200
@@ -24,7 +24,7 @@
 
 import java.math.*;
 
-import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.api.dsl.*;
 
 @TypeSystem({int.class, BigInteger.class, boolean.class, String.class})
 public class SLTypes {
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ArithmeticNode.java	Mon Jul 01 20:32:20 2013 +0200
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ArithmeticNode.java	Mon Jul 01 20:58:32 2013 +0200
@@ -25,7 +25,7 @@
 import java.math.*;
 
 import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.api.dsl.*;
 
 public abstract class ArithmeticNode extends BinaryNode {
 
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/BigIntegerLiteralNode.java	Mon Jul 01 20:32:20 2013 +0200
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/BigIntegerLiteralNode.java	Mon Jul 01 20:58:32 2013 +0200
@@ -24,7 +24,7 @@
 
 import java.math.*;
 
-import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.api.dsl.*;
 
 public abstract class BigIntegerLiteralNode extends TypedNode {
 
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/BinaryNode.java	Mon Jul 01 20:32:20 2013 +0200
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/BinaryNode.java	Mon Jul 01 20:58:32 2013 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.truffle.sl.nodes;
 
-import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.api.dsl.*;
 
 @NodeChildren({@NodeChild("leftNode"), @NodeChild("rightNode")})
 public abstract class BinaryNode extends TypedNode {
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/IfNode.java	Mon Jul 01 20:32:20 2013 +0200
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/IfNode.java	Mon Jul 01 20:58:32 2013 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.truffle.sl.nodes;
 
-import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.frame.*;
 
 @NodeChild(value = "conditionNode", type = ConditionNode.class)
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/IntegerLiteralNode.java	Mon Jul 01 20:32:20 2013 +0200
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/IntegerLiteralNode.java	Mon Jul 01 20:58:32 2013 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.truffle.sl.nodes;
 
-import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.api.dsl.*;
 
 public abstract class IntegerLiteralNode extends TypedNode {
 
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/LessThanNode.java	Mon Jul 01 20:32:20 2013 +0200
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/LessThanNode.java	Mon Jul 01 20:58:32 2013 +0200
@@ -24,7 +24,7 @@
 
 import java.math.*;
 
-import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.api.dsl.*;
 
 public abstract class LessThanNode extends BinaryNode {
 
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/LogicalAndNode.java	Mon Jul 01 20:32:20 2013 +0200
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/LogicalAndNode.java	Mon Jul 01 20:58:32 2013 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.truffle.sl.nodes;
 
-import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.api.dsl.*;
 
 @SuppressWarnings("unused")
 public abstract class LogicalAndNode extends BinaryNode {
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/PrintNode.java	Mon Jul 01 20:32:20 2013 +0200
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/PrintNode.java	Mon Jul 01 20:58:32 2013 +0200
@@ -24,7 +24,7 @@
 
 import java.io.*;
 
-import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.api.dsl.*;
 
 @NodeChild(type = TypedNode.class)
 public abstract class PrintNode extends StatementNode {
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ReadLocalNode.java	Mon Jul 01 20:32:20 2013 +0200
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ReadLocalNode.java	Mon Jul 01 20:58:32 2013 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.truffle.sl.nodes;
 
-import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.frame.*;
 
 public abstract class ReadLocalNode extends FrameSlotNode {
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/StringLiteralNode.java	Mon Jul 01 20:32:20 2013 +0200
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/StringLiteralNode.java	Mon Jul 01 20:58:32 2013 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.truffle.sl.nodes;
 
-import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.api.dsl.*;
 
 public abstract class StringLiteralNode extends TypedNode {
 
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/TernaryNode.java	Mon Jul 01 20:32:20 2013 +0200
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/TernaryNode.java	Mon Jul 01 20:58:32 2013 +0200
@@ -23,7 +23,8 @@
 package com.oracle.truffle.sl.nodes;
 
 import java.math.*;
-import com.oracle.truffle.api.codegen.*;
+
+import com.oracle.truffle.api.dsl.*;
 
 @SuppressWarnings("unused")
 @NodeChildren({@NodeChild(value = "conditionNode", type = ConditionNode.class), @NodeChild("ifPartNode"), @NodeChild("elsePartNode")})
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/TimeNode.java	Mon Jul 01 20:32:20 2013 +0200
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/TimeNode.java	Mon Jul 01 20:58:32 2013 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.truffle.sl.nodes;
 
-import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.api.dsl.*;
 
 public abstract class TimeNode extends TypedNode {
 
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/WriteLocalNode.java	Mon Jul 01 20:32:20 2013 +0200
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/WriteLocalNode.java	Mon Jul 01 20:58:32 2013 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.truffle.sl.nodes;
 
-import com.oracle.truffle.api.codegen.*;
+import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.frame.*;
 
 @NodeChild(value = "rightNode", type = TypedNode.class)
--- a/mx/projects	Mon Jul 01 20:32:20 2013 +0200
+++ b/mx/projects	Mon Jul 01 20:58:32 2013 +0200
@@ -498,38 +498,38 @@
 project@com.oracle.truffle.api.test@javaCompliance=1.7
 project@com.oracle.truffle.api.test@workingSets=API,Truffle,Test
 
-# truffle.api.codegen
-project@com.oracle.truffle.api.codegen@subDir=graal
-project@com.oracle.truffle.api.codegen@sourceDirs=src
-project@com.oracle.truffle.api.codegen@dependencies=com.oracle.truffle.api
-project@com.oracle.truffle.api.codegen@checkstyle=com.oracle.graal.graph
-project@com.oracle.truffle.api.codegen@javaCompliance=1.7
-project@com.oracle.truffle.api.codegen@workingSets=API,Truffle,Codegen
+# truffle.api.dsl
+project@com.oracle.truffle.api.dsl@subDir=graal
+project@com.oracle.truffle.api.dsl@sourceDirs=src
+project@com.oracle.truffle.api.dsl@dependencies=com.oracle.truffle.api
+project@com.oracle.truffle.api.dsl@checkstyle=com.oracle.graal.graph
+project@com.oracle.truffle.api.dsl@javaCompliance=1.7
+project@com.oracle.truffle.api.dsl@workingSets=API,Truffle,Codegen
 
-# truffle.api.codegen.test
-project@com.oracle.truffle.api.codegen.test@subDir=graal
-project@com.oracle.truffle.api.codegen.test@sourceDirs=src
-project@com.oracle.truffle.api.codegen.test@dependencies=com.oracle.truffle.api.codegen,JUNIT
-project@com.oracle.truffle.api.codegen.test@checkstyle=com.oracle.graal.graph
-project@com.oracle.truffle.api.codegen.test@javaCompliance=1.7
-project@com.oracle.truffle.api.codegen.test@annotationProcessors=com.oracle.truffle.codegen.processor
-project@com.oracle.truffle.api.codegen.test@workingSets=API,Truffle,Codegen,Test
+# truffle.api.dsl.test
+project@com.oracle.truffle.api.dsl.test@subDir=graal
+project@com.oracle.truffle.api.dsl.test@sourceDirs=src
+project@com.oracle.truffle.api.dsl.test@dependencies=com.oracle.truffle.api.dsl,JUNIT
+project@com.oracle.truffle.api.dsl.test@checkstyle=com.oracle.graal.graph
+project@com.oracle.truffle.api.dsl.test@javaCompliance=1.7
+project@com.oracle.truffle.api.dsl.test@annotationProcessors=com.oracle.truffle.dsl.processor
+project@com.oracle.truffle.api.dsl.test@workingSets=API,Truffle,Codegen,Test
 
-# truffle.codegen.processor
-project@com.oracle.truffle.codegen.processor@subDir=graal
-project@com.oracle.truffle.codegen.processor@sourceDirs=src
-project@com.oracle.truffle.codegen.processor@dependencies=com.oracle.truffle.api.codegen
-project@com.oracle.truffle.codegen.processor@checkstyle=com.oracle.graal.graph
-project@com.oracle.truffle.codegen.processor@javaCompliance=1.7
-project@com.oracle.truffle.codegen.processor@workingSets=Truffle,Codegen
+# truffle.dsl.processor
+project@com.oracle.truffle.dsl.processor@subDir=graal
+project@com.oracle.truffle.dsl.processor@sourceDirs=src
+project@com.oracle.truffle.dsl.processor@dependencies=com.oracle.truffle.api.dsl
+project@com.oracle.truffle.dsl.processor@checkstyle=com.oracle.graal.graph
+project@com.oracle.truffle.dsl.processor@javaCompliance=1.7
+project@com.oracle.truffle.dsl.processor@workingSets=Truffle,Codegen
 
 # truffle.sl
 project@com.oracle.truffle.sl@subDir=graal
 project@com.oracle.truffle.sl@sourceDirs=src
-project@com.oracle.truffle.sl@dependencies=com.oracle.truffle.api.codegen
+project@com.oracle.truffle.sl@dependencies=com.oracle.truffle.api.dsl
 project@com.oracle.truffle.sl@checkstyle=com.oracle.graal.graph
 project@com.oracle.truffle.sl@javaCompliance=1.7
-project@com.oracle.truffle.sl@annotationProcessors=com.oracle.truffle.codegen.processor
+project@com.oracle.truffle.sl@annotationProcessors=com.oracle.truffle.dsl.processor
 project@com.oracle.truffle.sl@workingSets=Truffle,SimpleLanguage
 
 # truffle.sl.test