Initial
authorMaxim.Mossienko <Maxim.Mossienko@jetbrains.com>
Wed, 13 Oct 2010 16:00:39 +0000 (20:00 +0400)
committerMaxim.Mossienko <Maxim.Mossienko@jetbrains.com>
Wed, 13 Oct 2010 16:00:39 +0000 (20:00 +0400)
475 files changed:
JavaFX.iml [new file with mode: 0644]
src/META-INF/plugin.xml [new file with mode: 0644]
src/fileTemplates/internal/JavaFX Class.fx.ft [new file with mode: 0644]
src/fileTemplates/internal/JavaFX File.fx.ft [new file with mode: 0644]
src/fileTemplates/internal/JavaFX Stage.fx.ft [new file with mode: 0644]
src/org/jetbrains/javafx/JavaFxBundle.java [new file with mode: 0644]
src/org/jetbrains/javafx/JavaFxBundle.properties [new file with mode: 0644]
src/org/jetbrains/javafx/JavaFxConfigureSdkPanel.form [new file with mode: 0644]
src/org/jetbrains/javafx/JavaFxConfigureSdkPanel.java [new file with mode: 0644]
src/org/jetbrains/javafx/JavaFxEditorHighlighter.java [new file with mode: 0644]
src/org/jetbrains/javafx/JavaFxFileType.java [new file with mode: 0644]
src/org/jetbrains/javafx/JavaFxFileTypeFactory.java [new file with mode: 0644]
src/org/jetbrains/javafx/JavaFxLanguage.java [new file with mode: 0644]
src/org/jetbrains/javafx/JavaFxSupportConfigurable.form [new file with mode: 0644]
src/org/jetbrains/javafx/JavaFxSupportConfigurable.java [new file with mode: 0644]
src/org/jetbrains/javafx/JavaFxSupportProvider.java [new file with mode: 0644]
src/org/jetbrains/javafx/JavaFxUtil.java [new file with mode: 0644]
src/org/jetbrains/javafx/actions/NewJavaFxScriptAction.java [new file with mode: 0644]
src/org/jetbrains/javafx/actions/intentions/RemovePrivateQuickFix.java [new file with mode: 0644]
src/org/jetbrains/javafx/build/JavaFxCompiler.java [new file with mode: 0644]
src/org/jetbrains/javafx/build/JavaFxCompilerHandler.java [new file with mode: 0644]
src/org/jetbrains/javafx/build/JavaFxCompilerLoader.java [new file with mode: 0644]
src/org/jetbrains/javafx/codeInsight/completion/JavaFxKeywordCompletionContributor.java [new file with mode: 0644]
src/org/jetbrains/javafx/codeInsight/editorActions/JavaFxQuoteHandler.java [new file with mode: 0644]
src/org/jetbrains/javafx/codeInsight/navigation/JavaFxGotoBreakContinueHandler.java [new file with mode: 0644]
src/org/jetbrains/javafx/editor/JavaFxBraceMatcher.java [new file with mode: 0644]
src/org/jetbrains/javafx/editor/JavaFxCommenter.java [new file with mode: 0644]
src/org/jetbrains/javafx/editor/JavaFxFoldingBuilder.java [new file with mode: 0644]
src/org/jetbrains/javafx/editor/JavaFxHighlighter.java [new file with mode: 0644]
src/org/jetbrains/javafx/editor/JavaFxHighlightingLexer.java [new file with mode: 0644]
src/org/jetbrains/javafx/facet/ExecutionModel.java [new file with mode: 0644]
src/org/jetbrains/javafx/facet/JavaFxFacet.java [new file with mode: 0644]
src/org/jetbrains/javafx/facet/JavaFxFacetConfiguration.java [new file with mode: 0644]
src/org/jetbrains/javafx/facet/JavaFxFacetEditorTab.form [new file with mode: 0644]
src/org/jetbrains/javafx/facet/JavaFxFacetEditorTab.java [new file with mode: 0644]
src/org/jetbrains/javafx/facet/JavaFxFacetListener.java [new file with mode: 0644]
src/org/jetbrains/javafx/facet/JavaFxFacetType.java [new file with mode: 0644]
src/org/jetbrains/javafx/gotoByName/JavaFxGotoClassContributor.java [new file with mode: 0644]
src/org/jetbrains/javafx/gotoByName/JavaFxGotoSymbolContributor.java [new file with mode: 0644]
src/org/jetbrains/javafx/javafxFile.png [new file with mode: 0644]
src/org/jetbrains/javafx/lang/JavaFxElementType.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/lexer/BraceQuoteTracker.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/lexer/JavaFxFlexLexer.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/lexer/JavaFxLexer.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/lexer/JavaFxTokenTypes.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/lexer/_JavaFxLexer.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/lexer/javafx.flex [new file with mode: 0644]
src/org/jetbrains/javafx/lang/parser/JavaFxElementTypes.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/parser/JavaFxParser.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/parser/JavaFxParserDefinition.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/parser/JavaFxStubElementTypes.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxAssignmentExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxBinaryExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxBlockExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxBoundExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxBreakExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxCallExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxCatchClause.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxClassDefinition.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxContinueExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxDeleteExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxElement.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxElementVisitor.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxExpressionList.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxFile.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxFinallyClause.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxForExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxFunction.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxFunctionDefinition.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxFunctionExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxFunctionTypeElement.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxIfExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxImportList.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxImportStatement.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxInClause.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxIndexExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxIndexofExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxInitBlock.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxInsertExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxInvalidateExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxLiteralExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxLoopExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxModifierList.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxNewExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxObjectLiteral.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxObjectLiteralInit.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxOnInvalidateClause.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxOnReplaceClause.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxPackageDefinition.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxParameter.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxParameterList.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxParenthesizedExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxPostinitBlock.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxPsiManager.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxPsiUtil.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxQualifiedNamedElement.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxRangeExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxReferenceElement.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxReferenceExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxReferenceList.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxReturnExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxSequenceLiteral.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxSequenceSelectExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxSignature.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxSliceExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxStringCompoundElement.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxStringExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxSuffixedExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxThisReferenceExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxThrowExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxTimelineExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxTryExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxTypeElement.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxTypeExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxUnaryExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxValueExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxVariableDeclaration.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/JavaFxWhileExpression.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxAssignmentExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxBaseElementImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxBinaryExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxBlockExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxBoundExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxBreakExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxCallExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxCatchClauseImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxClassDefinitionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxContinueExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxDeleteExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxExpressionListImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxFileImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxFinallyClauseImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxForExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxFunctionDefinitionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxFunctionExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxFunctionTypeElementImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxIfExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxImportListImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxImportStatementImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxInClauseImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxIndexExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxIndexofExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxInitBlockImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxInsertExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxInvalidateExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxLiteralExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxModifierListImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxNewExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxObjectLiteralImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxObjectLiteralInitImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxOnInvalidateClauseImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxOnReplaceClauseImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxPackageDefinitionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxParameterImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxParameterListImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxParenthesizedExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxPostinitBlockImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxPresentableElementImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxPsiManagerImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxQualifiedName.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxRangeExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxReferenceElementImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxReferenceExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxReferenceListImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxReturnExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxSequenceLiteralImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxSequenceSelectExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxSignatureImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxSliceExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxStringCompoundElementImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxStringExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxSuffixedExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxThisReferenceExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxThrowExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxTimelineExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxTryExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxTypeElementImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxTypeExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxUnaryExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxVariableDeclarationImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxVoidExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/JavaFxWhileExpressionImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/resolve/JavaFxImportReference.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/resolve/JavaFxPackageReference.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/resolve/JavaFxQualifiedReference.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/resolve/JavaFxReference.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/resolve/JavaFxReferenceElementManipulator.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/resolve/JavaFxResolveProcessor.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/resolve/JavaFxResolveUtil.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/resolve/JavaFxThisReference.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/stubs/JavaFxClassStubImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/stubs/JavaFxFunctionStubImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/stubs/JavaFxImportListStubImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/stubs/JavaFxNamedStub.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/stubs/JavaFxPackageDefinitionStubImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/stubs/JavaFxParameterListStubImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/stubs/JavaFxParameterStubImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/stubs/JavaFxQualifiedNamedStubImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/stubs/JavaFxSignatureStubImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/stubs/JavaFxVariableStubImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/stubs/index/JavaFxClassNameIndex.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/stubs/index/JavaFxFunctionNameIndex.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/stubs/index/JavaFxQualifiedNameIndex.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/stubs/index/JavaFxVariableNameIndex.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/stubs/types/JavaFxClassElementType.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/stubs/types/JavaFxFunctionElementType.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/stubs/types/JavaFxImportListElementType.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/stubs/types/JavaFxPackageDefinitionElementType.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/stubs/types/JavaFxParameterElementType.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/stubs/types/JavaFxParameterListElementType.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/stubs/types/JavaFxSignatureElementType.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/stubs/types/JavaFxVariableElementType.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/types/JavaFxClassTypeImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/types/JavaFxFileTypeImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/types/JavaFxFunctionTypeImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/types/JavaFxPrimitiveType.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/types/JavaFxSequenceTypeImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/types/JavaFxTypeUtil.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/types/JavaFxVoidType.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/types/java/JavaClassTypeImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/impl/types/java/JavaFunctionTypeImpl.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/stubs/JavaFxClassStub.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/stubs/JavaFxFunctionStub.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/stubs/JavaFxImportListStub.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/stubs/JavaFxPackageDefinitionStub.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/stubs/JavaFxParameterListStub.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/stubs/JavaFxParameterStub.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/stubs/JavaFxQualifiedNamedStub.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/stubs/JavaFxSignatureStub.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/stubs/JavaFxStubElementType.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/stubs/JavaFxVariableStub.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/types/JavaFxClassType.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/types/JavaFxFileType.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/types/JavaFxFunctionType.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/types/JavaFxSequenceType.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/psi/types/JavaFxType.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/validation/BreakContinueAnnotatingVisitor.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/validation/JavaFxAnnotatingVisitor.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/validation/JavaFxAnnotator.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/validation/JavaFxDeprecationVisitor.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/validation/LiteralAnnotatingVisitor.java [new file with mode: 0644]
src/org/jetbrains/javafx/lang/validation/UnresolvedReferenceVisitor.java [new file with mode: 0644]
src/org/jetbrains/javafx/refactoring/JavaFxChangeUtil.java [new file with mode: 0644]
src/org/jetbrains/javafx/refactoring/JavaFxRefactoringUtil.java [new file with mode: 0644]
src/org/jetbrains/javafx/refactoring/surround/JavaFxExpressionSurroundDescriptor.java [new file with mode: 0644]
src/org/jetbrains/javafx/refactoring/surround/surrounders/expressions/JavaFxExpressionSurrounder.java [new file with mode: 0644]
src/org/jetbrains/javafx/refactoring/surround/surrounders/expressions/JavaFxWithAsSurrounder.java [new file with mode: 0644]
src/org/jetbrains/javafx/refactoring/surround/surrounders/expressions/JavaFxWithNotInstanceofSurrounder.java [new file with mode: 0644]
src/org/jetbrains/javafx/refactoring/surround/surrounders/expressions/JavaFxWithNotSurrounder.java [new file with mode: 0644]
src/org/jetbrains/javafx/refactoring/surround/surrounders/expressions/JavaFxWithParenthesesSurrounder.java [new file with mode: 0644]
src/org/jetbrains/javafx/run/JavaFxProgramRunner.java [new file with mode: 0644]
src/org/jetbrains/javafx/run/JavaFxRunConfiguration.java [new file with mode: 0644]
src/org/jetbrains/javafx/run/JavaFxRunConfigurationEditor.form [new file with mode: 0644]
src/org/jetbrains/javafx/run/JavaFxRunConfigurationEditor.java [new file with mode: 0644]
src/org/jetbrains/javafx/run/JavaFxRunConfigurationProducer.java [new file with mode: 0644]
src/org/jetbrains/javafx/run/JavaFxRunConfigurationType.java [new file with mode: 0644]
src/org/jetbrains/javafx/run/RunnableScriptUtil.java [new file with mode: 0644]
src/org/jetbrains/javafx/sdk/JavaFxSdkListener.java [new file with mode: 0644]
src/org/jetbrains/javafx/sdk/JavaFxSdkRootsListener.java [new file with mode: 0644]
src/org/jetbrains/javafx/sdk/JavaFxSdkType.java [new file with mode: 0644]
src/org/jetbrains/javafx/sdk/JavaFxSdkUtil.java [new file with mode: 0644]
src/org/jetbrains/javafx/structure/JavaFxStructureViewElement.java [new file with mode: 0644]
src/org/jetbrains/javafx/structure/JavaFxStructureViewFactory.java [new file with mode: 0644]
testData/commenter/Block.fx [new file with mode: 0644]
testData/commenter/BlockUncomment.fx [new file with mode: 0644]
testData/commenter/BlockUncomment_after.fx [new file with mode: 0644]
testData/commenter/Block_after.fx [new file with mode: 0644]
testData/commenter/Multiline.fx [new file with mode: 0644]
testData/commenter/MultilineUncomment.fx [new file with mode: 0644]
testData/commenter/MultilineUncomment_after.fx [new file with mode: 0644]
testData/commenter/Multiline_after.fx [new file with mode: 0644]
testData/commenter/Simple.fx [new file with mode: 0644]
testData/commenter/SimpleUncomment.fx [new file with mode: 0644]
testData/commenter/SimpleUncomment_after.fx [new file with mode: 0644]
testData/commenter/Simple_after.fx [new file with mode: 0644]
testData/folding/ClassDefinition.fx [new file with mode: 0644]
testData/folding/Comments.fx [new file with mode: 0644]
testData/folding/FunctionDefinition.fx [new file with mode: 0644]
testData/folding/Imports.fx [new file with mode: 0644]
testData/folding/ObjectLiteral.fx [new file with mode: 0644]
testData/folding/OneImport.fx [new file with mode: 0644]
testData/folding/VariableDecl.fx [new file with mode: 0644]
testData/goto/BreakEof.fx [new file with mode: 0644]
testData/goto/BreakEof_after.fx [new file with mode: 0644]
testData/goto/BreakFor.fx [new file with mode: 0644]
testData/goto/BreakFor_after.fx [new file with mode: 0644]
testData/goto/BreakInsideVar.fx [new file with mode: 0644]
testData/goto/BreakInsideVar_after.fx [new file with mode: 0644]
testData/goto/BreakWhile.fx [new file with mode: 0644]
testData/goto/BreakWhile_after.fx [new file with mode: 0644]
testData/goto/ContinueFor.fx [new file with mode: 0644]
testData/goto/ContinueFor_after.fx [new file with mode: 0644]
testData/goto/ContinueInsideVar.fx [new file with mode: 0644]
testData/goto/ContinueInsideVar_after.fx [new file with mode: 0644]
testData/goto/ContinueWhile.fx [new file with mode: 0644]
testData/goto/ContinueWhile_after.fx [new file with mode: 0644]
testData/goto/NestedLoop.fx [new file with mode: 0644]
testData/goto/NestedLoop_after.fx [new file with mode: 0644]
testData/highlighting/Attribute.fx [new file with mode: 0644]
testData/highlighting/Break.fx [new file with mode: 0644]
testData/highlighting/Continue.fx [new file with mode: 0644]
testData/highlighting/LargeInteger.fx [new file with mode: 0644]
testData/highlighting/LargeNumber.fx [new file with mode: 0644]
testData/highlighting/Private.fx [new file with mode: 0644]
testData/highlighting/Static.fx [new file with mode: 0644]
testData/highlighting/UnterminatedString.fx [new file with mode: 0644]
testData/intentions/RemovePrivate.fx [new file with mode: 0644]
testData/intentions/RemovePrivate_after.fx [new file with mode: 0644]
testData/psi/Arguments.fx [new file with mode: 0644]
testData/psi/Arguments.txt [new file with mode: 0644]
testData/psi/Bind.fx [new file with mode: 0644]
testData/psi/Bind.txt [new file with mode: 0644]
testData/psi/Bound.fx [new file with mode: 0644]
testData/psi/Bound.txt [new file with mode: 0644]
testData/psi/BracesInFormat.fx [new file with mode: 0644]
testData/psi/BracesInFormat.txt [new file with mode: 0644]
testData/psi/BreakContinue.fx [new file with mode: 0644]
testData/psi/BreakContinue.txt [new file with mode: 0644]
testData/psi/Class.fx [new file with mode: 0644]
testData/psi/Class.txt [new file with mode: 0644]
testData/psi/Declarations.fx [new file with mode: 0644]
testData/psi/Declarations.txt [new file with mode: 0644]
testData/psi/DeleteExpression.fx [new file with mode: 0644]
testData/psi/DeleteExpression.txt [new file with mode: 0644]
testData/psi/ForExpression.fx [new file with mode: 0644]
testData/psi/ForExpression.txt [new file with mode: 0644]
testData/psi/FunctionExpression.fx [new file with mode: 0644]
testData/psi/FunctionExpression.txt [new file with mode: 0644]
testData/psi/FunctionType.fx [new file with mode: 0644]
testData/psi/FunctionType.txt [new file with mode: 0644]
testData/psi/HelloWorld.fx [new file with mode: 0644]
testData/psi/HelloWorld.txt [new file with mode: 0644]
testData/psi/IfElseExpression.fx [new file with mode: 0644]
testData/psi/IfElseExpression.txt [new file with mode: 0644]
testData/psi/IfExpression.fx [new file with mode: 0644]
testData/psi/IfExpression.txt [new file with mode: 0644]
testData/psi/ImplicitConcat.fx [new file with mode: 0644]
testData/psi/ImplicitConcat.txt [new file with mode: 0644]
testData/psi/Imports.fx [new file with mode: 0644]
testData/psi/Imports.txt [new file with mode: 0644]
testData/psi/InsertExpression.fx [new file with mode: 0644]
testData/psi/InsertExpression.txt [new file with mode: 0644]
testData/psi/Invalidate.fx [new file with mode: 0644]
testData/psi/Invalidate.txt [new file with mode: 0644]
testData/psi/InvalidateFunction.fx [new file with mode: 0644]
testData/psi/InvalidateFunction.txt [new file with mode: 0644]
testData/psi/Modifiers.fx [new file with mode: 0644]
testData/psi/Modifiers.txt [new file with mode: 0644]
testData/psi/ObjectLiteral.fx [new file with mode: 0644]
testData/psi/ObjectLiteral.txt [new file with mode: 0644]
testData/psi/ObjectLiteral2.fx [new file with mode: 0644]
testData/psi/ObjectLiteral2.txt [new file with mode: 0644]
testData/psi/ObjectLiteralBind.fx [new file with mode: 0644]
testData/psi/ObjectLiteralBind.txt [new file with mode: 0644]
testData/psi/OnInvalidate.fx [new file with mode: 0644]
testData/psi/OnInvalidate.txt [new file with mode: 0644]
testData/psi/OnReplace.fx [new file with mode: 0644]
testData/psi/OnReplace.txt [new file with mode: 0644]
testData/psi/Parameters.fx [new file with mode: 0644]
testData/psi/Parameters.txt [new file with mode: 0644]
testData/psi/QualifiedThis.fx [new file with mode: 0644]
testData/psi/QualifiedThis.txt [new file with mode: 0644]
testData/psi/SequenceLiteral.fx [new file with mode: 0644]
testData/psi/SequenceLiteral.txt [new file with mode: 0644]
testData/psi/Sequences.fx [new file with mode: 0644]
testData/psi/Sequences.txt [new file with mode: 0644]
testData/psi/SimpleExpression.fx [new file with mode: 0644]
testData/psi/SimpleExpression.txt [new file with mode: 0644]
testData/psi/StaticFunction.fx [new file with mode: 0644]
testData/psi/StaticFunction.txt [new file with mode: 0644]
testData/psi/This.fx [new file with mode: 0644]
testData/psi/This.txt [new file with mode: 0644]
testData/psi/ThrowExpression.fx [new file with mode: 0644]
testData/psi/ThrowExpression.txt [new file with mode: 0644]
testData/psi/TimeLineExpression.fx [new file with mode: 0644]
testData/psi/TimeLineExpression.txt [new file with mode: 0644]
testData/psi/TryExpression.fx [new file with mode: 0644]
testData/psi/TryExpression.txt [new file with mode: 0644]
testData/psi/TypeExpression.fx [new file with mode: 0644]
testData/psi/TypeExpression.txt [new file with mode: 0644]
testData/resolve/CatchParameter.fx [new file with mode: 0644]
testData/resolve/Field.fx [new file with mode: 0644]
testData/resolve/FieldFromObjectLiteralFunction.fx [new file with mode: 0644]
testData/resolve/FieldFromObjectLiteralInit.fx [new file with mode: 0644]
testData/resolve/ForParameter.fx [new file with mode: 0644]
testData/resolve/ForParameterMember.fx [new file with mode: 0644]
testData/resolve/FromString.fx [new file with mode: 0644]
testData/resolve/FunctionExpressionParameter.fx [new file with mode: 0644]
testData/resolve/FunctionExpressionReturnField.fx [new file with mode: 0644]
testData/resolve/FunctionParameter.fx [new file with mode: 0644]
testData/resolve/FunctionReturnField.fx [new file with mode: 0644]
testData/resolve/FunctionVar.fx [new file with mode: 0644]
testData/resolve/GlobalVar.fx [new file with mode: 0644]
testData/resolve/IDEA_57804.fx [new file with mode: 0644]
testData/resolve/LocalVar.fx [new file with mode: 0644]
testData/resolve/ObjectLiteralName.fx [new file with mode: 0644]
testData/resolve/ObjectLiteralVarFromInit.fx [new file with mode: 0644]
testData/resolve/QualifiedThis.fx [new file with mode: 0644]
testData/resolve/QuotedIdentifier.fx [new file with mode: 0644]
testData/resolve/QuotedIdentifier2.fx [new file with mode: 0644]
testData/resolve/QuotedIdentifier3.fx [new file with mode: 0644]
testData/resolve/RecursiveFunction.fx [new file with mode: 0644]
testData/resolve/ReturnType.fx [new file with mode: 0644]
testData/resolve/SequenceElementMethod.fx [new file with mode: 0644]
testData/resolve/SuperClassMember.fx [new file with mode: 0644]
testData/resolve/This.fx [new file with mode: 0644]
testData/resolve/ThisMethod.fx [new file with mode: 0644]
testData/resolve/TypeExpression.fx [new file with mode: 0644]
testData/resolve/UndefinedVariable.fx [new file with mode: 0644]
testData/resolve/UndefinedVariable2.fx [new file with mode: 0644]
testData/resolve/VarFromOnReplace.fx [new file with mode: 0644]
testData/resolve/VariableBeforeDefinition.fx [new file with mode: 0644]
testData/resolve/VariableFromInit.fx [new file with mode: 0644]
testData/run/Assignment.fx [new file with mode: 0644]
testData/run/NonRunnable.fx [new file with mode: 0644]
testData/run/QualifiedStage.fx [new file with mode: 0644]
testData/run/Run.fx [new file with mode: 0644]
testData/run/Stage.fx [new file with mode: 0644]
testData/run/Variable.fx [new file with mode: 0644]
testData/run/Variable2.fx [new file with mode: 0644]
testData/structure/All.fx [new file with mode: 0644]
testData/structure/Classes.fx [new file with mode: 0644]
testData/structure/Functions.fx [new file with mode: 0644]
testData/structure/Vars.fx [new file with mode: 0644]
testData/surround/As.fx [new file with mode: 0644]
testData/surround/As_after.fx [new file with mode: 0644]
testData/surround/Not.fx [new file with mode: 0644]
testData/surround/NotInstanceof.fx [new file with mode: 0644]
testData/surround/NotInstanceof_after.fx [new file with mode: 0644]
testData/surround/Not_after.fx [new file with mode: 0644]
testData/surround/Parentheses.fx [new file with mode: 0644]
testData/surround/Parentheses_after.fx [new file with mode: 0644]
testData/typed/BeforeIdent1.fx [new file with mode: 0644]
testData/typed/BeforeIdent1_after.fx [new file with mode: 0644]
testData/typed/BeforeIdent2.fx [new file with mode: 0644]
testData/typed/BeforeIdent2_after.fx [new file with mode: 0644]
testData/typed/Braces.fx [new file with mode: 0644]
testData/typed/Braces_after.fx [new file with mode: 0644]
testData/typed/Brackets.fx [new file with mode: 0644]
testData/typed/Brackets_after.fx [new file with mode: 0644]
testData/typed/ClosingQuote1.fx [new file with mode: 0644]
testData/typed/ClosingQuote1_after.fx [new file with mode: 0644]
testData/typed/ClosingQuote2.fx [new file with mode: 0644]
testData/typed/ClosingQuote2_after.fx [new file with mode: 0644]
testData/typed/Concat1.fx [new file with mode: 0644]
testData/typed/Concat1_after.fx [new file with mode: 0644]
testData/typed/Concat2.fx [new file with mode: 0644]
testData/typed/Concat2_after.fx [new file with mode: 0644]
testData/typed/InFormat.fx [new file with mode: 0644]
testData/typed/InFormat_after.fx [new file with mode: 0644]
testData/typed/ParenBeforeIdent.fx [new file with mode: 0644]
testData/typed/ParenBeforeIdent_after.fx [new file with mode: 0644]
testData/typed/Parens.fx [new file with mode: 0644]
testData/typed/Parens_after.fx [new file with mode: 0644]
testData/typed/Simple1.fx [new file with mode: 0644]
testData/typed/Simple1_after.fx [new file with mode: 0644]
testData/typed/Simple2.fx [new file with mode: 0644]
testData/typed/Simple2_after.fx [new file with mode: 0644]
testSrc/org/jetbrains/javafx/JavaFxCommenterTest.java [new file with mode: 0644]
testSrc/org/jetbrains/javafx/JavaFxFoldingTest.java [new file with mode: 0644]
testSrc/org/jetbrains/javafx/JavaFxGotoBreakContinueTest.java [new file with mode: 0644]
testSrc/org/jetbrains/javafx/JavaFxHighlightingTest.java [new file with mode: 0644]
testSrc/org/jetbrains/javafx/JavaFxIntentionTest.java [new file with mode: 0644]
testSrc/org/jetbrains/javafx/JavaFxLexerTest.java [new file with mode: 0644]
testSrc/org/jetbrains/javafx/JavaFxParserTest.java [new file with mode: 0644]
testSrc/org/jetbrains/javafx/JavaFxResolveTest.java [new file with mode: 0644]
testSrc/org/jetbrains/javafx/JavaFxStructureViewTest.java [new file with mode: 0644]
testSrc/org/jetbrains/javafx/JavaFxSurroundWithTest.java [new file with mode: 0644]
testSrc/org/jetbrains/javafx/JavaFxTypedHandlerTest.java [new file with mode: 0644]
testSrc/org/jetbrains/javafx/RunnableScriptUtilTest.java [new file with mode: 0644]
testSrc/org/jetbrains/javafx/testUtils/FoldingTestBase.java [new file with mode: 0644]
testSrc/org/jetbrains/javafx/testUtils/JavaFxLightFixtureTestCase.java [new file with mode: 0644]
testSrc/org/jetbrains/javafx/testUtils/JavaFxResolveTestCase.java [new file with mode: 0644]
testSrc/org/jetbrains/javafx/testUtils/JavaFxTestUtil.java [new file with mode: 0644]

diff --git a/JavaFX.iml b/JavaFX.iml
new file mode 100644 (file)
index 0000000..502be05
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/testSrc" isTestSource="true" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module" module-name="openapi" />
+    <orderEntry type="module" module-name="testFramework" scope="TEST" />
+    <orderEntry type="module" module-name="idea-tests" scope="TEST" />
+    <orderEntry type="module" module-name="lang-impl" />
+    <orderEntry type="module" module-name="execution-impl" />
+    <orderEntry type="module" module-name="compiler-openapi" />
+    <orderEntry type="module" module-name="idea-ui" />
+    <orderEntry type="module" module-name="java-impl" />
+    <orderEntry type="module" module-name="compiler-impl" />
+  </component>
+</module>
+
diff --git a/src/META-INF/plugin.xml b/src/META-INF/plugin.xml
new file mode 100644 (file)
index 0000000..754a095
--- /dev/null
@@ -0,0 +1,119 @@
+<!--
+  ~ Copyright 2000-2010 JetBrains s.r.o.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<idea-plugin version="2">
+  <name>JavaFx Support</name>
+  <description><![CDATA[
+    Supports development of JavaFX applications with IntelliJ IDEA
+    <p>Features:
+      <ul>
+        <li>Syntax highlighting (with basic errors highlighting)
+        <li>Compilation
+        <li>Run (desktop only)
+        <li>Structure view
+        <li>Brace and quote matching
+        <li>Code folding
+        <li>Keyword completion
+        <li>Go To Class/Symbol
+        <li>Go To definition
+        <li>Surround with expression
+      </ul>
+    </p>
+  ]]></description>
+  <change-notes>
+    Go to definition, Surround with expression
+  </change-notes>
+  <version>0.4</version>
+  <vendor>JetBrains</vendor>
+  <idea-version since-build="96.1190"/>
+
+  <application-components>
+    <component>
+      <implementation-class>org.jetbrains.javafx.sdk.JavaFxSdkListener</implementation-class>
+    </component>
+  </application-components>
+
+  <project-components>
+    <component>
+      <implementation-class>org.jetbrains.javafx.build.JavaFxCompilerLoader</implementation-class>
+    </component>
+    <component>
+      <interface-class>org.jetbrains.javafx.lang.psi.JavaFxPsiManager</interface-class>
+      <implementation-class>org.jetbrains.javafx.lang.psi.impl.JavaFxPsiManagerImpl</implementation-class>
+    </component>
+  </project-components>
+
+  <module-components>
+    <component>
+      <implementation-class>org.jetbrains.javafx.facet.JavaFxFacetListener</implementation-class>
+    </component>
+  </module-components>
+
+  <actions>
+    <action id="JavaFX.NewJavaFxScript" class="org.jetbrains.javafx.actions.NewJavaFxScriptAction"
+            text="JavaFX Script" description="Create new JavaFX script">
+      <add-to-group group-id="NewGroup" anchor="after" relative-to-action="NewGroup1"/>
+    </action>
+  </actions>
+
+  <extensions defaultExtensionNs="com.intellij">
+    <fileTypeFactory implementation="org.jetbrains.javafx.JavaFxFileTypeFactory"/>
+
+    <syntaxHighlighter key="JavaFx" implementationClass="org.jetbrains.javafx.editor.JavaFxHighlighter"/>
+    <lang.braceMatcher language="JavaFx" implementationClass="org.jetbrains.javafx.editor.JavaFxBraceMatcher"/>
+    <quoteHandler fileType="JavaFx" className="org.jetbrains.javafx.codeInsight.editorActions.JavaFxQuoteHandler"/>
+    <lang.parserDefinition language="JavaFx" implementationClass="org.jetbrains.javafx.lang.parser.JavaFxParserDefinition"/>
+    <lang.foldingBuilder language="JavaFx" implementationClass="org.jetbrains.javafx.editor.JavaFxFoldingBuilder"/>
+    <lang.commenter language="JavaFx" implementationClass="org.jetbrains.javafx.editor.JavaFxCommenter"/>
+    <lang.psiStructureViewFactory language="JavaFx"
+                                  implementationClass="org.jetbrains.javafx.structure.JavaFxStructureViewFactory"/>
+    <gotoDeclarationHandler implementation="org.jetbrains.javafx.codeInsight.navigation.JavaFxGotoBreakContinueHandler" order="FIRST"/>
+    <gotoClassContributor implementation="org.jetbrains.javafx.gotoByName.JavaFxGotoClassContributor"/>
+    <gotoSymbolContributor implementation="org.jetbrains.javafx.gotoByName.JavaFxGotoSymbolContributor"/>
+    <completion.contributor language="JavaFx"
+                            implementationClass="org.jetbrains.javafx.codeInsight.completion.JavaFxKeywordCompletionContributor"/>
+    <lang.elementManipulator forClass="org.jetbrains.javafx.lang.psi.JavaFxReferenceElement"
+                             implementationClass="org.jetbrains.javafx.lang.psi.impl.resolve.JavaFxReferenceElementManipulator"/>
+    <lang.surroundDescriptor language="JavaFx"
+                             implementationClass="org.jetbrains.javafx.refactoring.surround.JavaFxExpressionSurroundDescriptor"/>
+
+
+    <frameworkSupport implementation="org.jetbrains.javafx.JavaFxSupportProvider"/>
+    <sdkType implementation="org.jetbrains.javafx.sdk.JavaFxSdkType"/>
+    <facetType implementation="org.jetbrains.javafx.facet.JavaFxFacetType"/>
+
+    <!--Compile/Run-->
+    <configurationType implementation="org.jetbrains.javafx.run.JavaFxRunConfigurationType"/>
+    <programRunner implementation="org.jetbrains.javafx.run.JavaFxProgramRunner"/>
+    <configurationProducer implementation="org.jetbrains.javafx.run.JavaFxRunConfigurationProducer"/>
+
+    <!--Stubs-->
+    <stubElementTypeHolder class="org.jetbrains.javafx.lang.parser.JavaFxElementTypes"/>
+
+    <stubIndex implementation="org.jetbrains.javafx.lang.psi.impl.stubs.index.JavaFxClassNameIndex"/>
+    <stubIndex implementation="org.jetbrains.javafx.lang.psi.impl.stubs.index.JavaFxFunctionNameIndex"/>
+    <stubIndex implementation="org.jetbrains.javafx.lang.psi.impl.stubs.index.JavaFxVariableNameIndex"/>
+    <stubIndex implementation="org.jetbrains.javafx.lang.psi.impl.stubs.index.JavaFxQualifiedNameIndex"/>
+
+    <errorHandler implementation="com.intellij.diagnostic.ITNReporter"/>
+
+    <annotator language="JavaFx" implementationClass="org.jetbrains.javafx.lang.validation.JavaFxAnnotator"/>
+
+    <!--Templates-->
+    <internalFileTemplate name="JavaFX Class"/>
+    <internalFileTemplate name="JavaFX File"/>
+    <internalFileTemplate name="JavaFX Stage"/>
+  </extensions>
+</idea-plugin>
\ No newline at end of file
diff --git a/src/fileTemplates/internal/JavaFX Class.fx.ft b/src/fileTemplates/internal/JavaFX Class.fx.ft
new file mode 100644 (file)
index 0000000..ec6ca88
--- /dev/null
@@ -0,0 +1,7 @@
+#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
+
+#parse("File Header.java")
+
+public class ${NAME} {
+
+}
\ No newline at end of file
diff --git a/src/fileTemplates/internal/JavaFX File.fx.ft b/src/fileTemplates/internal/JavaFX File.fx.ft
new file mode 100644 (file)
index 0000000..98b3208
--- /dev/null
@@ -0,0 +1,3 @@
+#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
+
+#parse("File Header.java")
diff --git a/src/fileTemplates/internal/JavaFX Stage.fx.ft b/src/fileTemplates/internal/JavaFX Stage.fx.ft
new file mode 100644 (file)
index 0000000..d49b627
--- /dev/null
@@ -0,0 +1,26 @@
+#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
+
+import javafx.stage.Stage;
+import javafx.scene.Scene;
+import javafx.scene.text.Text;
+import javafx.scene.text.Font;
+
+#parse("File Header.java")
+
+Stage {
+    title: "JavaFX Application Title"
+    scene: Scene {
+        width: 320
+        height: 240
+        content: [
+            Text {
+                font : Font {
+                    size : 16
+                }
+                x: 10
+                y: 30
+                content: "Application content"
+            }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/src/org/jetbrains/javafx/JavaFxBundle.java b/src/org/jetbrains/javafx/JavaFxBundle.java
new file mode 100644 (file)
index 0000000..c704f6d
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx;
+
+import com.intellij.CommonBundle;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.PropertyKey;
+
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
+import java.util.ResourceBundle;
+
+/**
+ * JavaFx plugin messages
+ *
+ * @author andrey
+ */
+public class JavaFxBundle {
+  private static Reference<ResourceBundle> ourBundle;
+
+  @NonNls
+  private static final String BUNDLE = "org.jetbrains.javafx.JavaFxBundle";
+
+  private JavaFxBundle() {
+  }
+
+  public static String message(@PropertyKey(resourceBundle = BUNDLE) String key, Object... params) {
+    return CommonBundle.message(getBundle(), key, params);
+  }
+
+  private static ResourceBundle getBundle() {
+    ResourceBundle bundle = null;
+
+    if (ourBundle != null) bundle = ourBundle.get();
+
+    if (bundle == null) {
+      bundle = ResourceBundle.getBundle(BUNDLE);
+      ourBundle = new SoftReference<ResourceBundle>(bundle);
+    }
+    return bundle;
+  }
+}
diff --git a/src/org/jetbrains/javafx/JavaFxBundle.properties b/src/org/jetbrains/javafx/JavaFxBundle.properties
new file mode 100644 (file)
index 0000000..c2d37c6
--- /dev/null
@@ -0,0 +1,101 @@
+else.without.if='else' without 'if'
+catch.without.try='catch' without 'try'
+finally.without.try='finally' without 'try'
+name.expected=Name expected
+rbrack.expected=']' expected
+range.expected='..' expected
+replace.or.invalidate.expected='replace' or 'invalidate' expected
+def.or.var.expected='def' or 'var' expected
+into.before.or.after.expected='into', 'before' or 'after' expected
+lbrace.expected='{' expected
+rbrace.expected='}' expected
+break.expected='break' expected
+semicolon.expected=';' expected
+catch.expected='catch' expected
+lparen.expected='(' expected
+rparen.expected=')' expected
+class.expected='class' expected
+continue.expected='continue' expected
+delete.expected='delete' expected
+lbrack.expected='[' expected
+expression.expected = Expression expected
+finally.expected='finally' expected
+type.name.expected=Type name expected
+in.expected='in' expected
+rparen.or.comma.expected=')' or ',' expected
+rbrack.or.comma.expected=']' or ',' expected
+for.expected='for' expected
+function.expected='function' expected
+if.expected='if' expected
+inverse.expected='inverse' expected
+bind.or.value.expression.expected='bind' or value expression expected
+value.expression.expected=Value expression expected
+insert.expected='insert' expected
+new.expected='new' expected
+colon.expected=':' expected
+return.expected='return' expected
+at.expected='at' expected
+time.literal.expected=Time literal expected
+try.expected='try' expected
+catch.or.finally.expected='catch' or 'finally' expected
+override.expected='override' expected
+var.or.def.expected='var' or 'def' expected
+while.expected='while' expected
+import.keyword.expected='import' expected
+import.identifier.expected=Import reference expected
+separator.expected=Separator expected
+import.not.allowed='import' not allowed here
+class.or.expression.expected=Class definition or expression expected
+duplicate.modifier=Duplicate modifier '{0}'
+delim.expected='|' expected
+throw.expected='throw' expected
+package.expected='package' expected
+identifier.or.star.expected=Indentifier or '*' expected
+class.or.function.or.expression.expected=Class or function definition, or expression expected
+range.delim.or.rbrack.expected='..', '|', or '[' expected
+var.of.function.expected='var' of 'function' expected
+string.expected=String literal expected
+unexpected.token=Unexpected token
+
+missing.closing.quote=Missing closing quote
+integer.too.large=Integer number too large
+number.too.large=Number too large
+break.outside.loop=Break outside loop
+continue.outside.loop=Continue outside loop
+attribute.keyword.is.no.supported=The 'attribute' keyword is no longer supported. Please use 'def' or 'var' to declare class variables.
+private.keyword.is.no.supported=The 'private' keyword is no longer supported. The default access is script-private, so you can simply remove 'private'.
+static.keyword.is.no.supported='static' is no longer supported. It will be removed from the language soon. Use script-level declarations.
+
+javafx.sdk.name=JavaFX SDK
+javafx.application=JavaFX
+
+main.script.path=Main script path
+javafx.run.parameters=JavaFX parameters
+execution.model.title=Execution model
+use.sdk=Use SDK of module
+
+invalid.module=Invalid module
+couldnt.find.javafx.sdk=Couldn't find JavaFX SDK
+couldnt.find.main.class=Couldn't find main class file
+wrong.compiler.output.path=Wrong compiler output path
+invalid.main.script=Invalid main script
+invalid.sdk=Invalid SDK
+configure.sdks=Configure SDKs
+sdk.not.yet.selected=JavaFX SDK not yet selected
+invalid.facet=Invalid facet
+javafx.sdk.is.not.set.facet.$1.module.$2=JavaFX SDK is not set for facet ''{0}'' of module ''{1}''
+javafx.compiler.problem=JavaFX compiler problem
+
+create.new.javafx.script=Create new JavaFX script
+javafx.script=JavaFX Script
+javafx.file=JavaFX File
+javafx.class=JavaFX Class
+javafx.stage=JavaFX Stage
+
+javafx.surround.with.not.template=not (expr)
+javafx.surround.with.as.template=(expr as Type)
+javafx.surround.with.not.instanceof.template=not (expr instanceof Type)
+
+javafx.unresolved.symbol.$0=Cannot resolve symbol ''{0}''
+
+INTN.remove.private.keyword=Remove 'private' keyword
\ No newline at end of file
diff --git a/src/org/jetbrains/javafx/JavaFxConfigureSdkPanel.form b/src/org/jetbrains/javafx/JavaFxConfigureSdkPanel.form
new file mode 100644 (file)
index 0000000..eef4a2c
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.javafx.JavaFxConfigureSdkPanel">
+  <grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+    <margin top="0" left="0" bottom="0" right="0"/>
+    <constraints>
+      <xy x="20" y="20" width="500" height="400"/>
+    </constraints>
+    <properties/>
+    <border type="none"/>
+    <children>
+      <component id="250e8" class="com.intellij.openapi.ui.LabeledComponent" binding="mySdkComponent">
+        <constraints>
+          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <componentClass value="javax.swing.JComboBox" noi18n="true"/>
+          <labelLocation value="West"/>
+          <text value="JavaFX SDK"/>
+        </properties>
+      </component>
+      <component id="d4b8" class="javax.swing.JButton" binding="myConfigureSdksButton">
+        <constraints>
+          <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <text value="Configure SDKs"/>
+        </properties>
+      </component>
+    </children>
+  </grid>
+</form>
diff --git a/src/org/jetbrains/javafx/JavaFxConfigureSdkPanel.java b/src/org/jetbrains/javafx/JavaFxConfigureSdkPanel.java
new file mode 100644 (file)
index 0000000..403539d
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx;
+
+import com.intellij.facet.ui.FacetEditorValidator;
+import com.intellij.facet.ui.FacetValidatorsManager;
+import com.intellij.facet.ui.ValidationResult;
+import com.intellij.ide.DataManager;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.ui.ProjectJdksEditor;
+import com.intellij.openapi.ui.LabeledComponent;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.Icons;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.javafx.sdk.JavaFxSdkUtil;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @author: Alexey.Ivanov
+ */
+public class JavaFxConfigureSdkPanel extends JComponent {
+  private LabeledComponent<JComboBox> mySdkComponent;
+  private JButton myConfigureSdksButton;
+  private JPanel myMainPanel;
+
+  public JavaFxConfigureSdkPanel() {
+    super();
+
+    final JComboBox comboBox = mySdkComponent.getComponent();
+    comboBox.setRenderer(new DefaultListCellRenderer() {
+      public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+        super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
+        if (value instanceof Sdk) {
+          setText(((Sdk)value).getName());
+          setIcon(((Sdk)value).getSdkType().getIcon());
+        }
+        else {
+          setIcon(Icons.ERROR_INTRODUCTION_ICON);
+          if (comboBox.isEnabled()) {
+            setText("<html><font color='red'>&lt;No SDK&gt;</font></html>");
+          }
+          else {
+            setText("<No SDK>");
+          }
+        }
+        return this;
+      }
+    });
+    initConfigureSdksButton();
+    resetSdk(null);
+  }
+
+  private void initConfigureSdksButton() {
+    myConfigureSdksButton.addActionListener(new ActionListener() {
+      public void actionPerformed(ActionEvent e) {
+        final Sdk selectedSdk = getSelectedSdk();
+        Project project = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext());
+        if (project == null) {
+          project = ProjectManager.getInstance().getDefaultProject();
+        }
+        final ProjectJdksEditor editor = new ProjectJdksEditor(selectedSdk, project, JavaFxConfigureSdkPanel.this.myMainPanel);
+        editor.show();
+        if (editor.isOK()) {
+          resetSdk(editor.getSelectedJdk());
+        }
+      }
+    });
+  }
+
+  public void registerValidator(FacetValidatorsManager validatorsManager) {
+    final JComboBox comboBox = mySdkComponent.getComponent();
+    validatorsManager.registerValidator(new FacetEditorValidator() {
+      @Override
+      public ValidationResult check() {
+        final Object selectedItem = comboBox.getSelectedItem();
+        if (selectedItem instanceof Sdk) {
+          return ValidationResult.OK;
+        }
+        return new ValidationResult(JavaFxBundle.message("invalid.sdk"));
+      }
+    }, comboBox);
+  }
+
+  @Nullable
+  public Sdk getSelectedSdk() {
+    final Object selectedItem = mySdkComponent.getComponent().getSelectedItem();
+    if (selectedItem instanceof Sdk) {
+      return (Sdk)selectedItem;
+    }
+    return null;
+  }
+
+  public void resetSdk(@Nullable final Sdk javaFxSdk) {
+    Object initiallySelectedItem = javaFxSdk != null ? javaFxSdk : JavaFxBundle.message("sdk.not.yet.selected");
+    final List<Sdk> sdks = JavaFxSdkUtil.getAllRelatedSdks();
+    final List<Object> sdksForCombo = new ArrayList<Object>(sdks);
+    if (javaFxSdk != null) {
+      for (final Sdk sdk : sdks) {
+        if (sdk.getName().equals(javaFxSdk.getName())) {
+          initiallySelectedItem = sdk;
+          break;
+        }
+      }
+    }
+    final JComboBox comboBox = mySdkComponent.getComponent();
+    comboBox.setModel(new DefaultComboBoxModel(ArrayUtil.toObjectArray(sdksForCombo)));
+    comboBox.setSelectedItem(initiallySelectedItem);
+  }
+}
diff --git a/src/org/jetbrains/javafx/JavaFxEditorHighlighter.java b/src/org/jetbrains/javafx/JavaFxEditorHighlighter.java
new file mode 100644 (file)
index 0000000..eb4ee7d
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx;
+
+/**
+ * @author andrey
+ */
+public class JavaFxEditorHighlighter {
+}
diff --git a/src/org/jetbrains/javafx/JavaFxFileType.java b/src/org/jetbrains/javafx/JavaFxFileType.java
new file mode 100644 (file)
index 0000000..2efe940
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx;
+
+import com.intellij.openapi.fileTypes.LanguageFileType;
+import com.intellij.openapi.util.IconLoader;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+
+/**
+ * JavaFx File type
+ *
+ * @author andrey, Alexey.Ivanov
+ */
+public class JavaFxFileType extends LanguageFileType {
+  /**
+   * File icon in project explorer
+   */
+  static final Icon ICON = IconLoader.getIcon("javafxFile.png");
+
+  /**
+   * Singleton instance
+   */
+  public static final JavaFxFileType INSTANCE = new JavaFxFileType();
+
+  private JavaFxFileType() {
+    super(JavaFxLanguage.INSTANCE);
+  }
+
+  @NotNull
+  public String getName() {
+    return "JavaFx";
+  }
+
+  @NotNull
+  public String getDescription() {
+    return "JavaFx Script Files";
+  }
+
+  @NotNull
+  public String getDefaultExtension() {
+    return "fx";
+  }
+
+  public Icon getIcon() {
+    return ICON;
+  }
+
+  //@Override
+  //public EditorHighlighter getEditorHighlighter(@Nullable Project project, @Nullable VirtualFile virtualFile, @NotNull EditorColorsScheme colors) {
+  //  return new JavaFxEditorHighlighter(colors, project, virtualFile);
+  //}
+}
diff --git a/src/org/jetbrains/javafx/JavaFxFileTypeFactory.java b/src/org/jetbrains/javafx/JavaFxFileTypeFactory.java
new file mode 100644 (file)
index 0000000..5a24ead
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx;
+
+import com.intellij.openapi.fileTypes.FileTypeConsumer;
+import com.intellij.openapi.fileTypes.FileTypeFactory;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * File factory for JavaFx Script files
+ *
+ * @author andrey
+ */
+public class JavaFxFileTypeFactory extends FileTypeFactory {
+
+  @Override
+  public void createFileTypes(@NotNull FileTypeConsumer fileTypeConsumer) {
+    final JavaFxFileType javaFxFileType = JavaFxFileType.INSTANCE;
+    fileTypeConsumer.consume(javaFxFileType, javaFxFileType.getDefaultExtension());
+  }
+}
diff --git a/src/org/jetbrains/javafx/JavaFxLanguage.java b/src/org/jetbrains/javafx/JavaFxLanguage.java
new file mode 100644 (file)
index 0000000..f8fafdf
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx;
+
+import com.intellij.lang.Language;
+import com.intellij.util.containers.HashSet;
+import org.jetbrains.javafx.lang.validation.*;
+
+import java.util.Set;
+
+/**
+ * Descriptor of JavaFx Script language
+ *
+ * @author andrey, Alexey.Ivanov
+ */
+public class JavaFxLanguage extends Language {
+  public static final JavaFxLanguage INSTANCE = new JavaFxLanguage();
+  private final Set<Class<? extends JavaFxAnnotatingVisitor>> myAnnotators = new HashSet<Class<? extends JavaFxAnnotatingVisitor>>();
+
+  {
+    myAnnotators.add(LiteralAnnotatingVisitor.class);
+    myAnnotators.add(BreakContinueAnnotatingVisitor.class);
+    myAnnotators.add(JavaFxDeprecationVisitor.class);
+    myAnnotators.add(UnresolvedReferenceVisitor.class);
+  }
+
+  public static JavaFxLanguage getInstance() {
+    return INSTANCE;
+  }
+
+  private JavaFxLanguage() {
+    super("JavaFx");
+  }
+
+  public Set<Class<? extends JavaFxAnnotatingVisitor>> getAnnotators() {
+    return myAnnotators;
+  }
+
+  @Override
+  public boolean isCaseSensitive() {
+    return true;
+  }
+}
diff --git a/src/org/jetbrains/javafx/JavaFxSupportConfigurable.form b/src/org/jetbrains/javafx/JavaFxSupportConfigurable.form
new file mode 100644 (file)
index 0000000..b1e2c46
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.javafx.JavaFxSupportConfigurable">
+  <grid id="27dc6" binding="myContentPane" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+    <margin top="0" left="0" bottom="0" right="0"/>
+    <constraints>
+      <xy x="20" y="20" width="500" height="400"/>
+    </constraints>
+    <properties/>
+    <border type="none"/>
+    <children>
+      <nested-form id="cd826" form-file="org/jetbrains/javafx/JavaFxConfigureSdkPanel.form" binding="myConfigureSdkPanel">
+        <constraints>
+          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+        </constraints>
+      </nested-form>
+      <hspacer id="989a">
+        <constraints>
+          <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+        </constraints>
+      </hspacer>
+      <vspacer id="79003">
+        <constraints>
+          <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+        </constraints>
+      </vspacer>
+    </children>
+  </grid>
+</form>
diff --git a/src/org/jetbrains/javafx/JavaFxSupportConfigurable.java b/src/org/jetbrains/javafx/JavaFxSupportConfigurable.java
new file mode 100644 (file)
index 0000000..e591e51
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx;
+
+import com.intellij.ide.util.frameworkSupport.FrameworkSupportConfigurable;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.ModifiableRootModel;
+import com.intellij.openapi.roots.libraries.Library;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @author: Alexey.Ivanov
+ */
+public class JavaFxSupportConfigurable extends FrameworkSupportConfigurable {
+  private JavaFxConfigureSdkPanel myConfigureSdkPanel;
+  private JPanel myContentPane;
+
+  @Override
+  public JComponent getComponent() {
+    return myContentPane;
+  }
+
+  @Override
+  public void addSupport(@NotNull Module module, @NotNull ModifiableRootModel model, @Nullable Library library) {
+    final Sdk sdk = myConfigureSdkPanel.getSelectedSdk();
+    JavaFxUtil.addFacet(module, sdk);
+  }
+}
diff --git a/src/org/jetbrains/javafx/JavaFxSupportProvider.java b/src/org/jetbrains/javafx/JavaFxSupportProvider.java
new file mode 100644 (file)
index 0000000..84f0493
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx;
+
+import com.intellij.ide.util.frameworkSupport.FrameworkSupportConfigurable;
+import com.intellij.ide.util.frameworkSupport.FrameworkSupportModel;
+import com.intellij.ide.util.frameworkSupport.FrameworkSupportProvider;
+import com.intellij.openapi.module.JavaModuleType;
+import com.intellij.openapi.module.ModuleType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.javafx.facet.JavaFxFacet;
+
+import javax.swing.*;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @author: Alexey.Ivanov
+ */
+public class JavaFxSupportProvider extends FrameworkSupportProvider {
+  protected JavaFxSupportProvider() {
+    super("Support Provider: " + JavaFxFacet.ID.toString(), "JavaFX");
+  }
+
+  @NotNull
+  @Override
+  public FrameworkSupportConfigurable createConfigurable(@NotNull FrameworkSupportModel model) {
+    return new JavaFxSupportConfigurable();
+  }
+
+  @Override
+  public Icon getIcon() {
+    return JavaFxFileType.INSTANCE.getIcon();
+  }
+
+  @Override
+  public boolean isEnabledForModuleType(@NotNull ModuleType moduleType) {
+    return moduleType instanceof JavaModuleType;
+  }
+}
diff --git a/src/org/jetbrains/javafx/JavaFxUtil.java b/src/org/jetbrains/javafx/JavaFxUtil.java
new file mode 100644 (file)
index 0000000..cb0149b
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx;
+
+import com.intellij.facet.FacetManager;
+import com.intellij.facet.ModifiableFacetModel;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.CompilerModuleExtension;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiManager;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.javafx.facet.JavaFxFacet;
+import org.jetbrains.javafx.lang.psi.JavaFxFile;
+import org.jetbrains.javafx.lang.psi.JavaFxPackageDefinition;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @author: Alexey.Ivanov
+ */
+public class JavaFxUtil {
+  private JavaFxUtil() {
+  }
+
+  @Nullable
+  public static String getCompilerOutputPath(@NotNull final Module module) {
+    final CompilerModuleExtension compilerModuleExtension = CompilerModuleExtension.getInstance(module);
+    if (compilerModuleExtension != null) {
+      final VirtualFile outputPath = compilerModuleExtension.getCompilerOutputPath();
+      if (outputPath != null) {
+        return outputPath.getPath();
+      }
+    }
+    return null;
+  }
+
+  @NotNull
+  public static String scriptNameToClassName(final Project project, final String scriptName) {
+    final VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByPath(scriptName);
+    if (virtualFile != null) {
+      final PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
+      if (psiFile != null && psiFile instanceof JavaFxFile) {
+        final JavaFxPackageDefinition packageDefinition = ((JavaFxFile)psiFile).getPackageDefinition();
+        final String nameWithoutExtension = virtualFile.getNameWithoutExtension();
+        if (packageDefinition != null) {
+          final String packageName = packageDefinition.getName();
+          if (!"".equals(packageName)) {
+            return packageName + "." + nameWithoutExtension;
+          }
+        }
+        return nameWithoutExtension;
+      }
+    }
+    return scriptName;
+  }
+
+  public static JavaFxFacet addFacet(final Module module, final @Nullable Sdk sdk) {
+    final ModifiableFacetModel facetModel = FacetManager.getInstance(module).createModifiableModel();
+    final JavaFxFacet javaFxFacet = JavaFxFacet.FACET_TYPE
+      .createFacet(module, JavaFxFacet.FACET_TYPE.getDefaultFacetName(), JavaFxFacet.FACET_TYPE.createDefaultConfiguration(), null);
+    facetModel.addFacet(javaFxFacet);
+
+    if (sdk != null) {
+      javaFxFacet.getConfiguration().setJavaFxSdk(sdk);
+    }
+    facetModel.commit();
+    return javaFxFacet;
+  }
+
+  public static VirtualFile[] getModuleSourceRoots(final Module module) {
+    return ModuleRootManager.getInstance(module).getSourceRoots();
+  }
+}
diff --git a/src/org/jetbrains/javafx/actions/NewJavaFxScriptAction.java b/src/org/jetbrains/javafx/actions/NewJavaFxScriptAction.java
new file mode 100644 (file)
index 0000000..f6766e1
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx.actions;
+
+import com.intellij.facet.FacetManager;
+import com.intellij.ide.actions.CreateFileFromTemplateDialog;
+import com.intellij.ide.actions.JavaCreateTemplateInPackageAction;
+import com.intellij.ide.fileTemplates.FileTemplate;
+import com.intellij.ide.fileTemplates.FileTemplateManager;
+import com.intellij.ide.fileTemplates.JavaTemplateUtil;
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.actionSystem.DataKeys;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiFileFactory;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.javafx.JavaFxBundle;
+import org.jetbrains.javafx.JavaFxFileType;
+import org.jetbrains.javafx.facet.JavaFxFacet;
+import org.jetbrains.javafx.lang.psi.JavaFxFile;
+
+import javax.swing.*;
+import java.util.Properties;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @author: Alexey.Ivanov
+ */
+public class NewJavaFxScriptAction extends JavaCreateTemplateInPackageAction<JavaFxFile> implements DumbAware {
+  private static final String NAME_TEMPLATE_PROPERTY = "NAME";
+
+  private static String getFileName(final String fileName) {
+    return fileName + "." + JavaFxFileType.INSTANCE.getDefaultExtension();
+  }
+
+  protected NewJavaFxScriptAction() {
+    super(JavaFxBundle.message("javafx.script"), JavaFxBundle.message("create.new.javafx.script"), JavaFxFileType.INSTANCE.getIcon(), true);
+  }
+
+  @Override
+  protected boolean isAvailable(final DataContext dataContext) {
+    final Module module = DataKeys.MODULE.getData(dataContext);
+    return super.isAvailable(dataContext) && module != null && FacetManager.getInstance(module).getFacetByType(JavaFxFacet.ID) != null;
+  }
+
+  @Override
+  protected PsiElement getNavigationElement(@NotNull final JavaFxFile createdElement) {
+    return createdElement;
+  }
+
+  @Override
+  protected void doCheckCreate(final PsiDirectory dir, final String className, final String templateName)
+    throws IncorrectOperationException {
+    dir.checkCreateFile(getFileName(className));
+  }
+
+  @Override
+  protected void buildDialog(Project project, PsiDirectory directory, CreateFileFromTemplateDialog.Builder builder) {
+    final Icon icon = getTemplatePresentation().getIcon();
+    builder.setTitle(getTemplatePresentation().getText())
+      .addKind(JavaFxBundle.message("javafx.class"), icon, "JavaFX Class")
+      .addKind(JavaFxBundle.message("javafx.file"), icon, "JavaFX File")
+      .addKind(JavaFxBundle.message("javafx.stage"), icon, "JavaFX Stage");
+  }
+
+
+  @Override
+  protected String getActionName(final PsiDirectory directory, final String newName, final String templateName) {
+    return getTemplatePresentation().getText();
+  }
+
+  @Override
+  protected JavaFxFile doCreate(final PsiDirectory directory,
+                                final String className,
+                                final String templateName) throws IncorrectOperationException {
+    final FileTemplate template = FileTemplateManager.getInstance().getInternalTemplate(templateName);
+    final Properties properties = new Properties(FileTemplateManager.getInstance().getDefaultProperties());
+    JavaTemplateUtil.setPackageNameAttribute(properties, directory);
+    properties.setProperty(NAME_TEMPLATE_PROPERTY, className);
+    final String text;
+    try {
+      text = template.getText(properties);
+    }
+    catch (Exception e) {
+      throw new RuntimeException("Unable to load template for " + FileTemplateManager.getInstance().internalTemplateToSubject(templateName),
+                                 e);
+    }
+
+    final PsiFileFactory factory = PsiFileFactory.getInstance(directory.getProject());
+    final PsiFile file = factory.createFileFromText(getFileName(className), text);
+
+    return (JavaFxFile)directory.add(file);
+  }
+}
diff --git a/src/org/jetbrains/javafx/actions/intentions/RemovePrivateQuickFix.java b/src/org/jetbrains/javafx/actions/intentions/RemovePrivateQuickFix.java
new file mode 100644 (file)
index 0000000..3f69683
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx.actions.intentions;
+
+import com.intellij.codeInspection.IntentionAndQuickFixAction;
+import com.intellij.lang.ASTNode;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.javafx.JavaFxBundle;
+import org.jetbrains.javafx.lang.lexer.JavaFxTokenTypes;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @author: Alexey.Ivanov
+ */
+public class RemovePrivateQuickFix extends IntentionAndQuickFixAction {
+  @NotNull
+  @Override
+  public String getName() {
+    return JavaFxBundle.message("INTN.remove.private.keyword");
+  }
+
+  @NotNull
+  @Override
+  public String getFamilyName() {
+    return JavaFxBundle.message("INTN.remove.private.keyword");
+  }
+
+  @Override
+  public boolean isAvailable(@NotNull Project project, @Nullable Editor editor, PsiFile file) {
+    if (editor != null) {
+      final PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
+      if (element != null) {
+        final ASTNode node = element.getNode();
+        return node != null && node.getElementType() == JavaFxTokenTypes.PRIVATE_KEYWORD;
+      }
+    }
+    return false;
+  }
+
+  @Override
+  public void applyFix(@NotNull final Project project, final PsiFile file, @Nullable final Editor editor)
+    throws IncorrectOperationException {
+    if (editor != null) {
+      final PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
+      if (element != null) {
+        element.delete();
+      }
+    }
+  }
+}
diff --git a/src/org/jetbrains/javafx/build/JavaFxCompiler.java b/src/org/jetbrains/javafx/build/JavaFxCompiler.java
new file mode 100644 (file)
index 0000000..8618e8e
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx.build;
+
+import com.intellij.compiler.CompilerException;
+import com.intellij.compiler.impl.CompilerUtil;
+import com.intellij.facet.FacetManager;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompileScope;
+import com.intellij.openapi.compiler.CompilerMessageCategory;
+import com.intellij.openapi.compiler.TranslatingCompiler;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.Chunk;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.javafx.JavaFxBundle;
+import org.jetbrains.javafx.JavaFxFileType;
+import org.jetbrains.javafx.facet.JavaFxFacet;
+import org.jetbrains.javafx.sdk.JavaFxSdkType;
+import org.jetbrains.javafx.sdk.JavaFxSdkUtil;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @author: Alexey.Ivanov
+ */
+public class JavaFxCompiler implements TranslatingCompiler {
+  private static final Logger LOG = Logger.getInstance("#org.jetbrains.javafx.build.JavaFxCompiler");
+
+  @Override
+  public boolean isCompilableFile(VirtualFile file, CompileContext context) {
+    return file.getFileType() instanceof JavaFxFileType;
+  }
+
+  @Override
+  public void compile(CompileContext context, Chunk<Module> moduleChunk, VirtualFile[] files, OutputSink sink) {
+    Map<Module, List<VirtualFile>> mapModulesToVirtualFiles;
+    if (moduleChunk.getNodes().size() == 1) {
+      mapModulesToVirtualFiles = Collections.singletonMap(moduleChunk.getNodes().iterator().next(), Arrays.asList(files));
+    }
+    else {
+      mapModulesToVirtualFiles = CompilerUtil.buildModuleToFilesMap(context, files);
+    }
+    for (final Module module : moduleChunk.getNodes()) {
+      final List<VirtualFile> moduleFiles = mapModulesToVirtualFiles.get(module);
+      if (moduleFiles == null) {
+        continue;
+      }
+      final JavaFxFacet facet = FacetManager.getInstance(module).getFacetByType(JavaFxFacet.ID);
+      if (facet == null) {
+        continue;
+      }
+      final Sdk sdk = JavaFxSdkUtil.getSdk(facet);
+      final JavaFxCompilerHandler compilerHandler = new JavaFxCompilerHandler(context, sdk, module.getProject());
+      context.getProgressIndicator().checkCanceled();
+      try {
+        compilerHandler.runCompiler(context, module, moduleFiles);
+      }
+      catch (CompilerException e) {
+        LOG.debug(e);
+        context.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1);
+      }
+      finally {
+        compilerHandler.compileFinished();
+      }
+      sink.add(compilerHandler.getCompilerOutputPath(), compilerHandler.getOutputItems(), VirtualFile.EMPTY_ARRAY);
+    }
+  }
+
+  @NotNull
+  @Override
+  public String getDescription() {
+    return "JavaFxCompiler";
+  }
+
+  @Override
+  public boolean validateConfiguration(CompileScope scope) {
+    final Module[] modules = scope.getAffectedModules();
+    for (final Module module : modules) {
+      final JavaFxFacet facet = FacetManager.getInstance(module).getFacetByType(JavaFxFacet.ID);
+      if (facet == null) {
+        continue;
+      }
+      final Sdk sdk = JavaFxSdkUtil.getSdk(facet);
+      if (sdk == null || !(sdk.getSdkType() instanceof JavaFxSdkType)) {
+        ApplicationManager.getApplication().invokeLater(new Runnable() {
+          public void run() {
+            Messages.showErrorDialog(module.getProject(),
+                                     JavaFxBundle.message("javafx.sdk.is.not.set.facet.$1.module.$2", facet.getName(), module.getName()),
+                                     JavaFxBundle.message("javafx.compiler.problem"));
+          }
+        });
+        return false;
+      }
+    }
+    return true;
+  }
+}
diff --git a/src/org/jetbrains/javafx/build/JavaFxCompilerHandler.java b/src/org/jetbrains/javafx/build/JavaFxCompilerHandler.java
new file mode 100644 (file)
index 0000000..8e4c259
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx.build;
+
+import com.intellij.compiler.CompilerException;
+import com.intellij.compiler.impl.javaCompiler.ModuleChunk;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompilerMessageCategory;
+import com.intellij.openapi.compiler.TranslatingCompiler;
+import com.intellij.openapi.compiler.ex.CompileContextEx;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.Chunk;
+import com.intellij.util.PathUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.javafx.JavaFxUtil;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @author: Alexey.Ivanov
+ */
+public class JavaFxCompilerHandler {
+  private static final Logger LOG = Logger.getInstance("#org.jetbrains.javafx.build.JavaFxCompilerHandler");
+
+  private final CompileContext myContext;
+  private final Sdk mySdk;
+  private final Project myProject;
+  private String myCompilerOutputPath;
+  private List<File> myTempFiles = new ArrayList<File>();
+
+  public JavaFxCompilerHandler(CompileContext context, Sdk sdk, Project project) {
+    myContext = context;
+    mySdk = sdk;
+    myProject = project;
+  }
+
+  public void runCompiler(final CompileContext context, final Module module, final List<VirtualFile> files) throws CompilerException {
+    LOG.debug("JavaFX SDK version: " + mySdk.getVersionString());
+    final List<String> command = new ArrayList<String>();
+    command.add(mySdk.getHomePath() + "/bin/javafxc");
+    command.add("-cp");
+    command.add(createClasspath(context, module));
+    myCompilerOutputPath = JavaFxUtil.getCompilerOutputPath(module);
+    if (myCompilerOutputPath != null) {
+      command.add("-d");
+      command.add(myCompilerOutputPath);
+    }
+    command.add(createSourcePathCommand(files));
+    LOG.debug("Compilation command: " + command);
+
+    final ProcessBuilder builder = new ProcessBuilder(command);
+    builder.redirectErrorStream(true);
+    try {
+      final Process process = builder.start();
+      readProcessOutput(process);
+    }
+    catch (IOException e) {
+      myContext.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1);
+    }
+  }
+
+  private String createClasspath(final CompileContext context, final Module module) throws CompilerException {
+    final ModuleChunk chunk =
+      new ModuleChunk((CompileContextEx)context, new Chunk<Module>(module), Collections.<Module, List<VirtualFile>>emptyMap());
+    final String compilationClasspath = chunk.getCompilationClasspath();
+    LOG.debug("Classpath: " + compilationClasspath);
+    return compilationClasspath;
+  }
+
+  private String createSourcePathCommand(final List<VirtualFile> files) throws CompilerException {
+    try {
+      final File tempFile = createTempFile("idea_javafxc_src");
+      final PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(tempFile)));
+      try {
+        for (VirtualFile file : files) {
+          writer.println(PathUtil.getLocalPath(file));
+          LOG.debug("Source file: " + file.getPath());
+        }
+      }
+      finally {
+        writer.close();
+      }
+      return ("@" + tempFile.getAbsolutePath());
+    }
+    catch (IOException e) {
+      throw new CompilerException(e.getMessage(), e);
+    }
+  }
+
+  private File createTempFile(final String prefix) throws IOException {
+    final File tempFile = FileUtil.createTempFile(prefix, ".tmp");
+    tempFile.deleteOnExit();
+    myTempFiles.add(tempFile);
+    return tempFile;
+  }
+
+  @Nullable
+  public String getCompilerOutputPath() {
+    return myCompilerOutputPath;
+  }
+
+  // TODO:
+
+  @NotNull
+  public Collection<TranslatingCompiler.OutputItem> getOutputItems() {
+    return Collections.emptyList();
+  }
+
+  public void compileFinished() {
+    FileUtil.asyncDelete(myTempFiles);
+    myTempFiles.clear();
+  }
+
+  private void readProcessOutput(final Process process) throws IOException {
+    try {
+      final InputStreamReader reader = new InputStreamReader(process.getInputStream());
+      try {
+        final StringBuilder builder = new StringBuilder();
+        final char[] buf = new char[2048];
+        int read = reader.read(buf);
+        while (read >= 0) {
+          final String output = new String(buf, 0, read);
+          builder.append(output);
+          read = reader.read(buf);
+        }
+        handleOutput(builder.toString());
+      }
+      finally {
+        cancel(process);
+        reader.close();
+      }
+    }
+    catch (IOException e) {
+      myContext.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1);
+    }
+  }
+
+  private static void cancel(Process process) {
+    if (process != null) {
+      process.destroy();
+    }
+  }
+
+  private void handleOutput(final String output) {
+    // TODO: better errors parsing
+    LOG.debug("Compiler output: " + output);
+    final Pattern errorPattern = Pattern.compile("((?:[A-Z]:\\\\)?[\\.\\w\\\\/]*):(\\d*): (.*)");
+    final String[] outputLines = output.split("[\\n\\r]");
+    for (String outputLine : outputLines) {
+      if (StringUtil.isEmptyOrSpaces(outputLine)) {
+        continue;
+      }
+      final Matcher matcher = errorPattern.matcher(outputLine);
+      if (matcher.matches()) {
+        final String file = matcher.group(1);
+        final String line = matcher.group(2);
+        String message = matcher.group(3);
+        final String column = "0";
+
+        CompilerMessageCategory messageCategory = CompilerMessageCategory.ERROR;
+        if (StringUtil.startsWith(message, "warning:")) {
+          messageCategory = CompilerMessageCategory.WARNING;
+          message = message.substring(9);
+        }
+        final ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
+        final VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByPath(file);
+        final VirtualFile relativeFile = VfsUtil.findRelativeFile(file, projectFileIndex.getSourceRootForFile(virtualFile));
+        myContext.addMessage(messageCategory, message, relativeFile != null ? relativeFile.getUrl() : null,
+                             line != null ? Integer.parseInt(line) : 0, column != null ? Integer.parseInt(column) : 0);
+        LOG.debug("Message: " + message);
+      }
+      else {
+        //myContext.addMessage(CompilerMessageCategory.INFORMATION, output, null, -1, -1);
+      }
+    }
+  }
+}
diff --git a/src/org/jetbrains/javafx/build/JavaFxCompilerLoader.java b/src/org/jetbrains/javafx/build/JavaFxCompilerLoader.java
new file mode 100644 (file)
index 0000000..dfcf43e
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx.build;
+
+import com.intellij.openapi.compiler.CompilerManager;
+import com.intellij.openapi.components.AbstractProjectComponent;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.StdFileTypes;
+import com.intellij.openapi.project.Project;
+import com.intellij.util.containers.HashSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.javafx.JavaFxFileType;
+
+import java.util.Arrays;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @author: Alexey.Ivanov
+ */
+public class JavaFxCompilerLoader extends AbstractProjectComponent {
+  protected JavaFxCompilerLoader(Project project) {
+    super(project);
+  }
+
+  @Override
+  public void projectOpened() {
+    final CompilerManager compilerManager = CompilerManager.getInstance(myProject);
+    compilerManager.addTranslatingCompiler(new JavaFxCompiler(),
+                                           new HashSet<FileType>(Arrays.asList(JavaFxFileType.INSTANCE, StdFileTypes.CLASS)),
+                                           new HashSet<FileType>(Arrays.asList(StdFileTypes.CLASS)));
+  }
+
+  @NotNull
+  @Override
+  public String getComponentName() {
+    return "JavaFxCompilerLoader";
+  }
+}
diff --git a/src/org/jetbrains/javafx/codeInsight/completion/JavaFxKeywordCompletionContributor.java b/src/org/jetbrains/javafx/codeInsight/completion/JavaFxKeywordCompletionContributor.java
new file mode 100644 (file)
index 0000000..74b5b85
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx.codeInsight.completion;
+
+import com.intellij.codeInsight.completion.*;
+import com.intellij.codeInsight.lookup.LookupElementBuilder;
+import com.intellij.patterns.PsiElementPattern;
+import com.intellij.psi.PsiElement;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.ProcessingContext;
+import com.intellij.util.containers.HashSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.javafx.JavaFxLanguage;
+import org.jetbrains.javafx.lang.psi.JavaFxBlockExpression;
+import org.jetbrains.javafx.lang.psi.JavaFxClassDefinition;
+import org.jetbrains.javafx.lang.psi.JavaFxFile;
+import org.jetbrains.javafx.lang.psi.JavaFxLoopExpression;
+
+import java.util.Collection;
+import java.util.Set;
+
+import static com.intellij.patterns.PlatformPatterns.psiElement;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @author: Alexey.Ivanov
+ */
+public class JavaFxKeywordCompletionContributor extends CompletionContributor {
+  private static final PsiElementPattern.Capture<PsiElement> JAVA_FX_ELEMENT_CAPTURE =
+    psiElement().withLanguage(JavaFxLanguage.getInstance());
+
+  private static final Set<String> COMMON_MODIFIERS = new HashSet<String>();
+  private static final Set<String> SCRIPT_ITEMS = new HashSet<String>();
+  private static final Set<String> EXPRESSIONS = new HashSet<String>();
+  private static final Set<String> VALUE_EXPRESSIONS = new HashSet<String>();
+  private static final Set<String> INITIALIZER_PARTS = new HashSet<String>();
+
+  static {
+    COMMON_MODIFIERS.add("abstract");
+    COMMON_MODIFIERS.add("bound");
+    COMMON_MODIFIERS.add("public");
+    COMMON_MODIFIERS.add("public-read");
+    COMMON_MODIFIERS.add("protected");  // ?
+    COMMON_MODIFIERS.add("package");
+
+    SCRIPT_ITEMS.add("import");
+    SCRIPT_ITEMS.add("function");
+    SCRIPT_ITEMS.add("class");
+
+    EXPRESSIONS.add("insert");
+    EXPRESSIONS.add("delete");
+    EXPRESSIONS.add("while");
+    EXPRESSIONS.add("throw");
+    EXPRESSIONS.add("try");
+
+    VALUE_EXPRESSIONS.add("if");
+    VALUE_EXPRESSIONS.add("for");
+    VALUE_EXPRESSIONS.add("new");
+    VALUE_EXPRESSIONS.add("def");
+    VALUE_EXPRESSIONS.add("var");
+    VALUE_EXPRESSIONS.add("insert");
+    VALUE_EXPRESSIONS.add("delete");
+    VALUE_EXPRESSIONS.add("reverse");
+    VALUE_EXPRESSIONS.add("return");
+
+    INITIALIZER_PARTS.add("bind");
+    INITIALIZER_PARTS.add("false");
+    INITIALIZER_PARTS.add("function");
+    INITIALIZER_PARTS.add("new");
+    INITIALIZER_PARTS.add("null");
+    INITIALIZER_PARTS.add("true");
+  }
+
+  private static final PsiElementPattern.Capture<PsiElement> AT_TOP_LEVEL =
+    JAVA_FX_ELEMENT_CAPTURE.withSuperParent(2, JavaFxFile.class).andNot(psiElement().inside(JavaFxClassDefinition.class));
+  private static final PsiElementPattern.Capture<PsiElement> IN_BLOCK =
+    JAVA_FX_ELEMENT_CAPTURE.withSuperParent(2, JavaFxBlockExpression.class);
+  private static final PsiElementPattern.Capture<PsiElement> IN_LOOP = JAVA_FX_ELEMENT_CAPTURE.inside(JavaFxLoopExpression.class);
+  private static final PsiElementPattern.Capture<PsiElement> IN_CLASS = JAVA_FX_ELEMENT_CAPTURE.withParent(JavaFxClassDefinition.class);
+  private static final PsiElementPattern.Capture<PsiElement> AFTER_EQ = JAVA_FX_ELEMENT_CAPTURE.afterLeaf("=");
+
+  public JavaFxKeywordCompletionContributor() {
+    topLevel();
+    inBlock();
+    inLoop();
+    inClass();
+    afterEq();
+  }
+
+  private void topLevel() {
+    final Set<String> keywords = new HashSet<String>(COMMON_MODIFIERS);
+    keywords.addAll(SCRIPT_ITEMS);
+    keywords.addAll(EXPRESSIONS);
+    keywords.addAll(VALUE_EXPRESSIONS);
+    keywords.add("mixin");
+    extend(CompletionType.BASIC, psiElement().and(AT_TOP_LEVEL), provider(keywords));
+  }
+
+  private void inBlock() {
+    final Set<String> keywords = new HashSet<String>(EXPRESSIONS);
+    keywords.addAll(VALUE_EXPRESSIONS);
+    extend(CompletionType.BASIC, psiElement().and(IN_BLOCK), provider(keywords));
+  }
+
+  private void inLoop() {
+    extend(CompletionType.BASIC, psiElement().and(IN_LOOP), provider("break", "continue"));
+  }
+
+  private void inClass() {
+    final Set<String> keywords = new HashSet<String>(COMMON_MODIFIERS);
+    keywords.add("public-init");
+    keywords.add("override");
+    keywords.add("def");
+    keywords.add("var");
+    keywords.add("function");
+    keywords.add("init");
+    keywords.add("post-init");
+    extend(CompletionType.BASIC, psiElement().and(IN_CLASS), provider(keywords));
+  }
+
+  private void afterEq() {
+    extend(CompletionType.BASIC, psiElement().and(AFTER_EQ), provider(INITIALIZER_PARTS));
+  }
+
+  private static CompletionProvider<CompletionParameters> provider(@NotNull final Collection<String> keywords) {
+    return provider(ArrayUtil.toStringArray(keywords));
+  }
+
+  private static CompletionProvider<CompletionParameters> provider(@NotNull final String... keywords) {
+    return new CompletionProvider<CompletionParameters>() {
+      @Override
+      protected void addCompletions(@NotNull final CompletionParameters parameters,
+                                    final ProcessingContext context,
+                                    @NotNull final CompletionResultSet result) {
+        for (String keyword : keywords) {
+          result.addElement(LookupElementBuilder.create(keyword).setBold());
+        }
+      }
+    };
+  }
+}
diff --git a/src/org/jetbrains/javafx/codeInsight/editorActions/JavaFxQuoteHandler.java b/src/org/jetbrains/javafx/codeInsight/editorActions/JavaFxQuoteHandler.java
new file mode 100644 (file)
index 0000000..9f45de6
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx.codeInsight.editorActions;
+
+import com.intellij.codeInsight.editorActions.JavaLikeQuoteHandler;
+import com.intellij.codeInsight.editorActions.SimpleTokenSetQuoteHandler;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.tree.TokenSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.javafx.lang.lexer.JavaFxTokenTypes;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @author: Alexey.Ivanov
+ */
+public class JavaFxQuoteHandler extends SimpleTokenSetQuoteHandler implements JavaLikeQuoteHandler {
+  public JavaFxQuoteHandler() {
+    super(JavaFxTokenTypes.STRINGS);
+  }
+
+  public TokenSet getConcatenatableStringTokenTypes() {
+    return JavaFxTokenTypes.STRINGS;
+  }
+
+  public String getStringConcatenationOperatorRepresentation() {
+    return "";
+  }
+
+  public TokenSet getStringTokenTypes() {
+    return myLiteralTokenSet;
+  }
+
+  public boolean isAppropriateElementTypeForLiteral(@NotNull IElementType tokenType) {
+    return JavaFxTokenTypes.WHITESPACES.contains(tokenType) ||
+           JavaFxTokenTypes.COMMENTS.contains(tokenType) ||
+           JavaFxTokenTypes.ALL_STRINGS.contains(tokenType) ||
+           tokenType == JavaFxTokenTypes.SEMICOLON ||
+           tokenType == JavaFxTokenTypes.COMMA ||
+           tokenType == JavaFxTokenTypes.RPAREN ||
+           tokenType == JavaFxTokenTypes.RBRACK ||
+           tokenType == JavaFxTokenTypes.RBRACE;
+  }
+
+  public boolean needParenthesesAroundConcatenation(PsiElement element) {
+    return false;
+  }
+}
diff --git a/src/org/jetbrains/javafx/codeInsight/navigation/JavaFxGotoBreakContinueHandler.java b/src/org/jetbrains/javafx/codeInsight/navigation/JavaFxGotoBreakContinueHandler.java
new file mode 100644 (file)
index 0000000..91e1b3a
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx.codeInsight.navigation;
+
+import com.intellij.codeInsight.navigation.actions.GotoDeclarationHandler;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.util.PsiTreeUtil;
+import org.jetbrains.javafx.JavaFxLanguage;
+import org.jetbrains.javafx.lang.psi.*;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @author: Alexey.Ivanov
+ */
+public class JavaFxGotoBreakContinueHandler implements GotoDeclarationHandler {
+  public PsiElement getGotoDeclarationTarget(PsiElement sourceElement) {
+    if (sourceElement == null || !(sourceElement.getLanguage() instanceof JavaFxLanguage)) {
+      return null;
+    }
+    final JavaFxBreakExpression breakExpression = PsiTreeUtil.getParentOfType(sourceElement, JavaFxBreakExpression.class, false);
+    if (breakExpression != null) {
+      final JavaFxLoopExpression parentExpression = PsiTreeUtil.getParentOfType(breakExpression, JavaFxLoopExpression.class);
+      if (parentExpression == null) {
+        return null;
+      }
+      PsiElement nextSibling = PsiTreeUtil.getNextSiblingOfType(parentExpression, JavaFxExpression.class);
+      if (nextSibling != null) {
+        return nextSibling;
+      }
+      nextSibling = parentExpression.getNextSibling();
+      if (nextSibling != null) {
+        return nextSibling;
+      }
+
+      final JavaFxVariableDeclaration variableDeclaration = PsiTreeUtil.getParentOfType(parentExpression, JavaFxVariableDeclaration.class);
+      if (variableDeclaration != null) {
+        nextSibling = PsiTreeUtil.getNextSiblingOfType(variableDeclaration, JavaFxExpression.class);
+        if (nextSibling != null) {
+          return nextSibling;
+        }
+      }
+
+      final JavaFxExpression body = parentExpression.getBody();
+      assert body != null;
+      return body.getLastChild();
+    }
+    final JavaFxContinueExpression continueExpression = PsiTreeUtil.getParentOfType(sourceElement, JavaFxContinueExpression.class, false);
+    if (continueExpression != null) {
+      return PsiTreeUtil.getParentOfType(continueExpression, JavaFxLoopExpression.class);
+    }
+    return null;
+  }
+}
diff --git a/src/org/jetbrains/javafx/editor/JavaFxBraceMatcher.java b/src/org/jetbrains/javafx/editor/JavaFxBraceMatcher.java
new file mode 100644 (file)
index 0000000..6c2a8b3
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx.editor;
+
+import com.intellij.lang.BracePair;
+import com.intellij.lang.PairedBraceMatcher;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.javafx.lang.JavaFxElementType;
+import org.jetbrains.javafx.lang.lexer.JavaFxTokenTypes;
+
+/**
+ * Brace matcher for JavaFx
+ *
+ * @author andrey, Alexey.Ivanov
+ */
+public class JavaFxBraceMatcher implements PairedBraceMatcher {
+  private static final BracePair[] PAIRS = {new BracePair(JavaFxTokenTypes.LPAREN, JavaFxTokenTypes.RPAREN, false),
+    new BracePair(JavaFxTokenTypes.LBRACK, JavaFxTokenTypes.RBRACK, false),
+    new BracePair(JavaFxTokenTypes.LBRACE, JavaFxTokenTypes.RBRACE, true)};
+
+  public BracePair[] getPairs() {
+    return PAIRS;
+  }
+
+  public boolean isPairedBracesAllowedBeforeType(@NotNull IElementType braceType, @Nullable IElementType tokenType) {
+    if (!(tokenType instanceof JavaFxElementType)) {
+      return true;
+    }
+    return JavaFxTokenTypes.WHITESPACES.contains(tokenType) ||
+           JavaFxTokenTypes.COMMENTS.contains(tokenType) ||
+           tokenType == JavaFxTokenTypes.SEMICOLON ||
+           tokenType == JavaFxTokenTypes.COMMA ||
+           tokenType == JavaFxTokenTypes.RPAREN ||
+           tokenType == JavaFxTokenTypes.RBRACK ||
+           tokenType == JavaFxTokenTypes.RBRACE ||
+           tokenType == JavaFxTokenTypes.LBRACE;
+  }
+
+  public int getCodeConstructStart(PsiFile file, int openingBraceOffset) {
+    return openingBraceOffset;
+  }
+}
diff --git a/src/org/jetbrains/javafx/editor/JavaFxCommenter.java b/src/org/jetbrains/javafx/editor/JavaFxCommenter.java
new file mode 100644 (file)
index 0000000..6835985
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx.editor;
+
+import com.intellij.lang.CodeDocumentationAwareCommenter;
+import com.intellij.psi.PsiComment;
+import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.javafx.lang.lexer.JavaFxTokenTypes;
+
+/**
+ * Commenting support
+ *
+ * @author andrey
+ */
+public class JavaFxCommenter implements CodeDocumentationAwareCommenter, JavaFxTokenTypes {
+  public String getLineCommentPrefix() {
+    return "//";
+  }
+
+  public String getBlockCommentPrefix() {
+    return "/*";
+  }
+
+  public String getBlockCommentSuffix() {
+    return "*/";
+  }
+
+  public String getCommentedBlockCommentPrefix() {
+    return null;
+  }
+
+  public String getCommentedBlockCommentSuffix() {
+    return null;
+  }
+
+  @Nullable
+  public IElementType getLineCommentTokenType() {
+    return END_OF_LINE_COMMENT;
+  }
+
+  @Nullable
+  public IElementType getBlockCommentTokenType() {
+    return C_STYLE_COMMENT;
+  }
+
+  @Nullable
+  public IElementType getDocumentationCommentTokenType() {
+    return DOC_COMMENT;
+  }
+
+  @Nullable
+  public String getDocumentationCommentPrefix() {
+    return "/**";
+  }
+
+  @Nullable
+  public String getDocumentationCommentLinePrefix() {
+    return "*";
+  }
+
+  @Nullable
+  public String getDocumentationCommentSuffix() {
+    return "*/";
+  }
+
+  public boolean isDocumentationComment(PsiComment element) {
+    return element.getText().startsWith(getDocumentationCommentPrefix());
+  }
+}
diff --git a/src/org/jetbrains/javafx/editor/JavaFxFoldingBuilder.java b/src/org/jetbrains/javafx/editor/JavaFxFoldingBuilder.java
new file mode 100644 (file)
index 0000000..c5d2e79
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx.editor;
+
+import com.intellij.codeInsight.folding.JavaCodeFoldingSettings;
+import com.intellij.lang.ASTNode;
+import com.intellij.lang.folding.FoldingBuilder;
+import com.intellij.lang.folding.FoldingDescriptor;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.tree.TokenSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.javafx.lang.lexer.JavaFxTokenTypes;
+import org.jetbrains.javafx.lang.parser.JavaFxElementTypes;
+import org.jetbrains.javafx.lang.psi.JavaFxFile;
+import org.jetbrains.javafx.lang.psi.JavaFxImportList;
+import org.jetbrains.javafx.lang.psi.JavaFxImportStatement;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Code folding support
+ *
+ * @author andrey, Alexey.Ivanov
+ */
+public class JavaFxFoldingBuilder implements FoldingBuilder, DumbAware {
+  private static final TokenSet DEFINITIONS = TokenSet.create(
+    JavaFxElementTypes.OBJECT_LITERAL,
+    JavaFxElementTypes.FUNCTION_DEFINITION,
+    JavaFxElementTypes.VARIABLE_DECLARATION,
+    JavaFxElementTypes.CLASS_DEFINITION);
+
+  @NotNull
+  public FoldingDescriptor[] buildFoldRegions(@NotNull final ASTNode node, @NotNull final Document document) {
+    final List<FoldingDescriptor> descriptors = new ArrayList<FoldingDescriptor>();
+    appendDescriptors(node.getPsi(), document, descriptors);
+    return descriptors.toArray(new FoldingDescriptor[descriptors.size()]);
+  }
+
+  private static void appendDescriptorsForImports(final JavaFxFile fxFile, final List<FoldingDescriptor> descriptors) {
+    final JavaFxImportList[] importLists = fxFile.getImportLists();
+    for (JavaFxImportList importList : importLists) {
+      final JavaFxImportStatement[] importStatements = importList.getImportStatements();
+      if (importStatements.length > 1) {
+        final int tail = "import ".length();
+        descriptors.add(new FoldingDescriptor(importList.getNode(), new TextRange(importList.getTextOffset() + tail,
+                                                                                            importList.getTextRange()
+                                                                                              .getEndOffset())));
+      }
+    }
+  }
+
+  private static void appendDescriptors(PsiElement element, Document document, List<FoldingDescriptor> descriptors) {
+    final ASTNode node = element.getNode();
+    if (node == null) {
+      return;
+    }
+    final IElementType type = node.getElementType();
+
+    // comments
+    if ((type == JavaFxTokenTypes.C_STYLE_COMMENT || type == JavaFxTokenTypes.DOC_COMMENT) &&
+        isMultiline(element, document) &&
+        isWellEndedComment(element)) {
+      descriptors.add(new FoldingDescriptor(node, node.getTextRange()));
+    }
+    else if (DEFINITIONS.contains(type) && isMultiline(element, document)) {
+      int leftBracePosition = element.getText().indexOf('{');
+      if (leftBracePosition != -1) {
+        descriptors.add(new FoldingDescriptor(node,
+                                              new TextRange(node.getStartOffset() + leftBracePosition,
+                                                            node.getTextRange().getEndOffset())));
+      }
+    }
+
+    PsiElement child = element.getFirstChild();
+    while (child != null) {
+      appendDescriptors(child, document, descriptors);
+      child = child.getNextSibling();
+    }
+
+    if (element instanceof JavaFxFile) {
+      appendDescriptorsForImports((JavaFxFile)element, descriptors);
+    }
+  }
+
+  private static boolean isWellEndedComment(final PsiElement element) {
+    return element.getText().endsWith("*/");
+  }
+
+  private static boolean isMultiline(PsiElement element, Document document) {
+    final int start = document.getLineNumber(element.getTextOffset());
+    final int end = document.getLineNumber(element.getTextRange().getEndOffset());
+    return start != end;
+  }
+
+  @Nullable
+  public String getPlaceholderText(@NotNull final ASTNode node) {
+    final IElementType elementType = node.getElementType();
+    if (elementType == JavaFxTokenTypes.C_STYLE_COMMENT) {
+      return "/*...*/";
+    }
+    if (elementType == JavaFxTokenTypes.DOC_COMMENT) {
+      return "/**...*/";
+    }
+    if (elementType == JavaFxElementTypes.IMPORT_LIST) {
+      return "...";
+    }
+    if (DEFINITIONS.contains(elementType)) {
+      return "{...}";
+    }
+    return null;
+  }
+
+  public boolean isCollapsedByDefault(@NotNull final ASTNode node) {
+    if (node.getElementType() == JavaFxElementTypes.IMPORT_LIST) {
+      return JavaCodeFoldingSettings.getInstance().isCollapseImports();
+    }
+    if (node.getElementType() == JavaFxTokenTypes.C_STYLE_COMMENT) {
+      return JavaCodeFoldingSettings.getInstance().isCollapseFileHeader();
+    }
+    if (node.getElementType() == JavaFxTokenTypes.DOC_COMMENT) {
+      return JavaCodeFoldingSettings.getInstance().isCollapseJavadocs();
+    }
+    if (node.getElementType() == JavaFxElementTypes.FUNCTION_DEFINITION) {
+      return JavaCodeFoldingSettings.getInstance().isCollapseMethods();
+    }
+    return false;
+  }
+}
diff --git a/src/org/jetbrains/javafx/editor/JavaFxHighlighter.java b/src/org/jetbrains/javafx/editor/JavaFxHighlighter.java
new file mode 100644 (file)
index 0000000..06a6201
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx.editor;
+
+import com.intellij.lexer.Lexer;
+import com.intellij.openapi.editor.SyntaxHighlighterColors;
+import com.intellij.openapi.editor.colors.TextAttributesKey;
+import com.intellij.openapi.fileTypes.SyntaxHighlighterBase;
+import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.javafx.lang.lexer.JavaFxTokenTypes;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Higlighter of JavaFx syntax
+ *
+ * @author andrey, Alexey.Ivanov
+ */
+public class JavaFxHighlighter extends SyntaxHighlighterBase {
+  private static final Map<IElementType, TextAttributesKey> ATTRIBUTES = new HashMap<IElementType, TextAttributesKey>();
+  private static final TextAttributesKey CUSTOM_KEYWORD2_ATTRIBUTES =
+    TextAttributesKey.createTextAttributesKey("CUSTOM_KEYWORD2_ATTRIBUTES");
+
+  static {
+    fillMap(ATTRIBUTES, JavaFxTokenTypes.BLOCK_COMMENTS, SyntaxHighlighterColors.JAVA_BLOCK_COMMENT);
+    fillMap(ATTRIBUTES, JavaFxTokenTypes.LINE_COMMENTS, SyntaxHighlighterColors.LINE_COMMENT);
+    fillMap(ATTRIBUTES, JavaFxTokenTypes.ALL_WORDS, SyntaxHighlighterColors.KEYWORD);
+    fillMap(ATTRIBUTES, JavaFxTokenTypes.NUMBERS, SyntaxHighlighterColors.NUMBER);
+    fillMap(ATTRIBUTES, JavaFxTokenTypes.ALL_STRINGS, SyntaxHighlighterColors.STRING);
+    fillMap(ATTRIBUTES, JavaFxTokenTypes.BRACES, SyntaxHighlighterColors.BRACES);
+    //fillMap(ATTRIBUTES, JavaFxTokenTypes.TYPES, CUSTOM_KEYWORD2_ATTRIBUTES);
+  }
+
+  @NotNull
+  public Lexer getHighlightingLexer() {
+    return new JavaFxHighlightingLexer();
+  }
+
+  @NotNull
+  public TextAttributesKey[] getTokenHighlights(IElementType elementType) {
+    return pack(ATTRIBUTES.get(elementType));
+  }
+}
diff --git a/src/org/jetbrains/javafx/editor/JavaFxHighlightingLexer.java b/src/org/jetbrains/javafx/editor/JavaFxHighlightingLexer.java
new file mode 100644 (file)
index 0000000..119a95c
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx.editor;
+
+import org.jetbrains.javafx.lang.lexer.JavaFxFlexLexer;
+
+/**
+ * Highlighting lexer
+ *
+ * @author Alexey.Ivanov
+ */
+public class JavaFxHighlightingLexer extends JavaFxFlexLexer {
+}
diff --git a/src/org/jetbrains/javafx/facet/ExecutionModel.java b/src/org/jetbrains/javafx/facet/ExecutionModel.java
new file mode 100644 (file)
index 0000000..ed74229
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx.facet;
+
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileFilter;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.HashSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.javafx.sdk.JavaFxSdkUtil;
+
+import java.util.Collection;
+import java.util.Set;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @author: Alexey.Ivanov
+ */
+// TODO: adding Jars
+public enum ExecutionModel {
+  COMMON("shared", "javafxrt.jar"),
+  DESKTOP("desktop"),
+  MOBILE("mobile"),
+  TV("tv"),
+  PRISM("prism");
+
+  private final String myDirectoryName;
+  private final Set<String> myRootsNames;
+  private final VirtualFileFilter myFileFilter;
+
+  ExecutionModel(@NotNull final String directoryName, @NotNull final String... rootsNames) {
+    myDirectoryName = directoryName;
+    myRootsNames = new HashSet<String>();
+    ContainerUtil.addAll(myRootsNames, rootsNames);
+    myFileFilter = new VirtualFileFilter() {
+      public boolean accept(final VirtualFile f) {
+        if (f.isDirectory()) {
+          return false;
+        }
+        if (myRootsNames.contains(f.getName())) {
+          return true;
+        }
+        return false;
+      }
+    };
+  }
+
+  ExecutionModel(@NotNull final String directoryName) {
+    myDirectoryName = directoryName;
+    myRootsNames = null;
+    myFileFilter = new VirtualFileFilter() {
+      public boolean accept(final VirtualFile f) {
+        if (f.isDirectory()) {
+          return false;
+        }
+        if (StringUtil.endsWith(f.getName(), ".jar")) {
+          return true;
+        }
+        return false;
+      }
+    };
+  }
+
+  @NotNull
+  public VirtualFile[] getRoots(@NotNull final Sdk sdk) {
+    final VirtualFile libDirectory = JavaFxSdkUtil.getLibDirectory(sdk);
+    if (libDirectory == null) {
+      return VirtualFile.EMPTY_ARRAY;
+    }
+    final VirtualFile profileDirectory = libDirectory.findChild(myDirectoryName);
+    if (profileDirectory == null) {
+      return VirtualFile.EMPTY_ARRAY;
+    }
+    final Collection<VirtualFile> res = new HashSet<VirtualFile>();
+    for (VirtualFile file : profileDirectory.getChildren()) {
+      if (myFileFilter.accept(file)) {
+        res.add(JavaFxSdkUtil.findInJar(file, ""));
+      }
+    }
+    return VfsUtil.toVirtualFileArray(res);
+  }
+}
diff --git a/src/org/jetbrains/javafx/facet/JavaFxFacet.java b/src/org/jetbrains/javafx/facet/JavaFxFacet.java
new file mode 100644 (file)
index 0000000..914608c
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx.facet;
+
+import com.intellij.facet.Facet;
+import com.intellij.facet.FacetType;
+import com.intellij.facet.FacetTypeId;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.LibraryOrderEntry;
+import com.intellij.openapi.roots.ModifiableRootModel;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.roots.OrderEntry;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
+import com.intellij.openapi.util.text.StringUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.javafx.sdk.JavaFxSdkListener;
+import org.jetbrains.javafx.sdk.JavaFxSdkUtil;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @author: Alexey.Ivanov
+ */
+public class JavaFxFacet extends Facet<JavaFxFacetConfiguration> {
+  public static final FacetTypeId<JavaFxFacet> ID = new FacetTypeId<JavaFxFacet>("javafx");
+  public static final FacetType<JavaFxFacet, JavaFxFacetConfiguration> FACET_TYPE = new JavaFxFacetType();
+  private static final String JAVAFX_FACET_LIBRARY_PREFIX = "Library for: ";
+
+  public JavaFxFacet(@NotNull final Module module,
+                     @NotNull final String name,
+                     @NotNull final JavaFxFacetConfiguration configuration) {
+    super(FACET_TYPE, module, name, configuration, null);
+  }
+
+  public static String getFacetLibraryName(final String sdkName) {
+    return JAVAFX_FACET_LIBRARY_PREFIX + sdkName;
+  }
+
+  void updateLibrary() {
+    ApplicationManager.getApplication().runWriteAction(new Runnable() {
+      public void run() {
+        final Module module = getModule();
+        final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel();
+        boolean modelChanged = false;
+        // Just remove all old facet libraries except one, that is neccessary
+        final Sdk sdk = JavaFxSdkUtil.getSdk(JavaFxFacet.this);
+        final String name = (sdk != null) ? getFacetLibraryName(sdk.getName()) : null;
+        boolean librarySeen = false;
+        for (OrderEntry entry : model.getOrderEntries()) {
+          if (entry instanceof LibraryOrderEntry) {
+            final String libraryName = ((LibraryOrderEntry)entry).getLibraryName();
+            if (name != null && name.equals(libraryName)) {
+              librarySeen = true;
+              continue;
+            }
+            if (libraryName != null && StringUtil.startsWith(libraryName, JAVAFX_FACET_LIBRARY_PREFIX)) {
+              model.removeOrderEntry(entry);
+              modelChanged = true;
+            }
+          }
+        }
+        if (!librarySeen && name != null) {
+          Library library = LibraryTablesRegistrar.getInstance().getLibraryTable().getLibraryByName(name);
+          if (library == null) {
+            // we just create new project library
+            library = JavaFxSdkListener.addLibrary(sdk);
+          }
+          model.addLibraryEntry(library);
+          modelChanged = true;
+        }
+        if (modelChanged) {
+          model.commit();
+        }
+        else {
+          model.dispose();
+        }
+      }
+    });
+  }
+
+  void removeLibrary() {
+    ApplicationManager.getApplication().runWriteAction(new Runnable() {
+      public void run()  {
+        final Module module = getModule();
+        final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel();
+        // Just remove all old facet libraries
+        for (OrderEntry entry : model.getOrderEntries()) {
+          if (entry instanceof LibraryOrderEntry) {
+            final Library library = ((LibraryOrderEntry)entry).getLibrary();
+            if (library != null) {
+              final String libraryName = library.getName();
+              if (libraryName != null && libraryName.startsWith(JAVAFX_FACET_LIBRARY_PREFIX)) {
+                model.removeOrderEntry(entry);
+              }
+            }
+          }
+        }
+        model.commit();
+      }
+    });
+  }
+
+  @Override
+  public void initFacet() {
+    super.initFacet();
+    updateLibrary();
+  }
+}
diff --git a/src/org/jetbrains/javafx/facet/JavaFxFacetConfiguration.java b/src/org/jetbrains/javafx/facet/JavaFxFacetConfiguration.java
new file mode 100644 (file)
index 0000000..60a6945
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx.facet;
+
+import com.intellij.facet.FacetConfiguration;
+import com.intellij.facet.ui.FacetEditorContext;
+import com.intellij.facet.ui.FacetEditorTab;
+import com.intellij.facet.ui.FacetValidatorsManager;
+import com.intellij.openapi.projectRoots.ProjectJdkTable;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.WriteExternalException;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.javafx.sdk.JavaFxSdkType;
+import org.jetbrains.javafx.sdk.JavaFxSdkUtil;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @author: Alexey.Ivanov
+ */
+public class JavaFxFacetConfiguration implements FacetConfiguration {
+  private static final @NonNls String JAVAFX_SDK_ATTR_NAME = "javafx_sdk";
+
+  private Sdk myJavaFxSdk;
+
+  @Override
+  public FacetEditorTab[] createEditorTabs(FacetEditorContext editorContext, FacetValidatorsManager validatorsManager) {
+    return new FacetEditorTab[]{new JavaFxFacetEditorTab(this, editorContext, validatorsManager)};
+  }
+
+  @Override
+  public void readExternal(Element element) throws InvalidDataException {
+    final String s = element.getAttributeValue(JAVAFX_SDK_ATTR_NAME);
+    final Sdk sdk = ProjectJdkTable.getInstance().findJdk(s);
+    if (sdk != null && sdk.getSdkType() instanceof JavaFxSdkType) {
+      setJavaFxSdk(sdk);
+    }
+  }
+
+  @Override
+  public void writeExternal(Element element) throws WriteExternalException {
+    if (myJavaFxSdk != null) {
+      element.setAttribute(JAVAFX_SDK_ATTR_NAME, myJavaFxSdk.getName());
+    }
+  }
+
+  @Nullable
+  public Sdk getJavaFxSdk() {
+    return myJavaFxSdk;
+  }
+
+  public void setJavaFxSdk(final Sdk javaFxSdk) {
+    JavaFxSdkUtil.registerSdkRootListener(javaFxSdk);
+    myJavaFxSdk = javaFxSdk;
+  }
+}
diff --git a/src/org/jetbrains/javafx/facet/JavaFxFacetEditorTab.form b/src/org/jetbrains/javafx/facet/JavaFxFacetEditorTab.form
new file mode 100644 (file)
index 0000000..990cc5f
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.javafx.facet.JavaFxFacetEditorTab">
+  <grid id="27dc6" binding="myContentPane" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+    <margin top="0" left="0" bottom="0" right="0"/>
+    <constraints>
+      <xy x="20" y="20" width="467" height="380"/>
+    </constraints>
+    <properties/>
+    <border type="none"/>
+    <children>
+      <vspacer id="7c4f2">
+        <constraints>
+          <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+        </constraints>
+      </vspacer>
+      <nested-form id="c4f47" form-file="org/jetbrains/javafx/JavaFxConfigureSdkPanel.form" binding="myJavaFxConfigureSdkPanel">
+        <constraints>
+          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+        </constraints>
+      </nested-form>
+      <hspacer id="d6a89">
+        <constraints>
+          <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+        </constraints>
+      </hspacer>
+    </children>
+  </grid>
+</form>
diff --git a/src/org/jetbrains/javafx/facet/JavaFxFacetEditorTab.java b/src/org/jetbrains/javafx/facet/JavaFxFacetEditorTab.java
new file mode 100644 (file)
index 0000000..db08265
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx.facet;
+
+import com.intellij.facet.ui.FacetEditorContext;
+import com.intellij.facet.ui.FacetEditorTab;
+import com.intellij.facet.ui.FacetValidatorsManager;
+import com.intellij.openapi.projectRoots.Sdk;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.javafx.JavaFxConfigureSdkPanel;
+
+import javax.swing.*;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @author: Alexey.Ivanov
+ */
+class JavaFxFacetEditorTab extends FacetEditorTab {
+  private JPanel myContentPane;
+  private JavaFxConfigureSdkPanel myJavaFxConfigureSdkPanel;
+
+  private final JavaFxFacetConfiguration myFacetConfiguration;
+
+  public JavaFxFacetEditorTab(final JavaFxFacetConfiguration facetConfiguration,
+                              final FacetEditorContext context,
+                              FacetValidatorsManager validatorsManager) {
+    myFacetConfiguration = facetConfiguration;
+    myJavaFxConfigureSdkPanel.registerValidator(validatorsManager);
+  }
+
+  @Nls
+  @Override
+  public String getDisplayName() {
+    return "JavaFX";
+  }
+
+  @Override
+  public JComponent createComponent() {
+    return myContentPane;
+  }
+
+  @Override
+  public boolean isModified() {
+    final Sdk selectedSdk = myJavaFxConfigureSdkPanel.getSelectedSdk();
+    final Sdk fxSdk = myFacetConfiguration.getJavaFxSdk();
+    if (selectedSdk != null) {
+      if (fxSdk == null || !selectedSdk.getName().equals(fxSdk.getName())) {
+        return true;
+      }
+    }
+    else if (fxSdk != null && !fxSdk.equals(selectedSdk)) {
+      return true;
+    }
+    return false;
+  }
+
+  @Override
+  public void apply() {
+    final Sdk sdk = myJavaFxConfigureSdkPanel.getSelectedSdk();
+    myFacetConfiguration.setJavaFxSdk(sdk);
+  }
+
+  @Override
+  public void reset() {
+    myJavaFxConfigureSdkPanel.resetSdk(myFacetConfiguration.getJavaFxSdk());
+  }
+
+  @Override
+  public void disposeUIResources() {
+  }
+}
diff --git a/src/org/jetbrains/javafx/facet/JavaFxFacetListener.java b/src/org/jetbrains/javafx/facet/JavaFxFacetListener.java
new file mode 100644 (file)
index 0000000..ee6ac2d
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx.facet;
+
+import com.intellij.facet.Facet;
+import com.intellij.facet.FacetManager;
+import com.intellij.facet.FacetManagerAdapter;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleComponent;
+import com.intellij.util.messages.MessageBusConnection;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @author: Alexey.Ivanov
+ */
+public class JavaFxFacetListener implements ModuleComponent {
+  private MessageBusConnection myConnection;
+  private final Module myModule;
+
+  public JavaFxFacetListener(Module module) {
+    myModule = module;
+  }
+
+  public void initComponent() {
+    myConnection = myModule.getMessageBus().connect();
+    myConnection.subscribe(FacetManager.FACETS_TOPIC, new FacetManagerAdapter() {
+      @Override
+      public void beforeFacetRemoved(@NotNull Facet facet) {
+        if (facet instanceof JavaFxFacet) {
+          ((JavaFxFacet) facet).removeLibrary();
+        }
+      }
+
+      @Override
+      public void facetConfigurationChanged(@NotNull Facet facet) {
+        if (facet instanceof JavaFxFacet) {
+          ((JavaFxFacet) facet).updateLibrary();
+        }
+      }
+    });
+  }
+
+  public void projectOpened() {
+  }
+
+  public void projectClosed() {
+  }
+
+  public void moduleAdded() {
+  }
+
+  @NotNull
+  public String getComponentName() {
+    return "JavaFxFacetListener";
+  }
+
+  public void disposeComponent() {
+    myConnection.disconnect();
+  }
+}
diff --git a/src/org/jetbrains/javafx/facet/JavaFxFacetType.java b/src/org/jetbrains/javafx/facet/JavaFxFacetType.java
new file mode 100644 (file)
index 0000000..7f7267c
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx.facet;
+
+import com.intellij.facet.Facet;
+import com.intellij.facet.FacetType;
+import com.intellij.openapi.module.JavaModuleType;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.javafx.JavaFxFileType;
+
+import javax.swing.*;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @author: Alexey.Ivanov
+ */
+public class JavaFxFacetType extends FacetType<JavaFxFacet, JavaFxFacetConfiguration> {
+  public JavaFxFacetType() {
+    super(JavaFxFacet.ID, "javafx", "JavaFX");
+  }
+
+  @Override
+  public JavaFxFacetConfiguration createDefaultConfiguration() {
+    return new JavaFxFacetConfiguration();
+  }
+
+  @Override
+  public JavaFxFacet createFacet(@NotNull Module module,
+                                 String name,
+                                 @NotNull JavaFxFacetConfiguration configuration,
+                                 @Nullable Facet underlyingFacet) {
+    return new JavaFxFacet(module, name, configuration);
+  }
+
+  @Override
+  public Icon getIcon() {
+    return JavaFxFileType.INSTANCE.getIcon();
+  }
+
+  @Override
+  public boolean isSuitableModuleType(ModuleType moduleType) {
+    return moduleType instanceof JavaModuleType;
+  }
+}
diff --git a/src/org/jetbrains/javafx/gotoByName/JavaFxGotoClassContributor.java b/src/org/jetbrains/javafx/gotoByName/JavaFxGotoClassContributor.java
new file mode 100644 (file)
index 0000000..12f4052
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx.gotoByName;
+
+import com.intellij.navigation.GotoClassContributor;
+import com.intellij.navigation.NavigationItem;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.ProjectScope;
+import com.intellij.psi.stubs.StubIndex;
+import com.intellij.util.ArrayUtil;
+import org.jetbrains.javafx.lang.psi.JavaFxClassDefinition;
+import org.jetbrains.javafx.lang.psi.impl.JavaFxQualifiedName;
+import org.jetbrains.javafx.lang.psi.impl.stubs.index.JavaFxClassNameIndex;
+
+import java.util.Collection;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @author: Alexey.Ivanov
+ */
+public class JavaFxGotoClassContributor implements GotoClassContributor {
+  @Override
+  public String[] getNames(final Project project, final boolean includeNonProjectItems) {
+    final Collection<String> classNames = StubIndex.getInstance().getAllKeys(JavaFxClassNameIndex.KEY, project);
+    return ArrayUtil.toStringArray(classNames);
+  }
+
+  @Override
+  public NavigationItem[] getItemsByName(final String name,
+                                         final String pattern,
+                                         final Project project,
+                                         final boolean includeNonProjectItems) {
+    final GlobalSearchScope scope = includeNonProjectItems
+                                    ? ProjectScope.getAllScope(project)
+                                    : GlobalSearchScope.projectScope(project);
+    final Collection<JavaFxClassDefinition> classes = StubIndex.getInstance().get(JavaFxClassNameIndex.KEY, name, project, scope);
+    return classes.toArray(new NavigationItem[classes.size()]);
+  }
+
+  @Override
+  public String getQualifiedName(final NavigationItem item) {
+    if (item instanceof JavaFxClassDefinition) {
+      final JavaFxQualifiedName qualifiedName = ((JavaFxClassDefinition)item).getQualifiedName();
+      if (qualifiedName != null) {
+        return qualifiedName.toString();
+      }
+    }
+    return null;
+  }
+}
diff --git a/src/org/jetbrains/javafx/gotoByName/JavaFxGotoSymbolContributor.java b/src/org/jetbrains/javafx/gotoByName/JavaFxGotoSymbolContributor.java
new file mode 100644 (file)
index 0000000..de6e5cd
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx.gotoByName;
+
+import com.intellij.navigation.ChooseByNameContributor;
+import com.intellij.navigation.NavigationItem;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.ProjectScope;
+import com.intellij.psi.stubs.StubIndex;
+import com.intellij.util.ArrayUtil;
+import org.jetbrains.javafx.lang.psi.impl.stubs.index.JavaFxClassNameIndex;
+import org.jetbrains.javafx.lang.psi.impl.stubs.index.JavaFxFunctionNameIndex;
+import org.jetbrains.javafx.lang.psi.impl.stubs.index.JavaFxVariableNameIndex;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @author: Alexey.Ivanov
+ */
+public class JavaFxGotoSymbolContributor implements ChooseByNameContributor {
+  @Override
+  public String[] getNames(Project project, boolean includeNonProjectItems) {
+    final Set<String> symbols = new HashSet<String>();
+    symbols.addAll(StubIndex.getInstance().getAllKeys(JavaFxClassNameIndex.KEY, project));
+    symbols.addAll(StubIndex.getInstance().getAllKeys(JavaFxFunctionNameIndex.KEY, project));
+    symbols.addAll(StubIndex.getInstance().getAllKeys(JavaFxVariableNameIndex.KEY, project));
+    return ArrayUtil.toStringArray(symbols);
+  }
+
+  @Override
+  public NavigationItem[] getItemsByName(String name, String pattern, Project project, boolean includeNonProjectItems) {
+    final GlobalSearchScope scope = includeNonProjectItems
+                                    ? ProjectScope.getAllScope(project)
+                                    : GlobalSearchScope.projectScope(project);
+
+    final List<NavigationItem> symbols = new ArrayList<NavigationItem>();
+    symbols.addAll(StubIndex.getInstance().get(JavaFxClassNameIndex.KEY, name, project, scope));
+    symbols.addAll(StubIndex.getInstance().get(JavaFxFunctionNameIndex.KEY, name, project, scope));
+    symbols.addAll(StubIndex.getInstance().get(JavaFxVariableNameIndex.KEY, name, project, scope));
+
+    return symbols.toArray(new NavigationItem[symbols.size()]);
+  }
+}
diff --git a/src/org/jetbrains/javafx/javafxFile.png b/src/org/jetbrains/javafx/javafxFile.png
new file mode 100644 (file)
index 0000000..ab5b452
Binary files /dev/null and b/src/org/jetbrains/javafx/javafxFile.png differ
diff --git a/src/org/jetbrains/javafx/lang/JavaFxElementType.java b/src/org/jetbrains/javafx/lang/JavaFxElementType.java
new file mode 100644 (file)
index 0000000..a080525
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx.lang;
+
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.javafx.JavaFxLanguage;
+
+import java.lang.reflect.Constructor;
+
+/**
+ * JavaFx element type
+ *
+ * @author Alexey.Ivanov
+ */
+public class JavaFxElementType extends IElementType {
+  private static final Class[] PARAMETER_TYPES = new Class[]{ASTNode.class};
+  protected Class<? extends PsiElement> myPsiElementClass;
+  private Constructor<? extends PsiElement> myConstructor;
+
+  public JavaFxElementType(@NotNull @NonNls String debugName) {
+    super(debugName, JavaFxLanguage.getInstance());
+  }
+
+  public JavaFxElementType(@NonNls String debugName, Class<? extends PsiElement> psiElementClass) {
+    this(debugName);
+    myPsiElementClass = psiElementClass;
+  }
+
+  @Nullable
+  public PsiElement createElement(ASTNode node) {
+    if (myPsiElementClass == null) {
+      return null;
+    }
+
+    try {
+      if (myConstructor == null) {
+        myConstructor = myPsiElementClass.getConstructor(PARAMETER_TYPES);
+      }
+
+      return myConstructor.newInstance(node);
+    }
+    catch (Exception e) {
+      throw new IllegalStateException("No necessary constructor for " + node.getElementType(), e);
+    }
+  }
+
+  @Override
+  public String toString() {
+    return "JavaFx:" + super.toString();
+  }
+}
diff --git a/src/org/jetbrains/javafx/lang/lexer/BraceQuoteTracker.java b/src/org/jetbrains/javafx/lang/lexer/BraceQuoteTracker.java
new file mode 100644 (file)
index 0000000..ab2ce3b
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx.lang.lexer;
+
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @author: Alexey.Ivanov
+ */
+class BraceQuoteTracker {
+  public static final BraceQuoteTracker NULL_BQT = new BraceQuoteTracker(null, -1, false);
+
+  private final int myPreviousState;
+  private boolean myPercentIsFormat;
+  private int myBraceDepth;
+  private final BraceQuoteTracker myNext;
+
+  public BraceQuoteTracker(BraceQuoteTracker previous, int previousState, boolean percentIsFormat) {
+    myPreviousState = previousState;
+    myPercentIsFormat = percentIsFormat;
+    myBraceDepth = 1;
+    myNext = previous;
+  }
+
+  public void enterBrace() {
+    if (inBraceQuote()) {
+      ++myBraceDepth;
+    }
+  }
+
+  @Nullable
+  public BraceQuoteTracker enterBrace(int state, boolean percentIsFormat) {
+    return new BraceQuoteTracker(this, state, percentIsFormat); // push
+  }
+
+  public int leaveBrace() {
+    if (inBraceQuote() && --myBraceDepth == 0) {
+      return myPreviousState;
+    }
+    return -1;
+  }
+
+  public BraceQuoteTracker leaveQuote() {
+    assert (inBraceQuote() && myBraceDepth == 0);
+    return myNext; // pop
+  }
+
+  public boolean inBraceQuote() {
+    return this != NULL_BQT;
+  }
+}
diff --git a/src/org/jetbrains/javafx/lang/lexer/JavaFxFlexLexer.java b/src/org/jetbrains/javafx/lang/lexer/JavaFxFlexLexer.java
new file mode 100644 (file)
index 0000000..9242a6a
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx.lang.lexer;
+
+import com.intellij.lexer.FlexAdapter;
+
+/**
+ * Flex adapter for JavaFx
+ *
+ * @author andrey
+ */
+public class JavaFxFlexLexer extends FlexAdapter {
+  public JavaFxFlexLexer() {
+    super(new JavaFxLexer());
+  }
+}
diff --git a/src/org/jetbrains/javafx/lang/lexer/JavaFxLexer.java b/src/org/jetbrains/javafx/lang/lexer/JavaFxLexer.java
new file mode 100644 (file)
index 0000000..2d08a43
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx.lang.lexer;
+
+import java.io.Reader;
+
+/**
+ * Wrapper lexer
+ *
+ * @author andrey
+ */
+class JavaFxLexer extends _JavaFxLexer {
+  public JavaFxLexer() {
+    super((Reader)null);
+  }
+}
diff --git a/src/org/jetbrains/javafx/lang/lexer/JavaFxTokenTypes.java b/src/org/jetbrains/javafx/lang/lexer/JavaFxTokenTypes.java
new file mode 100644 (file)
index 0000000..3787c70
--- /dev/null
@@ -0,0 +1,213 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx.lang.lexer;
+
+import com.intellij.psi.TokenType;
+import com.intellij.psi.tree.TokenSet;
+import org.jetbrains.javafx.lang.JavaFxElementType;
+
+/**
+ * JavaFx-specific tokens
+ *
+ * @author andrey, Alexey.Iavnov
+ */
+public interface JavaFxTokenTypes extends TokenType {
+  JavaFxElementType IDENTIFIER = new JavaFxElementType("IDENTIFIER");
+  JavaFxElementType C_STYLE_COMMENT = new JavaFxElementType("C_STYLE_COMMENT");
+  JavaFxElementType END_OF_LINE_COMMENT = new JavaFxElementType("END_OF_LINE_COMMENT");
+  JavaFxElementType DOC_COMMENT = new JavaFxElementType("DOC_COMMENT");
+
+  JavaFxElementType INTEGER_LITERAL = new JavaFxElementType("INTEGER_LITERAL");
+  JavaFxElementType NUMBER_LITERAL = new JavaFxElementType("NUMBER_LITERAL");
+  JavaFxElementType STRING_LITERAL = new JavaFxElementType("STRING_LITERAL");
+  JavaFxElementType LBRACE_STRING_LITERAL = new JavaFxElementType("LBRACE_STRING_LITERAL");
+  JavaFxElementType LBRACE_RBRACE_STRING_LITERAL = new JavaFxElementType("LBRACE_RBRACE_STRING_LITERAL");
+  JavaFxElementType RBRACE_STRING_LITERAL = new JavaFxElementType("RBRACE_STRING_LITERAL");
+  JavaFxElementType DURATION_LITERAL = new JavaFxElementType("DURATION_LITERAL");
+
+  JavaFxElementType LOCALIZATION_PREFIX = new JavaFxElementType("LOCALIZATION_PREFIX");
+
+  /* **************************************************************************************************
+  *  Keywords
+  * ****************************************************************************************************/
+
+  JavaFxElementType ABSTRACT_KEYWORD = new JavaFxElementType("abstract");
+  JavaFxElementType AFTER_KEYWORD = new JavaFxElementType("after");
+  JavaFxElementType AND_KEYWORD = new JavaFxElementType("and");
+  JavaFxElementType AS_KEYWORD = new JavaFxElementType("as");
+  JavaFxElementType ASSERT_KEYWORD = new JavaFxElementType("assert");
+  JavaFxElementType AT_KEYWORD = new JavaFxElementType("at");
+  JavaFxElementType ATTRIBUTE_KEYWORD = new JavaFxElementType("attribute");
+  JavaFxElementType BEFORE_KEYWORD = new JavaFxElementType("before");
+  JavaFxElementType BIND_KEYWORD = new JavaFxElementType("bind");
+  JavaFxElementType BOUND_KEYWORD = new JavaFxElementType("bound");
+  JavaFxElementType BREAK_KEYWORD = new JavaFxElementType("break");
+  JavaFxElementType CATCH_KEYWORD = new JavaFxElementType("catch");
+  JavaFxElementType CLASS_KEYWORD = new JavaFxElementType("class");
+  JavaFxElementType CONTINUE_KEYWORD = new JavaFxElementType("continue");
+  JavaFxElementType DEF_KEYWORD = new JavaFxElementType("def");
+  JavaFxElementType DELETE_KEYWORD = new JavaFxElementType("delete");
+  JavaFxElementType ELSE_KEYWORD = new JavaFxElementType("else");
+  JavaFxElementType EXCLUSIVE_KEYWORD = new JavaFxElementType("exclusive");
+  JavaFxElementType EXTENDS_KEYWORD = new JavaFxElementType("extends");
+  JavaFxElementType FALSE_KEYWORD = new JavaFxElementType("false");
+  JavaFxElementType FINALLY_KEYWORD = new JavaFxElementType("finally");
+  JavaFxElementType FIRST_KEYWORD = new JavaFxElementType("first");
+  JavaFxElementType FOR_KEYWORD = new JavaFxElementType("for");
+  JavaFxElementType FROM_KEYWORD = new JavaFxElementType("from");
+  JavaFxElementType FUNCTION_KEYWORD = new JavaFxElementType("function");
+  JavaFxElementType IF_KEYWORD = new JavaFxElementType("if");
+  JavaFxElementType IMPORT_KEYWORD = new JavaFxElementType("import");
+  JavaFxElementType INDEXOF_KEYWORD = new JavaFxElementType("indexof");
+  JavaFxElementType IN_KEYWORD = new JavaFxElementType("in");
+  JavaFxElementType INIT_KEYWORD = new JavaFxElementType("init");
+  JavaFxElementType INSERT_KEYWORD = new JavaFxElementType("insert");
+  JavaFxElementType INSTANCEOF_KEYWORD = new JavaFxElementType("instanceof");
+  JavaFxElementType INTO_KEYWORD = new JavaFxElementType("into");
+  JavaFxElementType INVERSE_KEYWORD = new JavaFxElementType("inverse");
+  JavaFxElementType LAST_KEYWORD = new JavaFxElementType("last");
+  JavaFxElementType LAZY_KEYWORD = new JavaFxElementType("lazy");
+  JavaFxElementType MIXIN_KEYWORD = new JavaFxElementType("mixin");
+  JavaFxElementType MOD_KEYWORD = new JavaFxElementType("mod");
+  JavaFxElementType NEW_KEYWORD = new JavaFxElementType("new");
+  JavaFxElementType NOT_KEYWORD = new JavaFxElementType("not");
+  JavaFxElementType NULL_KEYWORD = new JavaFxElementType("null");
+  JavaFxElementType ON_KEYWORD = new JavaFxElementType("on");
+  JavaFxElementType OR_KEYWORD = new JavaFxElementType("or");
+  JavaFxElementType OVERRIDE_KEYWORD = new JavaFxElementType("override");
+  JavaFxElementType PACKAGE_KEYWORD = new JavaFxElementType("package");
+  JavaFxElementType POSTINIT_KEYWORD = new JavaFxElementType("postinit");
+  JavaFxElementType PRIVATE_KEYWORD = new JavaFxElementType("private");
+  JavaFxElementType PROTECTED_KEYWORD = new JavaFxElementType("protected");
+  JavaFxElementType PUBLIC_INIT_KEYWORD = new JavaFxElementType("public-init");
+  JavaFxElementType PUBLIC_KEYWORD = new JavaFxElementType("public");
+  JavaFxElementType PUBLIC_READ_KEYWORD = new JavaFxElementType("public-read");
+  JavaFxElementType REPLACE_KEYWORD = new JavaFxElementType("replace");
+  JavaFxElementType INVALIDATE_KEYWORD = new JavaFxElementType("invalidate");
+  JavaFxElementType RETURN_KEYWORD = new JavaFxElementType("return");
+  JavaFxElementType REVERSE_KEYWORD = new JavaFxElementType("reverse");
+  JavaFxElementType SIZEOF_KEYWORD = new JavaFxElementType("sizeof");
+  JavaFxElementType STATIC_KEYWORD = new JavaFxElementType("static");
+  JavaFxElementType STEP_KEYWORD = new JavaFxElementType("step");
+  JavaFxElementType SUPER_KEYWORD = new JavaFxElementType("super");
+  JavaFxElementType THEN_KEYWORD = new JavaFxElementType("then");
+  JavaFxElementType THIS_KEYWORD = new JavaFxElementType("this");
+  JavaFxElementType THROW_KEYWORD = new JavaFxElementType("throw");
+  JavaFxElementType TRIGGER_KEYWORD = new JavaFxElementType("trigger");
+  JavaFxElementType TRUE_KEYWORD = new JavaFxElementType("true");
+  JavaFxElementType TRY_KEYWORD = new JavaFxElementType("try");
+  JavaFxElementType TWEEN_KEYWORD = new JavaFxElementType("tween");
+  JavaFxElementType TYPEOF_KEYWORD = new JavaFxElementType("typeof");
+  JavaFxElementType VAR_KEYWORD = new JavaFxElementType("var");
+  JavaFxElementType WHERE_KEYWORD = new JavaFxElementType("where");
+  JavaFxElementType WHILE_KEYWORD = new JavaFxElementType("while");
+  JavaFxElementType WITH_KEYWORD = new JavaFxElementType("with");
+
+  JavaFxElementType LPAREN = new JavaFxElementType("LPAREN"); // )
+  JavaFxElementType RPAREN = new JavaFxElementType("RPAREN");  // (
+  JavaFxElementType LBRACE = new JavaFxElementType("LBRACE");  // {
+  JavaFxElementType RBRACE = new JavaFxElementType("RBRACE");  // }
+  JavaFxElementType LBRACK = new JavaFxElementType("LBRACK");  // ]
+  JavaFxElementType RBRACK = new JavaFxElementType("RBRACK");  // [
+  JavaFxElementType SEMICOLON = new JavaFxElementType("SEMICOLON");  // ;
+  JavaFxElementType COMMA = new JavaFxElementType("COMMA");  // ,
+  JavaFxElementType DOT = new JavaFxElementType("DOT");  // .
+  JavaFxElementType COLON = new JavaFxElementType("COLON");  // :
+  JavaFxElementType RANGE = new JavaFxElementType("RANGE");  // ..
+  JavaFxElementType DELIM = new JavaFxElementType("DELIM");  // |
+
+  JavaFxElementType EQEQ = new JavaFxElementType("EQEQ");  // ==
+  JavaFxElementType LT = new JavaFxElementType("LT");  // <
+  JavaFxElementType GT = new JavaFxElementType("GT");  // >
+  JavaFxElementType NOTEQ = new JavaFxElementType("NOTEQ");  // !=
+  JavaFxElementType LTEQ = new JavaFxElementType("LTEQ");  // <=
+  JavaFxElementType GTEQ = new JavaFxElementType("GTEQ");  // >=
+  JavaFxElementType EQGT = new JavaFxElementType("EQGT");  // EQGT
+  JavaFxElementType EQ = new JavaFxElementType("EQ");  // EQ
+
+  JavaFxElementType PLUSEQ = new JavaFxElementType("PLUSEQ");  // +=
+  JavaFxElementType MINUSEQ = new JavaFxElementType("MINUSEQ");  // -=
+  JavaFxElementType MULTEQ = new JavaFxElementType("MULTEQ");  // *=
+  JavaFxElementType DIVEQ = new JavaFxElementType("DIVEQ");  // /=
+
+  JavaFxElementType PLUS = new JavaFxElementType("PLUS");  // +
+  JavaFxElementType MINUS = new JavaFxElementType("MINUS");  // -
+  JavaFxElementType MULT = new JavaFxElementType("MULT");  // *
+  JavaFxElementType DIV = new JavaFxElementType("DIV");  // /
+  JavaFxElementType PLUSPLUS = new JavaFxElementType("PLUSPLUS");  // ++
+  JavaFxElementType MINUSMINUS = new JavaFxElementType("MINUSMINUS");  // --
+
+  //JavaFxElementType NUMBER = new JavaFxElementType("Number");
+  //JavaFxElementType INTEGER = new JavaFxElementType("Integer");
+  //JavaFxElementType BOOLEAN = new JavaFxElementType("Boolean");
+  //JavaFxElementType DURATION = new JavaFxElementType("Duration");
+  //JavaFxElementType VOID = new JavaFxElementType("Void");
+  //JavaFxElementType STRING = new JavaFxElementType("String");
+
+  TokenSet RESERVED_WORDS = TokenSet
+    .create(ABSTRACT_KEYWORD, AFTER_KEYWORD, AND_KEYWORD, AS_KEYWORD, ASSERT_KEYWORD, AT_KEYWORD, ATTRIBUTE_KEYWORD, BEFORE_KEYWORD,
+            BIND_KEYWORD, BOUND_KEYWORD, BREAK_KEYWORD, CATCH_KEYWORD, CLASS_KEYWORD, CONTINUE_KEYWORD, DEF_KEYWORD, DELETE_KEYWORD,
+            ELSE_KEYWORD, EXCLUSIVE_KEYWORD, EXTENDS_KEYWORD, FALSE_KEYWORD, FINALLY_KEYWORD, FOR_KEYWORD, FROM_KEYWORD, FUNCTION_KEYWORD,
+            IF_KEYWORD, IMPORT_KEYWORD, INDEXOF_KEYWORD, INSERT_KEYWORD, INSTANCEOF_KEYWORD, LAZY_KEYWORD, MIXIN_KEYWORD, MOD_KEYWORD,
+            NEW_KEYWORD, NOT_KEYWORD, NULL_KEYWORD, OR_KEYWORD, OVERRIDE_KEYWORD, PACKAGE_KEYWORD, PRIVATE_KEYWORD, PROTECTED_KEYWORD,
+            PUBLIC_INIT_KEYWORD, PUBLIC_KEYWORD, PUBLIC_READ_KEYWORD, RETURN_KEYWORD, REVERSE_KEYWORD, SIZEOF_KEYWORD, STATIC_KEYWORD,
+            SUPER_KEYWORD, THEN_KEYWORD, THIS_KEYWORD, THROW_KEYWORD, TRUE_KEYWORD, TRY_KEYWORD, TYPEOF_KEYWORD, VAR_KEYWORD,
+            WHILE_KEYWORD);
+
+  TokenSet KEYWORDS = TokenSet
+    .create(FIRST_KEYWORD, IN_KEYWORD, INIT_KEYWORD, INTO_KEYWORD, INVERSE_KEYWORD, LAST_KEYWORD, ON_KEYWORD, POSTINIT_KEYWORD,
+            REPLACE_KEYWORD, INVALIDATE_KEYWORD, STEP_KEYWORD, TWEEN_KEYWORD, WHERE_KEYWORD, WITH_KEYWORD);
+
+  TokenSet ALL_WORDS = TokenSet.orSet(RESERVED_WORDS, KEYWORDS);
+
+  TokenSet NAME = TokenSet.orSet(TokenSet.create(IDENTIFIER), KEYWORDS);
+
+  TokenSet NAME_ALL = TokenSet.orSet(TokenSet.create(IDENTIFIER), ALL_WORDS);
+
+  TokenSet BRACES = TokenSet.create(LPAREN, RPAREN, LBRACE, RBRACE, LBRACK, RBRACK);
+
+  TokenSet BLOCK_COMMENTS = TokenSet.create(C_STYLE_COMMENT, DOC_COMMENT);
+
+  TokenSet LINE_COMMENTS = TokenSet.create(END_OF_LINE_COMMENT);
+
+  TokenSet COMMENTS = TokenSet.create(C_STYLE_COMMENT, DOC_COMMENT, END_OF_LINE_COMMENT);
+
+  TokenSet WHITESPACES = TokenSet.create(WHITE_SPACE);
+
+  TokenSet NUMBERS = TokenSet.create(INTEGER_LITERAL, NUMBER_LITERAL, DURATION_LITERAL);
+
+  TokenSet STRING_START = TokenSet.create(LOCALIZATION_PREFIX, STRING_LITERAL, LBRACE_STRING_LITERAL);
+
+  TokenSet STRINGS = TokenSet.create(STRING_LITERAL, LBRACE_STRING_LITERAL, LBRACE_RBRACE_STRING_LITERAL, RBRACE_STRING_LITERAL);
+
+  TokenSet ALL_STRINGS = TokenSet.orSet(STRINGS, TokenSet.create(LOCALIZATION_PREFIX));
+
+  //TokenSet TYPES = TokenSet.create(BOOLEAN, DURATION, INTEGER, NUMBER, STRING, VOID);
+
+  TokenSet MODIFIERS = TokenSet
+    .create(PACKAGE_KEYWORD, PROTECTED_KEYWORD, PUBLIC_KEYWORD, PUBLIC_READ_KEYWORD, PUBLIC_INIT_KEYWORD, ABSTRACT_KEYWORD, BOUND_KEYWORD,
+            OVERRIDE_KEYWORD, STATIC_KEYWORD, PRIVATE_KEYWORD, MIXIN_KEYWORD);
+
+  TokenSet EQ_OPERATORS = TokenSet.create(PLUSEQ, MINUSEQ, MULTEQ, DIVEQ);
+  TokenSet RELATIONAL_OPERATORS = TokenSet.create(EQEQ, NOTEQ, LTEQ, GTEQ, LT, GT);
+  TokenSet BINARY_OPERATORS = TokenSet.orSet(RELATIONAL_OPERATORS, TokenSet
+    .create(PLUS, MINUS, MULT, DIV, MOD_KEYWORD, OR_KEYWORD, AND_KEYWORD, AS_KEYWORD, INSTANCEOF_KEYWORD));
+  TokenSet UNARY_OPERATORS = TokenSet.create(MINUS, NOT_KEYWORD, SIZEOF_KEYWORD, PLUSPLUS, MINUSMINUS, REVERSE_KEYWORD);
+  TokenSet LITERALS =
+    TokenSet.create(INTEGER_LITERAL, NUMBER_LITERAL, DURATION_LITERAL, NULL_KEYWORD, TRUE_KEYWORD, FALSE_KEYWORD);
+
+  TokenSet VARIABLE_LABEL = TokenSet.create(VAR_KEYWORD, DEF_KEYWORD, ATTRIBUTE_KEYWORD);
+}
diff --git a/src/org/jetbrains/javafx/lang/lexer/_JavaFxLexer.java b/src/org/jetbrains/javafx/lang/lexer/_JavaFxLexer.java
new file mode 100644 (file)
index 0000000..42509fe
--- /dev/null
@@ -0,0 +1,1580 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* The following code was generated by JFlex 1.4.3 on 18.08.10 22:45 */
+
+package org.jetbrains.javafx.lang.lexer;
+
+import com.intellij.lexer.FlexLexer;
+import com.intellij.psi.tree.IElementType;
+
+
+/**
+ * This class is a scanner generated by 
+ * <a href="http://www.jflex.de/">JFlex</a> 1.4.3
+ * on 18.08.10 22:45 from the specification file
+ * <tt>C:/src/IDEA/tools/lexer/../../plugins/JavaFX/src/org/jetbrains/javafx/lang/lexer/javafx.flex</tt>
+ */
+class _JavaFxLexer implements FlexLexer {
+  /** initial size of the lookahead buffer */
+  private static final int ZZ_BUFFERSIZE = 16384;
+
+  /** lexical states */
+  public static final int STRING = 2;
+  public static final int YYINITIAL = 0;
+  public static final int CHAR = 4;
+
+  /**
+   * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l
+   * ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l
+   *                  at the beginning of a line
+   * l is of the form l = 2*k, k a non negative integer
+   */
+  private static final int ZZ_LEXSTATE[] = { 
+     0,  0,  1,  1,  2, 2
+  };
+
+  /** 
+   * Translates characters to character classes
+   */
+  private static final String ZZ_CMAP_PACKED = 
+    "\11\13\1\3\1\2\1\0\1\3\1\1\16\13\4\0\1\3\1\72"+
+    "\1\25\1\32\1\12\2\0\1\31\1\63\1\64\1\11\1\21\1\66"+
+    "\1\62\1\17\1\10\1\5\7\6\2\4\1\67\1\65\1\14\1\71"+
+    "\1\15\2\0\4\7\1\20\1\7\21\12\1\16\2\12\1\33\1\26"+
+    "\1\34\1\0\1\12\1\0\1\35\1\36\1\41\1\45\1\43\1\42"+
+    "\1\61\1\24\1\46\1\12\1\51\1\52\1\22\1\44\1\50\1\56"+
+    "\1\12\1\40\1\23\1\37\1\47\1\54\1\60\1\53\1\55\1\57"+
+    "\1\27\1\70\1\30\1\0\41\13\2\0\4\12\4\0\1\12\2\0"+
+    "\1\13\7\0\1\12\4\0\1\12\5\0\27\12\1\0\37\12\1\0"+
+    "\u013f\12\31\0\162\12\4\0\14\12\16\0\5\12\11\0\1\12\21\0"+
+    "\130\13\5\0\23\13\12\0\1\12\13\0\1\12\1\0\3\12\1\0"+
+    "\1\12\1\0\24\12\1\0\54\12\1\0\46\12\1\0\5\12\4\0"+
+    "\202\12\1\0\4\13\3\0\105\12\1\0\46\12\2\0\2\12\6\0"+
+    "\20\12\41\0\46\12\2\0\1\12\7\0\47\12\11\0\21\13\1\0"+
+    "\27\13\1\0\3\13\1\0\1\13\1\0\2\13\1\0\1\13\13\0"+
+    "\33\12\5\0\3\12\15\0\4\13\14\0\6\13\13\0\32\12\5\0"+
+    "\13\12\16\13\7\0\12\13\4\0\2\12\1\13\143\12\1\0\1\12"+
+    "\10\13\1\0\6\13\2\12\2\13\1\0\4\13\2\12\12\13\3\12"+
+    "\2\0\1\12\17\0\1\13\1\12\1\13\36\12\33\13\2\0\3\12"+
+    "\60\0\46\12\13\13\1\12\u014f\0\3\13\66\12\2\0\1\13\1\12"+
+    "\20\13\2\0\1\12\4\13\3\0\12\12\2\13\2\0\12\13\21\0"+
+    "\3\13\1\0\10\12\2\0\2\12\2\0\26\12\1\0\7\12\1\0"+
+    "\1\12\3\0\4\12\2\0\1\13\1\12\7\13\2\0\2\13\2\0"+
+    "\3\13\11\0\1\13\4\0\2\12\1\0\3\12\2\13\2\0\12\13"+
+    "\4\12\15\0\3\13\1\0\6\12\4\0\2\12\2\0\26\12\1\0"+
+    "\7\12\1\0\2\12\1\0\2\12\1\0\2\12\2\0\1\13\1\0"+
+    "\5\13\4\0\2\13\2\0\3\13\13\0\4\12\1\0\1\12\7\0"+
+    "\14\13\3\12\14\0\3\13\1\0\11\12\1\0\3\12\1\0\26\12"+
+    "\1\0\7\12\1\0\2\12\1\0\5\12\2\0\1\13\1\12\10\13"+
+    "\1\0\3\13\1\0\3\13\2\0\1\12\17\0\2\12\2\13\2\0"+
+    "\12\13\1\0\1\12\17\0\3\13\1\0\10\12\2\0\2\12\2\0"+
+    "\26\12\1\0\7\12\1\0\2\12\1\0\5\12\2\0\1\13\1\12"+
+    "\6\13\3\0\2\13\2\0\3\13\10\0\2\13\4\0\2\12\1\0"+
+    "\3\12\4\0\12\13\1\0\1\12\20\0\1\13\1\12\1\0\6\12"+
+    "\3\0\3\12\1\0\4\12\3\0\2\12\1\0\1\12\1\0\2\12"+
+    "\3\0\2\12\3\0\3\12\3\0\10\12\1\0\3\12\4\0\5\13"+
+    "\3\0\3\13\1\0\4\13\11\0\1\13\17\0\11\13\11\0\1\12"+
+    "\7\0\3\13\1\0\10\12\1\0\3\12\1\0\27\12\1\0\12\12"+
+    "\1\0\5\12\4\0\7\13\1\0\3\13\1\0\4\13\7\0\2\13"+
+    "\11\0\2\12\4\0\12\13\22\0\2\13\1\0\10\12\1\0\3\12"+
+    "\1\0\27\12\1\0\12\12\1\0\5\12\2\0\1\13\1\12\7\13"+
+    "\1\0\3\13\1\0\4\13\7\0\2\13\7\0\1\12\1\0\2\12"+
+    "\4\0\12\13\22\0\2\13\1\0\10\12\1\0\3\12\1\0\27\12"+
+    "\1\0\20\12\4\0\6\13\2\0\3\13\1\0\4\13\11\0\1\13"+
+    "\10\0\2\12\4\0\12\13\22\0\2\13\1\0\22\12\3\0\30\12"+
+    "\1\0\11\12\1\0\1\12\2\0\7\12\3\0\1\13\4\0\6\13"+
+    "\1\0\1\13\1\0\10\13\22\0\2\13\15\0\60\12\1\13\2\12"+
+    "\7\13\4\0\10\12\10\13\1\0\12\13\47\0\2\12\1\0\1\12"+
+    "\2\0\2\12\1\0\1\12\2\0\1\12\6\0\4\12\1\0\7\12"+
+    "\1\0\3\12\1\0\1\12\1\0\1\12\2\0\2\12\1\0\4\12"+
+    "\1\13\2\12\6\13\1\0\2\13\1\12\2\0\5\12\1\0\1\12"+
+    "\1\0\6\13\2\0\12\13\2\0\2\12\42\0\1\12\27\0\2\13"+
+    "\6\0\12\13\13\0\1\13\1\0\1\13\1\0\1\13\4\0\2\13"+
+    "\10\12\1\0\42\12\6\0\24\13\1\0\2\13\4\12\4\0\10\13"+
+    "\1\0\44\13\11\0\1\13\71\0\42\12\1\0\5\12\1\0\2\12"+
+    "\1\0\7\13\3\0\4\13\6\0\12\13\6\0\6\12\4\13\106\0"+
+    "\46\12\12\0\51\12\7\0\132\12\5\0\104\12\5\0\122\12\6\0"+
+    "\7\12\1\0\77\12\1\0\1\12\1\0\4\12\2\0\7\12\1\0"+
+    "\1\12\1\0\4\12\2\0\47\12\1\0\1\12\1\0\4\12\2\0"+
+    "\37\12\1\0\1\12\1\0\4\12\2\0\7\12\1\0\1\12\1\0"+
+    "\4\12\2\0\7\12\1\0\7\12\1\0\27\12\1\0\37\12\1\0"+
+    "\1\12\1\0\4\12\2\0\7\12\1\0\47\12\1\0\23\12\16\0"+
+    "\11\13\56\0\125\12\14\0\u026c\12\2\0\10\12\12\0\32\12\5\0"+
+    "\113\12\3\0\3\12\17\0\15\12\1\0\4\12\3\13\13\0\22\12"+
+    "\3\13\13\0\22\12\2\13\14\0\15\12\1\0\3\12\1\0\2\13"+
+    "\14\0\64\12\40\13\3\0\1\12\3\0\2\12\1\13\2\0\12\13"+
+    "\41\0\3\13\2\0\12\13\6\0\130\12\10\0\51\12\1\13\126\0"+
+    "\35\12\3\0\14\13\4\0\14\13\12\0\12\13\36\12\2\0\5\12"+
+    "\u038b\0\154\12\224\0\234\12\4\0\132\12\6\0\26\12\2\0\6\12"+
+    "\2\0\46\12\2\0\6\12\2\0\10\12\1\0\1\12\1\0\1\12"+
+    "\1\0\1\12\1\0\37\12\2\0\65\12\1\0\7\12\1\0\1\12"+
+    "\3\0\3\12\1\0\7\12\3\0\4\12\2\0\6\12\4\0\15\12"+
+    "\5\0\3\12\1\0\7\12\17\0\4\13\32\0\5\13\20\0\2\12"+
+    "\23\0\1\12\13\0\4\13\6\0\6\13\1\0\1\12\15\0\1\12"+
+    "\40\0\22\12\36\0\15\13\4\0\1\13\3\0\6\13\27\0\1\12"+
+    "\4\0\1\12\2\0\12\12\1\0\1\12\3\0\5\12\6\0\1\12"+
+    "\1\0\1\12\1\0\1\12\1\0\4\12\1\0\3\12\1\0\7\12"+
+    "\3\0\3\12\5\0\5\12\26\0\44\12\u0e81\0\3\12\31\0\11\12"+
+    "\6\13\1\0\5\12\2\0\5\12\4\0\126\12\2\0\2\13\2\0"+
+    "\3\12\1\0\137\12\5\0\50\12\4\0\136\12\21\0\30\12\70\0"+
+    "\20\12\u0200\0\u19b6\12\112\0\u51a6\12\132\0\u048d\12\u0773\0\u2ba4\12\u215c\0"+
+    "\u012e\12\2\0\73\12\225\0\7\12\14\0\5\12\5\0\1\12\1\13"+
+    "\12\12\1\0\15\12\1\0\5\12\1\0\1\12\1\0\2\12\1\0"+
+    "\2\12\1\0\154\12\41\0\u016b\12\22\0\100\12\2\0\66\12\50\0"+
+    "\15\12\3\0\20\13\20\0\4\13\17\0\2\12\30\0\3\12\31\0"+
+    "\1\12\6\0\5\12\1\0\207\12\2\0\1\13\4\0\1\12\13\0"+
+    "\12\13\7\0\32\12\4\0\1\12\1\0\32\12\12\0\132\12\3\0"+
+    "\6\12\2\0\6\12\2\0\6\12\2\0\3\12\3\0\2\12\3\0"+
+    "\2\12\22\0\3\13\4\0";
+
+  /** 
+   * Translates characters to character classes
+   */
+  private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED);
+
+  /** 
+   * Translates DFA states to action switch labels.
+   */
+  private static final int [] ZZ_ACTION = zzUnpackAction();
+
+  private static final String ZZ_ACTION_PACKED_0 =
+    "\3\0\1\1\2\2\2\3\1\4\1\5\1\6\1\7"+
+    "\1\10\1\11\1\12\2\4\1\13\1\14\1\15\1\16"+
+    "\1\1\1\17\1\20\17\4\1\21\1\22\1\23\1\24"+
+    "\1\25\1\26\1\27\1\30\1\1\1\31\2\32\1\31"+
+    "\2\0\2\33\1\34\1\3\1\0\1\35\1\36\1\37"+
+    "\1\40\1\0\1\41\1\42\1\34\1\43\1\44\1\45"+
+    "\5\4\1\46\1\47\1\4\1\50\32\4\1\51\1\52"+
+    "\1\53\1\54\11\4\1\55\1\56\1\57\1\60\1\61"+
+    "\2\31\1\62\2\32\1\63\1\32\1\31\1\64\1\34"+
+    "\1\0\1\3\2\35\1\36\1\65\1\0\1\4\1\66"+
+    "\4\4\1\0\4\4\1\67\11\4\1\70\15\4\1\71"+
+    "\3\4\1\72\1\4\1\73\1\74\12\4\1\75\10\4"+
+    "\1\0\2\65\3\4\1\76\2\4\1\0\6\4\1\77"+
+    "\2\4\1\100\1\101\1\4\1\102\11\4\1\103\3\4"+
+    "\1\104\2\4\1\105\4\4\1\106\1\4\1\107\3\4"+
+    "\1\110\1\111\7\4\1\112\1\36\3\0\1\113\2\4"+
+    "\1\114\1\46\3\4\1\115\1\116\1\4\1\117\1\120"+
+    "\2\4\1\121\3\4\1\122\1\4\1\123\1\124\1\125"+
+    "\21\4\1\126\1\127\1\65\1\0\1\130\1\131\1\132"+
+    "\2\4\1\133\1\4\1\134\1\135\7\4\1\136\1\137"+
+    "\1\4\1\140\7\4\1\141\3\4\1\142\1\143\1\144"+
+    "\1\4\1\145\1\4\1\146\2\4\1\147\1\4\1\150"+
+    "\1\4\1\151\1\152\1\4\1\0\1\4\1\153\1\4"+
+    "\1\154\1\155\3\4\1\156\1\4\2\0\1\157\1\160"+
+    "\1\161\2\4\1\162\2\0\1\163\1\164\2\0\1\165"+
+    "\1\166";
+
+  private static int [] zzUnpackAction() {
+    int [] result = new int[385];
+    int offset = 0;
+    offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result);
+    return result;
+  }
+
+  private static int zzUnpackAction(String packed, int offset, int [] result) {
+    int i = 0;       /* index in packed string  */
+    int j = offset;  /* index in unpacked array */
+    int l = packed.length();
+    while (i < l) {
+      int count = packed.charAt(i++);
+      int value = packed.charAt(i++);
+      do result[j++] = value; while (--count > 0);
+    }
+    return j;
+  }
+
+
+  /** 
+   * Translates a state to a row index in the transition table
+   */
+  private static final int [] ZZ_ROWMAP = zzUnpackRowMap();
+
+  private static final String ZZ_ROWMAP_PACKED_0 =
+    "\0\0\0\73\0\166\0\261\0\354\0\261\0\u0127\0\u0162"+
+    "\0\u019d\0\u01d8\0\u0213\0\u024e\0\u0289\0\u02c4\0\u02ff\0\u033a"+
+    "\0\u0375\0\261\0\261\0\261\0\261\0\u03b0\0\261\0\261"+
+    "\0\u03eb\0\u0426\0\u0461\0\u049c\0\u04d7\0\u0512\0\u054d\0\u0588"+
+    "\0\u05c3\0\u05fe\0\u0639\0\u0674\0\u06af\0\u06ea\0\u0725\0\u0760"+
+    "\0\261\0\261\0\261\0\261\0\261\0\261\0\u079b\0\u07d6"+
+    "\0\u0811\0\u084c\0\u0887\0\u08c2\0\u08fd\0\u0938\0\u0973\0\261"+
+    "\0\u09ae\0\u09e9\0\u0a24\0\u0a5f\0\u0a9a\0\261\0\261\0\u0ad5"+
+    "\0\261\0\261\0\u0b10\0\261\0\261\0\261\0\u0b4b\0\u0b86"+
+    "\0\u0bc1\0\u0bfc\0\u0c37\0\u0c72\0\u0cad\0\u0ce8\0\u0d23\0\u0d5e"+
+    "\0\u0d99\0\u0dd4\0\u0e0f\0\u0e4a\0\u0e85\0\u0ec0\0\u0efb\0\u0f36"+
+    "\0\u0f71\0\u0fac\0\u0fe7\0\u1022\0\u105d\0\u1098\0\u10d3\0\u110e"+
+    "\0\u1149\0\u1184\0\u11bf\0\u11fa\0\u1235\0\u1270\0\u12ab\0\u12e6"+
+    "\0\u1321\0\u019d\0\u135c\0\u019d\0\u019d\0\u1397\0\u13d2\0\u140d"+
+    "\0\u1448\0\u1483\0\u14be\0\u14f9\0\u1534\0\u156f\0\261\0\261"+
+    "\0\261\0\261\0\261\0\261\0\u15aa\0\261\0\261\0\u15e5"+
+    "\0\261\0\u1620\0\u165b\0\261\0\u1696\0\u16d1\0\u0a24\0\u170c"+
+    "\0\261\0\u1747\0\u1782\0\u17bd\0\u17f8\0\u019d\0\u1833\0\u186e"+
+    "\0\u18a9\0\u18e4\0\u191f\0\u195a\0\u1995\0\u19d0\0\u1a0b\0\u019d"+
+    "\0\u1a46\0\u1a81\0\u1abc\0\u1af7\0\u1b32\0\u1b6d\0\u1ba8\0\u1be3"+
+    "\0\u1c1e\0\u019d\0\u1c59\0\u1c94\0\u1ccf\0\u1d0a\0\u1d45\0\u1d80"+
+    "\0\u1dbb\0\u1df6\0\u1e31\0\u1e6c\0\u1ea7\0\u1ee2\0\u1f1d\0\u019d"+
+    "\0\u1f58\0\u1f93\0\u1fce\0\u019d\0\u2009\0\u019d\0\u019d\0\u2044"+
+    "\0\u207f\0\u20ba\0\u20f5\0\u2130\0\u216b\0\u21a6\0\u21e1\0\u221c"+
+    "\0\u2257\0\u019d\0\u2292\0\u22cd\0\u2308\0\u2343\0\u237e\0\u23b9"+
+    "\0\u23f4\0\u242f\0\u246a\0\u24a5\0\u24e0\0\u251b\0\u2556\0\u2591"+
+    "\0\u019d\0\u25cc\0\u2607\0\u2642\0\u267d\0\u26b8\0\u26f3\0\u272e"+
+    "\0\u2769\0\u27a4\0\u019d\0\u27df\0\u281a\0\u019d\0\u019d\0\u2855"+
+    "\0\u019d\0\u2890\0\u28cb\0\u2906\0\u2941\0\u297c\0\u29b7\0\u29f2"+
+    "\0\u2a2d\0\u2a68\0\u019d\0\u2aa3\0\u2ade\0\u2b19\0\u019d\0\u2b54"+
+    "\0\u2b8f\0\u019d\0\u2bca\0\u2c05\0\u2c40\0\u2c7b\0\u019d\0\u2cb6"+
+    "\0\u019d\0\u2cf1\0\u2d2c\0\u2d67\0\u019d\0\u019d\0\u2da2\0\u2ddd"+
+    "\0\u2e18\0\u2e53\0\u2e8e\0\u2ec9\0\u2f04\0\u019d\0\261\0\u2f3f"+
+    "\0\u2f7a\0\u2fb5\0\u019d\0\u2ff0\0\u302b\0\u019d\0\261\0\u3066"+
+    "\0\u30a1\0\u30dc\0\u019d\0\u019d\0\u3117\0\u019d\0\u019d\0\u3152"+
+    "\0\u318d\0\u019d\0\u31c8\0\u3203\0\u323e\0\u019d\0\u3279\0\u019d"+
+    "\0\u019d\0\u019d\0\u32b4\0\u32ef\0\u332a\0\u3365\0\u33a0\0\u33db"+
+    "\0\u3416\0\u3451\0\u348c\0\u34c7\0\u3502\0\u353d\0\u3578\0\u35b3"+
+    "\0\u35ee\0\u3629\0\u3664\0\u019d\0\u019d\0\261\0\u369f\0\u019d"+
+    "\0\u019d\0\u019d\0\u36da\0\u3715\0\u019d\0\u3750\0\u019d\0\u019d"+
+    "\0\u378b\0\u37c6\0\u3801\0\u383c\0\u3877\0\u38b2\0\u38ed\0\u019d"+
+    "\0\u019d\0\u3928\0\u019d\0\u3963\0\u399e\0\u39d9\0\u3a14\0\u3a4f"+
+    "\0\u3a8a\0\u3ac5\0\u3b00\0\u3b3b\0\u3b76\0\u3bb1\0\u019d\0\u019d"+
+    "\0\u019d\0\u3bec\0\u019d\0\u3c27\0\u019d\0\u3c62\0\u3c9d\0\u019d"+
+    "\0\u3cd8\0\u019d\0\u3d13\0\u019d\0\u019d\0\u3d4e\0\u3d89\0\u3dc4"+
+    "\0\u019d\0\u3dff\0\u019d\0\u019d\0\u3e3a\0\u3e75\0\u3eb0\0\u019d"+
+    "\0\u3eeb\0\u3f26\0\u3f61\0\u019d\0\u019d\0\u019d\0\u3f9c\0\u3fd7"+
+    "\0\u019d\0\u4012\0\u404d\0\u019d\0\u019d\0\u4088\0\u40c3\0\261"+
+    "\0\261";
+
+  private static int [] zzUnpackRowMap() {
+    int [] result = new int[385];
+    int offset = 0;
+    offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result);
+    return result;
+  }
+
+  private static int zzUnpackRowMap(String packed, int offset, int [] result) {
+    int i = 0;  /* index in packed string  */
+    int j = offset;  /* index in unpacked array */
+    int l = packed.length();
+    while (i < l) {
+      int high = packed.charAt(i++) << 16;
+      result[j++] = high | packed.charAt(i++);
+    }
+    return j;
+  }
+
+  /** 
+   * The transition table of the DFA
+   */
+  private static final int [] ZZ_TRANS = zzUnpackTrans();
+
+  private static final String ZZ_TRANS_PACKED_0 =
+    "\1\4\1\5\2\6\1\7\1\10\1\7\1\11\1\12"+
+    "\1\13\1\11\1\4\1\14\1\15\1\11\1\16\1\11"+
+    "\1\17\1\20\1\21\1\11\1\22\1\4\1\23\1\24"+
+    "\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\34"+
+    "\1\35\1\36\1\37\1\40\1\41\1\42\1\11\1\43"+
+    "\1\11\1\44\1\11\1\45\1\11\1\46\1\11\1\47"+
+    "\1\11\1\50\1\51\1\52\1\53\1\54\1\55\1\56"+
+    "\1\57\1\60\2\4\1\0\22\4\1\61\2\4\1\62"+
+    "\44\4\1\0\25\4\1\63\1\64\41\4\75\0\1\6"+
+    "\74\0\3\7\10\0\1\65\1\66\1\0\1\67\2\70"+
+    "\16\0\1\66\33\0\1\71\2\72\7\0\1\73\1\65"+
+    "\1\66\1\0\1\67\2\70\16\0\1\66\7\0\1\73"+
+    "\23\0\4\11\2\0\2\11\2\0\1\11\1\0\1\11"+
+    "\1\0\3\11\10\0\25\11\21\0\1\74\1\75\57\0"+
+    "\1\76\72\0\1\77\15\0\1\100\54\0\1\101\72\0"+
+    "\1\102\5\0\3\103\10\0\1\104\74\0\1\105\47\0"+
+    "\1\106\5\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\11\11\1\107\1\11\1\110"+
+    "\11\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\2\11\1\111\6\11\1\112"+
+    "\1\113\12\11\43\0\1\114\44\0\4\11\2\0\2\11"+
+    "\2\0\1\11\1\0\1\11\1\0\1\11\1\115\1\11"+
+    "\10\0\1\11\1\116\1\117\2\11\1\120\1\11\1\121"+
+    "\15\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\3\11\1\122\2\11\1\123"+
+    "\2\11\1\124\1\11\1\125\11\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\2\11\1\126"+
+    "\10\0\3\11\1\127\14\11\1\130\2\11\1\131\1\11"+
+    "\15\0\4\11\2\0\2\11\2\0\1\11\1\0\1\11"+
+    "\1\0\3\11\10\0\6\11\1\132\16\11\15\0\4\11"+
+    "\2\0\2\11\2\0\1\11\1\0\1\11\1\0\3\11"+
+    "\10\0\1\133\12\11\1\134\1\11\1\135\7\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\1\136\2\11\1\137\5\11\1\140\1\141"+
+    "\1\142\11\11\15\0\4\11\2\0\2\11\2\0\1\11"+
+    "\1\0\1\11\1\0\3\11\10\0\15\11\1\143\1\144"+
+    "\6\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\6\11\1\145\3\11\1\146"+
+    "\1\147\11\11\15\0\4\11\2\0\2\11\2\0\1\11"+
+    "\1\0\1\11\1\0\3\11\10\0\6\11\1\150\16\11"+
+    "\15\0\4\11\2\0\2\11\2\0\1\11\1\0\1\11"+
+    "\1\0\1\151\2\11\10\0\5\11\1\152\1\11\1\153"+
+    "\15\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\3\11\1\154\3\11\1\155"+
+    "\7\11\1\156\5\11\15\0\4\11\2\0\2\11\2\0"+
+    "\1\11\1\0\1\11\1\0\3\11\10\0\1\157\24\11"+
+    "\15\0\4\11\2\0\2\11\2\0\1\11\1\0\1\11"+
+    "\1\0\3\11\10\0\1\160\24\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\3\11\10\0"+
+    "\1\161\2\11\1\162\6\11\1\163\1\164\11\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\2\11\1\165\10\0\11\11\1\166\13\11\73\0\1\167"+
+    "\6\0\1\170\16\0\1\171\53\0\1\172\72\0\1\173"+
+    "\1\0\1\61\2\0\22\61\1\174\1\175\1\176\1\0"+
+    "\42\61\1\62\2\0\22\62\1\177\1\200\1\201\1\0"+
+    "\42\62\1\63\2\0\23\63\1\202\1\201\1\0\1\177"+
+    "\41\63\1\64\2\0\23\64\1\203\1\204\1\0\1\174"+
+    "\41\64\4\0\3\103\70\0\3\205\12\0\1\206\40\0"+
+    "\1\206\33\0\1\70\53\0\3\71\10\0\1\65\1\66"+
+    "\1\0\1\67\2\70\16\0\1\66\33\0\1\71\2\72"+
+    "\10\0\1\65\1\66\1\0\1\67\2\70\16\0\1\66"+
+    "\33\0\4\207\10\0\1\207\14\0\2\207\2\0\3\207"+
+    "\1\0\1\207\25\0\1\74\1\210\1\211\70\74\11\212"+
+    "\1\213\61\212\15\100\1\214\55\100\4\0\3\103\11\0"+
+    "\1\66\1\0\1\67\2\70\16\0\1\66\33\0\4\11"+
+    "\2\0\2\11\2\0\1\11\1\0\1\11\1\0\3\11"+
+    "\10\0\16\11\1\215\6\11\15\0\4\11\2\0\2\11"+
+    "\2\0\1\11\1\0\1\11\1\0\3\11\10\0\10\11"+
+    "\1\216\14\11\15\0\4\11\2\0\2\11\2\0\1\11"+
+    "\1\0\1\11\1\0\3\11\10\0\1\217\5\11\1\220"+
+    "\16\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\22\11\1\221\2\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\21\11\1\222\3\11\44\0\1\223\43\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\1\11\1\224\1\11\10\0\25\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\1\11\1\225"+
+    "\1\11\10\0\25\11\15\0\4\11\2\0\2\11\2\0"+
+    "\1\11\1\0\1\11\1\0\3\11\10\0\2\11\1\226"+
+    "\22\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\2\11\1\227\22\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\10\11\1\230\14\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\3\11\10\0"+
+    "\6\11\1\231\16\11\15\0\4\11\2\0\2\11\2\0"+
+    "\1\11\1\0\1\11\1\0\3\11\10\0\5\11\1\232"+
+    "\17\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\7\11\1\233\15\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\12\11\1\234\12\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\3\11\10\0"+
+    "\3\11\1\235\2\11\1\236\2\11\1\237\13\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\11\11\1\240\1\241\5\11\1\242\4\11"+
+    "\15\0\4\11\2\0\2\11\2\0\1\11\1\0\1\11"+
+    "\1\0\3\11\10\0\21\11\1\243\3\11\15\0\4\11"+
+    "\2\0\2\11\2\0\1\11\1\0\1\11\1\0\3\11"+
+    "\10\0\6\11\1\244\16\11\15\0\4\11\2\0\2\11"+
+    "\2\0\1\11\1\0\1\11\1\0\3\11\10\0\2\11"+
+    "\1\245\14\11\1\246\1\11\1\247\3\11\15\0\4\11"+
+    "\2\0\2\11\2\0\1\11\1\0\1\11\1\0\3\11"+
+    "\10\0\2\11\1\250\22\11\15\0\4\11\2\0\2\11"+
+    "\2\0\1\11\1\0\1\11\1\0\3\11\10\0\7\11"+
+    "\1\251\15\11\15\0\4\11\2\0\2\11\2\0\1\11"+
+    "\1\0\1\11\1\0\3\11\10\0\1\252\24\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\15\11\1\253\7\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\3\11\10\0"+
+    "\13\11\1\254\11\11\15\0\4\11\2\0\2\11\2\0"+
+    "\1\11\1\0\1\11\1\0\3\11\10\0\3\11\1\255"+
+    "\3\11\1\256\15\11\15\0\4\11\2\0\2\11\2\0"+
+    "\1\11\1\0\1\11\1\0\3\11\10\0\7\11\1\257"+
+    "\15\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\3\11\1\260\21\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\1\11\1\261\1\11\10\0\25\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\3\11\10\0"+
+    "\2\11\1\262\1\11\1\263\20\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\3\11\10\0"+
+    "\23\11\1\264\1\11\15\0\4\11\2\0\2\11\2\0"+
+    "\1\11\1\0\1\11\1\0\3\11\10\0\15\11\1\265"+
+    "\7\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\2\11\1\266\22\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\5\11\1\267\7\11\1\270\7\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\21\11\1\271\3\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\1\11\1\272"+
+    "\1\11\10\0\2\11\1\273\5\11\1\274\1\275\5\11"+
+    "\1\276\5\11\15\0\4\11\2\0\2\11\2\0\1\11"+
+    "\1\0\1\11\1\0\3\11\10\0\6\11\1\277\16\11"+
+    "\15\0\4\11\2\0\2\11\2\0\1\11\1\0\1\11"+
+    "\1\0\1\11\1\300\1\11\10\0\22\11\1\301\2\11"+
+    "\15\0\4\11\2\0\2\11\2\0\1\11\1\0\1\11"+
+    "\1\0\3\11\10\0\3\11\1\302\21\11\15\0\4\11"+
+    "\2\0\2\11\2\0\1\11\1\0\1\11\1\0\3\11"+
+    "\10\0\4\11\1\303\20\11\15\0\4\11\2\0\2\11"+
+    "\2\0\1\11\1\0\1\11\1\0\3\11\10\0\11\11"+
+    "\1\304\1\11\1\305\11\11\15\0\4\11\2\0\2\11"+
+    "\2\0\1\11\1\0\1\11\1\0\3\11\10\0\1\11"+
+    "\1\306\23\11\15\0\4\11\2\0\2\11\2\0\1\11"+
+    "\1\0\1\11\1\0\1\11\1\307\1\11\10\0\25\11"+
+    "\15\0\4\11\2\0\2\11\2\0\1\11\1\0\1\11"+
+    "\1\0\3\11\10\0\6\11\1\310\2\11\1\311\13\11"+
+    "\15\0\4\11\2\0\2\11\2\0\1\11\1\0\1\11"+
+    "\1\0\3\11\10\0\2\11\1\312\22\11\11\0\1\61"+
+    "\2\0\70\61\1\62\2\0\70\62\1\63\2\0\70\63"+
+    "\1\64\2\0\70\64\4\0\3\205\13\0\1\67\2\70"+
+    "\52\0\3\205\66\0\1\211\70\0\11\212\1\313\61\212"+
+    "\10\314\1\315\1\0\61\314\15\100\1\316\55\100\4\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\11\11\1\317\13\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\3\11\10\0"+
+    "\2\11\1\320\22\11\15\0\4\11\2\0\2\11\2\0"+
+    "\1\11\1\0\1\11\1\0\3\11\10\0\21\11\1\321"+
+    "\3\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\6\11\1\322\16\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\6\11\1\323\16\11\11\0\34\324\1\0"+
+    "\36\324\4\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\6\11\1\325\16\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\2\11\1\326\22\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\3\11\10\0"+
+    "\3\11\1\327\21\11\15\0\4\11\2\0\2\11\2\0"+
+    "\1\11\1\0\1\11\1\0\3\11\10\0\6\11\1\330"+
+    "\16\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\1\331\24\11\15\0\4\11"+
+    "\2\0\2\11\2\0\1\11\1\0\1\11\1\0\3\11"+
+    "\10\0\13\11\1\332\11\11\15\0\4\11\2\0\2\11"+
+    "\2\0\1\11\1\0\1\11\1\0\3\11\10\0\10\11"+
+    "\1\333\14\11\15\0\4\11\2\0\2\11\2\0\1\11"+
+    "\1\0\1\11\1\0\3\11\10\0\7\11\1\334\15\11"+
+    "\15\0\4\11\2\0\2\11\2\0\1\11\1\0\1\11"+
+    "\1\0\3\11\10\0\13\11\1\335\11\11\15\0\4\11"+
+    "\2\0\2\11\2\0\1\11\1\0\1\11\1\0\3\11"+
+    "\10\0\7\11\1\336\15\11\15\0\4\11\2\0\2\11"+
+    "\2\0\1\11\1\0\1\11\1\0\1\11\1\337\1\11"+
+    "\10\0\25\11\15\0\4\11\2\0\2\11\2\0\1\11"+
+    "\1\0\1\11\1\0\3\11\10\0\24\11\1\340\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\6\11\1\341\16\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\3\11\10\0"+
+    "\6\11\1\342\16\11\15\0\4\11\2\0\2\11\2\0"+
+    "\1\11\1\0\1\11\1\0\3\11\10\0\6\11\1\343"+
+    "\16\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\12\11\1\344\12\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\6\11\1\345\16\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\3\11\10\0"+
+    "\15\11\1\346\7\11\15\0\4\11\2\0\2\11\2\0"+
+    "\1\11\1\0\1\11\1\0\3\11\10\0\4\11\1\347"+
+    "\20\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\2\11\1\350\22\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\1\11\1\351\1\11\10\0\25\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\1\11\1\352"+
+    "\1\11\10\0\25\11\15\0\4\11\2\0\2\11\2\0"+
+    "\1\11\1\0\1\11\1\0\1\353\2\11\10\0\25\11"+
+    "\15\0\4\11\2\0\2\11\2\0\1\11\1\0\1\11"+
+    "\1\0\1\11\1\354\1\11\10\0\25\11\15\0\4\11"+
+    "\2\0\2\11\2\0\1\11\1\0\1\11\1\0\3\11"+
+    "\10\0\1\355\24\11\15\0\4\11\2\0\2\11\2\0"+
+    "\1\11\1\0\1\11\1\0\3\11\10\0\4\11\1\356"+
+    "\20\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\6\11\1\357\16\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\6\11\1\360\16\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\3\11\10\0"+
+    "\15\11\1\361\7\11\15\0\4\11\2\0\2\11\2\0"+
+    "\1\11\1\0\1\11\1\0\3\11\10\0\15\11\1\362"+
+    "\7\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\6\11\1\363\16\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\13\11\1\364\11\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\3\11\10\0"+
+    "\2\11\1\365\3\11\1\366\16\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\3\11\10\0"+
+    "\13\11\1\367\11\11\15\0\4\11\2\0\2\11\2\0"+
+    "\1\11\1\0\1\11\1\0\3\11\10\0\6\11\1\370"+
+    "\16\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\2\11\1\371\22\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\1\372\5\11\1\373\16\11\15\0\4\11"+
+    "\2\0\2\11\2\0\1\11\1\0\1\11\1\0\3\11"+
+    "\10\0\3\11\1\374\21\11\15\0\4\11\2\0\2\11"+
+    "\2\0\1\11\1\0\1\11\1\0\3\11\10\0\2\11"+
+    "\1\375\22\11\15\0\4\11\2\0\2\11\2\0\1\11"+
+    "\1\0\1\11\1\0\3\11\10\0\20\11\1\376\4\11"+
+    "\15\0\4\11\2\0\2\11\2\0\1\11\1\0\1\11"+
+    "\1\0\3\11\10\0\14\11\1\377\10\11\15\0\4\11"+
+    "\2\0\2\11\2\0\1\11\1\0\1\11\1\0\3\11"+
+    "\10\0\17\11\1\u0100\5\11\15\0\4\11\2\0\2\11"+
+    "\2\0\1\11\1\0\1\11\1\0\3\11\10\0\2\11"+
+    "\1\u0101\22\11\15\0\4\11\2\0\2\11\2\0\1\11"+
+    "\1\0\1\11\1\0\3\11\10\0\15\11\1\u0102\7\11"+
+    "\15\0\4\11\2\0\2\11\2\0\1\11\1\0\1\11"+
+    "\1\0\3\11\10\0\2\11\1\u0103\22\11\15\0\4\11"+
+    "\2\0\2\11\2\0\1\11\1\0\1\11\1\0\3\11"+
+    "\10\0\3\11\1\u0104\21\11\15\0\4\11\2\0\2\11"+
+    "\2\0\1\11\1\0\1\11\1\0\3\11\10\0\15\11"+
+    "\1\u0105\7\11\15\0\4\11\2\0\2\11\2\0\1\11"+
+    "\1\0\1\11\1\0\2\11\1\u0106\10\0\25\11\11\0"+
+    "\10\212\1\u0107\1\u0108\61\212\11\314\1\u0109\61\314\11\0"+
+    "\1\u010a\76\0\1\316\61\0\4\11\2\0\2\11\2\0"+
+    "\1\11\1\0\1\11\1\0\3\11\10\0\7\11\1\u010b"+
+    "\15\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\11\11\1\u010c\13\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\13\11\1\u010d\11\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\3\11\10\0"+
+    "\3\11\1\u010e\21\11\11\0\34\324\1\u010f\36\324\4\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\3\11\1\u0110\21\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\3\11\10\0"+
+    "\3\11\1\u0111\21\11\15\0\4\11\2\0\2\11\2\0"+
+    "\1\11\1\0\1\11\1\0\3\11\10\0\11\11\1\u0112"+
+    "\13\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\3\11\1\u0113\21\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\14\11\1\u0114\10\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\3\11\10\0"+
+    "\3\11\1\u0115\21\11\15\0\4\11\2\0\2\11\2\0"+
+    "\1\11\1\0\1\11\1\0\3\11\10\0\10\11\1\u0116"+
+    "\14\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\23\11\1\u0117\1\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\24\11\1\u0118\15\0\4\11\2\0\2\11"+
+    "\2\0\1\11\1\0\1\11\1\0\3\11\10\0\13\11"+
+    "\1\u0119\11\11\15\0\4\11\2\0\2\11\2\0\1\11"+
+    "\1\0\1\11\1\0\3\11\10\0\7\11\1\u011a\15\11"+
+    "\15\0\4\11\2\0\2\11\2\0\1\11\1\0\1\11"+
+    "\1\0\3\11\10\0\3\11\1\u011b\21\11\15\0\4\11"+
+    "\2\0\2\11\2\0\1\11\1\0\1\11\1\0\3\11"+
+    "\10\0\3\11\1\u011c\21\11\15\0\4\11\2\0\2\11"+
+    "\2\0\1\11\1\0\1\11\1\0\3\11\10\0\1\u011d"+
+    "\24\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\2\11\1\u011e\10\0\25\11\15\0\4\11"+
+    "\2\0\2\11\2\0\1\11\1\0\1\11\1\0\3\11"+
+    "\10\0\11\11\1\u011f\13\11\15\0\4\11\2\0\2\11"+
+    "\2\0\1\11\1\0\1\11\1\0\1\11\1\u0120\1\11"+
+    "\10\0\25\11\15\0\4\11\2\0\2\11\2\0\1\11"+
+    "\1\0\1\11\1\0\3\11\10\0\6\11\1\u0121\16\11"+
+    "\15\0\4\11\2\0\2\11\2\0\1\11\1\0\1\11"+
+    "\1\0\3\11\10\0\2\11\1\u0122\22\11\15\0\4\11"+
+    "\2\0\2\11\2\0\1\11\1\0\1\11\1\0\3\11"+
+    "\10\0\15\11\1\u0123\7\11\15\0\4\11\2\0\2\11"+
+    "\2\0\1\11\1\0\1\11\1\0\3\11\10\0\2\11"+
+    "\1\u0124\22\11\15\0\4\11\2\0\2\11\2\0\1\11"+
+    "\1\0\1\11\1\0\3\11\10\0\7\11\1\u0125\15\11"+
+    "\15\0\4\11\2\0\2\11\2\0\1\11\1\0\1\11"+
+    "\1\0\3\11\10\0\12\11\1\u0126\12\11\15\0\4\11"+
+    "\2\0\2\11\2\0\1\11\1\0\1\11\1\0\3\11"+
+    "\10\0\2\11\1\u0127\22\11\15\0\4\11\2\0\2\11"+
+    "\2\0\1\11\1\0\1\11\1\0\3\11\10\0\3\11"+
+    "\1\u0128\21\11\15\0\4\11\2\0\2\11\2\0\1\11"+
+    "\1\0\1\11\1\0\3\11\10\0\1\u0129\24\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\3\11\1\u012a\21\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\3\11\10\0"+
+    "\16\11\1\u012b\6\11\15\0\4\11\2\0\2\11\2\0"+
+    "\1\11\1\0\1\11\1\0\3\11\10\0\15\11\1\u012c"+
+    "\7\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\3\11\1\u012d\21\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\3\11\1\u012e\21\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\3\11\10\0"+
+    "\1\u012f\24\11\15\0\4\11\2\0\2\11\2\0\1\11"+
+    "\1\0\1\11\1\0\3\11\10\0\1\u0130\24\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\6\11\1\u0131\16\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\3\11\10\0"+
+    "\11\11\1\u0132\13\11\15\0\4\11\2\0\2\11\2\0"+
+    "\1\11\1\0\1\11\1\0\3\11\10\0\11\11\1\u0133"+
+    "\13\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\6\11\1\u0134\16\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\6\11\1\u0135\16\11\11\0\10\212\1\0"+
+    "\1\u0108\61\212\10\314\1\u0136\1\u0137\61\314\11\0\1\213"+
+    "\65\0\4\11\2\0\2\11\2\0\1\11\1\0\1\11"+
+    "\1\0\3\11\10\0\4\11\1\u0138\20\11\15\0\4\11"+
+    "\2\0\2\11\2\0\1\11\1\0\1\11\1\0\3\11"+
+    "\10\0\5\11\1\u0139\17\11\15\0\4\11\2\0\2\11"+
+    "\2\0\1\11\1\0\1\11\1\0\3\11\10\0\2\11"+
+    "\1\u013a\22\11\15\0\4\11\2\0\2\11\2\0\1\11"+
+    "\1\0\1\11\1\0\3\11\10\0\1\u013b\24\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\1\11\1\u013c\23\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\3\11\10\0"+
+    "\6\11\1\u013d\16\11\15\0\4\11\2\0\2\11\2\0"+
+    "\1\11\1\0\1\11\1\0\3\11\10\0\6\11\1\u013e"+
+    "\16\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\5\11\1\u013f\17\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\7\11\1\u0140\15\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\1\11\1\u0141"+
+    "\1\11\10\0\25\11\15\0\4\11\2\0\2\11\2\0"+
+    "\1\11\1\0\1\11\1\0\3\11\10\0\4\11\1\u0142"+
+    "\20\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\7\11\1\u0143\15\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\15\11\1\u0144\7\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\3\11\10\0"+
+    "\11\11\1\u0145\13\11\15\0\4\11\2\0\2\11\2\0"+
+    "\1\11\1\0\1\11\1\0\3\11\10\0\10\11\1\u0146"+
+    "\14\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\1\11\1\u0147\1\11\10\0\25\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\6\11\1\u0148\16\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\3\11\10\0"+
+    "\2\11\1\u0149\22\11\15\0\4\11\2\0\2\11\2\0"+
+    "\1\11\1\0\1\11\1\0\3\11\10\0\7\11\1\u014a"+
+    "\15\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\2\11\1\u014b\22\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\13\11\1\u014c\11\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\3\11\10\0"+
+    "\11\11\1\u014d\13\11\15\0\4\11\2\0\2\11\2\0"+
+    "\1\11\1\0\1\11\1\0\1\11\1\u014e\1\11\10\0"+
+    "\25\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\11\11\1\u014f\13\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\24\11\1\u0150\15\0\4\11\2\0\2\11"+
+    "\2\0\1\11\1\0\1\11\1\0\3\11\10\0\2\11"+
+    "\1\u0151\22\11\15\0\4\11\2\0\2\11\2\0\1\11"+
+    "\1\0\1\11\1\0\3\11\10\0\4\11\1\u0152\20\11"+
+    "\15\0\4\11\2\0\2\11\2\0\1\11\1\0\1\11"+
+    "\1\0\3\11\10\0\4\11\1\u0153\20\11\15\0\4\11"+
+    "\2\0\2\11\2\0\1\11\1\0\1\11\1\0\3\11"+
+    "\10\0\7\11\1\u0154\15\11\11\0\10\314\1\0\1\u0137"+
+    "\61\314\4\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\4\11\1\u0155\20\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\12\11\1\u0156\12\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\3\11\10\0"+
+    "\3\11\1\u0157\21\11\15\0\4\11\2\0\2\11\2\0"+
+    "\1\11\1\0\1\11\1\0\3\11\10\0\6\11\1\u0158"+
+    "\16\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\6\11\1\u0159\16\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\12\11\1\u015a\12\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\3\11\10\0"+
+    "\20\11\1\u015b\4\11\15\0\4\11\2\0\2\11\2\0"+
+    "\1\11\1\0\1\11\1\0\3\11\10\0\13\11\1\u015c"+
+    "\11\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\1\11\1\u015d\1\11\10\0\25\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\11\11\1\u015e\13\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\3\11\10\0"+
+    "\4\11\1\u015f\20\11\15\0\4\11\2\0\2\11\2\0"+
+    "\1\11\1\0\1\11\1\0\3\11\10\0\5\11\1\u0160"+
+    "\17\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\10\11\1\u0161\14\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\6\11\1\u0162\16\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\3\11\10\0"+
+    "\10\11\1\u0163\14\11\15\0\4\11\2\0\2\11\2\0"+
+    "\1\11\1\0\1\11\1\0\3\11\10\0\6\11\1\u0164"+
+    "\16\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\6\11\1\u0165\16\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\2\11\1\u0166\22\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\3\11\10\0"+
+    "\25\11\1\u0167\14\0\4\11\2\0\2\11\2\0\1\11"+
+    "\1\0\1\11\1\0\3\11\10\0\11\11\1\u0168\13\11"+
+    "\15\0\4\11\2\0\2\11\2\0\1\11\1\0\1\11"+
+    "\1\0\3\11\10\0\2\11\1\u0169\22\11\15\0\4\11"+
+    "\2\0\2\11\2\0\1\11\1\0\1\11\1\0\3\11"+
+    "\10\0\2\11\1\u016a\22\11\15\0\4\11\2\0\2\11"+
+    "\2\0\1\11\1\0\1\11\1\0\3\11\10\0\6\11"+
+    "\1\u016b\16\11\15\0\4\11\2\0\2\11\2\0\1\11"+
+    "\1\0\1\11\1\0\3\11\10\0\7\11\1\u016c\15\11"+
+    "\15\0\4\11\2\0\2\11\2\0\1\11\1\0\1\11"+
+    "\1\0\3\11\10\0\17\11\1\u016d\5\11\15\0\4\11"+
+    "\2\0\2\11\2\0\1\11\1\0\1\11\1\0\3\11"+
+    "\10\0\6\11\1\u016e\16\11\15\0\4\11\2\0\2\11"+
+    "\2\0\1\11\1\0\1\11\1\0\3\11\10\0\1\u016f"+
+    "\24\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\6\11\1\u0170\16\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\6\11\1\u0171\16\11\51\0\1\u0172\5\0"+
+    "\1\u0173\30\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\2\11\1\u0174\22\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\6\11\1\u0175\16\11\15\0\4\11\2\0"+
+    "\2\11\2\0\1\11\1\0\1\11\1\0\3\11\10\0"+
+    "\6\11\1\u0176\16\11\15\0\4\11\2\0\2\11\2\0"+
+    "\1\11\1\0\1\11\1\0\3\11\10\0\13\11\1\u0177"+
+    "\11\11\15\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\2\11\1\u0178\22\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\10\11\1\u0179\14\11\54\0\1\u017a\73\0"+
+    "\1\u017b\32\0\4\11\2\0\2\11\2\0\1\11\1\0"+
+    "\1\11\1\0\3\11\10\0\5\11\1\u017c\17\11\15\0"+
+    "\4\11\2\0\2\11\2\0\1\11\1\0\1\11\1\0"+
+    "\3\11\10\0\6\11\1\u017d\16\11\46\0\1\u017e\103\0"+
+    "\1\u017f\71\0\1\u0180\64\0\1\u0181\33\0";
+
+  private static int [] zzUnpackTrans() {
+    int [] result = new int[16638];
+    int offset = 0;
+    offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result);
+    return result;
+  }
+
+  private static int zzUnpackTrans(String packed, int offset, int [] result) {
+    int i = 0;       /* index in packed string  */
+    int j = offset;  /* index in unpacked array */
+    int l = packed.length();
+    while (i < l) {
+      int count = packed.charAt(i++);
+      int value = packed.charAt(i++);
+      value--;
+      do result[j++] = value; while (--count > 0);
+    }
+    return j;
+  }
+
+
+  /* error codes */
+  private static final int ZZ_UNKNOWN_ERROR = 0;
+  private static final int ZZ_NO_MATCH = 1;
+  private static final int ZZ_PUSHBACK_2BIG = 2;
+  private static final char[] EMPTY_BUFFER = new char[0];
+  private static final int YYEOF = -1;
+  private static java.io.Reader zzReader = null; // Fake
+
+  /* error messages for the codes above */
+  private static final String ZZ_ERROR_MSG[] = {
+    "Unkown internal scanner error",
+    "Error: could not match input",
+    "Error: pushback value was too large"
+  };
+
+  /**
+   * ZZ_ATTRIBUTE[aState] contains the attributes of state <code>aState</code>
+   */
+  private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute();
+
+  private static final String ZZ_ATTRIBUTE_PACKED_0 =
+    "\3\0\1\11\1\1\1\11\13\1\4\11\1\1\2\11"+
+    "\20\1\6\11\6\1\2\0\1\1\1\11\2\1\1\0"+
+    "\2\1\2\11\1\0\2\11\1\1\3\11\60\1\6\11"+
+    "\1\1\2\11\1\1\1\11\2\1\1\11\1\1\1\0"+
+    "\2\1\1\11\2\1\1\0\6\1\1\0\67\1\1\0"+
+    "\10\1\1\0\62\1\1\11\3\0\4\1\1\11\46\1"+
+    "\1\11\1\0\57\1\1\0\12\1\2\0\6\1\2\0"+
+    "\2\1\2\0\2\11";
+
+  private static int [] zzUnpackAttribute() {
+    int [] result = new int[385];
+    int offset = 0;
+    offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result);
+    return result;
+  }
+
+  private static int zzUnpackAttribute(String packed, int offset, int [] result) {
+    int i = 0;       /* index in packed string  */
+    int j = offset;  /* index in unpacked array */
+    int l = packed.length();
+    while (i < l) {
+      int count = packed.charAt(i++);
+      int value = packed.charAt(i++);
+      do result[j++] = value; while (--count > 0);
+    }
+    return j;
+  }
+
+  /** the current state of the DFA */
+  private int zzState;
+
+  /** the current lexical state */
+  private int zzLexicalState = YYINITIAL;
+
+  /** this buffer contains the current text to be matched and is
+      the source of the yytext() string */
+  private CharSequence zzBuffer = "";
+
+  /** this buffer may contains the current text array to be matched when it is cheap to acquire it */
+  private char[] zzBufferArray;
+
+  /** the textposition at the last accepting state */
+  private int zzMarkedPos;
+
+  /** the textposition at the last state to be included in yytext */
+  private int zzPushbackPos;
+
+  /** the current text position in the buffer */
+  private int zzCurrentPos;
+
+  /** startRead marks the beginning of the yytext() string in the buffer */
+  private int zzStartRead;
+
+  /** endRead marks the last character in the buffer, that has been read
+      from input */
+  private int zzEndRead;
+
+  /**
+   * zzAtBOL == true <=> the scanner is currently at the beginning of a line
+   */
+  private boolean zzAtBOL = true;
+
+  /** zzAtEOF == true <=> the scanner is at the EOF */
+  private boolean zzAtEOF;
+
+  /** denotes if the user-EOF-code has already been executed */
+  private boolean zzEOFDone;
+
+  /* user code: */
+  private BraceQuoteTracker myQuoteStack = BraceQuoteTracker.NULL_BQT;
+
+
+  _JavaFxLexer(java.io.Reader in) {
+    this.zzReader = in;
+  }
+
+  /**
+   * Creates a new scanner.
+   * There is also java.io.Reader version of this constructor.
+   *
+   * @param   in  the java.io.Inputstream to read input from.
+   */
+  _JavaFxLexer(java.io.InputStream in) {
+    this(new java.io.InputStreamReader(in));
+  }
+
+  /** 
+   * Unpacks the compressed character translation table.
+   *
+   * @param packed   the packed character translation table
+   * @return         the unpacked character translation table
+   */
+  private static char [] zzUnpackCMap(String packed) {
+    char [] map = new char[0x10000];
+    int i = 0;  /* index in packed string  */
+    int j = 0;  /* index in unpacked array */
+    while (i < 1768) {
+      int  count = packed.charAt(i++);
+      char value = packed.charAt(i++);
+      do map[j++] = value; while (--count > 0);
+    }
+    return map;
+  }
+
+  public final int getTokenStart(){
+    return zzStartRead;
+  }
+
+  public final int getTokenEnd(){
+    return getTokenStart() + yylength();
+  }
+
+  public void reset(CharSequence buffer, int start, int end,int initialState){
+    zzBuffer = buffer;
+    zzBufferArray = com.intellij.util.text.CharArrayUtil.fromSequenceWithoutCopying(buffer);
+    zzCurrentPos = zzMarkedPos = zzStartRead = start;
+    zzPushbackPos = 0;
+    zzAtEOF  = false;
+    zzAtBOL = true;
+    zzEndRead = end;
+    yybegin(initialState);
+  }
+
+  /**
+   * Refills the input buffer.
+   *
+   * @return      <code>false</code>, iff there was new input.
+   *
+   * @exception   java.io.IOException  if any I/O-Error occurs
+   */
+  private boolean zzRefill() throws java.io.IOException {
+    return true;
+  }
+
+
+  /**
+   * Returns the current lexical state.
+   */
+  public final int yystate() {
+    return zzLexicalState;
+  }
+
+
+  /**
+   * Enters a new lexical state
+   *
+   * @param newState the new lexical state
+   */
+  public final void yybegin(int newState) {
+    zzLexicalState = newState;
+  }
+
+
+  /**
+   * Returns the text matched by the current regular expression.
+   */
+  public final CharSequence yytext() {
+    return zzBuffer.subSequence(zzStartRead, zzMarkedPos);
+  }
+
+
+  /**
+   * Returns the character at position <tt>pos</tt> from the
+   * matched text.
+   *
+   * It is equivalent to yytext().charAt(pos), but faster
+   *
+   * @param pos the position of the character to fetch.
+   *            A value from 0 to yylength()-1.
+   *
+   * @return the character at position pos
+   */
+  public final char yycharat(int pos) {
+    return zzBufferArray != null ? zzBufferArray[zzStartRead+pos]:zzBuffer.charAt(zzStartRead+pos);
+  }
+
+
+  /**
+   * Returns the length of the matched text region.
+   */
+  public final int yylength() {
+    return zzMarkedPos-zzStartRead;
+  }
+
+
+  /**
+   * Reports an error that occured while scanning.
+   *
+   * In a wellformed scanner (no or only correct usage of
+   * yypushback(int) and a match-all fallback rule) this method
+   * will only be called with things that "Can't Possibly Happen".
+   * If this method is called, something is seriously wrong
+   * (e.g. a JFlex bug producing a faulty scanner etc.).
+   *
+   * Usual syntax/scanner level error handling should be done
+   * in error fallback rules.
+   *
+   * @param   errorCode  the code of the errormessage to display
+   */
+  private void zzScanError(int errorCode) {
+    String message;
+    try {
+      message = ZZ_ERROR_MSG[errorCode];
+    }
+    catch (ArrayIndexOutOfBoundsException e) {
+      message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR];
+    }
+
+    throw new Error(message);
+  }
+
+
+  /**
+   * Pushes the specified amount of characters back into the input stream.
+   *
+   * They will be read again by then next call of the scanning method
+   *
+   * @param number  the number of characters to be read again.
+   *                This number must not be greater than yylength()!
+   */
+  public void yypushback(int number)  {
+    if ( number > yylength() )
+      zzScanError(ZZ_PUSHBACK_2BIG);
+
+    zzMarkedPos -= number;
+  }
+
+
+  /**
+   * Contains user EOF-code, which will be executed exactly once,
+   * when the end of file is reached
+   */
+  private void zzDoEOF() {
+    if (!zzEOFDone) {
+      zzEOFDone = true;
+    
+    }
+  }
+
+
+  /**
+   * Resumes scanning until the next regular expression is matched,
+   * the end of input is encountered or an I/O-Error occurs.
+   *
+   * @return      the next token
+   * @exception   java.io.IOException  if any I/O-Error occurs
+   */
+  public IElementType advance() throws java.io.IOException {
+    int zzInput;
+    int zzAction;
+
+    // cached fields:
+    int zzCurrentPosL;
+    int zzMarkedPosL;
+    int zzEndReadL = zzEndRead;
+    CharSequence zzBufferL = zzBuffer;
+    char[] zzBufferArrayL = zzBufferArray;
+    char [] zzCMapL = ZZ_CMAP;
+
+    int [] zzTransL = ZZ_TRANS;
+    int [] zzRowMapL = ZZ_ROWMAP;
+    int [] zzAttrL = ZZ_ATTRIBUTE;
+
+    while (true) {
+      zzMarkedPosL = zzMarkedPos;
+
+      zzAction = -1;
+
+      zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL;
+
+      zzState = ZZ_LEXSTATE[zzLexicalState];
+
+
+      zzForAction: {
+        while (true) {
+
+          if (zzCurrentPosL < zzEndReadL)
+            zzInput = zzBufferArrayL != null ? zzBufferArrayL[zzCurrentPosL++]:zzBufferL.charAt(zzCurrentPosL++);
+          else if (zzAtEOF) {
+            zzInput = YYEOF;
+            break zzForAction;
+          }
+          else {
+            // store back cached positions
+            zzCurrentPos  = zzCurrentPosL;
+            zzMarkedPos   = zzMarkedPosL;
+            boolean eof = zzRefill();
+            // get translated positions and possibly new buffer
+            zzCurrentPosL  = zzCurrentPos;
+            zzMarkedPosL   = zzMarkedPos;
+            zzBufferL      = zzBuffer;
+            zzEndReadL     = zzEndRead;
+            if (eof) {
+              zzInput = YYEOF;
+              break zzForAction;
+            }
+            else {
+              zzInput = zzBufferArrayL != null ? zzBufferArrayL[zzCurrentPosL++]:zzBufferL.charAt(zzCurrentPosL++);
+            }
+          }
+          int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ];
+          if (zzNext == -1) break zzForAction;
+          zzState = zzNext;
+
+          int zzAttributes = zzAttrL[zzState];
+          if ( (zzAttributes & 1) == 1 ) {
+            zzAction = zzState;
+            zzMarkedPosL = zzCurrentPosL;
+            if ( (zzAttributes & 8) == 8 ) break zzForAction;
+          }
+
+        }
+      }
+
+      // store back cached position
+      zzMarkedPos = zzMarkedPosL;
+
+      switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) {
+        case 65: 
+          { return JavaFxTokenTypes.THIS_KEYWORD;
+          }
+        case 119: break;
+        case 99: 
+          { return JavaFxTokenTypes.REVERSE_KEYWORD;
+          }
+        case 120: break;
+        case 9: 
+          { return (JavaFxTokenTypes.DOT);
+          }
+        case 121: break;
+        case 50: 
+          { yybegin(YYINITIAL);
+    myQuoteStack = myQuoteStack.enterBrace(STRING, false);
+    return JavaFxTokenTypes.LBRACE_STRING_LITERAL;
+          }
+        case 122: break;
+        case 14: 
+          { zzMarkedPos = zzCurrentPos; yybegin(CHAR);
+          }
+        case 123: break;
+        case 116: 
+          { return JavaFxTokenTypes.INVALIDATE_KEYWORD;
+          }
+        case 124: break;
+        case 104: 
+          { return JavaFxTokenTypes.INVERSE_KEYWORD;
+          }
+        case 125: break;
+        case 107: 
+          { return JavaFxTokenTypes.ABSTRACT_KEYWORD;
+          }
+        case 126: break;
+        case 31: 
+          { return (JavaFxTokenTypes.DIVEQ);
+          }
+        case 127: break;
+        case 20: 
+          { return (JavaFxTokenTypes.SEMICOLON);
+          }
+        case 128: break;
+        case 69: 
+          { return JavaFxTokenTypes.NULL_KEYWORD;
+          }
+        case 129: break;
+        case 55: 
+          { return JavaFxTokenTypes.AND_KEYWORD;
+          }
+        case 130: break;
+        case 98: 
+          { return JavaFxTokenTypes.TRIGGER_KEYWORD;
+          }
+        case 131: break;
+        case 41: 
+          { return JavaFxTokenTypes.IF_KEYWORD;
+          }
+        case 132: break;
+        case 57: 
+          { return JavaFxTokenTypes.FOR_KEYWORD;
+          }
+        case 133: break;
+        case 59: 
+          { return JavaFxTokenTypes.NOT_KEYWORD;
+          }
+        case 134: break;
+        case 16: 
+          { return (JavaFxTokenTypes.RBRACK);
+          }
+        case 135: break;
+        case 30: 
+          { return JavaFxTokenTypes.C_STYLE_COMMENT;
+          }
+        case 136: break;
+        case 70: 
+          { return JavaFxTokenTypes.INTO_KEYWORD;
+          }
+        case 137: break;
+        case 113: 
+          { return JavaFxTokenTypes.EXCLUSIVE_KEYWORD;
+          }
+        case 138: break;
+        case 101: 
+          { return JavaFxTokenTypes.FINALLY_KEYWORD;
+          }
+        case 139: break;
+        case 110: 
+          { return JavaFxTokenTypes.OVERRIDE_KEYWORD;
+          }
+        case 140: break;
+        case 68: 
+          { return JavaFxTokenTypes.ELSE_KEYWORD;
+          }
+        case 141: break;
+        case 82: 
+          { return JavaFxTokenTypes.CATCH_KEYWORD;
+          }
+        case 142: break;
+        case 35: 
+          { return (JavaFxTokenTypes.RANGE);
+          }
+        case 143: break;
+        case 62: 
+          { return JavaFxTokenTypes.STEP_KEYWORD;
+          }
+        case 144: break;
+        case 85: 
+          { return JavaFxTokenTypes.FIRST_KEYWORD;
+          }
+        case 145: break;
+        case 28: 
+          { return JavaFxTokenTypes.NUMBER_LITERAL;
+          }
+        case 146: break;
+        case 105: 
+          { return JavaFxTokenTypes.PACKAGE_KEYWORD;
+          }
+        case 147: break;
+        case 75: 
+          { return JavaFxTokenTypes.MIXIN_KEYWORD;
+          }
+        case 148: break;
+        case 27: 
+          { return JavaFxTokenTypes.DURATION_LITERAL;
+          }
+        case 149: break;
+        case 17: 
+          { return (JavaFxTokenTypes.MINUS);
+          }
+        case 150: break;
+        case 56: 
+          { return JavaFxTokenTypes.TRY_KEYWORD;
+          }
+        case 151: break;
+        case 88: 
+          { return JavaFxTokenTypes.STATIC_KEYWORD;
+          }
+        case 152: break;
+        case 29: 
+          { return JavaFxTokenTypes.END_OF_LINE_COMMENT;
+          }
+        case 153: break;
+        case 15: 
+          { return (JavaFxTokenTypes.LBRACK);
+          }
+        case 154: break;
+        case 4: 
+          { return JavaFxTokenTypes.IDENTIFIER;
+          }
+        case 155: break;
+        case 26: 
+          { yybegin(YYINITIAL);
+    myQuoteStack = myQuoteStack.leaveQuote();
+    return JavaFxTokenTypes.RBRACE_STRING_LITERAL;
+          }
+        case 156: break;
+        case 86: 
+          { return JavaFxTokenTypes.WHERE_KEYWORD;
+          }
+        case 157: break;
+        case 54: 
+          { return JavaFxTokenTypes.MOD_KEYWORD;
+          }
+        case 158: break;
+        case 111: 
+          { return JavaFxTokenTypes.POSTINIT_KEYWORD;
+          }
+        case 159: break;
+        case 2: 
+          { return JavaFxTokenTypes.WHITE_SPACE;
+          }
+        case 160: break;
+        case 33: 
+          { return (JavaFxTokenTypes.LTEQ);
+          }
+        case 161: break;
+        case 83: 
+          { return JavaFxTokenTypes.CLASS_KEYWORD;
+          }
+        case 162: break;
+        case 80: 
+          { return JavaFxTokenTypes.THROW_KEYWORD;
+          }
+        case 163: break;
+        case 42: 
+          { return JavaFxTokenTypes.IN_KEYWORD;
+          }
+        case 164: break;
+        case 61: 
+          { return JavaFxTokenTypes.VAR_KEYWORD;
+          }
+        case 165: break;
+        case 60: 
+          { return JavaFxTokenTypes.DEF_KEYWORD;
+          }
+        case 166: break;
+        case 22: 
+          { return (JavaFxTokenTypes.COLON);
+          }
+        case 167: break;
+        case 45: 
+          { return (JavaFxTokenTypes.MINUSMINUS);
+          }
+        case 168: break;
+        case 40: 
+          { return JavaFxTokenTypes.AT_KEYWORD;
+          }
+        case 169: break;
+        case 37: 
+          { return (JavaFxTokenTypes.PLUSEQ);
+          }
+        case 170: break;
+        case 71: 
+          { return JavaFxTokenTypes.INIT_KEYWORD;
+          }
+        case 171: break;
+        case 72: 
+          { return JavaFxTokenTypes.LAST_KEYWORD;
+          }
+        case 172: break;
+        case 6: 
+          { return (JavaFxTokenTypes.MULT);
+          }
+        case 173: break;
+        case 52: 
+          { yybegin(YYINITIAL);
+    myQuoteStack = myQuoteStack.enterBrace(CHAR, false);
+    return JavaFxTokenTypes.LBRACE_STRING_LITERAL;
+          }
+        case 174: break;
+        case 11: 
+          { zzMarkedPos = zzCurrentPos; yybegin(STRING);
+          }
+        case 175: break;
+        case 53: 
+          { return JavaFxTokenTypes.DOC_COMMENT;
+          }
+        case 176: break;
+        case 92: 
+          { return JavaFxTokenTypes.TYPEOF_KEYWORD;
+          }
+        case 177: break;
+        case 25: 
+          { yybegin(YYINITIAL); return JavaFxTokenTypes.STRING_LITERAL;
+          }
+        case 178: break;
+        case 114: 
+          { return JavaFxTokenTypes.PROTECTED_KEYWORD;
+          }
+        case 179: break;
+        case 21: 
+          { return (JavaFxTokenTypes.COMMA);
+          }
+        case 180: break;
+        case 23: 
+          { return (JavaFxTokenTypes.DELIM);
+          }
+        case 181: break;
+        case 38: 
+          { return JavaFxTokenTypes.LOCALIZATION_PREFIX;
+          }
+        case 182: break;
+        case 34: 
+          { return (JavaFxTokenTypes.GTEQ);
+          }
+        case 183: break;
+        case 100: 
+          { return JavaFxTokenTypes.REPLACE_KEYWORD;
+          }
+        case 184: break;
+        case 8: 
+          { return (JavaFxTokenTypes.GT);
+          }
+        case 185: break;
+        case 94: 
+          { return JavaFxTokenTypes.DELETE_KEYWORD;
+          }
+        case 186: break;
+        case 84: 
+          { return JavaFxTokenTypes.FALSE_KEYWORD;
+          }
+        case 187: break;
+        case 1: 
+          { return JavaFxTokenTypes.BAD_CHARACTER;
+          }
+        case 188: break;
+        case 46: 
+          { return (JavaFxTokenTypes.MINUSEQ);
+          }
+        case 189: break;
+        case 112: 
+          { return JavaFxTokenTypes.ATTRIBUTE_KEYWORD;
+          }
+        case 190: break;
+        case 106: 
+          { return JavaFxTokenTypes.PRIVATE_KEYWORD;
+          }
+        case 191: break;
+        case 103: 
+          { return JavaFxTokenTypes.INDEXOF_KEYWORD;
+          }
+        case 192: break;
+        case 90: 
+          { return JavaFxTokenTypes.ASSERT_KEYWORD;
+          }
+        case 193: break;
+        case 117: 
+          { return JavaFxTokenTypes.PUBLIC_READ_KEYWORD;
+          }
+        case 194: break;
+        case 24: 
+          { return (JavaFxTokenTypes.EQ);
+          }
+        case 195: break;
+        case 49: 
+          { return (JavaFxTokenTypes.NOTEQ);
+          }
+        case 196: break;
+        case 96: 
+          { return JavaFxTokenTypes.INSERT_KEYWORD;
+          }
+        case 197: break;
+        case 78: 
+          { return JavaFxTokenTypes.BREAK_KEYWORD;
+          }
+        case 198: break;
+        case 67: 
+          { return JavaFxTokenTypes.FROM_KEYWORD;
+          }
+        case 199: break;
+        case 108: 
+          { return JavaFxTokenTypes.CONTINUE_KEYWORD;
+          }
+        case 200: break;
+        case 66: 
+          { return JavaFxTokenTypes.TRUE_KEYWORD;
+          }
+        case 201: break;
+        case 7: 
+          { return (JavaFxTokenTypes.LT);
+          }
+        case 202: break;
+        case 79: 
+          { return JavaFxTokenTypes.BOUND_KEYWORD;
+          }
+        case 203: break;
+        case 44: 
+          { return JavaFxTokenTypes.ON_KEYWORD;
+          }
+        case 204: break;
+        case 118: 
+          { return JavaFxTokenTypes.PUBLIC_INIT_KEYWORD;
+          }
+        case 205: break;
+        case 77: 
+          { return JavaFxTokenTypes.AFTER_KEYWORD;
+          }
+        case 206: break;
+        case 12: 
+          { myQuoteStack.enterBrace();
+    return (JavaFxTokenTypes.LBRACE);
+          }
+        case 207: break;
+        case 102: 
+          { return JavaFxTokenTypes.EXTENDS_KEYWORD;
+          }
+        case 208: break;
+        case 64: 
+          { return JavaFxTokenTypes.THEN_KEYWORD;
+          }
+        case 209: break;
+        case 58: 
+          { return JavaFxTokenTypes.NEW_KEYWORD;
+          }
+        case 210: break;
+        case 91: 
+          { return JavaFxTokenTypes.BEFORE_KEYWORD;
+          }
+        case 211: break;
+        case 47: 
+          { return (JavaFxTokenTypes.EQGT);
+          }
+        case 212: break;
+        case 81: 
+          { return JavaFxTokenTypes.TWEEN_KEYWORD;
+          }
+        case 213: break;
+        case 19: 
+          { return (JavaFxTokenTypes.RPAREN);
+          }
+        case 214: break;
+        case 5: 
+          { return (JavaFxTokenTypes.DIV);
+          }
+        case 215: break;
+        case 63: 
+          { return JavaFxTokenTypes.BIND_KEYWORD;
+          }
+        case 216: break;
+        case 48: 
+          { return (JavaFxTokenTypes.EQEQ);
+          }
+        case 217: break;
+        case 32: 
+          { return (JavaFxTokenTypes.MULTEQ);
+          }
+        case 218: break;
+        case 10: 
+          { return (JavaFxTokenTypes.PLUS);
+          }
+        case 219: break;
+        case 36: 
+          { return (JavaFxTokenTypes.PLUSPLUS);
+          }
+        case 220: break;
+        case 76: 
+          { return JavaFxTokenTypes.SUPER_KEYWORD;
+          }
+        case 221: break;
+        case 39: 
+          { return JavaFxTokenTypes.AS_KEYWORD;
+          }
+        case 222: break;
+        case 13: 
+          { final int state = myQuoteStack.leaveBrace();
+    if (state == -1) {
+      return (JavaFxTokenTypes.RBRACE);
+    }
+    zzMarkedPos = zzCurrentPos;
+    yybegin(state);
+          }
+        case 223: break;
+        case 3: 
+          { return JavaFxTokenTypes.INTEGER_LITERAL;
+          }
+        case 224: break;
+        case 73: 
+          { return JavaFxTokenTypes.LAZY_KEYWORD;
+          }
+        case 225: break;
+        case 93: 
+          { return JavaFxTokenTypes.RETURN_KEYWORD;
+          }
+        case 226: break;
+        case 95: 
+          { return JavaFxTokenTypes.IMPORT_KEYWORD;
+          }
+        case 227: break;
+        case 43: 
+          { return JavaFxTokenTypes.OR_KEYWORD;
+          }
+        case 228: break;
+        case 74: 
+          { return JavaFxTokenTypes.WITH_KEYWORD;
+          }
+        case 229: break;
+        case 87: 
+          { return JavaFxTokenTypes.WHILE_KEYWORD;
+          }
+        case 230: break;
+        case 115: 
+          { return JavaFxTokenTypes.INSTANCEOF_KEYWORD;
+          }
+        case 231: break;
+        case 109: 
+          { return JavaFxTokenTypes.FUNCTION_KEYWORD;
+          }
+        case 232: break;
+        case 89: 
+          { return JavaFxTokenTypes.SIZEOF_KEYWORD;
+          }
+        case 233: break;
+        case 51: 
+          { yybegin(YYINITIAL);
+    myQuoteStack.enterBrace();
+    return JavaFxTokenTypes.LBRACE_RBRACE_STRING_LITERAL;
+          }
+        case 234: break;
+        case 97: 
+          { return JavaFxTokenTypes.PUBLIC_KEYWORD;
+          }
+        case 235: break;
+        case 18: 
+          { return (JavaFxTokenTypes.LPAREN);
+          }
+        case 236: break;
+        default:
+          if (zzInput == YYEOF && zzStartRead == zzCurrentPos) {
+            zzAtEOF = true;
+            zzDoEOF();
+            return null;
+          }
+          else {
+            zzScanError(ZZ_NO_MATCH);
+          }
+      }
+    }
+  }
+
+
+}
diff --git a/src/org/jetbrains/javafx/lang/lexer/javafx.flex b/src/org/jetbrains/javafx/lang/lexer/javafx.flex
new file mode 100644 (file)
index 0000000..5eec490
--- /dev/null
@@ -0,0 +1,292 @@
+package org.jetbrains.javafx.lang.lexer;
+
+import com.intellij.lexer.FlexLexer;
+import com.intellij.psi.tree.IElementType;
+import java.util.*;
+import java.lang.reflect.Field;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.javafx.lang.lexer.JavaFxTokenTypes;
+
+%%
+
+%unicode
+%class _JavaFxLexer
+%implements FlexLexer
+
+
+
+%function advance
+%type IElementType
+%eof{ return;
+%eof}
+
+%{
+  private BraceQuoteTracker myQuoteStack = BraceQuoteTracker.NULL_BQT;
+%}
+
+/* main character classes */
+LineTerminator = \r|\n|\r\n
+InputCharacter = [^\r\n]
+
+WhiteSpace = {LineTerminator} | [ \t\f]
+
+NonZeroDigit = [1-9]
+Digit = 0 | {NonZeroDigit}
+OctDigit = [0-7]
+HexDigit = [0-9A-Fa-f]
+
+/* comments */
+//Comment = {TraditionalComment} | {EndOfLineComment} | {DocumentationComment}
+
+TraditionalComment = ("/*"[^"*"]{CommentTail})|"/*"
+DocumentationComment = "/**"+("/"|([^"/""*"]{CommentTail}))?
+CommentTail = ([^"*"]*("*"+[^"*""/"])?)*("*/")?
+EndOfLineComment = "//" {InputCharacter}* {LineTerminator}?
+
+/* identifiers */
+Identifier = {JavaIdentifier}|{QuotedIdentifier}
+JavaIdentifier = [:jletter:][:jletterdigit:]*
+QuotedIdentifier = "<<" ([^>]|>[^>])*>* ">>"
+
+/* integer literals */
+DecIntegerLiteral = 0 | {NonZeroDigit} {Digit}*
+
+HexIntegerLiteral = 0 [xX] {HexDigit}+
+
+OctIntegerLiteral = 0+ {OctDigit}+
+
+/* number literals */
+NumberLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}?
+
+FLit1    = {Digit}+ \. {Digit}+
+FLit2    = \. {Digit}+
+FLit3    = {Digit}+
+Exponent = [eE] [+-]? {Digit}+
+
+DurationLiteral = ({DecIntegerLiteral}|{NumberLiteral}) {TimeUnit}
+TimeUnit = ms | s | m | h
+
+/* string and character literals */
+StringLiteral = \"{DoubleQuotedBody}(\"|\\)?
+LbraceStringLiteral=\"{DoubleQuotedBody}\{
+LbraceRbraceStringLiteral=\}{DoubleQuotedBody}\{
+RbraceStringLiteral=\}{DoubleQuotedBody}(\"|\\)?
+
+CharLiteral = \'{SingleQuotedBody}(\'|\\)?
+LbraceCharLiteral=\'{SingleQuotedBody}\{
+LbraceRbraceCharLiteral=\}{SingleQuotedBody}\{
+RbraceCharLiteral=\}{SingleQuotedBody}(\'|\\)?
+
+DoubleQuotedBody=({StringCharacter}|{EscapeSequence})*
+SingleQuotedBody=({SingleCharacter}|{EscapeSequence})*
+
+StringCharacter = [^\r\n\"\\{}]
+SingleCharacter = [^\r\n\'\\{}]
+EscapeSequence = \\[^\r\n]
+
+LocalizationPrefix=##(\[[^\]]+\])?
+
+%state STRING, CHAR
+
+%%
+
+<YYINITIAL> {
+
+  /* keywords */
+  "abstract"                     { return JavaFxTokenTypes.ABSTRACT_KEYWORD; }
+  "after"                     { return JavaFxTokenTypes.AFTER_KEYWORD; }
+  "and"                     { return JavaFxTokenTypes.AND_KEYWORD; }
+  "as"                     { return JavaFxTokenTypes.AS_KEYWORD; }
+  "assert"                     { return JavaFxTokenTypes.ASSERT_KEYWORD; }
+  "at"                     { return JavaFxTokenTypes.AT_KEYWORD; }
+  "attribute"                     { return JavaFxTokenTypes.ATTRIBUTE_KEYWORD; }
+  "before"                     { return JavaFxTokenTypes.BEFORE_KEYWORD; }
+  "bind"                     { return JavaFxTokenTypes.BIND_KEYWORD; }
+  "bound"                     { return JavaFxTokenTypes.BOUND_KEYWORD; }
+  "break"                     { return JavaFxTokenTypes.BREAK_KEYWORD; }
+  "catch"                     { return JavaFxTokenTypes.CATCH_KEYWORD; }
+  "class"                     { return JavaFxTokenTypes.CLASS_KEYWORD; }
+  "continue"                     { return JavaFxTokenTypes.CONTINUE_KEYWORD; }
+  "def"                     { return JavaFxTokenTypes.DEF_KEYWORD; }
+  "delete"                     { return JavaFxTokenTypes.DELETE_KEYWORD; }
+  "else"                     { return JavaFxTokenTypes.ELSE_KEYWORD; }
+  "exclusive"                     { return JavaFxTokenTypes.EXCLUSIVE_KEYWORD; }
+  "extends"                     { return JavaFxTokenTypes.EXTENDS_KEYWORD; }
+  "false"                     { return JavaFxTokenTypes.FALSE_KEYWORD; }
+  "finally"                     { return JavaFxTokenTypes.FINALLY_KEYWORD; }
+  "first"                     { return JavaFxTokenTypes.FIRST_KEYWORD; }
+  "for"                     { return JavaFxTokenTypes.FOR_KEYWORD; }
+  "from"                     { return JavaFxTokenTypes.FROM_KEYWORD; }
+  "function"                     { return JavaFxTokenTypes.FUNCTION_KEYWORD; }
+  "if"                     { return JavaFxTokenTypes.IF_KEYWORD; }
+  "import"                     { return JavaFxTokenTypes.IMPORT_KEYWORD; }
+  "indexof"                     { return JavaFxTokenTypes.INDEXOF_KEYWORD; }
+  "in"                     { return JavaFxTokenTypes.IN_KEYWORD; }
+  "init"                     { return JavaFxTokenTypes.INIT_KEYWORD; }
+  "insert"                     { return JavaFxTokenTypes.INSERT_KEYWORD; }
+  "instanceof"                     { return JavaFxTokenTypes.INSTANCEOF_KEYWORD; }
+  "into"                     { return JavaFxTokenTypes.INTO_KEYWORD; }
+  "invalidate"                     { return JavaFxTokenTypes.INVALIDATE_KEYWORD; }
+  "inverse"                     { return JavaFxTokenTypes.INVERSE_KEYWORD; }
+  "last"                     { return JavaFxTokenTypes.LAST_KEYWORD; }
+  "lazy"                     { return JavaFxTokenTypes.LAZY_KEYWORD; }
+  "mixin"                     { return JavaFxTokenTypes.MIXIN_KEYWORD; }
+  "mod"                     { return JavaFxTokenTypes.MOD_KEYWORD; }
+  "new"                     { return JavaFxTokenTypes.NEW_KEYWORD; }
+  "not"                     { return JavaFxTokenTypes.NOT_KEYWORD; }
+  "null"                     { return JavaFxTokenTypes.NULL_KEYWORD; }
+  "on"                     { return JavaFxTokenTypes.ON_KEYWORD; }
+  "or"                     { return JavaFxTokenTypes.OR_KEYWORD; }
+  "override"                     { return JavaFxTokenTypes.OVERRIDE_KEYWORD; }
+  "package"                     { return JavaFxTokenTypes.PACKAGE_KEYWORD; }
+  "postinit"                     { return JavaFxTokenTypes.POSTINIT_KEYWORD; }
+  "private"                     { return JavaFxTokenTypes.PRIVATE_KEYWORD; }
+  "protected"                     { return JavaFxTokenTypes.PROTECTED_KEYWORD; }
+  "public-init"                     { return JavaFxTokenTypes.PUBLIC_INIT_KEYWORD; }
+  "public"                     { return JavaFxTokenTypes.PUBLIC_KEYWORD; }
+  "public-read"                     { return JavaFxTokenTypes.PUBLIC_READ_KEYWORD; }
+  "replace"                     { return JavaFxTokenTypes.REPLACE_KEYWORD; }
+  "return"                     { return JavaFxTokenTypes.RETURN_KEYWORD; }
+  "reverse"                     { return JavaFxTokenTypes.REVERSE_KEYWORD; }
+  "sizeof"                     { return JavaFxTokenTypes.SIZEOF_KEYWORD; }
+  "static"                     { return JavaFxTokenTypes.STATIC_KEYWORD; }
+  "step"                     { return JavaFxTokenTypes.STEP_KEYWORD; }
+  "super"                     { return JavaFxTokenTypes.SUPER_KEYWORD; }
+  "then"                     { return JavaFxTokenTypes.THEN_KEYWORD; }
+  "this"                     { return JavaFxTokenTypes.THIS_KEYWORD; }
+  "throw"                     { return JavaFxTokenTypes.THROW_KEYWORD; }
+  "trigger"                     { return JavaFxTokenTypes.TRIGGER_KEYWORD; }
+  "true"                     { return JavaFxTokenTypes.TRUE_KEYWORD; }
+  "try"                     { return JavaFxTokenTypes.TRY_KEYWORD; }
+  "tween"                     { return JavaFxTokenTypes.TWEEN_KEYWORD; }
+  "typeof"                     { return JavaFxTokenTypes.TYPEOF_KEYWORD; }
+  "var"                     { return JavaFxTokenTypes.VAR_KEYWORD; }
+  "where"                     { return JavaFxTokenTypes.WHERE_KEYWORD; }
+  "while"                     { return JavaFxTokenTypes.WHILE_KEYWORD; }
+  "with"                     { return JavaFxTokenTypes.WITH_KEYWORD; }
+
+  /* separators */
+  "("                            { return (JavaFxTokenTypes.LPAREN); }
+  ")"                            { return (JavaFxTokenTypes.RPAREN); }
+  "["                            { return (JavaFxTokenTypes.LBRACK); }
+  "]"                            { return (JavaFxTokenTypes.RBRACK); }
+  ";"                            { return (JavaFxTokenTypes.SEMICOLON); }
+  ","                            { return (JavaFxTokenTypes.COMMA); }
+  "."                            { return (JavaFxTokenTypes.DOT); }
+  ".."                           { return (JavaFxTokenTypes.RANGE); }
+  ":"                            { return (JavaFxTokenTypes.COLON); }
+  "|"                            { return (JavaFxTokenTypes.DELIM); }
+
+  "{"  {
+    myQuoteStack.enterBrace();
+    return (JavaFxTokenTypes.LBRACE);
+  }
+  "}"  {
+    final int state = myQuoteStack.leaveBrace();
+    if (state == -1) {
+      return (JavaFxTokenTypes.RBRACE);
+    }
+    zzMarkedPos = zzCurrentPos;
+    yybegin(state);
+  }
+
+  /* operators */
+  ">"                            { return (JavaFxTokenTypes.GT); }
+  "<"                            { return (JavaFxTokenTypes.LT); }
+  "=="                           { return (JavaFxTokenTypes.EQEQ); }
+  "<="                           { return (JavaFxTokenTypes.LTEQ); }
+  ">="                           { return (JavaFxTokenTypes.GTEQ); }
+  "=>"                           { return (JavaFxTokenTypes.EQGT); }
+  "!="                           { return (JavaFxTokenTypes.NOTEQ); }
+
+  "+="                           { return (JavaFxTokenTypes.PLUSEQ); }
+  "-="                           { return (JavaFxTokenTypes.MINUSEQ); }
+  "*="                           { return (JavaFxTokenTypes.MULTEQ); }
+  "/="                           { return (JavaFxTokenTypes.DIVEQ); }
+
+  "++"                           { return (JavaFxTokenTypes.PLUSPLUS); }
+  "--"                           { return (JavaFxTokenTypes.MINUSMINUS); }
+  "+"                            { return (JavaFxTokenTypes.PLUS); }
+  "-"                            { return (JavaFxTokenTypes.MINUS); }
+  "*"                            { return (JavaFxTokenTypes.MULT); }
+  "/"                            { return (JavaFxTokenTypes.DIV); }
+  "="                            { return (JavaFxTokenTypes.EQ); }
+  ///* string literal */
+  //\"                             { yybegin(STRING); string.setLength(0); }
+  //
+  ///* character literal */
+  //\'                             { yybegin(CHARLITERAL); string.setLength(0);}
+
+  /* numeric literals */
+
+  {DecIntegerLiteral}            { return JavaFxTokenTypes.INTEGER_LITERAL; }
+  {HexIntegerLiteral}            { return JavaFxTokenTypes.INTEGER_LITERAL; }
+  {OctIntegerLiteral}            { return JavaFxTokenTypes.INTEGER_LITERAL; }
+  {NumberLiteral}                { return JavaFxTokenTypes.NUMBER_LITERAL; }
+  {DurationLiteral}              { return JavaFxTokenTypes.DURATION_LITERAL; }
+  
+  /* comments */
+  {TraditionalComment}           { return JavaFxTokenTypes.C_STYLE_COMMENT; }
+  {EndOfLineComment}             { return JavaFxTokenTypes.END_OF_LINE_COMMENT; }
+  {DocumentationComment}         { return JavaFxTokenTypes.DOC_COMMENT; }
+
+  /* whitespace */
+  {WhiteSpace}                   { return JavaFxTokenTypes.WHITE_SPACE; }
+
+  /* identifiers */
+  {Identifier}                   { return JavaFxTokenTypes.IDENTIFIER; }
+
+  /* string literals */
+  \"              { zzMarkedPos = zzCurrentPos; yybegin(STRING); }
+
+  \'              { zzMarkedPos = zzCurrentPos; yybegin(CHAR); }
+
+  {LocalizationPrefix}           { return JavaFxTokenTypes.LOCALIZATION_PREFIX; }
+}
+
+<STRING> {
+  {StringLiteral}                            { yybegin(YYINITIAL); return JavaFxTokenTypes.STRING_LITERAL; }
+
+  {LbraceStringLiteral} {
+    yybegin(YYINITIAL);
+    myQuoteStack = myQuoteStack.enterBrace(STRING, false);
+    return JavaFxTokenTypes.LBRACE_STRING_LITERAL;
+  }
+
+  {LbraceRbraceStringLiteral} {
+    yybegin(YYINITIAL);
+    myQuoteStack.enterBrace();
+    return JavaFxTokenTypes.LBRACE_RBRACE_STRING_LITERAL;
+  }
+
+  {RbraceStringLiteral} {
+    yybegin(YYINITIAL);
+    myQuoteStack = myQuoteStack.leaveQuote();
+    return JavaFxTokenTypes.RBRACE_STRING_LITERAL;
+  }
+}
+
+<CHAR> {
+  {CharLiteral}                            { yybegin(YYINITIAL); return JavaFxTokenTypes.STRING_LITERAL; }
+
+  {LbraceCharLiteral} {
+    yybegin(YYINITIAL);
+    myQuoteStack = myQuoteStack.enterBrace(CHAR, false);
+    return JavaFxTokenTypes.LBRACE_STRING_LITERAL;
+  }
+
+  {LbraceRbraceCharLiteral} {
+    yybegin(YYINITIAL);
+    myQuoteStack.enterBrace();
+    return JavaFxTokenTypes.LBRACE_RBRACE_STRING_LITERAL;
+  }
+  
+  {RbraceCharLiteral} {
+    yybegin(YYINITIAL);
+    myQuoteStack = myQuoteStack.leaveQuote();
+    return JavaFxTokenTypes.RBRACE_STRING_LITERAL;
+  }
+}
+
+/* error fallback */
+.                                { return JavaFxTokenTypes.BAD_CHARACTER; }
diff --git a/src/org/jetbrains/javafx/lang/parser/JavaFxElementTypes.java b/src/org/jetbrains/javafx/lang/parser/JavaFxElementTypes.java
new file mode 100644 (file)
index 0000000..53e2464
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx.lang.parser;
+
+import com.intellij.psi.tree.TokenSet;
+import org.jetbrains.javafx.lang.JavaFxElementType;
+import org.jetbrains.javafx.lang.lexer.JavaFxTokenTypes;
+import org.jetbrains.javafx.lang.psi.impl.*;
+
+/**
+ * JavaFx element types
+ *
+ * @author Alexey.Ivanov
+ */
+public interface JavaFxElementTypes extends JavaFxStubElementTypes, JavaFxTokenTypes {
+
+  JavaFxElementType IMPORT_STATEMENT = new JavaFxElementType("IMPORT_STATEMENT", JavaFxImportStatementImpl.class);
+  JavaFxElementType INIT_BLOCK = new JavaFxElementType("INIT_BLOCK", JavaFxInitBlockImpl.class);
+  JavaFxElementType POSTINIT_BLOCK = new JavaFxElementType("POSTINIT_BLOCK", JavaFxPostinitBlockImpl.class);
+  JavaFxElementType TYPE_ELEMENT = new JavaFxElementType("TYPE_ELEMENT", JavaFxTypeElementImpl.class);
+  JavaFxElementType FUNCTION_TYPE_ELEMENT = new JavaFxElementType("FUNCTION_TYPE_ELEMENT", JavaFxFunctionTypeElementImpl.class);
+  JavaFxElementType MODIFIER_LIST = new JavaFxElementType("MODIFIER_LIST", JavaFxModifierListImpl.class);
+
+  JavaFxElementType INSERT_EXPRESSION = new JavaFxElementType("INSERT_EXPRESSION", JavaFxInsertExpressionImpl.class);
+  JavaFxElementType DELETE_EXPRESSION = new JavaFxElementType("DELETE_EXPRESSION", JavaFxDeleteExpressionImpl.class);
+  JavaFxElementType WHILE_EXPRESSION = new JavaFxElementType("WHILE_EXPRESSION", JavaFxWhileExpressionImpl.class);
+  JavaFxElementType BREAK_EXPRESSION = new JavaFxElementType("BREAK_EXPRESSION", JavaFxBreakExpressionImpl.class);
+  JavaFxElementType CONTINUE_EXPRESSION = new JavaFxElementType("CONTINUE_EXPRESSION", JavaFxContinueExpressionImpl.class);
+  JavaFxElementType THROW_EXPRESSION = new JavaFxElementType("THROW_EXPRESSION", JavaFxThrowExpressionImpl.class);
+  JavaFxElementType RETURN_EXPRESSION = new JavaFxElementType("RETURN_EXPRESSION", JavaFxReturnExpressionImpl.class);
+  JavaFxElementType TRY_EXPRESSION = new JavaFxElementType("TRY_EXPRESSION", JavaFxTryExpressionImpl.class);
+  JavaFxElementType CATCH_CLAUSE = new JavaFxElementType("CATCH_CLAUSE", JavaFxCatchClauseImpl.class);
+  JavaFxElementType FINALLY_CLAUSE = new JavaFxElementType("FINALLY_CLAUSE", JavaFxFinallyClauseImpl.class);
+  JavaFxElementType INVALIDATE_EXPRESSION = new JavaFxElementType("INVALIDATE_EXPRESSION", JavaFxInvalidateExpressionImpl.class);
+
+  JavaFxElementType IF_EXPRESSION = new JavaFxElementType("IF_EXPRESSION", JavaFxIfExpressionImpl.class);
+  JavaFxElementType FOR_EXPRESSION = new JavaFxElementType("FOR_EXPRESSION", JavaFxForExpressionImpl.class);
+  JavaFxElementType IN_CLAUSE = new JavaFxElementType("IN_CLAUSE", JavaFxInClauseImpl.class);
+  JavaFxElementType NEW_EXPRESSION = new JavaFxElementType("NEW_EXPRESSION", JavaFxNewExpressionImpl.class);
+  JavaFxElementType ON_REPLACE_CLAUSE = new JavaFxElementType("ON_REPLACE_CLAUSE", JavaFxOnReplaceClauseImpl.class);
+  JavaFxElementType ON_INVALIDATE_CLAUSE = new JavaFxElementType("ON_INVALIDATE_CLAUSE", JavaFxOnInvalidateClauseImpl.class);
+
+  JavaFxElementType ASSIGNMENT_EXPRESSION = new JavaFxElementType("ASSIGNMENT_EXPRESSION", JavaFxAssignmentExpressionImpl.class);
+  JavaFxElementType BINARY_EXPRESSION = new JavaFxElementType("BINARY_EXPRESSION", JavaFxBinaryExpressionImpl.class);
+  JavaFxElementType TYPE_EXPRESSION = new JavaFxElementType("TYPE_EXPRESSION", JavaFxTypeExpressionImpl.class);
+  JavaFxElementType INDEXOF_EXPRESSION = new JavaFxElementType("INDEXOF_EXPRESSION", JavaFxIndexofExpressionImpl.class);
+  JavaFxElementType UNARY_EXPRESSION = new JavaFxElementType("UNARY_EXPRESSION", JavaFxUnaryExpressionImpl.class);
+  JavaFxElementType SUFFIXED_EXPRESSION = new JavaFxElementType("SUFFIXED_EXPRESSION", JavaFxSuffixedExpressionImpl.class);
+  JavaFxElementType CALL_EXPRESSION = new JavaFxElementType("CALL_EXPRESSION", JavaFxCallExpressionImpl.class);
+  JavaFxElementType EXPRESSION_LIST = new JavaFxElementType("EXPRESSION_LIST", JavaFxExpressionListImpl.class);
+  JavaFxElementType INDEX_EXPRESSION = new JavaFxElementType("INDEX_EXPRESSION", JavaFxIndexExpressionImpl.class);
+  JavaFxElementType SEQUENCE_SELECT_EXPRESSION =
+    new JavaFxElementType("SEQUENCE_SELECT_EXPRESSION", JavaFxSequenceSelectExpressionImpl.class);
+  JavaFxElementType SLICE_EXPRESSION = new JavaFxElementType("SLICE_EXPRESSION", JavaFxSliceExpressionImpl.class);
+  JavaFxElementType REFERENCE_ELEMENT = new JavaFxElementType("REFERENCE_ELEMENT", JavaFxReferenceElementImpl.class);
+  JavaFxElementType REFERENCE_LIST = new JavaFxElementType("REFERENCE_LIST", JavaFxReferenceListImpl.class);
+  JavaFxElementType REFERENCE_EXPRESSION = new JavaFxElementType("REFERENCE_EXPRESSION", JavaFxReferenceExpressionImpl.class);
+
+  JavaFxElementType OBJECT_LITERAL = new JavaFxElementType("OBJECT_LITERAL", JavaFxObjectLiteralImpl.class);
+  JavaFxElementType SEQUENCE_LITERAL = new JavaFxElementType("SEQUENCE_LITERAL", JavaFxSequenceLiteralImpl.class);
+  JavaFxElementType RANGE_EXPRESSION = new JavaFxElementType("RANGE_EXPRESSION", JavaFxRangeExpressionImpl.class);
+  JavaFxElementType LITERAL_EXPRESSION = new JavaFxElementType("LITERAL", JavaFxLiteralExpressionImpl.class);
+  JavaFxElementType THIS_EXPRESSION = new JavaFxElementType("THIS_EXPRESSION", JavaFxThisReferenceExpressionImpl.class);
+  JavaFxElementType OBJECT_LITERAL_INIT = new JavaFxElementType("OBJECT_LITERAL_INIT", JavaFxObjectLiteralInitImpl.class);
+
+  JavaFxElementType FUNCTION_EXPRESSION = new JavaFxElementType("FUNCTION_EXPRESSION", JavaFxFunctionExpressionImpl.class);
+  JavaFxElementType STRING_EXPRESSION = new JavaFxElementType("STRING_EXPRESSION", JavaFxStringExpressionImpl.class);
+  JavaFxElementType STRING_ELEMENT = new JavaFxElementType("STRING_ELEMENT", JavaFxStringCompoundElementImpl.class);
+  JavaFxElementType BLOCK_EXPRESSION = new JavaFxElementType("BLOCK_EXPRESSION", JavaFxBlockExpressionImpl.class);
+  JavaFxElementType PARENTHESIZED_EXPRESSION = new JavaFxElementType("PARENTHESIZED_EXPRESSION", JavaFxParenthesizedExpressionImpl.class);
+  JavaFxElementType TIMELINE_EXPRESSION = new JavaFxElementType("TIMELINE_EXPRESSION", JavaFxTimelineExpressionImpl.class);
+  JavaFxElementType BOUND_EXPRESSION = new JavaFxElementType("BOUND_EXPRESSION", JavaFxBoundExpressionImpl.class);
+
+  TokenSet EXPRESSIONS = TokenSet.create(INSERT_EXPRESSION, DELETE_EXPRESSION, WHILE_EXPRESSION,
+                                         BREAK_EXPRESSION, CONTINUE_EXPRESSION, THROW_EXPRESSION,
+                                         RETURN_EXPRESSION, TRY_EXPRESSION, IF_EXPRESSION, FOR_EXPRESSION,
+                                         NEW_EXPRESSION, VARIABLE_DECLARATION, ASSIGNMENT_EXPRESSION, BINARY_EXPRESSION,
+                                         TYPE_EXPRESSION, INDEXOF_EXPRESSION, SUFFIXED_EXPRESSION, CALL_EXPRESSION,
+                                         INDEX_EXPRESSION, SEQUENCE_SELECT_EXPRESSION, SLICE_EXPRESSION,
+                                         REFERENCE_EXPRESSION, OBJECT_LITERAL, SEQUENCE_LITERAL, RANGE_EXPRESSION,
+                                         LITERAL_EXPRESSION, FUNCTION_EXPRESSION, BLOCK_EXPRESSION, PARENTHESIZED_EXPRESSION,
+                                         TIMELINE_EXPRESSION, THIS_EXPRESSION, INVALIDATE_EXPRESSION, BOUND_EXPRESSION);
+
+  TokenSet CLASS_MEMBERS = TokenSet.create(INIT_BLOCK, POSTINIT_BLOCK, VARIABLE_DECLARATION, FUNCTION_DEFINITION);
+  TokenSet DEFINITIONS = TokenSet.orSet(EXPRESSIONS, TokenSet.create(CLASS_DEFINITION, FUNCTION_DEFINITION));
+  TokenSet TOP_LEVEL_ELEMENTS =
+    TokenSet.orSet(DEFINITIONS, TokenSet.create(PACKAGE_DEFINITION, IMPORT_LIST));
+  TokenSet TYPE_ELEMENTS = TokenSet.create(TYPE_ELEMENT, FUNCTION_TYPE_ELEMENT);
+}
diff --git a/src/org/jetbrains/javafx/lang/parser/JavaFxParser.java b/src/org/jetbrains/javafx/lang/parser/JavaFxParser.java
new file mode 100644 (file)
index 0000000..3b188b5
--- /dev/null
@@ -0,0 +1,1254 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.javafx.lang.parser;
+
+import com.intellij.lang.ASTNode;
+import com.intellij.lang.PsiBuilder;
+import com.intellij.lang.PsiParser;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.tree.TokenSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.javafx.JavaFxBundle;
+import org.jetbrains.javafx.lang.JavaFxElementType;
+import org.jetbrains.javafx.lang.lexer.JavaFxTokenTypes;
+
+/**
+ * Psi parser for JavaFx
+ *
+ * @author Alexey.Ivanov
+ */
+public class JavaFxParser implements PsiParser {
+  private static final Logger LOG = Logger.getInstance("#org.jetbrains.javafx.lang.parser.JavaFxParser");
+  protected PsiBuilder myBuilder;
+  private IElementType myPreviousTokenType;
+
+  protected boolean atToken(final IElementType tokenType) {
+    return myBuilder.getTokenType() == tokenType;
+  }
+
+  private void nextToken() {
+    myPreviousTokenType = myBuilder.getTokenType();
+    myBuilder.advanceLexer();
+  }
+
+  protected void checkMatches(final IElementType token, final String message) {
+    if (myBuilder.getTokenType() == token) {
+      nextToken();
+    }
+    else {
+      myBuilder.error(message);
+    }
+  }
+
+  protected void checkMatches(final TokenSet tokenSet, final String message) {
+    if (tokenSet.contains(myBuilder.getTokenType())) {
+      nextToken();
+    }
+    else {
+      myBuilder.error(message);
+    }
+  }
+
+  @NotNull
+  public ASTNode parse(final IElementType root, @NotNull final PsiBuilder builder) {
+    myBuilder = builder;
+    myBuilder.setDebugMode(true);
+    final PsiBuilder.Marker rootMarker = builder.mark();
+    final long start = System.nanoTime();
+    parseRoot();
+    LOG.info(String.format("Parsing time: %d", (System.nanoTime() - start)));
+    rootMarker.done(root);
+    return builder.getTreeBuilt();
+  }
+
+  private void parseRoot() {
+    if (atToken(JavaFxTokenTypes.PACKAGE_KEYWORD)) {
+      parsePackageDefinition();
+    }
+    while (!myBuilder.eof()) {
+      parseScriptItem();
+      checkForSemicolon();
+    }
+  }
+
+  private void parsePackageDefinition() {
+    LOG.assertTrue(atToken(JavaFxTokenTypes.PACKAGE_KEYWORD));
+    final PsiBuilder.Marker marker = myBuilder.mark();
+    nextToken();
+    parseQualifiedName(JavaFxElementTypes.REFERENCE_ELEMENT);
+    checkForSemicolon();
+    marker.done(JavaFxElementTypes.PACKAGE_DEFINITION);
+  }
+
+  private void parseScriptItem() {
+    final IElementType firstToken = myBuilder.getTokenType();
+    if (firstToken == JavaFxTokenTypes.IMPORT_KEYWORD) {
+      parseImportList();
+    }
+    else if (firstToken == JavaFxTokenTypes.CLASS_KEYWORD) {
+      final PsiBuilder.Marker marker = myBuilder.mark();
+      parseModifiers();
+      parseClassDefinition(marker);
+    }
+    else if (firstToken == JavaFxTokenTypes.FUNCTION_KEYWORD) {
+      final PsiBuilder.Marker marker = myBuilder.mark();
+      parseModifiers();
+      parseFunctionDefinition(marker);
+    }
+    else if (JavaFxElementTypes.MODIFIERS.contains(firstToken)) {
+      final PsiBuilder.Marker marker = myBuilder.mark();
+      parseModifiers();
+      if (atToken(JavaFxTokenTypes.CLASS_KEYWORD)) {
+        parseClassDefinition(marker);
+      }
+      else if (atToken(JavaFxTokenTypes.FUNCTION_KEYWORD)) {
+        parseFunctionDefinition(marker);
+      }
+      else {
+        marker.rollbackTo();
+        parseExpression();
+      }
+    }
+    else if (firstToken == JavaFxTokenTypes.SEMICOLON) {
+      nextToken();
+    }
+    else if (firstToken != null) {
+      parseExpression();
+    }
+  }
+
+  private void parseImportList() {
+    final PsiBuilder.Marker importList = myBuilder.mark();
+    while (atToken(JavaFxTokenTypes.IMPORT_KEYWORD)) {
+      parseImportStatement();
+      checkForSemicolon();
+    }
+    importList.done(JavaFxElementTypes.IMPORT_LIST);
+  }
+
+  private void parseImportStatement() {
+    LOG.assertTrue(atToken(JavaFxTokenTypes.IMPORT_KEYWORD));
+    final PsiBuilder.Marker importStatement = myBuilder.mark();
+    nextToken();
+    PsiBuilder.Marker reference = myBuilder.mark();
+    checkMatches(JavaFxTokenTypes.NAME_ALL, JavaFxBundle.message("name.expected"));
+    reference.done(JavaFxElementTypes.REFERENCE_ELEMENT);
+    while (atToken(JavaFxElementTypes.DOT)) {
+      nextToken();
+      if (atToken(JavaFxElementTypes.MULT)) {
+        nextToken();
+        break;
+      }
+      reference = createReferenceFragment(JavaFxElementTypes.REFERENCE_ELEMENT, reference);
+    }
+    importStatement.done(JavaFxElementTypes.IMPORT_STATEMENT);
+  }
+
+  private void parseExpression() {
+    final IElementType firstToken = myBuilder.getTokenType();
+    if (firstToken == JavaFxTokenTypes.INSERT_KEYWORD) {
+      parseInsertExpression();
+    }
+    else if (firstToken == JavaFxTokenTypes.DELETE_KEYWORD) {
+      parseDeleteExpression();
+    }
+    else if (firstToken == JavaFxTokenTypes.WHILE_KEYWORD) {
+      parseWhileExpression();
+    }
+    else if (firstToken == JavaFxTokenTypes.BREAK_KEYWORD) {
+      parseBreakExpression();
+    }
+    else if (firstToken == JavaFxTokenTypes.CONTINUE_KEYWORD) {
+      parseContinueExpression();
+    }
+    else if (firstToken == JavaFxTokenTypes.THROW_KEYWORD) {
+      parseThrowExpression();
+    }
+    else if (firstToken == JavaFxTokenTypes.RETURN_KEYWORD) {
+      parseReturnExpression();
+    }
+    else if (firstToken == JavaFxTokenTypes.TRY_KEYWORD) {
+      parseTryExpression();
+    }
+    else if (firstToken == JavaFxTokenTypes.INVALIDATE_KEYWORD) {
+      parseInvalidateExpression();
+    }
+    else {
+      if (!parseValueExpressionOptional()) {
+        myBuilder.error(JavaFxBundle.message("expression.expected"));
+        nextToken();
+      }
+    }
+  }
+
+  private void checkForSemicolon() {
+    final IElementType currentToken = myBuilder.getTokenType();
+    if (currentToken == JavaFxTokenTypes.SEMICOLON) {
+      nextToken();
+      return;
+    }
+    if (currentToken == null ||
+        currentToken == JavaFxTokenTypes.RBRACE ||
+        currentToken == JavaFxTokenTypes.ELSE_KEYWORD ||
+        currentToken == JavaFxTokenTypes.RBRACE_STRING_LITERAL ||
+        currentToken == JavaFxTokenTypes.LBRACE_RBRACE_STRING_LITERAL) {
+      return;
+    }
+    if (myPreviousTokenType == null ||
+        myPreviousTokenType == JavaFxTokenTypes.RBRACE ||
+        myPreviousTokenType == JavaFxTokenTypes.SEMICOLON) {
+      return;
+    }
+    myBuilder.error(JavaFxBundle.message("semicolon.expected"));
+  }
+
+  private void parseClassDefinition(final PsiBuilder.Marker marker) {
+    LOG.assertTrue(atToken(JavaFxTokenTypes.CLASS_KEYWORD));
+    nextToken();
+    checkMatches(JavaFxTokenTypes.NAME, JavaFxBundle.message("name.expected"));
+    final PsiBuilder.Marker extendsListMarker = myBuilder.mark();
+    if (atToken(JavaFxTokenTypes.EXTENDS_KEYWORD)) {
+      nextToken();
+      parseQualifiedName(JavaFxElementTypes.REFERENCE_ELEMENT);
+      while (atToken(JavaFxTokenTypes.COMMA)) {
+        nextToken();
+        parseQualifiedName(JavaFxElementTypes.REFERENCE_ELEMENT);
+      }
+    }
+    extendsListMarker.done(JavaFxElementTypes.REFERENCE_LIST);
+    checkMatches(JavaFxTokenTypes.LBRACE, JavaFxBundle.message("lbrace.expected"));
+    while (!atToken(JavaFxTokenTypes.RBRACE)) {
+      if (myBuilder.eof()) {
+        myBuilder.error(JavaFxBundle.message("rbrace.expected"));
+        marker.done(JavaFxElementTypes.CLASS_DEFINITION);
+        return;
+      }
+      parseClassMember();
+      checkForSemicolon();
+    }
+    nextToken();
+    marker.done(JavaFxElementTypes.CLASS_DEFINITION);
+  }
+
+  private void parseClassMember() {
+    final IElementType firstToken = myBuilder.getTokenType();
+    if (firstToken == JavaFxTokenTypes.INIT_KEYWORD) {
+      final PsiBuilder.Marker marker = myBuilder.mark();
+      nextToken();
+      parseBlockExpression();
+      marker.done(JavaFxElementTypes.INIT_BLOCK);
+    }
+    else if (firstToken == JavaFxTokenTypes.POSTINIT_KEYWORD) {
+      final PsiBuilder.Marker marker = myBuilder.mark();
+      nextToken();
+      parseBlockExpression();
+      marker.done(JavaFxElementTypes.POSTINIT_BLOCK);
+    }
+    else if (firstToken == JavaFxTokenTypes.FUNCTION_KEYWORD) {
+      final PsiBuilder.Marker functionMarker = myBuilder.mark();
+      parseModifiers();
+      parseFunctionDefinition(functionMarker);
+    }
+    else if (JavaFxTokenTypes.VARIABLE_LABEL.contains(firstToken)) {
+      final PsiBuilder.Marker variableMarker = myBuilder.mark();
+      parseModifiers();
+      parseVariableDeclaration(variableMarker);
+    }
+    else if (JavaFxTokenTypes.MODIFIERS.contains(firstToken)) {
+      final PsiBuilder.Marker marker = myBuilder.mark();
+      parseModifiers();
+      if (atToken(JavaFxTokenTypes.FUNCTION_KEYWORD)) {
+        parseFunctionDefinition(marker);
+      }
+      else if (JavaFxTokenTypes.VARIABLE_LABEL.contains(myBuilder.getTokenType())) {
+        parseVariableDeclaration(marker);
+      }
+      else {
+        myBuilder.error(JavaFxBundle.message("unexpected.token"));
+        marker.drop();
+      }
+    }
+    else if (firstToken == JavaFxTokenTypes.SEMICOLON) {
+      do {
+        nextToken();
+      }
+      while (atToken(JavaFxTokenTypes.SEMICOLON));
+    }
+    else {
+      myBuilder.error(JavaFxBundle.message("unexpected.token"));
+      nextToken();
+    }
+  }
+
+  private void parseModifiers() {
+    final PsiBuilder.Marker marker = myBuilder.mark();
+    while (JavaFxTokenTypes.MODIFIERS.contains(myBuilder.getTokenType())) {
+      nextToken();
+    }
+    marker.done(JavaFxElementTypes.MODIFIER_LIST);
+  }
+
+  private void parseFunctionDefinition(final PsiBuilder.Marker marker) {
+    LOG.assertTrue(atToken(JavaFxTokenTypes.FUNCTION_KEYWORD));
+    nextToken();
+    checkMatches(JavaFxTokenTypes.NAME, JavaFxBundle.message("name.expected"));
+    parseFunctionSignature(true);
+    if (atToken(JavaFxTokenTypes.LBRACE)) {
+      parseBlockExpression();
+    }
+    marker.done(JavaFxElementTypes.FUNCTION_DEFINITION);
+  }
+
+  private void parseInsertExpression() {
+    LOG.assertTrue(atToken(JavaFxTokenTypes.INSERT_KEYWORD));
+    final PsiBuilder.Marker marker = myBuilder.mark();
+    nextToken();
+    parseValueExpression();
+    if (atToken(JavaFxTokenTypes.INTO_KEYWORD)) {
+      nextToken();
+      parseValueExpression();
+    }
+    else if (atToken(JavaFxTokenTypes.AFTER_KEYWORD) || atToken(JavaFxTokenTypes.BEFORE_KEYWORD)) {
+      nextToken();
+      parseIndexedSequenceForInsert();
+    }
+    else {
+      myBuilder.error(JavaFxBundle.message("into.before.or.after.expected"));
+    }
+    marker.done(JavaFxElementTypes.INSERT_EXPRESSION);
+  }
+
+  private void parseIndexedSequenceForInsert() {
+    if (!parsePrimaryExpression()) {
+      myBuilder.error(JavaFxBundle.message("expression.expected"));
+    }
+    checkMatches(JavaFxTokenTypes.LBRACK, JavaFxBundle.message("lbrack.expected"));
+    parseValueExpression();
+    checkMatches(JavaFxTokenTypes.RBRACK, JavaFxBundle.message("rbrack.expected"));
+  }
+
+  private void parseDeleteExpression() {
+    LOG.assertTrue(atToken(JavaFxTokenTypes.DELETE_KEYWORD));
+    final PsiBuilder.Marker marker = myBuilder.mark();
+    nextToken();
+    parseValueExpression();
+    if (atToken(JavaFxTokenTypes.FROM_KEYWORD)) {
+      nextToken();
+      parseValueExpression();
+    }
+    marker.done(JavaFxElementTypes.DELETE_EXPRESSION);
+  }
+
+  private void parseWhileExpression() {
+    LOG.assertTrue(atToken(JavaFxTokenTypes.WHILE_KEYWORD));
+    final PsiBuilder.Marker marker = myBuilder.mark();
+    nextToken();
+    checkMatches(JavaFxTokenTypes.LPAREN, JavaFxBundle.message("lparen.expected"));
+    parseValueExpression();
+    checkMatches(JavaFxTokenTypes.RPAREN, JavaFxBundle.message("rparen.expected"));
+    parseExpression();
+    marker.done(JavaFxElementTypes.WHILE_EXPRESSION);
+  }
+
+  private void parseBreakExpression() {
+    LOG.assertTrue(atToken(JavaFxTokenTypes.BREAK_KEYWORD));
+    final PsiBuilder.Marker marker = myBuilder.mark();
+    nextToken();
+    marker.done(JavaFxElementTypes.BREAK_EXPRESSION);
+  }
+
+  private void parseContinueExpression() {
+    LOG.assertTrue(atToken(JavaFxTokenTypes.CONTINUE_KEYWORD));
+    final PsiBuilder.Marker marker = myBuilder.mark();
+    nextToken();
+    marker.done(JavaFxElementTypes.CONTINUE_EXPRESSION);
+  }
+
+  private void parseThrowExpression() {
+    LOG.assertTrue(atToken(JavaFxTokenTypes.THROW_KEYWORD));
+    final PsiBuilder.Marker marker = myBuilder.mark();
+    nextToken();
+    parseValueExpression();
+    marker.done(JavaFxElementTypes.THROW_EXPRESSION);
+  }
+
+  private void parseReturnExpression() {
+    LOG.assertTrue(atToken(JavaFxTokenTypes.RETURN_KEYWORD));
+    final PsiBuilder.Marker marker = myBuilder.mark();
+    nextToken();
+    if (!parseValueExpressionOptional()) {
+      checkForSemicolon();
+    }
+    marker.done(JavaFxElementTypes.RETURN_EXPRESSION);
+  }
+
+  private void parseTryExpression() {
+    LOG.assertTrue(atToken(JavaFxTokenTypes.TRY_KEYWORD));
+    final PsiBuilder.Marker marker = myBuilder.mark();
+    nextToken();
+    parseBlockExpression();
+    if (atToken(JavaFxTokenTypes.FINALLY_KEYWORD)) {
+      parseFinallyClause();
+    }
+    else if (atToken(JavaFxTokenTypes.CATCH_KEYWORD)) {
+      do {
+        parseCatchClause();
+      }
+      while (atToken(JavaFxTokenTypes.CATCH_KEYWORD));
+      if (atToken(JavaFxTokenTypes.FINALLY_KEYWORD)) {
+        parseFinallyClause();
+      }
+    }
+    else {
+      myBuilder.error(JavaFxBundle.message("catch.or.finally.expected"));
+    }
+    marker.done(JavaFxElementTypes.TRY_EXPRESSION);
+  }
+
+  private void parseCatchClause() {
+    LOG.assertTrue(atToken(JavaFxTokenTypes.CATCH_KEYWORD));
+    final PsiBuilder.Marker marker = myBuilder.mark();
+    nextToken();
+    checkMatches(JavaFxTokenTypes.LPAREN, JavaFxBundle.message("lparen.expected"));
+    parseFormalParameter(true);
+    checkMatches(JavaFxTokenTypes.RPAREN, JavaFxBundle.message("rparen.expected"));
+    parseBlockExpression();
+    marker.done(JavaFxElementTypes.CATCH_CLAUSE);
+  }
+
+  private void parseFinallyClause() {
+    LOG.assertTrue(atToken(JavaFxTokenTypes.FINALLY_KEYWORD));
+    final PsiBuilder.Marker marker = myBuilder.mark();
+    nextToken();
+    parseBlockExpression();
+    marker.done(JavaFxElementTypes.FINALLY_CLAUSE);
+  }
+
+  private void parseInvalidateExpression() {
+    LOG.assertTrue(atToken(JavaFxTokenTypes.INVALIDATE_KEYWORD));
+    final PsiBuilder.Marker marker = myBuilder.mark();
+    nextToken();
+    if (!parseValueExpressionOptional()) {
+      marker.rollbackTo();
+      parseValueExpression();
+      return;
+    }
+    marker.done(JavaFxElementTypes.INVALIDATE_EXPRESSION);
+  }
+
+  // TODO: better parsing for function types
+  private void parseFormalParameter(boolean checkParameterNames) {
+    PsiBuilder.Marker marker = myBuilder.mark();
+    if (checkParameterNames) {
+      checkMatches(JavaFxTokenTypes.NAME, JavaFxBundle.message("name.expected"));
+      parseTypeSpecifier();
+    }
+    else {
+      if (atToken(JavaFxTokenTypes.COLON)) {
+        parseTypeSpecifier();
+      }
+      else {
+        parseType();
+        if (atToken(JavaFxTokenTypes.COLON)) {
+          marker.rollbackTo();
+          marker = myBuilder.mark();
+          nextToken();
+          parseTypeSpecifier();
+        }
+      }
+    }
+    marker.done(JavaFxElementTypes.FORMAL_PARAMETER);
+  }
+
+  private void parseTypeSpecifier() {
+    if (atToken(JavaFxTokenTypes.COLON)) {
+      nextToken();
+      parseType();
+    }
+  }
+
+  private void parseType() {
+    final PsiBuilder.Marker marker = myBuilder.mark();
+    if (atToken(JavaFxTokenTypes.FUNCTION_KEYWORD)) {
+      nextToken();
+      parseFunctionSignature(false);
+      marker.done(JavaFxElementTypes.FUNCTION_TYPE_ELEMENT);
+    }
+    else {
+      parseQualifiedName(JavaFxElementTypes.REFERENCE_ELEMENT);
+      if (atToken(JavaFxTokenTypes.LBRACK)) {
+        nextToken();
+        checkMatches(JavaFxTokenTypes.RBRACK, JavaFxBundle.message("rbrack.expected"));
+      }
+      marker.done(JavaFxElementTypes.TYPE_ELEMENT);
+    }
+  }
+
+  private void parseQualifiedName(final JavaFxElementType elementType) {
+    if (!JavaFxTokenTypes.NAME.contains(myBuilder.getTokenType())) {
+      myBuilder.error(JavaFxBundle.message("name.expected"));
+      return;
+    }
+    PsiBuilder.Marker marker = myBuilder.mark();
+    nextToken();
+    marker.done(elementType);
+    while (atToken(JavaFxTokenTypes.DOT)) {
+      nextToken();
+      marker = createReferenceFragment(elementType, marker);
+    }
+  }
+
+  private PsiBuilder.Marker createReferenceFragment(final JavaFxElementType elementType, PsiBuilder.Marker marker) {
+    marker = marker.precede();
+    if (atToken(JavaFxTokenTypes.THIS_KEYWORD)) {
+      nextToken();
+      marker.done(JavaFxElementTypes.THIS_EXPRESSION);
+    }
+    else {
+      checkMatches(JavaFxTokenTypes.NAME_ALL, JavaFxBundle.message("name.expected"));
+      marker.done(elementType);
+    }
+    return marker;
+  }
+
+  private void parseValueExpression() {
+    if (!parseValueExpressionOptional()) {
+      myBuilder.error(JavaFxBundle.message("expression.expected"));
+    }
+  }
+
+  private boolean parseValueExpressionOptional() {
+    final IElementType firstToken = myBuilder.getTokenType();
+    if (firstToken == JavaFxTokenTypes.IF_KEYWORD) {
+      parseIfExpression();
+    }
+    else if (firstToken == JavaFxTokenTypes.FOR_KEYWORD) {
+      parseForExpression();
+    }
+    else if (firstToken == JavaFxTokenTypes.NEW_KEYWORD) {
+      parseNewExpression();
+    }
+    else if (JavaFxTokenTypes.VARIABLE_LABEL.contains(firstToken)) {
+      final PsiBuilder.Marker marker = myBuilder.mark();
+      parseModifiers();
+      parseVariableDeclaration(marker);
+    }
+    else if (JavaFxTokenTypes.MODIFIERS.contains(firstToken)) {
+      final PsiBuilder.Marker marker = myBuilder.mark();
+      parseModifiers();
+      if (JavaFxTokenTypes.VARIABLE_LABEL.contains(myBuilder.getTokenType())) {
+        parseVariableDeclaration(marker);
+      }
+      else {
+        marker.drop();
+        myBuilder.error(JavaFxBundle.message("var.or.def.expected"));
+      }
+    }
+    else {
+      return parseAssignmentExpression();
+    }
+    return true;
+  }
+
+  private void parseIfExpression() {
+    LOG.assertTrue(atToken(JavaFxTokenTypes.IF_KEYWORD));
+    final PsiBuilder.Marker marker = myBuilder.mark();
+    nextToken();
+    checkMatches(JavaFxTokenTypes.LPAREN, JavaFxBundle.message("lparen.expected"));
+    parseValueExpression();
+    checkMatches(JavaFxTokenTypes.RPAREN, JavaFxBundle.message("rparen.expected"));
+    if (atToken(JavaFxTokenTypes.THEN_KEYWORD)) {
+      nextToken();
+    }
+    parseExpression();
+    if (atToken(JavaFxTokenTypes.ELSE_KEYWORD)) {
+      nextToken();
+      parseExpression();
+    }
+    marker.done(JavaFxElementTypes.IF_EXPRESSION);
+  }
+
+  private void parseForExpression() {
+    LOG.assertTrue(atToken(JavaFxTokenTypes.FOR_KEYWORD));
+    final PsiBuilder.Marker marker = myBuilder.mark();
+    nextToken();
+    checkMatches(JavaFxTokenTypes.LPAREN, JavaFxBundle.message("lparen.expected"));
+    parseInClause();
+    while (atToken(JavaFxTokenTypes.COMMA)) {
+      nextToken();
+      parseInClause();
+    }
+    checkMatches(JavaFxTokenTypes.RPAREN, JavaFxBundle.message("rparen.expected"));
+    parseExpression();
+    marker.done(JavaFxElementTypes.FOR_EXPRESSION);
+  }
+
+  private void parseInClause() {
+    final PsiBuilder.Marker marker = myBuilder.mark();
+    parseFormalParameter(true);
+    checkMatches(JavaFxTokenTypes.IN_KEYWORD, JavaFxBundle.message("in.expected"));
+    parseValueExpression();
+    if (atToken(JavaFxTokenTypes.WHERE_KEYWORD)) {
+      nextToken();
+      parseValueExpression();
+    }
+    marker.done(JavaFxElementTypes.IN_CLAUSE);
+  }
+
+  private void parseNewExpression() {
+    LOG.assertTrue(atToken(JavaFxTokenTypes.NEW_KEYWORD));
+    final PsiBuilder.Marker marker = myBuilder.mark();
+    nextToken();
+    parseQualifiedName(JavaFxElementTypes.REFERENCE_ELEMENT);
+    if (atToken(JavaFxTokenTypes.LPAREN)) {
+      parseExpressionList();
+    }
+    marker.done(JavaFxElementTypes.NEW_EXPRESSION);
+  }
+
+  private void parseVariableDeclaration(final PsiBuilder.Marker marker) {
+    LOG.assertTrue(JavaFxTokenTypes.VARIABLE_LABEL.contains(myBuilder.getTokenType()));
+    nextToken();
+    checkMatches(JavaFxTokenTypes.NAME, JavaFxBundle.message("name.expected"));
+    parseTypeSpecifier();
+    if (atToken(JavaFxTokenTypes.EQ)) {
+      nextToken();
+      parseInitializingExpression();
+    }
+    if (atToken(JavaFxTokenTypes.ON_KEYWORD)) {
+      parseOnClause();
+    }
+    marker.done(JavaFxElementTypes.VARIABLE_DECLARATION);
+  }
+
+  private void parseOnClause() {
+    LOG.assertTrue(atToken(JavaFxTokenTypes.ON_KEYWORD));
+    final PsiBuilder.Marker marker = myBuilder.mark();
+    nextToken();
+    final IElementType firstToken = myBuilder.getTokenType();
+    if (firstToken == JavaFxTokenTypes.REPLACE_KEYWORD) {
+      parseOnReplaceClause(marker);
+    }
+    else if (firstToken == JavaFxTokenTypes.INVALIDATE_KEYWORD) {
+      parseInvalidateClause(marker);
+    }
+    else {
+      marker.drop();
+      myBuilder.error(JavaFxBundle.message("replace.or.invalidate.expected"));
+    }
+  }
+
+  private void parseOnReplaceClause(final PsiBuilder.Marker marker) {
+    LOG.assertTrue(atToken(JavaFxTokenTypes.REPLACE_KEYWORD));
+    nextToken();
+    if (JavaFxTokenTypes.NAME.contains(myBuilder.getTokenType())) {
+      nextToken();
+    }
+    if (atToken(JavaFxTokenTypes.LBRACK)) {
+      nextToken();
+      checkMatches(JavaFxTokenTypes.NAME, JavaFxBundle.message("name.expected"));
+      checkMatches(JavaFxTokenTypes.RANGE, JavaFxBundle.message("range.expected"));
+      checkMatches(JavaFxTokenTypes.NAME, JavaFxBundle.message("name.expected"));
+      checkMatches(JavaFxTokenTypes.RBRACK, JavaFxBundle.message("rbrack.expected"));
+    }
+    if (atToken(JavaFxTokenTypes.EQ)) {
+      nextToken();
+      checkMatches(JavaFxTokenTypes.NAME, JavaFxBundle.message("name.expected"));
+    }
+    parseBlockExpression();
+    marker.done(JavaFxElementTypes.ON_REPLACE_CLAUSE);
+  }
+
+  private void parseInvalidateClause(final PsiBuilder.Marker marker) {
+    LOG.assertTrue(atToken(JavaFxTokenTypes.INVALIDATE_KEYWORD));
+    nextToken();
+    parseBlockExpression();
+    marker.done(JavaFxElementTypes.ON_INVALIDATE_CLAUSE);
+  }
+
+  private boolean parseAssignmentExpression() {
+    final PsiBuilder.Marker marker = myBuilder.mark();
+    if (!parseAssignmentOpExpression()) {
+      marker.drop();
+      return false;
+    }
+    if (atToken(JavaFxTokenTypes.EQ)) {
+      nextToken();
+      parseValueExpression();
+      marker.done(JavaFxElementTypes.ASSIGNMENT_EXPRESSION);
+    }
+    else {
+      marker.drop();
+    }
+    return true;
+  }
+
+  private boolean parseAssignmentOpExpression() {
+    final PsiBuilder.Marker marker = myBuilder.mark();
+    if (!parseOrExpression()) {
+      marker.drop();
+      return false;
+    }
+    if (JavaFxTokenTypes.EQ_OPERATORS.contains(myBuilder.getTokenType())) {
+      nextToken();
+      parseValueExpression();
+      marker.done(JavaFxElementTypes.ASSIGNMENT_EXPRESSION);
+    }
+    else if (atToken(JavaFxTokenTypes.EQGT)) {
+      nextToken();
+      if (!parseOrExpression()) {
+        myBuilder.error(JavaFxBundle.message("expression.expected"));
+      }
+      if (atToken(JavaFxTokenTypes.TWEEN_KEYWORD)) {
+        nextToken();
+        if (!parseOrExpression()) {
+          myBuilder.error(JavaFxBundle.message("expression.expected"));
+        }
+      }
+      marker.done(JavaFxElementTypes.ASSIGNMENT_EXPRESSION);
+    }
+    else {
+      marker.drop();
+    }
+    return true;
+  }
+
+  private boolean parseOrExpression() {
+    PsiBuilder.Marker marker = myBuilder.mark();
+    if (!parseAndExpression()) {
+      marker.drop();
+      return false;
+    }
+    while (atToken(JavaFxTokenTypes.OR_KEYWORD)) {
+      nextToken();
+      if (!parseAndExpression()) {
+        myBuilder.error(JavaFxBundle.message("expression.expected"));
+      }
+      marker.done(JavaFxElementTypes.BINARY_EXPRESSION);
+      marker = marker.precede();
+    }
+    marker.drop();
+    return true;
+  }
+
+  private boolean parseAndExpression() {
+    PsiBuilder.Marker marker = myBuilder.mark();
+    if (!parseTypeExpression()) {
+      marker.drop();
+      return false;
+    }
+    while (atToken(JavaFxTokenTypes.AND_KEYWORD)) {
+      nextToken();
+      if (!parseTypeExpression()) {
+        myBuilder.error(JavaFxBundle.message("expression.expected"));
+      }
+      marker.done(JavaFxElementTypes.BINARY_EXPRESSION);
+      marker = marker.precede();
+    }
+    marker.drop();
+    return true;
+  }
+
+  private boolean parseTypeExpression() {
+    final PsiBuilder.Marker marker = myBuilder.mark();
+    if (!parseRelationalExpression()) {
+      marker.drop();
+      return false;
+    }
+    if (atToken(JavaFxTokenTypes.AS_KEYWORD) || atToken(JavaFxTokenTypes.INSTANCEOF_KEYWORD)) {
+      nextToken();
+      parseType();
+      marker.done(JavaFxElementTypes.TYPE_EXPRESSION);
+    }
+    else {
+      marker.drop();
+    }
+    return true;
+  }
+
+  private boolean parseRelationalExpression() {
+    PsiBuilder.Marker marker = myBuilder.mark();
+    if (!parseAdditiveExpression()) {
+      marker.drop();
+      return false;
+    }
+    while (JavaFxTokenTypes.RELATIONAL_OPERATORS.contains(myBuilder.getTokenType())) {
+      nextToken();
+      if (!parseAdditiveExpression()) {
+        myBuilder.error(JavaFxBundle.message("expression.expected"));
+      }
+      marker.done(JavaFxElementTypes.BINARY_EXPRESSION);
+      marker = marker.precede();
+    }
+    marker.drop();
+    return true;
+  }
+
+  private boolean parseAdditiveExpression() {
+    PsiBuilder.Marker marker = myBuilder.mark();
+    if (!parseMultiplicativeExpression()) {
+      marker.drop();
+      return false;
+    }
+    while (atToken(JavaFxTokenTypes.PLUS) || atToken(JavaFxTokenTypes.MINUS)) {
+      nextToken();
+      if (!parseMultiplicativeExpression()) {
+        myBuilder.error(JavaFxBundle.message("expression.expected"));
+      }
+      marker.done(JavaFxElementTypes.BINARY_EXPRESSION);
+      marker = marker.precede();
+    }
+    marker.drop();
+    return true;
+  }
+
+  private boolean parseMultiplicativeExpression() {
+    PsiBuilder.Marker marker = myBuilder.mark();
+    if (!parseUnaryExpression()) {
+      marker.drop();
+      return false;
+    }
+    while (atToken(JavaFxTokenTypes.MULT) || atToken(JavaFxTokenTypes.DIV) || atToken(JavaFxTokenTypes.MOD_KEYWORD)) {
+      nextToken();
+      if (!parseUnaryExpression()) {
+        myBuilder.error("expression.expected");
+      }
+      marker.done(JavaFxElementTypes.BINARY_EXPRESSION);
+      marker = marker.precede();
+    }
+    marker.drop();
+    return true;
+  }
+
+  private boolean parseUnaryExpression() {
+    if (atToken(JavaFxTokenTypes.INDEXOF_KEYWORD)) {
+      final PsiBuilder.Marker marker = myBuilder.mark();
+      nextToken();
+      checkMatches(JavaFxTokenTypes.IDENTIFIER, JavaFxBundle.message("name.expected"));
+      marker.done(JavaFxElementTypes.INDEXOF_EXPRESSION);
+      return true;
+    }
+    else if (JavaFxTokenTypes.UNARY_OPERATORS.contains(myBuilder.getTokenType())) {
+      final PsiBuilder.Marker marker = myBuilder.mark();
+      nextToken();
+      if (!parseUnaryExpression()) {
+        myBuilder.error(JavaFxBundle.message("expression.expected"));
+      }
+      marker.done(JavaFxElementTypes.UNARY_EXPRESSION);
+      return true;
+    }
+    return parseSuffixedExpression();
+  }
+
+  private boolean parseSuffixedExpression() {
+    final PsiBuilder.Marker marker = myBuilder.mark();
+    if (!parsePostfixExpression()) {
+      marker.drop();
+      return false;
+    }
+    if (atToken(JavaFxTokenTypes.PLUSPLUS) || atToken(JavaFxTokenTypes.MINUSMINUS)) {
+      nextToken();
+      if (myPreviousTokenType == JavaFxTokenTypes.RBRACE) {
+        myBuilder.error(JavaFxBundle.message("unexpected.token"));
+      }
+      marker.done(JavaFxElementTypes.SUFFIXED_EXPRESSION);
+    }
+    else {
+      marker.drop();
+    }
+    return true;
+  }
+
+  private boolean parsePostfixExpression() {
+    PsiBuilder.Marker marker = myBuilder.mark();
+    if (!parsePrimaryExpression()) {
+      marker.drop();
+      return false;
+    }
+    while (true) {
+      final JavaFxElementType expressionType;
+      if (atToken(JavaFxTokenTypes.DOT)) {
+        nextToken();
+        final IElementType elementType = myBuilder.getTokenType();
+        if (elementType == JavaFxTokenTypes.THIS_KEYWORD) {
+          expressionType = JavaFxElementTypes.THIS_EXPRESSION;
+        }
+        else {
+          checkMatches(JavaFxTokenTypes.NAME_ALL, JavaFxBundle.message("name.expected"));
+          expressionType = JavaFxElementTypes.REFERENCE_EXPRESSION;
+        }
+      }
+      else if (atToken(JavaFxTokenTypes.LPAREN)) {
+        parseExpressionList();
+        expressionType = JavaFxElementTypes.CALL_EXPRESSION;
+      }
+      else if (atToken(JavaFxTokenTypes.LBRACK)) {
+        nextToken();
+        parseValueExpression();
+        if (atToken(JavaFxTokenTypes.RBRACK)) {
+          nextToken();
+          expressionType = JavaFxElementTypes.INDEX_EXPRESSION;
+        }
+        else if (atToken(JavaFxTokenTypes.DELIM)) {
+          nextToken();
+          parseValueExpression();
+          checkMatches(JavaFxTokenTypes.RBRACK, JavaFxBundle.message("rbrack.expected"));
+          expressionType = JavaFxElementTypes.SEQUENCE_SELECT_EXPRESSION;
+        }
+        else if (atToken(JavaFxTokenTypes.RANGE)) {
+          nextToken();
+          if (atToken(JavaFxTokenTypes.LT)) {
+            nextToken();
+          }
+          if (!atToken(JavaFxTokenTypes.RBRACK)) {
+            parseValueExpression();
+          }
+          checkMatches(JavaFxTokenTypes.RBRACK, JavaFxBundle.message("rbrack.expected"));
+          expressionType = JavaFxElementTypes.SLICE_EXPRESSION;
+        }
+        else {
+          myBuilder.error(JavaFxBundle.message("range.delim.or.rbrack.expected"));
+          marker.drop();
+          return false;
+        }
+      }
+      else {
+        break;
+      }
+      marker.done(expressionType);
+      marker = marker.precede();
+    }
+    marker.drop();
+    return true;
+  }
+
+  private void parseExpressionList() {
+    LOG.assertTrue(atToken(JavaFxTokenTypes.LPAREN));
+    final PsiBuilder.Marker marker = myBuilder.mark();
+    nextToken();
+    if (atToken(JavaFxTokenTypes.RPAREN)) {
+      nextToken();
+      marker.done(JavaFxElementTypes.EXPRESSION_LIST);
+      return;
+    }
+    parseValueExpression();
+    while (atToken(JavaFxTokenTypes.COMMA)) {
+      nextToken();
+      if (atToken(JavaFxTokenTypes.RPAREN)) {
+        break;
+      }
+      parseValueExpression();
+    }
+    checkMatches(JavaFxTokenTypes.RPAREN, JavaFxBundle.message("rparen.expected"));
+    marker.done(JavaFxElementTypes.EXPRESSION_LIST);
+  }
+
+  private boolean parsePrimaryExpression() {
+    final IElementType firstToken = myBuilder.getTokenType();
+    if (JavaFxTokenTypes.NAME.contains(firstToken)) {
+      final PsiBuilder.Marker marker = myBuilder.mark();
+      parseQualifiedName(JavaFxElementTypes.REFERENCE_EXPRESSION);
+      if (atToken(JavaFxTokenTypes.LBRACE)) {
+        parseObjectLiteral(marker);
+      }
+      else {
+        marker.drop();
+      }
+    }
+    else if (firstToken == JavaFxTokenTypes.LBRACE) {
+      parseBlockExpression();
+    }
+    else if (firstToken == JavaFxTokenTypes.THIS_KEYWORD) {
+      final PsiBuilder.Marker marker = myBuilder.mark();
+      nextToken();
+      marker.done(JavaFxElementTypes.THIS_EXPRESSION);
+    }
+    else if (firstToken == JavaFxTokenTypes.LBRACK) {
+      parseSequenceOrRangeExpression();
+    }
+    else if (firstToken == JavaFxTokenTypes.LPAREN) {
+      final PsiBuilder.Marker marker = myBuilder.mark();
+      nextToken();
+      if (!parseValueExpressionOptional()) {
+        marker.drop();
+        return false;
+      }
+      checkMatches(JavaFxTokenTypes.RPAREN, JavaFxBundle.message("rparen.expected"));
+      marker.done(JavaFxElementTypes.PARENTHESIZED_EXPRESSION);
+    }
+    else if (firstToken == JavaFxTokenTypes.AT_KEYWORD) {
+      parseTimelineExpression();
+    }
+    else if (JavaFxTokenTypes.STRING_START.contains(firstToken)) {
+      parseStringExpression();
+    }
+    else if (JavaFxTokenTypes.LITERALS.contains(firstToken)) {
+      final PsiBuilder.Marker marker = myBuilder.mark();
+      nextToken();
+      marker.done(JavaFxElementTypes.LITERAL_EXPRESSION);
+    }
+    else if (firstToken == JavaFxTokenTypes.FUNCTION_KEYWORD) {
+      parseFunctionExpression();
+    }
+    else {
+      return false;
+    }
+    return true;
+  }
+
+  private void parseStringExpression() {
+    LOG.assertTrue(JavaFxTokenTypes.STRING_START.contains(myBuilder.getTokenType()));
+