Moving java.hints to sandbox
authorjlahoda
Sun, 23 Oct 2016 11:50:54 +0200
changeset 10195f3232e1cd46
parent 1018 a970874548a7
child 1020 e27afbce8568
Moving java.hints to sandbox
hudson/trunk
java.hints/build.sh
java.hints/build.xml
java.hints/hintsimpl/build.xml
java.hints/hintsimpl/manifest.mf
java.hints/hintsimpl/nbproject/build-impl.xml
java.hints/hintsimpl/nbproject/genfiles.properties
java.hints/hintsimpl/nbproject/project.properties
java.hints/hintsimpl/nbproject/project.xml
java.hints/hintsimpl/nbproject/suite.properties
java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/Bundle.properties
java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/GlobalyUnused.java
java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/NonPrivateMakeFinal.java
java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/duplicates/DuplicateMethodRefactoring.java
java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/duplicates/DuplicateMethodRefactoringAction.java
java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/duplicates/DuplicateMethodRefactoringPlugin.java
java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/duplicates/DuplicateMethodRefactoringUI.java
java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/duplicates/RefactoringPluginFactoryImpl.java
java.hints/hintsimpl/test/unit/src/org/netbeans/modules/jackpot30/hintsimpl/GlobalyUnusedNGTest.java
java.hints/hintsimpl/test/unit/src/org/netbeans/modules/jackpot30/hintsimpl/NonPrivateMakeFinalNGTest.java
java.hints/hintsimpl/test/unit/src/org/netbeans/modules/jackpot30/hintsimpl/borrowed/RefactoringTestBase.java
java.hints/hintsimpl/test/unit/src/org/netbeans/modules/jackpot30/hintsimpl/duplicates/DuplicateMethodRefactoringPluginTest.java
java.hints/java.hints.test/apichanges.xml
java.hints/java.hints.test/arch.xml
java.hints/java.hints.test/build.xml
java.hints/java.hints.test/manifest.mf
java.hints/java.hints.test/nbproject/build-impl.xml
java.hints/java.hints.test/nbproject/genfiles.properties
java.hints/java.hints.test/nbproject/org-netbeans-modules-java-hints-test.sig
java.hints/java.hints.test/nbproject/project.properties
java.hints/java.hints.test/nbproject/project.xml
java.hints/java.hints.test/nbproject/suite.properties
java.hints/java.hints.test/src/org/netbeans/modules/java/hints/test/Bundle.properties
java.hints/java.hints.test/src/org/netbeans/modules/java/hints/test/Utilities.java
java.hints/java.hints.test/src/org/netbeans/modules/java/hints/test/api/HintTest.java
java.hints/java.hints.test/src/org/netbeans/modules/parsing/impl/indexing/MimeTypes.java
java.hints/java.hints.test/test/unit/src/org/netbeans/modules/java/hints/test/api/HintTestTest.java
java.hints/nbproject/build-impl.xml
java.hints/nbproject/genfiles.properties
java.hints/nbproject/platform.properties
java.hints/nbproject/platform.xml
java.hints/nbproject/project.properties
java.hints/nbproject/project.xml
java.hints/spi.java.hints/apichanges.xml
java.hints/spi.java.hints/arch.xml
java.hints/spi.java.hints/build.xml
java.hints/spi.java.hints/manifest.mf
java.hints/spi.java.hints/nbproject/build-impl.xml
java.hints/spi.java.hints/nbproject/genfiles.properties
java.hints/spi.java.hints/nbproject/org-netbeans-spi-java-hints.sig
java.hints/spi.java.hints/nbproject/project.properties
java.hints/spi.java.hints/nbproject/project.xml
java.hints/spi.java.hints/nbproject/suite.properties
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/jackpot/spi/Bundle.properties
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/jackpot/spi/HintsRunner.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/jackpot/spi/PatternConvertor.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/jackpot/spi/ProjectDependencyUpgrader.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/code/CodeHintProviderImpl.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/code/FSWrapper.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/code/ReflectiveCustomizerProvider.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/ClassPathBasedHintProvider.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/ElementBasedHintProvider.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/HintDescription.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/HintDescriptionFactory.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/HintMetadata.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/HintProvider.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/PositionRefresherHelper.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/Trigger.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/Bundle.properties
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/Hacks.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/JackpotTrees.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/JavaFixImpl.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/JavaHintsPositionRefresher.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/MessageImpl.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/RulesManager.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/RulesManagerImpl.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/SPIAccessor.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/SyntheticFix.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/Utilities.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/batch/BatchSearch.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/batch/BatchUtilities.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/batch/ProgressHandleWrapper.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/batch/Scopes.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/hints/GlobalProcessingContext.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/hints/HintsInvoker.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/hints/HintsTask.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/ipi/upgrade/ProjectDependencyUpgrader.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/options/HintsSettings.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/pm/BulkSearch.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/pm/CopyFinderBasedBulkSearch.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/pm/NFA.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/pm/NFABasedBulkSearch.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/pm/PatternCompiler.java
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/processor/Bundle.properties
java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/processor/JavaHintsAnnotationProcessor.java
java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/BooleanOption.java
java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/Bundle.properties
java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/ConstraintVariableType.java
java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/CustomizerProvider.java
java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/Decision.java
java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/ErrorDescriptionFactory.java
java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/Hint.java
java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/HintContext.java
java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/HintSeverity.java
java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/IntegerOption.java
java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/JavaFix.java
java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/JavaFixUtilities.java
java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/MatcherUtilities.java
java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/TriggerDecision.java
java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/TriggerPattern.java
java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/TriggerPatterns.java
java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/TriggerTreeKind.java
java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/UseOptions.java
java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/support/FixFactory.java
java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/support/TransformationSupport.java
java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/providers/code/CodeHintProviderImplTest.java
java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/providers/code/FSWrapperTest.java
java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/providers/code/TestAnnotations.java
java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/TestBase.java
java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/TestCompilerSettings.java
java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/TestUtilities.java
java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/UtilitiesTest.java
java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/batch/BatchSearchTest.java
java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/batch/BatchUtilitiesTest.java
java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/batch/ProgressHandleWrapperTest.java
java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/batch/TestUtils.java
java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/hints/HintsInvokerTest.java
java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/pm/BulkSearchTestPerformer.java
java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/pm/CopyFinderBasedBulkSearchTest.java
java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/pm/NFABasedBulkSearchTest.java
java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/pm/PatternCompilerTest.java
java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/pm/PatternCompilerUtilities.java
java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/processor/JavaHintsAnnotationProcessorTest.java
java.hints/spi.java.hints/test/unit/src/org/netbeans/spi/java/hints/JavaFixUtilitiesTest.java
java.hints/spi.java.hints/test/unit/src/org/netbeans/spi/java/hints/MatcherUtilitiesTest.java
java.hints/spi.java.hints/test/unit/src/org/netbeans/spi/java/hints/TestUtils.java
java.hints/spi.java.hints/test/unit/src/org/netbeans/spi/java/hints/matching/CopyFinderTest.java
java.hints/spi.java.hints/test/unit/src/org/netbeans/spi/java/hints/support/FixFactoryTest.java
sandbox/java.hints/build.sh
sandbox/java.hints/build.xml
sandbox/java.hints/hintsimpl/build.xml
sandbox/java.hints/hintsimpl/manifest.mf
sandbox/java.hints/hintsimpl/nbproject/build-impl.xml
sandbox/java.hints/hintsimpl/nbproject/genfiles.properties
sandbox/java.hints/hintsimpl/nbproject/project.properties
sandbox/java.hints/hintsimpl/nbproject/project.xml
sandbox/java.hints/hintsimpl/nbproject/suite.properties
sandbox/java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/Bundle.properties
sandbox/java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/GlobalyUnused.java
sandbox/java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/NonPrivateMakeFinal.java
sandbox/java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/duplicates/DuplicateMethodRefactoring.java
sandbox/java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/duplicates/DuplicateMethodRefactoringAction.java
sandbox/java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/duplicates/DuplicateMethodRefactoringPlugin.java
sandbox/java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/duplicates/DuplicateMethodRefactoringUI.java
sandbox/java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/duplicates/RefactoringPluginFactoryImpl.java
sandbox/java.hints/hintsimpl/test/unit/src/org/netbeans/modules/jackpot30/hintsimpl/GlobalyUnusedNGTest.java
sandbox/java.hints/hintsimpl/test/unit/src/org/netbeans/modules/jackpot30/hintsimpl/NonPrivateMakeFinalNGTest.java
sandbox/java.hints/hintsimpl/test/unit/src/org/netbeans/modules/jackpot30/hintsimpl/borrowed/RefactoringTestBase.java
sandbox/java.hints/hintsimpl/test/unit/src/org/netbeans/modules/jackpot30/hintsimpl/duplicates/DuplicateMethodRefactoringPluginTest.java
sandbox/java.hints/java.hints.test/apichanges.xml
sandbox/java.hints/java.hints.test/arch.xml
sandbox/java.hints/java.hints.test/build.xml
sandbox/java.hints/java.hints.test/manifest.mf
sandbox/java.hints/java.hints.test/nbproject/build-impl.xml
sandbox/java.hints/java.hints.test/nbproject/genfiles.properties
sandbox/java.hints/java.hints.test/nbproject/org-netbeans-modules-java-hints-test.sig
sandbox/java.hints/java.hints.test/nbproject/project.properties
sandbox/java.hints/java.hints.test/nbproject/project.xml
sandbox/java.hints/java.hints.test/nbproject/suite.properties
sandbox/java.hints/java.hints.test/src/org/netbeans/modules/java/hints/test/Bundle.properties
sandbox/java.hints/java.hints.test/src/org/netbeans/modules/java/hints/test/Utilities.java
sandbox/java.hints/java.hints.test/src/org/netbeans/modules/java/hints/test/api/HintTest.java
sandbox/java.hints/java.hints.test/src/org/netbeans/modules/parsing/impl/indexing/MimeTypes.java
sandbox/java.hints/java.hints.test/test/unit/src/org/netbeans/modules/java/hints/test/api/HintTestTest.java
sandbox/java.hints/nbproject/build-impl.xml
sandbox/java.hints/nbproject/genfiles.properties
sandbox/java.hints/nbproject/platform.properties
sandbox/java.hints/nbproject/platform.xml
sandbox/java.hints/nbproject/project.properties
sandbox/java.hints/nbproject/project.xml
sandbox/java.hints/spi.java.hints/apichanges.xml
sandbox/java.hints/spi.java.hints/arch.xml
sandbox/java.hints/spi.java.hints/build.xml
sandbox/java.hints/spi.java.hints/manifest.mf
sandbox/java.hints/spi.java.hints/nbproject/build-impl.xml
sandbox/java.hints/spi.java.hints/nbproject/genfiles.properties
sandbox/java.hints/spi.java.hints/nbproject/org-netbeans-spi-java-hints.sig
sandbox/java.hints/spi.java.hints/nbproject/project.properties
sandbox/java.hints/spi.java.hints/nbproject/project.xml
sandbox/java.hints/spi.java.hints/nbproject/suite.properties
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/jackpot/spi/Bundle.properties
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/jackpot/spi/HintsRunner.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/jackpot/spi/PatternConvertor.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/jackpot/spi/ProjectDependencyUpgrader.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/code/CodeHintProviderImpl.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/code/FSWrapper.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/code/ReflectiveCustomizerProvider.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/ClassPathBasedHintProvider.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/ElementBasedHintProvider.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/HintDescription.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/HintDescriptionFactory.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/HintMetadata.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/HintProvider.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/PositionRefresherHelper.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/Trigger.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/Bundle.properties
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/Hacks.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/JackpotTrees.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/JavaFixImpl.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/JavaHintsPositionRefresher.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/MessageImpl.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/RulesManager.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/RulesManagerImpl.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/SPIAccessor.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/SyntheticFix.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/Utilities.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/batch/BatchSearch.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/batch/BatchUtilities.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/batch/ProgressHandleWrapper.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/batch/Scopes.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/hints/GlobalProcessingContext.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/hints/HintsInvoker.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/hints/HintsTask.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/ipi/upgrade/ProjectDependencyUpgrader.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/options/HintsSettings.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/pm/BulkSearch.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/pm/CopyFinderBasedBulkSearch.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/pm/NFA.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/pm/NFABasedBulkSearch.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/pm/PatternCompiler.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/processor/Bundle.properties
sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/processor/JavaHintsAnnotationProcessor.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/BooleanOption.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/Bundle.properties
sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/ConstraintVariableType.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/CustomizerProvider.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/Decision.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/ErrorDescriptionFactory.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/Hint.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/HintContext.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/HintSeverity.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/IntegerOption.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/JavaFix.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/JavaFixUtilities.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/MatcherUtilities.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/TriggerDecision.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/TriggerPattern.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/TriggerPatterns.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/TriggerTreeKind.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/UseOptions.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/support/FixFactory.java
sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/support/TransformationSupport.java
sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/providers/code/CodeHintProviderImplTest.java
sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/providers/code/FSWrapperTest.java
sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/providers/code/TestAnnotations.java
sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/TestBase.java
sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/TestCompilerSettings.java
sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/TestUtilities.java
sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/UtilitiesTest.java
sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/batch/BatchSearchTest.java
sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/batch/BatchUtilitiesTest.java
sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/batch/ProgressHandleWrapperTest.java
sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/batch/TestUtils.java
sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/hints/HintsInvokerTest.java
sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/pm/BulkSearchTestPerformer.java
sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/pm/CopyFinderBasedBulkSearchTest.java
sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/pm/NFABasedBulkSearchTest.java
sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/pm/PatternCompilerTest.java
sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/pm/PatternCompilerUtilities.java
sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/processor/JavaHintsAnnotationProcessorTest.java
sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/spi/java/hints/JavaFixUtilitiesTest.java
sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/spi/java/hints/MatcherUtilitiesTest.java
sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/spi/java/hints/TestUtils.java
sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/spi/java/hints/matching/CopyFinderTest.java
sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/spi/java/hints/support/FixFactoryTest.java
     1.1 --- a/hudson/trunk	Sun Oct 16 08:01:27 2016 +0200
     1.2 +++ b/hudson/trunk	Sun Oct 23 11:50:54 2016 +0200
     1.3 @@ -41,7 +41,7 @@
     1.4  
     1.5  ant -Dnbplatform.active.dir=$PLATFORM -f lib/download.xml download copy-from-platform
     1.6  
     1.7 -SUBPROJECTS="remoting duplicates language java.hints cmdline";
     1.8 +SUBPROJECTS="remoting duplicates language cmdline";
     1.9  
    1.10  for subproject in $SUBPROJECTS; do
    1.11      (cd $subproject; ./build.sh -Dnbplatform.default.harness.dir=$PLATFORM/harness -Dnbplatform.default.netbeans.dest.dir=$PLATFORM -Dnbplatform.active.dir=$PLATFORM) || exit 1
     2.1 --- a/java.hints/build.sh	Sun Oct 16 08:01:27 2016 +0200
     2.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.3 @@ -1,3 +0,0 @@
     2.4 -#!/bin/bash
     2.5 -ant "$@" clean && ant "$@" nbms && ant "$@" test || exit 1
     2.6 -
     3.1 --- a/java.hints/build.xml	Sun Oct 16 08:01:27 2016 +0200
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,8 +0,0 @@
     3.4 -<?xml version="1.0" encoding="UTF-8"?>
     3.5 -<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
     3.6 -<!-- for some information on what you could do (e.g. targets to override). -->
     3.7 -<!-- If you delete this file and reopen the project it will be recreated. -->
     3.8 -<project name="java.hints" basedir=".">
     3.9 -    <description>Builds the module suite java.hints.</description>
    3.10 -    <import file="nbproject/build-impl.xml"/>
    3.11 -</project>
     4.1 --- a/java.hints/hintsimpl/build.xml	Sun Oct 16 08:01:27 2016 +0200
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,8 +0,0 @@
     4.4 -<?xml version="1.0" encoding="UTF-8"?>
     4.5 -<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
     4.6 -<!-- for some information on what you could do (e.g. targets to override). -->
     4.7 -<!-- If you delete this file and reopen the project it will be recreated. -->
     4.8 -<project name="org.netbeans.modules.jackpot30.hintsimpl" default="netbeans" basedir=".">
     4.9 -    <description>Builds, tests, and runs the project org.netbeans.modules.jackpot30.hintsimpl.</description>
    4.10 -    <import file="nbproject/build-impl.xml"/>
    4.11 -</project>
     5.1 --- a/java.hints/hintsimpl/manifest.mf	Sun Oct 16 08:01:27 2016 +0200
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,5 +0,0 @@
     5.4 -Manifest-Version: 1.0
     5.5 -OpenIDE-Module: org.netbeans.modules.jackpot30.hintsimpl
     5.6 -OpenIDE-Module-Implementation-Version: 1
     5.7 -OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/jackpot30/hintsimpl/Bundle.properties
     5.8 -
     6.1 --- a/java.hints/hintsimpl/nbproject/build-impl.xml	Sun Oct 16 08:01:27 2016 +0200
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,45 +0,0 @@
     6.4 -<?xml version="1.0" encoding="UTF-8"?>
     6.5 -<!--
     6.6 -*** GENERATED FROM project.xml - DO NOT EDIT  ***
     6.7 -***         EDIT ../build.xml INSTEAD         ***
     6.8 --->
     6.9 -<project name="org.netbeans.modules.jackpot30.hintsimpl-impl" basedir="..">
    6.10 -    <fail message="Please build using Ant 1.7.1 or higher.">
    6.11 -        <condition>
    6.12 -            <not>
    6.13 -                <antversion atleast="1.7.1"/>
    6.14 -            </not>
    6.15 -        </condition>
    6.16 -    </fail>
    6.17 -    <property file="nbproject/private/suite-private.properties"/>
    6.18 -    <property file="nbproject/suite.properties"/>
    6.19 -    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
    6.20 -    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
    6.21 -    <property file="${suite.dir}/nbproject/platform.properties"/>
    6.22 -    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
    6.23 -        <attribute name="name"/>
    6.24 -        <attribute name="value"/>
    6.25 -        <sequential>
    6.26 -            <property name="@{name}" value="${@{value}}"/>
    6.27 -        </sequential>
    6.28 -    </macrodef>
    6.29 -    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
    6.30 -        <attribute name="property"/>
    6.31 -        <attribute name="value"/>
    6.32 -        <sequential>
    6.33 -            <property name="@{property}" value="@{value}"/>
    6.34 -        </sequential>
    6.35 -    </macrodef>
    6.36 -    <property file="${user.properties.file}"/>
    6.37 -    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
    6.38 -    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
    6.39 -    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
    6.40 -    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
    6.41 -        <condition>
    6.42 -            <not>
    6.43 -                <contains string="${cluster.path.evaluated}" substring="platform"/>
    6.44 -            </not>
    6.45 -        </condition>
    6.46 -    </fail>
    6.47 -    <import file="${harness.dir}/build.xml"/>
    6.48 -</project>
     7.1 --- a/java.hints/hintsimpl/nbproject/genfiles.properties	Sun Oct 16 08:01:27 2016 +0200
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,8 +0,0 @@
     7.4 -build.xml.data.CRC32=52580c5f
     7.5 -build.xml.script.CRC32=ef577a91
     7.6 -build.xml.stylesheet.CRC32=a56c6a5b@2.70
     7.7 -# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
     7.8 -# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
     7.9 -nbproject/build-impl.xml.data.CRC32=52580c5f
    7.10 -nbproject/build-impl.xml.script.CRC32=9204f652
    7.11 -nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.70
     8.1 --- a/java.hints/hintsimpl/nbproject/project.properties	Sun Oct 16 08:01:27 2016 +0200
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,5 +0,0 @@
     8.4 -javac.source=1.7
     8.5 -javac.compilerargs=-Xlint -Xlint:-serial
     8.6 -requires.nb.javac=true
     8.7 -spec.version.base=1.0
     8.8 -test.runner=junit
     9.1 --- a/java.hints/hintsimpl/nbproject/project.xml	Sun Oct 16 08:01:27 2016 +0200
     9.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.3 @@ -1,232 +0,0 @@
     9.4 -<?xml version="1.0" encoding="UTF-8"?>
     9.5 -<project xmlns="http://www.netbeans.org/ns/project/1">
     9.6 -    <type>org.netbeans.modules.apisupport.project</type>
     9.7 -    <configuration>
     9.8 -        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
     9.9 -            <code-name-base>org.netbeans.modules.jackpot30.hintsimpl</code-name-base>
    9.10 -            <suite-component/>
    9.11 -            <module-dependencies>
    9.12 -                <dependency>
    9.13 -                    <code-name-base>org.netbeans.api.annotations.common</code-name-base>
    9.14 -                    <build-prerequisite/>
    9.15 -                    <compile-dependency/>
    9.16 -                    <run-dependency>
    9.17 -                        <release-version>1</release-version>
    9.18 -                        <specification-version>1.20</specification-version>
    9.19 -                    </run-dependency>
    9.20 -                </dependency>
    9.21 -                <dependency>
    9.22 -                    <code-name-base>org.netbeans.api.java.classpath</code-name-base>
    9.23 -                    <build-prerequisite/>
    9.24 -                    <compile-dependency/>
    9.25 -                    <run-dependency>
    9.26 -                        <release-version>1</release-version>
    9.27 -                        <specification-version>1.39</specification-version>
    9.28 -                    </run-dependency>
    9.29 -                </dependency>
    9.30 -                <dependency>
    9.31 -                    <code-name-base>org.netbeans.libs.javacapi</code-name-base>
    9.32 -                    <build-prerequisite/>
    9.33 -                    <compile-dependency/>
    9.34 -                    <run-dependency>
    9.35 -                        <specification-version>8.4.0.3</specification-version>
    9.36 -                    </run-dependency>
    9.37 -                </dependency>
    9.38 -                <dependency>
    9.39 -                    <code-name-base>org.netbeans.modules.java.hints</code-name-base>
    9.40 -                    <build-prerequisite/>
    9.41 -                    <compile-dependency/>
    9.42 -                    <run-dependency>
    9.43 -                        <release-version>1</release-version>
    9.44 -                        <implementation-version/>
    9.45 -                    </run-dependency>
    9.46 -                </dependency>
    9.47 -                <dependency>
    9.48 -                    <code-name-base>org.netbeans.modules.java.source</code-name-base>
    9.49 -                    <build-prerequisite/>
    9.50 -                    <compile-dependency/>
    9.51 -                    <run-dependency>
    9.52 -                        <specification-version>0.124.0.24.1.23.6</specification-version>
    9.53 -                    </run-dependency>
    9.54 -                </dependency>
    9.55 -                <dependency>
    9.56 -                    <code-name-base>org.netbeans.modules.java.source.base</code-name-base>
    9.57 -                    <build-prerequisite/>
    9.58 -                    <compile-dependency/>
    9.59 -                    <run-dependency>
    9.60 -                        <specification-version>2.4.1.2.25.8.1</specification-version>
    9.61 -                    </run-dependency>
    9.62 -                </dependency>
    9.63 -                <dependency>
    9.64 -                    <code-name-base>org.netbeans.modules.java.sourceui</code-name-base>
    9.65 -                    <build-prerequisite/>
    9.66 -                    <compile-dependency/>
    9.67 -                    <run-dependency>
    9.68 -                        <release-version>1</release-version>
    9.69 -                        <specification-version>1.33.0.1.25</specification-version>
    9.70 -                    </run-dependency>
    9.71 -                </dependency>
    9.72 -                <dependency>
    9.73 -                    <code-name-base>org.netbeans.modules.queries</code-name-base>
    9.74 -                    <build-prerequisite/>
    9.75 -                    <compile-dependency/>
    9.76 -                    <run-dependency>
    9.77 -                        <release-version>1</release-version>
    9.78 -                        <specification-version>1.36</specification-version>
    9.79 -                    </run-dependency>
    9.80 -                </dependency>
    9.81 -                <dependency>
    9.82 -                    <code-name-base>org.netbeans.modules.refactoring.api</code-name-base>
    9.83 -                    <build-prerequisite/>
    9.84 -                    <compile-dependency/>
    9.85 -                    <run-dependency>
    9.86 -                        <specification-version>1.37.0.1</specification-version>
    9.87 -                    </run-dependency>
    9.88 -                </dependency>
    9.89 -                <dependency>
    9.90 -                    <code-name-base>org.netbeans.modules.refactoring.java</code-name-base>
    9.91 -                    <build-prerequisite/>
    9.92 -                    <compile-dependency/>
    9.93 -                    <run-dependency>
    9.94 -                        <release-version>1</release-version>
    9.95 -                        <implementation-version/>
    9.96 -                    </run-dependency>
    9.97 -                </dependency>
    9.98 -                <dependency>
    9.99 -                    <code-name-base>org.netbeans.spi.editor.hints</code-name-base>
   9.100 -                    <build-prerequisite/>
   9.101 -                    <compile-dependency/>
   9.102 -                    <run-dependency>
   9.103 -                        <release-version>0</release-version>
   9.104 -                        <specification-version>1.31.0.7.42</specification-version>
   9.105 -                    </run-dependency>
   9.106 -                </dependency>
   9.107 -                <dependency>
   9.108 -                    <code-name-base>org.netbeans.spi.java.hints</code-name-base>
   9.109 -                    <build-prerequisite/>
   9.110 -                    <compile-dependency/>
   9.111 -                    <run-dependency>
   9.112 -                        <specification-version>2.0</specification-version>
   9.113 -                    </run-dependency>
   9.114 -                </dependency>
   9.115 -                <dependency>
   9.116 -                    <code-name-base>org.openide.awt</code-name-base>
   9.117 -                    <build-prerequisite/>
   9.118 -                    <compile-dependency/>
   9.119 -                    <run-dependency>
   9.120 -                        <specification-version>7.59</specification-version>
   9.121 -                    </run-dependency>
   9.122 -                </dependency>
   9.123 -                <dependency>
   9.124 -                    <code-name-base>org.openide.filesystems</code-name-base>
   9.125 -                    <build-prerequisite/>
   9.126 -                    <compile-dependency/>
   9.127 -                    <run-dependency>
   9.128 -                        <specification-version>8.8</specification-version>
   9.129 -                    </run-dependency>
   9.130 -                </dependency>
   9.131 -                <dependency>
   9.132 -                    <code-name-base>org.openide.loaders</code-name-base>
   9.133 -                    <build-prerequisite/>
   9.134 -                    <compile-dependency/>
   9.135 -                    <run-dependency>
   9.136 -                        <specification-version>7.50</specification-version>
   9.137 -                    </run-dependency>
   9.138 -                </dependency>
   9.139 -                <dependency>
   9.140 -                    <code-name-base>org.openide.nodes</code-name-base>
   9.141 -                    <build-prerequisite/>
   9.142 -                    <compile-dependency/>
   9.143 -                    <run-dependency>
   9.144 -                        <specification-version>7.36</specification-version>
   9.145 -                    </run-dependency>
   9.146 -                </dependency>
   9.147 -                <dependency>
   9.148 -                    <code-name-base>org.openide.text</code-name-base>
   9.149 -                    <build-prerequisite/>
   9.150 -                    <compile-dependency/>
   9.151 -                    <run-dependency>
   9.152 -                        <specification-version>6.57</specification-version>
   9.153 -                    </run-dependency>
   9.154 -                </dependency>
   9.155 -                <dependency>
   9.156 -                    <code-name-base>org.openide.util</code-name-base>
   9.157 -                    <build-prerequisite/>
   9.158 -                    <compile-dependency/>
   9.159 -                    <run-dependency>
   9.160 -                        <specification-version>8.32</specification-version>
   9.161 -                    </run-dependency>
   9.162 -                </dependency>
   9.163 -                <dependency>
   9.164 -                    <code-name-base>org.openide.util.lookup</code-name-base>
   9.165 -                    <build-prerequisite/>
   9.166 -                    <compile-dependency/>
   9.167 -                    <run-dependency>
   9.168 -                        <specification-version>8.22</specification-version>
   9.169 -                    </run-dependency>
   9.170 -                </dependency>
   9.171 -                <dependency>
   9.172 -                    <code-name-base>org.openide.util.ui</code-name-base>
   9.173 -                    <build-prerequisite/>
   9.174 -                    <compile-dependency/>
   9.175 -                    <run-dependency>
   9.176 -                        <specification-version>9.3</specification-version>
   9.177 -                    </run-dependency>
   9.178 -                </dependency>
   9.179 -                <dependency>
   9.180 -                    <code-name-base>org.openide.windows</code-name-base>
   9.181 -                    <build-prerequisite/>
   9.182 -                    <compile-dependency/>
   9.183 -                    <run-dependency>
   9.184 -                        <specification-version>6.64</specification-version>
   9.185 -                    </run-dependency>
   9.186 -                </dependency>
   9.187 -            </module-dependencies>
   9.188 -            <test-dependencies>
   9.189 -                <test-type>
   9.190 -                    <name>unit</name>
   9.191 -                    <test-dependency>
   9.192 -                        <code-name-base>org.netbeans.libs.junit4</code-name-base>
   9.193 -                        <compile-dependency/>
   9.194 -                    </test-dependency>
   9.195 -                    <test-dependency>
   9.196 -                        <code-name-base>org.netbeans.libs.testng</code-name-base>
   9.197 -                        <compile-dependency/>
   9.198 -                    </test-dependency>
   9.199 -                    <test-dependency>
   9.200 -                        <code-name-base>org.netbeans.modules.editor.mimelookup.impl</code-name-base>
   9.201 -                        <compile-dependency/>
   9.202 -                    </test-dependency>
   9.203 -                    <test-dependency>
   9.204 -                        <code-name-base>org.netbeans.modules.jackpot30.test.borrowed</code-name-base>
   9.205 -                        <compile-dependency/>
   9.206 -                    </test-dependency>
   9.207 -                    <test-dependency>
   9.208 -                        <code-name-base>org.netbeans.modules.java.editor</code-name-base>
   9.209 -                        <recursive/>
   9.210 -                        <compile-dependency/>
   9.211 -                    </test-dependency>
   9.212 -                    <test-dependency>
   9.213 -                        <code-name-base>org.netbeans.modules.java.hints.test</code-name-base>
   9.214 -                        <recursive/>
   9.215 -                        <compile-dependency/>
   9.216 -                    </test-dependency>
   9.217 -                    <test-dependency>
   9.218 -                        <code-name-base>org.netbeans.modules.parsing.nb</code-name-base>
   9.219 -                        <compile-dependency/>
   9.220 -                    </test-dependency>
   9.221 -                    <test-dependency>
   9.222 -                        <code-name-base>org.netbeans.modules.projectapi.nb</code-name-base>
   9.223 -                        <compile-dependency/>
   9.224 -                    </test-dependency>
   9.225 -                    <test-dependency>
   9.226 -                        <code-name-base>org.netbeans.spi.java.hints</code-name-base>
   9.227 -                        <compile-dependency/>
   9.228 -                        <test/>
   9.229 -                    </test-dependency>
   9.230 -                </test-type>
   9.231 -            </test-dependencies>
   9.232 -            <public-packages/>
   9.233 -        </data>
   9.234 -    </configuration>
   9.235 -</project>
    10.1 --- a/java.hints/hintsimpl/nbproject/suite.properties	Sun Oct 16 08:01:27 2016 +0200
    10.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.3 @@ -1,1 +0,0 @@
    10.4 -suite.dir=${basedir}/..
    11.1 --- a/java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/Bundle.properties	Sun Oct 16 08:01:27 2016 +0200
    11.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.3 @@ -1,1 +0,0 @@
    11.4 -OpenIDE-Module-Name=Jackpot 3.0 Experimental Hints Impl
    12.1 --- a/java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/GlobalyUnused.java	Sun Oct 16 08:01:27 2016 +0200
    12.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.3 @@ -1,120 +0,0 @@
    12.4 -/*
    12.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    12.6 - *
    12.7 - * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
    12.8 - *
    12.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   12.10 - * Other names may be trademarks of their respective owners.
   12.11 - *
   12.12 - * The contents of this file are subject to the terms of either the GNU
   12.13 - * General Public License Version 2 only ("GPL") or the Common
   12.14 - * Development and Distribution License("CDDL") (collectively, the
   12.15 - * "License"). You may not use this file except in compliance with the
   12.16 - * License. You can obtain a copy of the License at
   12.17 - * http://www.netbeans.org/cddl-gplv2.html
   12.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   12.19 - * specific language governing permissions and limitations under the
   12.20 - * License.  When distributing the software, include this License Header
   12.21 - * Notice in each file and include the License file at
   12.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   12.23 - * particular file as subject to the "Classpath" exception as provided
   12.24 - * by Oracle in the GPL Version 2 section of the License file that
   12.25 - * accompanied this code. If applicable, add the following below the
   12.26 - * License Header, with the fields enclosed by brackets [] replaced by
   12.27 - * your own identifying information:
   12.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   12.29 - *
   12.30 - * If you wish your version of this file to be governed by only the CDDL
   12.31 - * or only the GPL Version 2, indicate your decision by adding
   12.32 - * "[Contributor] elects to include this software in this distribution
   12.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   12.34 - * single choice of license, a recipient has the option to distribute
   12.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   12.36 - * to extend the choice of license to its licensees as provided above.
   12.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   12.38 - * Version 2 license, then the option applies only if the new code is
   12.39 - * made subject to such option by the copyright holder.
   12.40 - *
   12.41 - * Contributor(s):
   12.42 - *
   12.43 - * Portions Copyrighted 2013 Sun Microsystems, Inc.
   12.44 - */
   12.45 -package org.netbeans.modules.jackpot30.hintsimpl;
   12.46 -
   12.47 -import com.sun.source.tree.Tree.Kind;
   12.48 -import javax.lang.model.element.Element;
   12.49 -import javax.lang.model.element.ElementKind;
   12.50 -import javax.lang.model.type.TypeKind;
   12.51 -import org.netbeans.api.java.source.TreePathHandle;
   12.52 -import org.netbeans.spi.editor.hints.ErrorDescription;
   12.53 -import org.netbeans.spi.java.hints.Decision;
   12.54 -import org.netbeans.spi.java.hints.Decision.Factory;
   12.55 -import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
   12.56 -import org.netbeans.spi.java.hints.Hint;
   12.57 -import org.netbeans.spi.java.hints.HintContext;
   12.58 -import org.netbeans.spi.java.hints.TriggerDecision;
   12.59 -import org.netbeans.spi.java.hints.TriggerTreeKind;
   12.60 -
   12.61 -/**
   12.62 - *
   12.63 - * @author lahvac
   12.64 - */
   12.65 -@Hint(displayName="Unused", description="Unused", category="general")
   12.66 -public class GlobalyUnused {
   12.67 -    
   12.68 -    @TriggerTreeKind({Kind.IDENTIFIER, Kind.MEMBER_SELECT})
   12.69 -    public static ErrorDescription usage(HintContext ctx) {
   12.70 -        DecisionImpl d = decisionOrNull(ctx);
   12.71 -        
   12.72 -        if (d != null) {
   12.73 -            System.err.println("recording usage");
   12.74 -            d.recordLocalFact(ctx.getInfo(), null);
   12.75 -        }
   12.76 -        
   12.77 -        return null;
   12.78 -    }
   12.79 -    
   12.80 -    @TriggerTreeKind({Kind.CLASS})
   12.81 -    public static ErrorDescription declaration(HintContext ctx) {
   12.82 -        decisionOrNull(ctx);
   12.83 -        return null;
   12.84 -    }
   12.85 -    
   12.86 -    @TriggerDecision(DecisionImpl.class)
   12.87 -    public static ErrorDescription produceWarning(HintContext ctx) {
   12.88 -        if (((DecisionImpl) ctx.decision).getCurrentResult() != Boolean.TRUE) {
   12.89 -            return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), "Unused");
   12.90 -        }
   12.91 -        
   12.92 -        return null;
   12.93 -    }
   12.94 -    
   12.95 -    private static DecisionImpl decisionOrNull(HintContext ctx) {
   12.96 -        Element el = ctx.getInfo().getTrees().getElement(ctx.getPath());
   12.97 -        
   12.98 -        if (el == null || (el.asType() != null && el.asType().getKind() == TypeKind.ERROR) || el.getKind() != ElementKind.CLASS) return null;
   12.99 -        
  12.100 -        TreePathHandle h = TreePathHandle.create(el, ctx.getInfo());
  12.101 -        
  12.102 -        System.err.println("decision for: " + el);
  12.103 -        return ctx.findDecision(h, new Factory<Void, Boolean, DecisionImpl>(DecisionImpl.class) {
  12.104 -            @Override
  12.105 -            public DecisionImpl create(TreePathHandle handle) {
  12.106 -                return new DecisionImpl(handle);
  12.107 -            }
  12.108 -        });
  12.109 -    }
  12.110 -    
  12.111 -    private static final class DecisionImpl extends Decision<Void, Boolean> {
  12.112 -
  12.113 -        public DecisionImpl(TreePathHandle root) {
  12.114 -            super(root);
  12.115 -        }
  12.116 -
  12.117 -        @Override
  12.118 -        protected Boolean makeDecision(Iterable<? extends Void> input) {
  12.119 -            return input.iterator().hasNext();
  12.120 -        }
  12.121 -        
  12.122 -    }
  12.123 -}
    13.1 --- a/java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/NonPrivateMakeFinal.java	Sun Oct 16 08:01:27 2016 +0200
    13.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.3 @@ -1,152 +0,0 @@
    13.4 -/*
    13.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    13.6 - *
    13.7 - * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
    13.8 - *
    13.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   13.10 - * Other names may be trademarks of their respective owners.
   13.11 - *
   13.12 - * The contents of this file are subject to the terms of either the GNU
   13.13 - * General Public License Version 2 only ("GPL") or the Common
   13.14 - * Development and Distribution License("CDDL") (collectively, the
   13.15 - * "License"). You may not use this file except in compliance with the
   13.16 - * License. You can obtain a copy of the License at
   13.17 - * http://www.netbeans.org/cddl-gplv2.html
   13.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   13.19 - * specific language governing permissions and limitations under the
   13.20 - * License.  When distributing the software, include this License Header
   13.21 - * Notice in each file and include the License file at
   13.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   13.23 - * particular file as subject to the "Classpath" exception as provided
   13.24 - * by Oracle in the GPL Version 2 section of the License file that
   13.25 - * accompanied this code. If applicable, add the following below the
   13.26 - * License Header, with the fields enclosed by brackets [] replaced by
   13.27 - * your own identifying information:
   13.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   13.29 - *
   13.30 - * If you wish your version of this file to be governed by only the CDDL
   13.31 - * or only the GPL Version 2, indicate your decision by adding
   13.32 - * "[Contributor] elects to include this software in this distribution
   13.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   13.34 - * single choice of license, a recipient has the option to distribute
   13.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   13.36 - * to extend the choice of license to its licensees as provided above.
   13.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   13.38 - * Version 2 license, then the option applies only if the new code is
   13.39 - * made subject to such option by the copyright holder.
   13.40 - *
   13.41 - * Contributor(s):
   13.42 - *
   13.43 - * Portions Copyrighted 2013 Sun Microsystems, Inc.
   13.44 - */
   13.45 -package org.netbeans.modules.jackpot30.hintsimpl;
   13.46 -
   13.47 -import com.sun.source.tree.Tree.Kind;
   13.48 -import com.sun.source.tree.VariableTree;
   13.49 -import com.sun.source.util.TreePath;
   13.50 -import java.util.EnumSet;
   13.51 -import javax.lang.model.element.Element;
   13.52 -import javax.lang.model.element.ElementKind;
   13.53 -import javax.lang.model.element.Modifier;
   13.54 -import javax.lang.model.element.VariableElement;
   13.55 -import org.netbeans.api.annotations.common.NonNull;
   13.56 -import org.netbeans.api.java.source.TreePathHandle;
   13.57 -import org.netbeans.modules.java.hints.introduce.Flow;
   13.58 -import org.netbeans.modules.java.hints.introduce.Flow.FlowResult;
   13.59 -import org.netbeans.spi.editor.hints.ErrorDescription;
   13.60 -import org.netbeans.spi.editor.hints.Fix;
   13.61 -import org.netbeans.spi.java.hints.Decision;
   13.62 -import org.netbeans.spi.java.hints.Decision.Factory;
   13.63 -import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
   13.64 -import org.netbeans.spi.java.hints.Hint;
   13.65 -import org.netbeans.spi.java.hints.HintContext;
   13.66 -import org.netbeans.spi.java.hints.TriggerDecision;
   13.67 -import org.netbeans.spi.java.hints.TriggerPattern;
   13.68 -import org.netbeans.spi.java.hints.TriggerTreeKind;
   13.69 -import org.netbeans.spi.java.hints.support.FixFactory;
   13.70 -import org.openide.util.NbBundle.Messages;
   13.71 -
   13.72 -/**
   13.73 - *
   13.74 - * @author lahvac
   13.75 - */
   13.76 -@Hint(displayName="Non Private Make Final", description="Non Private Make Final", category="general")
   13.77 -public class NonPrivateMakeFinal {
   13.78 -
   13.79 -    @TriggerPattern("$variable = $value")
   13.80 -    public static ErrorDescription write(HintContext ctx) {
   13.81 -        Element field = ctx.getInfo().getTrees().getElement(ctx.getVariables().get("$variable"));
   13.82 -
   13.83 -        if (field == null || field.getKind() != ElementKind.FIELD) {
   13.84 -            //unknown, or not a field, ignore.
   13.85 -            return null;
   13.86 -        }
   13.87 -
   13.88 -        if (ctx.getInfo().getTopLevelElements().contains(ctx.getInfo().getElementUtilities().outermostTypeElement(field))) {
   13.89 -            //field in current CU, ignore (will be handled by local flow)
   13.90 -            return null;
   13.91 -        }
   13.92 -
   13.93 -        decision(ctx, (VariableElement) field).recordLocalFact(ctx.getInfo(), false);
   13.94 -        
   13.95 -        return null;
   13.96 -    }
   13.97 -    
   13.98 -    @TriggerTreeKind({Kind.VARIABLE})
   13.99 -    public static ErrorDescription declaration(HintContext ctx) {
  13.100 -        Element ve = ctx.getInfo().getTrees().getElement(ctx.getPath());
  13.101 -
  13.102 -        if (ve == null || ve.getKind() != ElementKind.FIELD || ve.getModifiers().contains(Modifier.FINAL) || /*TODO: the point of volatile?*/ve.getModifiers().contains(Modifier.VOLATILE)) return null;
  13.103 -
  13.104 -        //handle all fields, even the private ones, which are handled by the standard hints.
  13.105 -        
  13.106 -        FlowResult flow = Flow.assignmentsForUse(ctx);
  13.107 -
  13.108 -        if (flow == null || ctx.isCanceled()) return null;
  13.109 -
  13.110 -        DecisionImpl decision = decision(ctx, (VariableElement) ve);
  13.111 -
  13.112 -        decision.recordLocalFact(ctx.getInfo(), flow.getFinalCandidates().contains((VariableElement) ve));
  13.113 -
  13.114 -        return null;
  13.115 -    }
  13.116 -    
  13.117 -    @TriggerDecision(DecisionImpl.class)
  13.118 -    @Messages("FIX_CanBeFinal={0} can be final")
  13.119 -    public static ErrorDescription produceWarning(HintContext ctx) {
  13.120 -        if (((DecisionImpl) ctx.decision).getCurrentResult() == Boolean.TRUE) {
  13.121 -            VariableTree vt = (VariableTree) ctx.getPath().getLeaf();
  13.122 -            Fix fix = FixFactory.addModifiersFix(ctx.getInfo(), new TreePath(ctx.getPath(), vt.getModifiers()), EnumSet.of(Modifier.FINAL), Bundle.FIX_CanBeFinal(vt.getName().toString()));
  13.123 -            return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), "Can be final", fix);
  13.124 -        }
  13.125 -        
  13.126 -        return null;
  13.127 -    }
  13.128 -    
  13.129 -    private static @NonNull DecisionImpl decision(HintContext ctx, @NonNull VariableElement field) {
  13.130 -        TreePathHandle h = TreePathHandle.create(field, ctx.getInfo());
  13.131 -        
  13.132 -        return ctx.findDecision(h, new Factory<Boolean, Boolean, DecisionImpl>(DecisionImpl.class) {
  13.133 -            @Override
  13.134 -            public DecisionImpl create(TreePathHandle handle) {
  13.135 -                return new DecisionImpl(handle);
  13.136 -            }
  13.137 -        });
  13.138 -    }
  13.139 -    
  13.140 -    private static final class DecisionImpl extends Decision<Boolean, Boolean> {
  13.141 -
  13.142 -        public DecisionImpl(TreePathHandle root) {
  13.143 -            super(root);
  13.144 -        }
  13.145 -
  13.146 -        @Override
  13.147 -        protected Boolean makeDecision(Iterable<? extends Boolean> input) {
  13.148 -            for (Boolean b : input) {
  13.149 -                if (b == null || !b) return false;
  13.150 -            }
  13.151 -            return true;
  13.152 -        }
  13.153 -        
  13.154 -    }
  13.155 -}
    14.1 --- a/java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/duplicates/DuplicateMethodRefactoring.java	Sun Oct 16 08:01:27 2016 +0200
    14.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.3 @@ -1,58 +0,0 @@
    14.4 -/*
    14.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    14.6 - *
    14.7 - * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
    14.8 - *
    14.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   14.10 - * Other names may be trademarks of their respective owners.
   14.11 - *
   14.12 - * The contents of this file are subject to the terms of either the GNU
   14.13 - * General Public License Version 2 only ("GPL") or the Common
   14.14 - * Development and Distribution License("CDDL") (collectively, the
   14.15 - * "License"). You may not use this file except in compliance with the
   14.16 - * License. You can obtain a copy of the License at
   14.17 - * http://www.netbeans.org/cddl-gplv2.html
   14.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   14.19 - * specific language governing permissions and limitations under the
   14.20 - * License.  When distributing the software, include this License Header
   14.21 - * Notice in each file and include the License file at
   14.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   14.23 - * particular file as subject to the "Classpath" exception as provided
   14.24 - * by Oracle in the GPL Version 2 section of the License file that
   14.25 - * accompanied this code. If applicable, add the following below the
   14.26 - * License Header, with the fields enclosed by brackets [] replaced by
   14.27 - * your own identifying information:
   14.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   14.29 - *
   14.30 - * If you wish your version of this file to be governed by only the CDDL
   14.31 - * or only the GPL Version 2, indicate your decision by adding
   14.32 - * "[Contributor] elects to include this software in this distribution
   14.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   14.34 - * single choice of license, a recipient has the option to distribute
   14.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   14.36 - * to extend the choice of license to its licensees as provided above.
   14.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   14.38 - * Version 2 license, then the option applies only if the new code is
   14.39 - * made subject to such option by the copyright holder.
   14.40 - *
   14.41 - * Contributor(s):
   14.42 - *
   14.43 - * Portions Copyrighted 2013 Sun Microsystems, Inc.
   14.44 - */
   14.45 -package org.netbeans.modules.jackpot30.hintsimpl.duplicates;
   14.46 -
   14.47 -import org.netbeans.api.java.source.TreePathHandle;
   14.48 -import org.netbeans.modules.refactoring.api.AbstractRefactoring;
   14.49 -import org.openide.util.lookup.Lookups;
   14.50 -
   14.51 -/**
   14.52 - *
   14.53 - * @author lahvac
   14.54 - */
   14.55 -public class DuplicateMethodRefactoring extends AbstractRefactoring {
   14.56 -
   14.57 -    public DuplicateMethodRefactoring(TreePathHandle source) {
   14.58 -        super(Lookups.singleton(source));
   14.59 -    }
   14.60 -
   14.61 -}
    15.1 --- a/java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/duplicates/DuplicateMethodRefactoringAction.java	Sun Oct 16 08:01:27 2016 +0200
    15.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.3 @@ -1,84 +0,0 @@
    15.4 -/*
    15.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    15.6 - *
    15.7 - * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
    15.8 - *
    15.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   15.10 - * Other names may be trademarks of their respective owners.
   15.11 - *
   15.12 - * The contents of this file are subject to the terms of either the GNU
   15.13 - * General Public License Version 2 only ("GPL") or the Common
   15.14 - * Development and Distribution License("CDDL") (collectively, the
   15.15 - * "License"). You may not use this file except in compliance with the
   15.16 - * License. You can obtain a copy of the License at
   15.17 - * http://www.netbeans.org/cddl-gplv2.html
   15.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   15.19 - * specific language governing permissions and limitations under the
   15.20 - * License.  When distributing the software, include this License Header
   15.21 - * Notice in each file and include the License file at
   15.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   15.23 - * particular file as subject to the "Classpath" exception as provided
   15.24 - * by Oracle in the GPL Version 2 section of the License file that
   15.25 - * accompanied this code. If applicable, add the following below the
   15.26 - * License Header, with the fields enclosed by brackets [] replaced by
   15.27 - * your own identifying information:
   15.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   15.29 - *
   15.30 - * If you wish your version of this file to be governed by only the CDDL
   15.31 - * or only the GPL Version 2, indicate your decision by adding
   15.32 - * "[Contributor] elects to include this software in this distribution
   15.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   15.34 - * single choice of license, a recipient has the option to distribute
   15.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   15.36 - * to extend the choice of license to its licensees as provided above.
   15.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   15.38 - * Version 2 license, then the option applies only if the new code is
   15.39 - * made subject to such option by the copyright holder.
   15.40 - *
   15.41 - * Contributor(s):
   15.42 - *
   15.43 - * Portions Copyrighted 2013 Sun Microsystems, Inc.
   15.44 - */
   15.45 -package org.netbeans.modules.jackpot30.hintsimpl.duplicates;
   15.46 -
   15.47 -import com.sun.source.tree.Tree.Kind;
   15.48 -import java.awt.event.ActionEvent;
   15.49 -import java.awt.event.ActionListener;
   15.50 -import org.netbeans.api.fileinfo.NonRecursiveFolder;
   15.51 -import org.netbeans.api.java.source.CompilationInfo;
   15.52 -import org.netbeans.api.java.source.TreePathHandle;
   15.53 -import org.netbeans.api.java.source.ui.ScanDialog;
   15.54 -import org.netbeans.modules.refactoring.java.ui.ContextAnalyzer;
   15.55 -import org.netbeans.modules.refactoring.java.ui.JavaRefactoringUIFactory;
   15.56 -import org.netbeans.modules.refactoring.spi.ui.RefactoringUI;
   15.57 -import org.openide.awt.ActionID;
   15.58 -import org.openide.awt.ActionReference;
   15.59 -import org.openide.awt.ActionRegistration;
   15.60 -import org.openide.filesystems.FileObject;
   15.61 -import org.openide.util.NbBundle.Messages;
   15.62 -import org.openide.util.Utilities;
   15.63 -
   15.64 -@ActionID(
   15.65 -        category = "Refactoring",
   15.66 -        id = "org.netbeans.modules.jackpot30.hintsimpl.duplicates.DuplicateMethodRefactoringAction")
   15.67 -@ActionRegistration(
   15.68 -        displayName = "#CTL_DuplicateMethodRefactoringAction")
   15.69 -@ActionReference(path = "Menu/Refactoring", position = 1120)
   15.70 -@Messages("CTL_DuplicateMethodRefactoringAction=Find and Replace Duplicates...")
   15.71 -public final class DuplicateMethodRefactoringAction implements ActionListener {
   15.72 -
   15.73 -    @Override
   15.74 -    public void actionPerformed(ActionEvent e) {
   15.75 -        Runnable task = ContextAnalyzer.createTask(Utilities.actionsGlobalContext()/*!!!*/, new JavaRefactoringUIFactory() {
   15.76 -            @Override public RefactoringUI create(CompilationInfo info, TreePathHandle[] handles, FileObject[] files, NonRecursiveFolder[] packages) {
   15.77 -                //todo: more precise verification of refactoring feasibility:
   15.78 -                return handles.length == 1 && handles[0].getKind() == Kind.METHOD ? new DuplicateMethodRefactoringUI(handles[0]) : null;
   15.79 -            }
   15.80 -        });
   15.81 -        ScanDialog.runWhenScanFinished(task, "Find&Replace Duplicates");
   15.82 -    }
   15.83 -
   15.84 -    public boolean isEnabled() {
   15.85 -        return ContextAnalyzer.canRefactorSingle(Utilities.actionsGlobalContext()/*!!!*/, true, true);
   15.86 -    }
   15.87 -}
    16.1 --- a/java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/duplicates/DuplicateMethodRefactoringPlugin.java	Sun Oct 16 08:01:27 2016 +0200
    16.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.3 @@ -1,183 +0,0 @@
    16.4 -/*
    16.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    16.6 - *
    16.7 - * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
    16.8 - *
    16.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   16.10 - * Other names may be trademarks of their respective owners.
   16.11 - *
   16.12 - * The contents of this file are subject to the terms of either the GNU
   16.13 - * General Public License Version 2 only ("GPL") or the Common
   16.14 - * Development and Distribution License("CDDL") (collectively, the
   16.15 - * "License"). You may not use this file except in compliance with the
   16.16 - * License. You can obtain a copy of the License at
   16.17 - * http://www.netbeans.org/cddl-gplv2.html
   16.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   16.19 - * specific language governing permissions and limitations under the
   16.20 - * License.  When distributing the software, include this License Header
   16.21 - * Notice in each file and include the License file at
   16.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   16.23 - * particular file as subject to the "Classpath" exception as provided
   16.24 - * by Oracle in the GPL Version 2 section of the License file that
   16.25 - * accompanied this code. If applicable, add the following below the
   16.26 - * License Header, with the fields enclosed by brackets [] replaced by
   16.27 - * your own identifying information:
   16.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   16.29 - *
   16.30 - * If you wish your version of this file to be governed by only the CDDL
   16.31 - * or only the GPL Version 2, indicate your decision by adding
   16.32 - * "[Contributor] elects to include this software in this distribution
   16.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   16.34 - * single choice of license, a recipient has the option to distribute
   16.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   16.36 - * to extend the choice of license to its licensees as provided above.
   16.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   16.38 - * Version 2 license, then the option applies only if the new code is
   16.39 - * made subject to such option by the copyright holder.
   16.40 - *
   16.41 - * Contributor(s):
   16.42 - *
   16.43 - * Portions Copyrighted 2013 Sun Microsystems, Inc.
   16.44 - */
   16.45 -package org.netbeans.modules.jackpot30.hintsimpl.duplicates;
   16.46 -
   16.47 -import com.sun.source.tree.BlockTree;
   16.48 -import com.sun.source.tree.ExpressionTree;
   16.49 -import com.sun.source.tree.MethodInvocationTree;
   16.50 -import com.sun.source.tree.MethodTree;
   16.51 -import com.sun.source.tree.StatementTree;
   16.52 -import com.sun.source.util.TreePath;
   16.53 -import java.net.URL;
   16.54 -import java.util.ArrayList;
   16.55 -import java.util.Collection;
   16.56 -import java.util.Collections;
   16.57 -import java.util.Enumeration;
   16.58 -import java.util.HashSet;
   16.59 -import java.util.List;
   16.60 -import java.util.Set;
   16.61 -import javax.lang.model.element.Element;
   16.62 -import javax.lang.model.element.ExecutableElement;
   16.63 -import javax.lang.model.element.VariableElement;
   16.64 -import org.netbeans.api.java.source.CancellableTask;
   16.65 -import org.netbeans.api.java.source.ClasspathInfo;
   16.66 -import org.netbeans.api.java.source.ClasspathInfo.PathKind;
   16.67 -import org.netbeans.api.java.source.JavaSource;
   16.68 -import org.netbeans.api.java.source.SourceUtils;
   16.69 -import org.netbeans.api.java.source.TreeMaker;
   16.70 -import org.netbeans.api.java.source.TreePathHandle;
   16.71 -import org.netbeans.api.java.source.WorkingCopy;
   16.72 -import org.netbeans.api.java.source.matching.Matcher;
   16.73 -import org.netbeans.api.java.source.matching.Occurrence;
   16.74 -import org.netbeans.api.java.source.matching.Pattern;
   16.75 -import org.netbeans.modules.refactoring.api.Problem;
   16.76 -import org.netbeans.modules.refactoring.java.spi.JavaRefactoringPlugin;
   16.77 -import org.netbeans.modules.refactoring.spi.RefactoringElementsBag;
   16.78 -import org.openide.filesystems.FileObject;
   16.79 -import org.openide.filesystems.FileUtil;
   16.80 -import org.openide.filesystems.URLMapper;
   16.81 -
   16.82 -/**
   16.83 - *
   16.84 - * @author lahvac
   16.85 - */
   16.86 -public class DuplicateMethodRefactoringPlugin extends JavaRefactoringPlugin {
   16.87 -    private final DuplicateMethodRefactoring refactoring;
   16.88 -
   16.89 -    DuplicateMethodRefactoringPlugin(DuplicateMethodRefactoring refactoring) {
   16.90 -        this.refactoring = refactoring;
   16.91 -    }
   16.92 -
   16.93 -    @Override
   16.94 -    public Problem preCheck() {
   16.95 -        return null;
   16.96 -    }
   16.97 -
   16.98 -    @Override
   16.99 -    public Problem checkParameters() {
  16.100 -        return null;
  16.101 -    }
  16.102 -
  16.103 -    @Override
  16.104 -    public Problem fastCheckParameters() {
  16.105 -        return null;
  16.106 -    }
  16.107 -
  16.108 -    @Override
  16.109 -    public void cancelRequest() {
  16.110 -    }
  16.111 -
  16.112 -    @Override
  16.113 -    public Problem prepare(RefactoringElementsBag refactoringElements) {
  16.114 -        final TreePathHandle source = refactoring.getRefactoringSource().lookup(TreePathHandle.class);
  16.115 -        Set<URL> dependent = new HashSet<>();
  16.116 -
  16.117 -        for (FileObject root : ClasspathInfo.create(source.getFileObject()).getClassPath(PathKind.SOURCE).getRoots()) {
  16.118 -            dependent.add(root.toURL());
  16.119 -            dependent.addAll(SourceUtils.getDependentRoots(root.toURL()));
  16.120 -        }
  16.121 -
  16.122 -        Set<FileObject> files = new HashSet<>();
  16.123 -
  16.124 -        for (URL root : dependent) {
  16.125 -            FileObject rootFO = URLMapper.findFileObject(root);
  16.126 -
  16.127 -            if (rootFO == null) continue;
  16.128 -
  16.129 -            for (Enumeration<? extends FileObject> en = rootFO.getChildren(true); en.hasMoreElements(); ){
  16.130 -                FileObject file = en.nextElement();
  16.131 -
  16.132 -                if (file.isData() && "text/x-java".equals(FileUtil.getMIMEType(file, "text/x-java"))) {
  16.133 -                    files.add(file);
  16.134 -                }
  16.135 -            }
  16.136 -        }
  16.137 -
  16.138 -        return createAndAddElements(files, new CancellableTask<WorkingCopy>() {
  16.139 -            @Override public void cancel() {
  16.140 -                //TODO - is used? if yes, implement.
  16.141 -            }
  16.142 -            @Override public void run(WorkingCopy parameter) throws Exception {
  16.143 -                if (parameter.toPhase(org.netbeans.api.java.source.JavaSource.Phase.RESOLVED).compareTo(org.netbeans.api.java.source.JavaSource.Phase.RESOLVED) < 0) {
  16.144 -                    return ;
  16.145 -                }
  16.146 -
  16.147 -                Element methodElement = source.getElementHandle().resolve(parameter);
  16.148 -                TreePath method = parameter.getTrees().getPath(methodElement);
  16.149 -
  16.150 -                if (method == null) {
  16.151 -                    //nothing to do
  16.152 -                    //TODO: create a problem
  16.153 -                    return ;
  16.154 -                }
  16.155 -
  16.156 -                BlockTree content = ((MethodTree) method.getLeaf()).getBody();
  16.157 -                TreePath bodyPath = new TreePath(method, content);
  16.158 -                List<TreePath> statements = new ArrayList<>();
  16.159 -
  16.160 -                for (StatementTree st : content.getStatements()) {
  16.161 -                    statements.add(new TreePath(bodyPath, st));
  16.162 -                }
  16.163 -
  16.164 -                List<? extends VariableElement> formalParameters = ((ExecutableElement) methodElement).getParameters();
  16.165 -                Pattern pattern = Pattern.createPatternWithRemappableVariables(statements, formalParameters, true);
  16.166 -                Collection<? extends Occurrence> found = Matcher.create(parameter).setCancel(cancelRequested).setSearchRoot(new TreePath(parameter.getCompilationUnit())).match(pattern);
  16.167 -                TreeMaker make = parameter.getTreeMaker();
  16.168 -
  16.169 -                for (Occurrence occ : found) {
  16.170 -                    List<ExpressionTree> newParams = new ArrayList<>();
  16.171 -                    for (VariableElement p : formalParameters) {
  16.172 -                        newParams.add((ExpressionTree) occ.getVariablesRemapToTrees().get(p).getLeaf());
  16.173 -                    }
  16.174 -                    MethodInvocationTree newCall = make.MethodInvocation(Collections.<ExpressionTree>emptyList(), make.QualIdent(methodElement), newParams);
  16.175 -                    parameter.rewrite(occ.getOccurrenceRoot().getLeaf(), make.ExpressionStatement(newCall));
  16.176 -                }
  16.177 -            }
  16.178 -        }, refactoringElements, refactoring);
  16.179 -    }
  16.180 -
  16.181 -    @Override
  16.182 -    protected JavaSource getJavaSource(Phase p) {
  16.183 -        return null;
  16.184 -    }
  16.185 -
  16.186 -}
    17.1 --- a/java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/duplicates/DuplicateMethodRefactoringUI.java	Sun Oct 16 08:01:27 2016 +0200
    17.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.3 @@ -1,108 +0,0 @@
    17.4 -/*
    17.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    17.6 - *
    17.7 - * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
    17.8 - *
    17.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   17.10 - * Other names may be trademarks of their respective owners.
   17.11 - *
   17.12 - * The contents of this file are subject to the terms of either the GNU
   17.13 - * General Public License Version 2 only ("GPL") or the Common
   17.14 - * Development and Distribution License("CDDL") (collectively, the
   17.15 - * "License"). You may not use this file except in compliance with the
   17.16 - * License. You can obtain a copy of the License at
   17.17 - * http://www.netbeans.org/cddl-gplv2.html
   17.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   17.19 - * specific language governing permissions and limitations under the
   17.20 - * License.  When distributing the software, include this License Header
   17.21 - * Notice in each file and include the License file at
   17.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   17.23 - * particular file as subject to the "Classpath" exception as provided
   17.24 - * by Oracle in the GPL Version 2 section of the License file that
   17.25 - * accompanied this code. If applicable, add the following below the
   17.26 - * License Header, with the fields enclosed by brackets [] replaced by
   17.27 - * your own identifying information:
   17.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   17.29 - *
   17.30 - * If you wish your version of this file to be governed by only the CDDL
   17.31 - * or only the GPL Version 2, indicate your decision by adding
   17.32 - * "[Contributor] elects to include this software in this distribution
   17.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   17.34 - * single choice of license, a recipient has the option to distribute
   17.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   17.36 - * to extend the choice of license to its licensees as provided above.
   17.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   17.38 - * Version 2 license, then the option applies only if the new code is
   17.39 - * made subject to such option by the copyright holder.
   17.40 - *
   17.41 - * Contributor(s):
   17.42 - *
   17.43 - * Portions Copyrighted 2013 Sun Microsystems, Inc.
   17.44 - */
   17.45 -package org.netbeans.modules.jackpot30.hintsimpl.duplicates;
   17.46 -
   17.47 -import javax.swing.event.ChangeListener;
   17.48 -import org.netbeans.api.java.source.TreePathHandle;
   17.49 -import org.netbeans.modules.refactoring.api.AbstractRefactoring;
   17.50 -import org.netbeans.modules.refactoring.api.Problem;
   17.51 -import org.netbeans.modules.refactoring.spi.ui.CustomRefactoringPanel;
   17.52 -import org.netbeans.modules.refactoring.spi.ui.RefactoringUI;
   17.53 -import org.openide.util.HelpCtx;
   17.54 -
   17.55 -/**
   17.56 - *
   17.57 - * @author lahvac
   17.58 - */
   17.59 -public class DuplicateMethodRefactoringUI implements RefactoringUI {
   17.60 -    private final TreePathHandle treePathHandle;
   17.61 -
   17.62 -    DuplicateMethodRefactoringUI(TreePathHandle treePathHandle) {
   17.63 -        this.treePathHandle = treePathHandle;
   17.64 -    }
   17.65 -
   17.66 -    @Override
   17.67 -    public String getName() {
   17.68 -        return "Duplicate Method Refactoring";
   17.69 -    }
   17.70 -
   17.71 -    @Override
   17.72 -    public String getDescription() {
   17.73 -        return "Duplicate Method Refactoring";
   17.74 -    }
   17.75 -
   17.76 -    @Override
   17.77 -    public boolean isQuery() {
   17.78 -        return false;
   17.79 -    }
   17.80 -
   17.81 -    @Override
   17.82 -    public CustomRefactoringPanel getPanel(ChangeListener parent) {
   17.83 -        return null;
   17.84 -    }
   17.85 -
   17.86 -    @Override
   17.87 -    public Problem setParameters() {
   17.88 -        return null;
   17.89 -    }
   17.90 -
   17.91 -    @Override
   17.92 -    public Problem checkParameters() {
   17.93 -        return null;
   17.94 -    }
   17.95 -
   17.96 -    @Override
   17.97 -    public boolean hasParameters() {
   17.98 -        return false;
   17.99 -    }
  17.100 -
  17.101 -    @Override
  17.102 -    public AbstractRefactoring getRefactoring() {
  17.103 -        return new DuplicateMethodRefactoring(treePathHandle);
  17.104 -    }
  17.105 -
  17.106 -    @Override
  17.107 -    public HelpCtx getHelpCtx() {
  17.108 -        return HelpCtx.DEFAULT_HELP;
  17.109 -    }
  17.110 -
  17.111 -}
    18.1 --- a/java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/duplicates/RefactoringPluginFactoryImpl.java	Sun Oct 16 08:01:27 2016 +0200
    18.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.3 @@ -1,62 +0,0 @@
    18.4 -/*
    18.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    18.6 - *
    18.7 - * Copyright 2008-2010 Sun Microsystems, Inc. All rights reserved.
    18.8 - *
    18.9 - * The contents of this file are subject to the terms of either the GNU
   18.10 - * General Public License Version 2 only ("GPL") or the Common
   18.11 - * Development and Distribution License("CDDL") (collectively, the
   18.12 - * "License"). You may not use this file except in compliance with the
   18.13 - * License. You can obtain a copy of the License at
   18.14 - * http://www.netbeans.org/cddl-gplv2.html
   18.15 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   18.16 - * specific language governing permissions and limitations under the
   18.17 - * License.  When distributing the software, include this License Header
   18.18 - * Notice in each file and include the License file at
   18.19 - * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
   18.20 - * particular file as subject to the "Classpath" exception as provided
   18.21 - * by Sun in the GPL Version 2 section of the License file that
   18.22 - * accompanied this code. If applicable, add the following below the
   18.23 - * License Header, with the fields enclosed by brackets [] replaced by
   18.24 - * your own identifying information:
   18.25 - * "Portions Copyrighted [year] [name of copyright owner]"
   18.26 - *
   18.27 - * If you wish your version of this file to be governed by only the CDDL
   18.28 - * or only the GPL Version 2, indicate your decision by adding
   18.29 - * "[Contributor] elects to include this software in this distribution
   18.30 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   18.31 - * single choice of license, a recipient has the option to distribute
   18.32 - * your version of this file under either the CDDL, the GPL Version 2 or
   18.33 - * to extend the choice of license to its licensees as provided above.
   18.34 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   18.35 - * Version 2 license, then the option applies only if the new code is
   18.36 - * made subject to such option by the copyright holder.
   18.37 - *
   18.38 - * Contributor(s):
   18.39 - *
   18.40 - * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
   18.41 - */
   18.42 -
   18.43 -package org.netbeans.modules.jackpot30.hintsimpl.duplicates;
   18.44 -
   18.45 -import org.netbeans.modules.refactoring.api.AbstractRefactoring;
   18.46 -import org.netbeans.modules.refactoring.spi.RefactoringPlugin;
   18.47 -import org.netbeans.modules.refactoring.spi.RefactoringPluginFactory;
   18.48 -import org.openide.util.lookup.ServiceProvider;
   18.49 -
   18.50 -/**
   18.51 - *
   18.52 - * @author Jan Lahoda
   18.53 - */
   18.54 -@ServiceProvider(service=RefactoringPluginFactory.class)
   18.55 -public class RefactoringPluginFactoryImpl implements RefactoringPluginFactory {
   18.56 -
   18.57 -    public RefactoringPlugin createInstance(AbstractRefactoring refactoring) {
   18.58 -        if (refactoring instanceof DuplicateMethodRefactoring) {
   18.59 -            return new DuplicateMethodRefactoringPlugin((DuplicateMethodRefactoring) refactoring);
   18.60 -        }
   18.61 -
   18.62 -        return null;
   18.63 -    }
   18.64 -
   18.65 -}
    19.1 --- a/java.hints/hintsimpl/test/unit/src/org/netbeans/modules/jackpot30/hintsimpl/GlobalyUnusedNGTest.java	Sun Oct 16 08:01:27 2016 +0200
    19.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.3 @@ -1,84 +0,0 @@
    19.4 -/*
    19.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    19.6 - *
    19.7 - * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
    19.8 - *
    19.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   19.10 - * Other names may be trademarks of their respective owners.
   19.11 - *
   19.12 - * The contents of this file are subject to the terms of either the GNU
   19.13 - * General Public License Version 2 only ("GPL") or the Common
   19.14 - * Development and Distribution License("CDDL") (collectively, the
   19.15 - * "License"). You may not use this file except in compliance with the
   19.16 - * License. You can obtain a copy of the License at
   19.17 - * http://www.netbeans.org/cddl-gplv2.html
   19.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   19.19 - * specific language governing permissions and limitations under the
   19.20 - * License.  When distributing the software, include this License Header
   19.21 - * Notice in each file and include the License file at
   19.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   19.23 - * particular file as subject to the "Classpath" exception as provided
   19.24 - * by Oracle in the GPL Version 2 section of the License file that
   19.25 - * accompanied this code. If applicable, add the following below the
   19.26 - * License Header, with the fields enclosed by brackets [] replaced by
   19.27 - * your own identifying information:
   19.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   19.29 - *
   19.30 - * If you wish your version of this file to be governed by only the CDDL
   19.31 - * or only the GPL Version 2, indicate your decision by adding
   19.32 - * "[Contributor] elects to include this software in this distribution
   19.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   19.34 - * single choice of license, a recipient has the option to distribute
   19.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   19.36 - * to extend the choice of license to its licensees as provided above.
   19.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   19.38 - * Version 2 license, then the option applies only if the new code is
   19.39 - * made subject to such option by the copyright holder.
   19.40 - *
   19.41 - * Contributor(s):
   19.42 - *
   19.43 - * Portions Copyrighted 2013 Sun Microsystems, Inc.
   19.44 - */
   19.45 -package org.netbeans.modules.jackpot30.hintsimpl;
   19.46 -
   19.47 -import org.junit.Test;
   19.48 -import org.netbeans.modules.java.hints.test.api.HintTest;
   19.49 -
   19.50 -/**
   19.51 - *
   19.52 - * @author lahvac
   19.53 - */
   19.54 -public class GlobalyUnusedNGTest {
   19.55 -
   19.56 -    @Test
   19.57 -    public void testUsed1() throws Exception {
   19.58 -        HintTest.create()
   19.59 -                .input("test/Test1.java",
   19.60 -                       "package test;\n" +
   19.61 -                       "public class Test1 {\n" +
   19.62 -                       "    private final Test2 test2 = null;\n" +
   19.63 -                       "}\n")
   19.64 -                .input("test/Test2.java",
   19.65 -                       "package test;\n" +
   19.66 -                       "public class Test2 {\n" +
   19.67 -                       "    private final Test1 test1 = null;\n" +
   19.68 -                       "}\n")
   19.69 -                .runGlobal(GlobalyUnused.class)
   19.70 -                .assertWarnings();
   19.71 -    }
   19.72 -    
   19.73 -    @Test
   19.74 -    public void testUnused() throws Exception {
   19.75 -        HintTest.create()
   19.76 -                .input("test/Test1.java",
   19.77 -                       "package test;\n" +
   19.78 -                       "public class Test1 { }\n")
   19.79 -                .input("test/Test2.java",
   19.80 -                       "package test;\n" +
   19.81 -                       "public class Test2 {\n" +
   19.82 -                       "}\n")
   19.83 -                .runGlobal(GlobalyUnused.class)
   19.84 -                .assertWarnings("1:13-1:18:verifier:Unused", "1:13-1:18:verifier:Unused");
   19.85 -    }
   19.86 -
   19.87 -}
    20.1 --- a/java.hints/hintsimpl/test/unit/src/org/netbeans/modules/jackpot30/hintsimpl/NonPrivateMakeFinalNGTest.java	Sun Oct 16 08:01:27 2016 +0200
    20.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.3 @@ -1,90 +0,0 @@
    20.4 -/*
    20.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    20.6 - *
    20.7 - * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
    20.8 - *
    20.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   20.10 - * Other names may be trademarks of their respective owners.
   20.11 - *
   20.12 - * The contents of this file are subject to the terms of either the GNU
   20.13 - * General Public License Version 2 only ("GPL") or the Common
   20.14 - * Development and Distribution License("CDDL") (collectively, the
   20.15 - * "License"). You may not use this file except in compliance with the
   20.16 - * License. You can obtain a copy of the License at
   20.17 - * http://www.netbeans.org/cddl-gplv2.html
   20.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   20.19 - * specific language governing permissions and limitations under the
   20.20 - * License.  When distributing the software, include this License Header
   20.21 - * Notice in each file and include the License file at
   20.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   20.23 - * particular file as subject to the "Classpath" exception as provided
   20.24 - * by Oracle in the GPL Version 2 section of the License file that
   20.25 - * accompanied this code. If applicable, add the following below the
   20.26 - * License Header, with the fields enclosed by brackets [] replaced by
   20.27 - * your own identifying information:
   20.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   20.29 - *
   20.30 - * If you wish your version of this file to be governed by only the CDDL
   20.31 - * or only the GPL Version 2, indicate your decision by adding
   20.32 - * "[Contributor] elects to include this software in this distribution
   20.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   20.34 - * single choice of license, a recipient has the option to distribute
   20.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   20.36 - * to extend the choice of license to its licensees as provided above.
   20.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   20.38 - * Version 2 license, then the option applies only if the new code is
   20.39 - * made subject to such option by the copyright holder.
   20.40 - *
   20.41 - * Contributor(s):
   20.42 - *
   20.43 - * Portions Copyrighted 2013 Sun Microsystems, Inc.
   20.44 - */
   20.45 -package org.netbeans.modules.jackpot30.hintsimpl;
   20.46 -
   20.47 -import org.junit.Test;
   20.48 -import org.netbeans.modules.java.hints.test.api.HintTest;
   20.49 -
   20.50 -/**
   20.51 - *
   20.52 - * @author lahvac
   20.53 - */
   20.54 -public class NonPrivateMakeFinalNGTest {
   20.55 -
   20.56 -    @Test
   20.57 -    public void testNotFinal() throws Exception {
   20.58 -        HintTest.create()
   20.59 -                .input("test/Test1.java",
   20.60 -                       "package test;\n" +
   20.61 -                       "public class Test1 {\n" +
   20.62 -                       "    public String str = \"\";\n" +
   20.63 -                       "}\n")
   20.64 -                .input("test/Test2.java",
   20.65 -                       "package test;\n" +
   20.66 -                       "public class Test2 {\n" +
   20.67 -                       "    {\n" +
   20.68 -                       "        new Test1().str = null;\n" +
   20.69 -                       "    }\n" +
   20.70 -                       "}\n")
   20.71 -                .runGlobal(NonPrivateMakeFinal.class)
   20.72 -                .assertWarnings();
   20.73 -    }
   20.74 -
   20.75 -    @Test
   20.76 -    public void testFinal() throws Exception {
   20.77 -        HintTest.create()
   20.78 -                .input("test/Test1.java",
   20.79 -                       "package test;\n" +
   20.80 -                       "public class Test1 {\n" +
   20.81 -                       "    public String str = \"\";\n" +
   20.82 -                       "}\n")
   20.83 -                .input("test/Test2.java",
   20.84 -                       "package test;\n" +
   20.85 -                       "public class Test2 {\n" +
   20.86 -                       "    {\n" +
   20.87 -                       "        System.err.println(new Test1().str);\n" +
   20.88 -                       "    }\n" +
   20.89 -                       "}\n")
   20.90 -                .runGlobal(NonPrivateMakeFinal.class)
   20.91 -                .assertWarnings("2:18-2:21:verifier:Can be final");
   20.92 -    }
   20.93 -}
    21.1 --- a/java.hints/hintsimpl/test/unit/src/org/netbeans/modules/jackpot30/hintsimpl/borrowed/RefactoringTestBase.java	Sun Oct 16 08:01:27 2016 +0200
    21.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.3 @@ -1,387 +0,0 @@
    21.4 -/*
    21.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    21.6 - *
    21.7 - * Copyright 2009-2010 Sun Microsystems, Inc. All rights reserved.
    21.8 - *
    21.9 - * The contents of this file are subject to the terms of either the GNU
   21.10 - * General Public License Version 2 only ("GPL") or the Common
   21.11 - * Development and Distribution License("CDDL") (collectively, the
   21.12 - * "License"). You may not use this file except in compliance with the
   21.13 - * License. You can obtain a copy of the License at
   21.14 - * http://www.netbeans.org/cddl-gplv2.html
   21.15 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   21.16 - * specific language governing permissions and limitations under the
   21.17 - * License.  When distributing the software, include this License Header
   21.18 - * Notice in each file and include the License file at
   21.19 - * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
   21.20 - * particular file as subject to the "Classpath" exception as provided
   21.21 - * by Sun in the GPL Version 2 section of the License file that
   21.22 - * accompanied this code. If applicable, add the following below the
   21.23 - * License Header, with the fields enclosed by brackets [] replaced by
   21.24 - * your own identifying information:
   21.25 - * "Portions Copyrighted [year] [name of copyright owner]"
   21.26 - *
   21.27 - * If you wish your version of this file to be governed by only the CDDL
   21.28 - * or only the GPL Version 2, indicate your decision by adding
   21.29 - * "[Contributor] elects to include this software in this distribution
   21.30 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   21.31 - * single choice of license, a recipient has the option to distribute
   21.32 - * your version of this file under either the CDDL, the GPL Version 2 or
   21.33 - * to extend the choice of license to its licensees as provided above.
   21.34 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   21.35 - * Version 2 license, then the option applies only if the new code is
   21.36 - * made subject to such option by the copyright holder.
   21.37 - *
   21.38 - * Contributor(s):
   21.39 - *
   21.40 - * Portions Copyrighted 2009-2010 Sun Microsystems, Inc.
   21.41 - */
   21.42 -package org.netbeans.modules.jackpot30.hintsimpl.borrowed;
   21.43 -
   21.44 -import java.io.EOFException;
   21.45 -import java.io.FileInputStream;
   21.46 -import java.io.IOException;
   21.47 -import java.nio.charset.Charset;
   21.48 -import java.util.Arrays;
   21.49 -import java.util.Collections;
   21.50 -import java.util.HashMap;
   21.51 -import java.util.HashSet;
   21.52 -import java.util.Iterator;
   21.53 -import java.util.LinkedList;
   21.54 -import java.util.List;
   21.55 -import java.util.Map;
   21.56 -import java.util.logging.Level;
   21.57 -import java.util.logging.Logger;
   21.58 -import javax.swing.event.ChangeListener;
   21.59 -import org.netbeans.api.editor.mimelookup.MimePath;
   21.60 -import org.netbeans.api.java.classpath.ClassPath;
   21.61 -import org.netbeans.api.java.classpath.GlobalPathRegistry;
   21.62 -import org.netbeans.api.java.source.SourceUtilsTestUtil;
   21.63 -import org.netbeans.api.java.source.TestUtilities;
   21.64 -import org.netbeans.api.java.source.TreeUtilities;
   21.65 -import org.netbeans.api.project.Project;
   21.66 -import org.netbeans.api.project.ProjectManager;
   21.67 -import org.netbeans.api.project.SourceGroup;
   21.68 -import org.netbeans.api.project.Sources;
   21.69 -import org.netbeans.core.startup.Main;
   21.70 -import org.netbeans.junit.NbTestCase;
   21.71 -import org.netbeans.modules.java.source.indexing.JavaCustomIndexer;
   21.72 -import org.netbeans.modules.parsing.api.indexing.IndexingManager;
   21.73 -import org.netbeans.modules.parsing.impl.indexing.CacheFolder;
   21.74 -import org.netbeans.modules.parsing.impl.indexing.MimeTypes;
   21.75 -import org.netbeans.modules.parsing.impl.indexing.RepositoryUpdater;
   21.76 -import org.netbeans.modules.refactoring.api.Problem;
   21.77 -import org.netbeans.spi.editor.mimelookup.MimeDataProvider;
   21.78 -import org.netbeans.spi.gototest.TestLocator;
   21.79 -import org.netbeans.spi.gototest.TestLocator.FileType;
   21.80 -import org.netbeans.spi.gototest.TestLocator.LocationListener;
   21.81 -import org.netbeans.spi.gototest.TestLocator.LocationResult;
   21.82 -import org.netbeans.spi.java.classpath.ClassPathProvider;
   21.83 -import org.netbeans.spi.java.classpath.support.ClassPathSupport;
   21.84 -import org.netbeans.spi.project.ProjectFactory;
   21.85 -import org.netbeans.spi.project.ProjectState;
   21.86 -import org.netbeans.spi.project.support.GenericSources;
   21.87 -import org.openide.filesystems.FileObject;
   21.88 -import org.openide.filesystems.FileUtil;
   21.89 -import org.openide.util.Lookup;
   21.90 -import org.openide.util.NbBundle;
   21.91 -import org.openide.util.lookup.Lookups;
   21.92 -import org.openide.util.lookup.ServiceProvider;
   21.93 -
   21.94 -public class RefactoringTestBase extends NbTestCase {
   21.95 -    // Turning off annoying info messages from treeutilities
   21.96 -    private static final Logger TREEUTILITIESLOGGER = Logger.getLogger(TreeUtilities.class.getName());
   21.97 -
   21.98 -    public RefactoringTestBase(String name) {
   21.99 -        super(name);
  21.100 -    }
  21.101 -
  21.102 -    protected static void writeFilesAndWaitForScan(FileObject sourceRoot, File... files) throws Exception {
  21.103 -        for (FileObject c : sourceRoot.getChildren()) {
  21.104 -            c.delete();
  21.105 -        }
  21.106 -
  21.107 -        for (File f : files) {
  21.108 -            FileObject fo = FileUtil.createData(sourceRoot, f.filename);
  21.109 -            TestUtilities.copyStringToFile(fo, f.content);
  21.110 -        }
  21.111 -
  21.112 -        IndexingManager.getDefault().refreshIndexAndWait(sourceRoot.toURL(), null, true);
  21.113 -    }
  21.114 -
  21.115 -    protected void verifyContent(FileObject sourceRoot, File... files) throws Exception {
  21.116 -        List<FileObject> todo = new LinkedList<FileObject>();
  21.117 -
  21.118 -        todo.add(sourceRoot);
  21.119 -
  21.120 -        Map<String, String> content = new HashMap<String, String>();
  21.121 -
  21.122 -        FileUtil.refreshFor(FileUtil.toFile(sourceRoot));
  21.123 -
  21.124 -        while (!todo.isEmpty()) {
  21.125 -            FileObject file = todo.remove(0);
  21.126 -
  21.127 -            if (file.isData()) {
  21.128 -                content.put(FileUtil.getRelativePath(sourceRoot, file), copyFileToString(FileUtil.toFile(file)));
  21.129 -            } else {
  21.130 -                todo.addAll(Arrays.asList(file.getChildren()));
  21.131 -            }
  21.132 -        }
  21.133 -
  21.134 -        for (File f : files) {
  21.135 -            String fileContent = content.remove(f.filename);
  21.136 -
  21.137 -            assertNotNull(f);
  21.138 -            assertNotNull(f.content);
  21.139 -            assertNotNull("Cannot find " + f.filename + " in map " + content, fileContent);
  21.140 -            assertEquals(getName() ,f.content.replaceAll("[ \t\r\n\n]+", " "), fileContent.replaceAll("[ \t\r\n\n]+", " "));
  21.141 -        }
  21.142 -
  21.143 -        assertTrue(content.toString(), content.isEmpty());
  21.144 -    }
  21.145 -    
  21.146 -    /**
  21.147 -     * Returns a string which contains the contents of a file.
  21.148 -     *
  21.149 -     * @param f the file to be read
  21.150 -     * @return the contents of the file(s).
  21.151 -     */
  21.152 -    private static String copyFileToString(java.io.File f) throws java.io.IOException {
  21.153 -        int s = (int) f.length();
  21.154 -        byte[] data = new byte[s];
  21.155 -        int len = new FileInputStream(f).read(data);
  21.156 -        if (len != s) {
  21.157 -            throw new EOFException("truncated file");
  21.158 -        }
  21.159 -        return new String(data, Charset.forName("UTF8"));
  21.160 -    }
  21.161 -
  21.162 -    protected static void addAllProblems(List<Problem> problems, Problem head) {
  21.163 -        while (head != null) {
  21.164 -            problems.add(head);
  21.165 -            head = head.getNext();
  21.166 -        }
  21.167 -    }
  21.168 -
  21.169 -    protected static void assertProblems(Iterable<? extends Problem> golden, Iterable<? extends Problem> real) {
  21.170 -        Iterator<? extends Problem> g = golden.iterator();
  21.171 -        Iterator<? extends Problem> r = real.iterator();
  21.172 -
  21.173 -        while (g.hasNext() && r.hasNext()) {
  21.174 -            Problem gp = g.next();
  21.175 -            Problem rp = r.next();
  21.176 -
  21.177 -            assertEquals(gp.isFatal(), rp.isFatal());
  21.178 -            assertEquals(gp.getMessage(), rp.getMessage());
  21.179 -        }
  21.180 -        boolean goldenHasNext = g.hasNext();
  21.181 -        boolean realHasNext = r.hasNext();
  21.182 -
  21.183 -        assertFalse(goldenHasNext?"Expected: " + g.next().getMessage():"", goldenHasNext);
  21.184 -        assertFalse(realHasNext?"Unexpected: " + r.next().getMessage():"", realHasNext);
  21.185 -    }
  21.186 -
  21.187 -    static {
  21.188 -        NbBundle.setBranding("test");
  21.189 -    }
  21.190 -
  21.191 -    protected static final class File {
  21.192 -        public final String filename;
  21.193 -        public final String content;
  21.194 -
  21.195 -        public File(String filename, String content) {
  21.196 -            this.filename = filename;
  21.197 -            this.content = content;
  21.198 -        }
  21.199 -    }
  21.200 -
  21.201 -    protected FileObject src;
  21.202 -    protected FileObject test;
  21.203 -    protected Project prj;
  21.204 -    private ClassPath sourcePath;
  21.205 -
  21.206 -    @Override
  21.207 -    protected void setUp() throws Exception {
  21.208 -        System.setProperty("org.netbeans.modules.java.source.usages.SourceAnalyser.fullIndex", "true");
  21.209 -        TREEUTILITIESLOGGER.setLevel(Level.SEVERE);
  21.210 -        MimeTypes.setAllMimeTypes(new HashSet<String>());
  21.211 -        SourceUtilsTestUtil.prepareTest(new String[] {"org/netbeans/modules/openide/loaders/layer.xml",
  21.212 -                    "org/netbeans/modules/java/source/resources/layer.xml",
  21.213 -                    "org/netbeans/modules/java/editor/resources/layer.xml",
  21.214 -            /*"org/netbeans/modules/refactoring/java/test/resources/layer.xml", */"META-INF/generated-layer.xml"}, new Object[] {
  21.215 -                    new ClassPathProvider() {
  21.216 -                        @Override
  21.217 -                        public ClassPath findClassPath(FileObject file, String type) {
  21.218 -                    if (sourcePath != null && sourcePath.contains(file)){
  21.219 -                                if (ClassPath.BOOT.equals(type)) {
  21.220 -                                    return ClassPathSupport.createClassPath(System.getProperty("sun.boot.class.path"));
  21.221 -                                }
  21.222 -                                if (ClassPath.COMPILE.equals(type)) {
  21.223 -                                    return ClassPathSupport.createClassPath(new FileObject[0]);
  21.224 -                                }
  21.225 -                                if (ClassPath.SOURCE.equals(type)) {
  21.226 -                                    return sourcePath;
  21.227 -                                }
  21.228 -                            }
  21.229 -
  21.230 -                            return null;
  21.231 -                        }
  21.232 -                    },
  21.233 -                    new ProjectFactory() {
  21.234 -                        @Override
  21.235 -                        public boolean isProject(FileObject projectDirectory) {
  21.236 -                            return src != null && src.getParent() == projectDirectory;
  21.237 -                        }
  21.238 -                        @Override
  21.239 -                        public Project loadProject(final FileObject projectDirectory, ProjectState state) throws IOException {
  21.240 -                if (!isProject(projectDirectory)) {
  21.241 -                    return null;
  21.242 -                }
  21.243 -                            return new Project() {
  21.244 -                                @Override
  21.245 -                                public FileObject getProjectDirectory() {
  21.246 -                                    return projectDirectory;
  21.247 -                                }
  21.248 -                                @Override
  21.249 -                                public Lookup getLookup() {
  21.250 -                                    final Project p = this;
  21.251 -                                    return Lookups.singleton(new Sources() {
  21.252 -
  21.253 -                                        @Override
  21.254 -                                        public SourceGroup[] getSourceGroups(String type) {
  21.255 -                                return new SourceGroup[] {GenericSources.group(p, src.getParent(), "source", "Java Sources", null, null),
  21.256 -                                                        GenericSources.group(p, test, "testsources", "Test Sources", null, null)};
  21.257 -                                        }
  21.258 -
  21.259 -                                        @Override
  21.260 -                                        public void addChangeListener(ChangeListener listener) {
  21.261 -                                        }
  21.262 -
  21.263 -                                        @Override
  21.264 -                                        public void removeChangeListener(ChangeListener listener) {
  21.265 -                                        }
  21.266 -                                    });
  21.267 -                                }
  21.268 -                            };
  21.269 -                        }
  21.270 -                        @Override
  21.271 -            public void saveProject(Project project) throws IOException, ClassCastException {}
  21.272 -                    },
  21.273 -                    new TestLocator() {
  21.274 -
  21.275 -                        @Override
  21.276 -                        public boolean appliesTo(FileObject fo) {
  21.277 -                            return true;
  21.278 -                        }
  21.279 -
  21.280 -                        @Override
  21.281 -                        public boolean asynchronous() {
  21.282 -                            return false;
  21.283 -                        }
  21.284 -
  21.285 -                        @Override
  21.286 -                        public LocationResult findOpposite(FileObject fo, int caretOffset) {
  21.287 -                            ClassPath srcCp;
  21.288 -
  21.289 -                            if ((srcCp = ClassPath.getClassPath(fo, ClassPath.SOURCE)) == null) {
  21.290 -                                return new LocationResult("File not found"); //NOI18N
  21.291 -                            }
  21.292 -
  21.293 -                            String baseResName = srcCp.getResourceName(fo, '/', false);
  21.294 -                            String testResName = getTestResName(baseResName, fo.getExt());
  21.295 -                            assert testResName != null;
  21.296 -                            FileObject fileObject = test.getFileObject(testResName);
  21.297 -                if(fileObject != null) {
  21.298 -                                return new LocationResult(fileObject, -1);
  21.299 -                            }
  21.300 -
  21.301 -                            return new LocationResult("File not found"); //NOI18N
  21.302 -                        }
  21.303 -
  21.304 -                        @Override
  21.305 -                        public void findOpposite(FileObject fo, int caretOffset, LocationListener callback) {
  21.306 -                            throw new UnsupportedOperationException("This should not be called on synchronous locators.");
  21.307 -                        }
  21.308 -
  21.309 -                        @Override
  21.310 -                        public FileType getFileType(FileObject fo) {
  21.311 -                if(FileUtil.isParentOf(test, fo)) {
  21.312 -                                return FileType.TEST;
  21.313 -                } else if(FileUtil.isParentOf(src, fo)) {
  21.314 -                                return FileType.TESTED;
  21.315 -                            }
  21.316 -                            return FileType.NEITHER;
  21.317 -                        }
  21.318 -
  21.319 -                        private String getTestResName(String baseResName, String ext) {
  21.320 -                StringBuilder buf
  21.321 -                        = new StringBuilder(baseResName.length() + ext.length() + 10);
  21.322 -                            buf.append(baseResName).append("Test");                         //NOI18N
  21.323 -                            if (ext.length() != 0) {
  21.324 -                                buf.append('.').append(ext);
  21.325 -                            }
  21.326 -                            return buf.toString();
  21.327 -                        }
  21.328 -                    }});
  21.329 -        Main.initializeURLFactory();
  21.330 -        org.netbeans.api.project.ui.OpenProjects.getDefault().getOpenProjects();
  21.331 -        prepareTest();
  21.332 -        org.netbeans.api.project.ui.OpenProjects.getDefault().open(new Project[] {prj = ProjectManager.getDefault().findProject(src.getParent())}, false);
  21.333 -        MimeTypes.setAllMimeTypes(Collections.singleton("text/x-java"));
  21.334 -        sourcePath = ClassPathSupport.createClassPath(src, test);
  21.335 -        GlobalPathRegistry.getDefault().register(ClassPath.SOURCE, new ClassPath[] {sourcePath});
  21.336 -        RepositoryUpdater.getDefault().start(true);
  21.337 -        super.setUp();
  21.338 -        FileUtil.createData(FileUtil.getConfigRoot(), "Templates/Classes/Empty.java");
  21.339 -        System.setProperty("org.netbeans.modules.parsing.impl.Source.excludedTasks", ".*");
  21.340 -    }
  21.341 -
  21.342 -    @Override
  21.343 -    protected void tearDown() throws Exception {
  21.344 -        super.tearDown();
  21.345 -        GlobalPathRegistry.getDefault().unregister(ClassPath.SOURCE, new ClassPath[] {sourcePath});
  21.346 -        org.netbeans.api.project.ui.OpenProjects.getDefault().close(new Project[] {prj});
  21.347 -        prj = null;
  21.348 -    }
  21.349 -
  21.350 -    private void prepareTest() throws Exception {
  21.351 -        FileObject workdir = SourceUtilsTestUtil.makeScratchDir(this);
  21.352 -
  21.353 -        FileObject projectFolder = FileUtil.createFolder(workdir, "testProject");
  21.354 -        src = FileUtil.createFolder(projectFolder, "src");
  21.355 -        test = FileUtil.createFolder(projectFolder, "test");
  21.356 -
  21.357 -        FileObject cache = FileUtil.createFolder(workdir, "cache");
  21.358 -
  21.359 -        CacheFolder.setCacheFolder(cache);
  21.360 -    }
  21.361 -
  21.362 -    @ServiceProvider(service=MimeDataProvider.class)
  21.363 -    public static final class MimeDataProviderImpl implements MimeDataProvider {
  21.364 -
  21.365 -        private static final Lookup L = Lookups.singleton(new JavaCustomIndexer.Factory());
  21.366 -
  21.367 -        @Override
  21.368 -        public Lookup getLookup(MimePath mimePath) {
  21.369 -            if ("text/x-java".equals(mimePath.getPath())) {
  21.370 -                return L;
  21.371 -            }
  21.372 -
  21.373 -            return null;
  21.374 -        }
  21.375 -        
  21.376 -    }
  21.377 -
  21.378 -    protected static boolean problemIsFatal(List<Problem> problems) {
  21.379 -        for (Problem problem : problems) {
  21.380 -            Problem next = problem;
  21.381 -            do {
  21.382 -                if (next.isFatal()) {
  21.383 -                    return true;
  21.384 -                }
  21.385 -                next = next.getNext();
  21.386 -            } while (next != null);
  21.387 -        }
  21.388 -        return false;
  21.389 -    }
  21.390 -}
  21.391 \ No newline at end of file
    22.1 --- a/java.hints/hintsimpl/test/unit/src/org/netbeans/modules/jackpot30/hintsimpl/duplicates/DuplicateMethodRefactoringPluginTest.java	Sun Oct 16 08:01:27 2016 +0200
    22.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.3 @@ -1,165 +0,0 @@
    22.4 -/*
    22.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    22.6 - *
    22.7 - * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
    22.8 - *
    22.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   22.10 - * Other names may be trademarks of their respective owners.
   22.11 - *
   22.12 - * The contents of this file are subject to the terms of either the GNU
   22.13 - * General Public License Version 2 only ("GPL") or the Common
   22.14 - * Development and Distribution License("CDDL") (collectively, the
   22.15 - * "License"). You may not use this file except in compliance with the
   22.16 - * License. You can obtain a copy of the License at
   22.17 - * http://www.netbeans.org/cddl-gplv2.html
   22.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   22.19 - * specific language governing permissions and limitations under the
   22.20 - * License.  When distributing the software, include this License Header
   22.21 - * Notice in each file and include the License file at
   22.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   22.23 - * particular file as subject to the "Classpath" exception as provided
   22.24 - * by Oracle in the GPL Version 2 section of the License file that
   22.25 - * accompanied this code. If applicable, add the following below the
   22.26 - * License Header, with the fields enclosed by brackets [] replaced by
   22.27 - * your own identifying information:
   22.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   22.29 - *
   22.30 - * If you wish your version of this file to be governed by only the CDDL
   22.31 - * or only the GPL Version 2, indicate your decision by adding
   22.32 - * "[Contributor] elects to include this software in this distribution
   22.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   22.34 - * single choice of license, a recipient has the option to distribute
   22.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   22.36 - * to extend the choice of license to its licensees as provided above.
   22.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   22.38 - * Version 2 license, then the option applies only if the new code is
   22.39 - * made subject to such option by the copyright holder.
   22.40 - *
   22.41 - * Contributor(s):
   22.42 - *
   22.43 - * Portions Copyrighted 2013 Sun Microsystems, Inc.
   22.44 - */
   22.45 -package org.netbeans.modules.jackpot30.hintsimpl.duplicates;
   22.46 -
   22.47 -import java.util.Arrays;
   22.48 -import java.util.LinkedList;
   22.49 -import java.util.List;
   22.50 -import javax.lang.model.element.ExecutableElement;
   22.51 -import javax.lang.model.util.ElementFilter;
   22.52 -import org.netbeans.api.java.source.CompilationController;
   22.53 -import org.netbeans.api.java.source.JavaSource;
   22.54 -import org.netbeans.api.java.source.Task;
   22.55 -import org.netbeans.api.java.source.TreePathHandle;
   22.56 -import org.netbeans.modules.jackpot30.hintsimpl.borrowed.RefactoringTestBase;
   22.57 -import org.netbeans.modules.refactoring.api.Problem;
   22.58 -import org.netbeans.modules.refactoring.api.RefactoringSession;
   22.59 -
   22.60 -/**
   22.61 - *
   22.62 - * @author lahvac
   22.63 - */
   22.64 -public class DuplicateMethodRefactoringPluginTest extends RefactoringTestBase {
   22.65 -
   22.66 -    public DuplicateMethodRefactoringPluginTest(String name) {
   22.67 -        super(name);
   22.68 -    }
   22.69 -
   22.70 -    public void testSimple() throws Exception {
   22.71 -        writeFilesAndWaitForScan(src,
   22.72 -                                 new File("test/Test.java",
   22.73 -                                          "package test;\n" +
   22.74 -                                          "public class Test {\n" +
   22.75 -                                          "    public static void toCall() {\n" +
   22.76 -                                          "        System.err.println(1);\n" +
   22.77 -                                          "    }\n" +
   22.78 -                                          "    public static void test1() {\n" +
   22.79 -                                          "        System.err.println(1);\n" +
   22.80 -                                          "    }\n" +
   22.81 -                                          "    public static void test2() {\n" +
   22.82 -                                          "        System.out.println(1);\n" +
   22.83 -                                          "    }\n" +
   22.84 -                                          "    public static void test3() {\n" +
   22.85 -                                          "        System.err.println(2);\n" +
   22.86 -                                          "    }\n" +
   22.87 -                                          "}\n"));
   22.88 -        performDuplicateMethod("toCall");
   22.89 -        verifyContent(src,
   22.90 -                      new File("test/Test.java",
   22.91 -                               "package test;\n" +
   22.92 -                               "public class Test {\n" +
   22.93 -                               "    public static void toCall() {\n" +
   22.94 -                               "        System.err.println(1);\n" +
   22.95 -                               "    }\n" +
   22.96 -                               "    public static void test1() {\n" +
   22.97 -                               "        toCall();\n" +
   22.98 -                               "    }\n" +
   22.99 -                               "    public static void test2() {\n" +
  22.100 -                               "        System.out.println(1);\n" +
  22.101 -                               "    }\n" +
  22.102 -                               "    public static void test3() {\n" +
  22.103 -                               "        System.err.println(2);\n" +
  22.104 -                               "    }\n" +
  22.105 -                               "}\n"));
  22.106 -    }
  22.107 -
  22.108 -    public void testParams() throws Exception {
  22.109 -        writeFilesAndWaitForScan(src,
  22.110 -                                 new File("test/Test.java",
  22.111 -                                          "package test;\n" +
  22.112 -                                          "public class Test {\n" +
  22.113 -                                          "    public static void toCall(int i) {\n" +
  22.114 -                                          "        System.err.println(i);\n" +
  22.115 -                                          "    }\n" +
  22.116 -                                          "    public static void test1(int j) {\n" +
  22.117 -                                          "        System.err.println(1 + j);\n" +
  22.118 -                                          "    }\n" +
  22.119 -                                          "    public static void test3() {\n" +
  22.120 -                                          "        System.err.println(2);\n" +
  22.121 -                                          "    }\n" +
  22.122 -                                          "}\n"));
  22.123 -        performDuplicateMethod("toCall");
  22.124 -        verifyContent(src,
  22.125 -                      new File("test/Test.java",
  22.126 -                               "package test;\n" +
  22.127 -                               "public class Test {\n" +
  22.128 -                               "    public static void toCall(int i) {\n" +
  22.129 -                               "        System.err.println(i);\n" +
  22.130 -                               "    }\n" +
  22.131 -                               "    public static void test1(int j) {\n" +
  22.132 -                               "        toCall(1 + j);\n" +
  22.133 -                               "    }\n" +
  22.134 -                               "    public static void test3() {\n" +
  22.135 -                               "        toCall(2);\n" +
  22.136 -                               "    }\n" +
  22.137 -                               "}\n"));
  22.138 -    }
  22.139 -
  22.140 -    private void performDuplicateMethod(final String methodName, Problem... expectedProblems) throws Exception {
  22.141 -        final DuplicateMethodRefactoring[] r = new DuplicateMethodRefactoring[1];
  22.142 -
  22.143 -        JavaSource.forFileObject(src.getFileObject("test/Test.java")).runUserActionTask(new Task<CompilationController>() {
  22.144 -            @Override public void run(CompilationController javac) throws Exception {
  22.145 -                javac.toPhase(JavaSource.Phase.RESOLVED);
  22.146 -
  22.147 -                for (ExecutableElement method : ElementFilter.methodsIn(javac.getTopLevelElements().get(0).getEnclosedElements())) {
  22.148 -                    if (method.getSimpleName().contentEquals(methodName)) {
  22.149 -                        r[0] = new DuplicateMethodRefactoring(TreePathHandle.create(javac.getTrees().getPath(method), javac));
  22.150 -                    }
  22.151 -                }
  22.152 -            }
  22.153 -        }, true);
  22.154 -
  22.155 -        RefactoringSession rs = RefactoringSession.create("Session");
  22.156 -        List<Problem> problems = new LinkedList<Problem>();
  22.157 -
  22.158 -        addAllProblems(problems, r[0].preCheck());
  22.159 -        if (!problemIsFatal(problems)) {
  22.160 -            addAllProblems(problems, r[0].prepare(rs));
  22.161 -        }
  22.162 -        if (!problemIsFatal(problems)) {
  22.163 -            addAllProblems(problems, rs.doRefactoring(true));
  22.164 -        }
  22.165 -
  22.166 -        assertProblems(Arrays.asList(expectedProblems), problems);
  22.167 -    }
  22.168 -}
    23.1 --- a/java.hints/java.hints.test/apichanges.xml	Sun Oct 16 08:01:27 2016 +0200
    23.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.3 @@ -1,181 +0,0 @@
    23.4 -<?xml version="1.0" encoding="UTF-8"?>
    23.5 -<!-- Search for CHANGEME in this document when copying and using it: -->
    23.6 -<!--
    23.7 -DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    23.8 -
    23.9 -Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
   23.10 -
   23.11 -Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   23.12 -Other names may be trademarks of their respective owners.
   23.13 -
   23.14 -The contents of this file are subject to the terms of either the GNU
   23.15 -General Public License Version 2 only ("GPL") or the Common
   23.16 -Development and Distribution License("CDDL") (collectively, the
   23.17 -"License"). You may not use this file except in compliance with the
   23.18 -License. You can obtain a copy of the License at
   23.19 -http://www.netbeans.org/cddl-gplv2.html
   23.20 -or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   23.21 -specific language governing permissions and limitations under the
   23.22 -License.  When distributing the software, include this License Header
   23.23 -Notice in each file and include the License file at
   23.24 -nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   23.25 -particular file as subject to the "Classpath" exception as provided
   23.26 -by Oracle in the GPL Version 2 section of the License file that
   23.27 -accompanied this code. If applicable, add the following below the
   23.28 -License Header, with the fields enclosed by brackets [] replaced by
   23.29 -your own identifying information:
   23.30 -"Portions Copyrighted [year] [name of copyright owner]"
   23.31 -
   23.32 -Contributor(s):
   23.33 -
   23.34 -The Original Software is NetBeans. The Initial Developer of the Original
   23.35 -Software is Sun Microsystems, Inc. Portions Copyright 1997-2010 Sun
   23.36 -Microsystems, Inc. All Rights Reserved.
   23.37 -
   23.38 -If you wish your version of this file to be governed by only the CDDL
   23.39 -or only the GPL Version 2, indicate your decision by adding
   23.40 -"[Contributor] elects to include this software in this distribution
   23.41 -under the [CDDL or GPL Version 2] license." If you do not indicate a
   23.42 -single choice of license, a recipient has the option to distribute
   23.43 -your version of this file under either the CDDL, the GPL Version 2 or
   23.44 -to extend the choice of license to its licensees as provided above.
   23.45 -However, if you add GPL Version 2 code and therefore, elected the GPL
   23.46 -Version 2 license, then the option applies only if the new code is
   23.47 -made subject to such option by the copyright holder.
   23.48 --->
   23.49 -<?xml-stylesheet type="text/xml" href="../nbbuild/javadoctools/apichanges.xsl"?>
   23.50 -<!DOCTYPE apichanges PUBLIC "-//NetBeans//DTD API changes list 1.0//EN" "../nbbuild/javadoctools/apichanges.dtd">
   23.51 -
   23.52 -<!--
   23.53 -
   23.54 -INFO FOR PEOPLE ADDING CHANGES:
   23.55 -
   23.56 -Check the DTD (apichanges.dtd) for details on the syntax. You do not
   23.57 -need to regenerate the HTML, as this is part of Javadoc generation; just
   23.58 -change the XML. Rough syntax of a change (several parts optional):
   23.59 -
   23.60 -<change>
   23.61 -    <api name="compiler"/>
   23.62 -    <summary>Some brief description here, can use <b>XHTML</b></summary>
   23.63 -    <version major="1" minor="99"/>
   23.64 -    <date day="13" month="6" year="2001"/>
   23.65 -    <author login="jrhacker"/>
   23.66 -    <compatibility addition="yes"/>
   23.67 -    <description>
   23.68 -        The main description of the change here.
   23.69 -        Again can use full <b>XHTML</b> as needed.
   23.70 -    </description>
   23.71 -    <class package="org.openide.compiler" name="DoWhatIWantCompiler"/>
   23.72 -    <issue number="14309"/>
   23.73 -</change>
   23.74 -
   23.75 -Also permitted elements: <package>, <branch>. <version> is API spec
   23.76 -version, recommended for all new changes. <compatibility> should say
   23.77 -if things were added/modified/deprecated/etc. and give all information
   23.78 -related to upgrading old code. List affected top-level classes and
   23.79 -link to issue numbers if applicable. See the DTD for more details.
   23.80 -
   23.81 -Changes need not be in any particular order, they are sorted in various
   23.82 -ways by the stylesheet anyway.
   23.83 -
   23.84 -Dates are assumed to mean "on the trunk". If you *also* make the same
   23.85 -change on a stabilization branch, use the <branch> tag to indicate this
   23.86 -and explain why the change was made on a branch in the <description>.
   23.87 -
   23.88 -Please only change this file on the trunk! Rather: you can change it
   23.89 -on branches if you want, but these changes will be ignored; only the
   23.90 -trunk version of this file is important.
   23.91 -
   23.92 -Deprecations do not count as incompatible, assuming that code using the
   23.93 -deprecated calls continues to see their documented behavior. But do
   23.94 -specify deprecation="yes" in <compatibility>.
   23.95 -
   23.96 -This file is not a replacement for Javadoc: it is intended to list changes,
   23.97 -not describe the complete current behavior, for which ordinary documentation
   23.98 -is the proper place.
   23.99 -
  23.100 --->
  23.101 -
  23.102 -<apichanges>
  23.103 -
  23.104 -    <!-- First, a list of API names you may use: -->
  23.105 -    <apidefs>
  23.106 -        <apidef name="JavaHintsTest">Java Hints Test API</apidef>
  23.107 -    </apidefs>
  23.108 -
  23.109 -    <!-- ACTUAL CHANGES BEGIN HERE: -->
  23.110 -
  23.111 -    <changes>
  23.112 -        <change id="HintTest-singleHint">
  23.113 -            <api name="JavaHintsTest"/>
  23.114 -            <summary>Allowed to check a single hint</summary>
  23.115 -            <version major="1" minor="9"/>
  23.116 -            <date day="3" month="4" year="2013"/>
  23.117 -            <author login="sdedic"/>
  23.118 -            <compatibility addition="yes" binary="compatible" deletion="no" deprecation="no" modification="no" semantic="compatible" source="compatible"/>
  23.119 -            <description>
  23.120 -                New method <code>run(Class, String)</code> was added so that hint with a specific ID can be run, if the
  23.121 -                class contains multiple hint implementations.
  23.122 -            </description>
  23.123 -            <class name="HintTest" package="org.netbeans.modules.java.hints.test.api"/>
  23.124 -            <issue number="227962"/>
  23.125 -        </change>
  23.126 -        <change id="HintTest-ensureJavaFixes">
  23.127 -             <api name="JavaHintsTest"/>
  23.128 -             <summary>Added assertFixes method to HintWarning</summary>
  23.129 -             <version major="1" minor="8"/>
  23.130 -             <date day="22" month="3" year="2013"/>
  23.131 -             <author login="jlahoda"/>
  23.132 -             <compatibility addition="no" binary="compatible" deletion="no" deprecation="no" modification="no" semantic="incompatible" source="compatible"/>
  23.133 -             <description>
  23.134 -                 <code>HintTest.HintWarning.applyFix</code> now enforces constraints for Inspect&amp;Transform. Unless a hint
  23.135 -                 is marked as <code>Options.QUERY</code>, <code>Options.NO_BULK</code> or <code>Kind.ACTION</code>,
  23.136 -                 the <code>Fix</code> that is being applied is tested to be <code>JavaFix</code> and repeatable,
  23.137 -                 which are the requirements of Inspect&amp;Transform.
  23.138 -             </description>
  23.139 -             <class name="HintTest" package="org.netbeans.modules.java.hints.test.api"/>
  23.140 -             <issue number="227271"/>
  23.141 -        </change>
  23.142 -        
  23.143 -        <change id="HintWarning-assertFixes">
  23.144 -             <api name="JavaHintsTest"/>
  23.145 -             <summary>Added assertFixes method to HintWarning</summary>
  23.146 -             <version major="1" minor="1"/>
  23.147 -             <date day="30" month="3" year="2012"/>
  23.148 -             <author login="jlahoda"/>
  23.149 -             <compatibility addition="yes" binary="compatible" deletion="no" deprecation="no" modification="no" semantic="compatible" source="compatible"/>
  23.150 -             <description>
  23.151 -                 Added assertFixes method to HintWarning
  23.152 -             </description>
  23.153 -             <class name="HintTest" package="org.netbeans.modules.java.hints.test.api"/>
  23.154 -             <issue number="209828"/>
  23.155 -        </change>
  23.156 -
  23.157 -    </changes>
  23.158 -
  23.159 -    <!-- Now the surrounding HTML text and document structure: -->
  23.160 -
  23.161 -    <htmlcontents>
  23.162 -<!-- Generated from apichanges.xml -->
  23.163 -    <head>
  23.164 -      <title>Change History for the Editor Hints SPI</title>
  23.165 -      <link rel="stylesheet" href="prose.css" type="text/css"/>
  23.166 -    </head>
  23.167 -    <body>
  23.168 -
  23.169 -<p class="overviewlink"><a href="@TOP@/overview-summary.html">Overview</a></p>
  23.170 -
  23.171 -<h1>Introduction</h1>
  23.172 -
  23.173 -<p>This document lists changes made to the <a href="@TOP@/overview-summary.html">Editor Hints SPI</a>.</p>
  23.174 -
  23.175 -<!-- The actual lists of changes, as summaries and details: -->
  23.176 -      <hr/>
  23.177 -      <standard-changelists module-code-name="org.netbeans.spi.editor.hints/0"/>
  23.178 -
  23.179 -      <hr/><p>@FOOTER@</p>
  23.180 -
  23.181 -    </body>
  23.182 -  </htmlcontents>
  23.183 -
  23.184 -</apichanges>
    24.1 --- a/java.hints/java.hints.test/arch.xml	Sun Oct 16 08:01:27 2016 +0200
    24.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.3 @@ -1,1078 +0,0 @@
    24.4 -<?xml version="1.0" encoding="UTF-8"?>
    24.5 -<!DOCTYPE api-answers PUBLIC "-//NetBeans//DTD Arch Answers//EN" "../nbbuild/antsrc/org/netbeans/nbbuild/Arch.dtd" [
    24.6 -  <!ENTITY api-questions SYSTEM "../nbbuild/antsrc/org/netbeans/nbbuild/Arch-api-questions.xml">
    24.7 -]>
    24.8 -
    24.9 -<api-answers
   24.10 -  question-version="1.29"
   24.11 -  author="yourname@netbeans.org"
   24.12 ->
   24.13 -
   24.14 -  &api-questions;
   24.15 -
   24.16 -
   24.17 -<!--
   24.18 -        <question id="arch-overall" when="init">
   24.19 -            Describe the overall architecture. 
   24.20 -            <hint>
   24.21 -            What will be API for 
   24.22 -            <a href="http://wiki.netbeans.org/API_Design#Separate_API_for_clients_from_support_API">
   24.23 -                clients and what support API</a>? 
   24.24 -            What parts will be pluggable?
   24.25 -            How will plug-ins be registered? Please use <code>&lt;api type="export"/&gt;</code>
   24.26 -            to describe your general APIs and specify their
   24.27 -            <a href="http://wiki.netbeans.org/API_Stability#Private">
   24.28 -            stability categories</a>.
   24.29 -            If possible please provide simple diagrams.
   24.30 -            </hint>
   24.31 -        </question>
   24.32 --->
   24.33 - <answer id="arch-overall">
   24.34 -  <p>
   24.35 -   <api type="export" category="devel" group="java" name="java.hints.test">
   24.36 -       API to create tests for the custom Java hints.
   24.37 -   </api>
   24.38 -  </p>
   24.39 - </answer>
   24.40 -
   24.41 -
   24.42 -
   24.43 -<!--
   24.44 -        <question id="arch-quality" when="init">
   24.45 -            How will the <a href="http://www.netbeans.org/community/guidelines/q-evangelism.html">quality</a>
   24.46 -            of your code be tested and 
   24.47 -            how are future regressions going to be prevented?
   24.48 -            <hint>
   24.49 -            What kind of testing do
   24.50 -            you want to use? How much functionality, in which areas,
   24.51 -            should be covered by the tests? How you find out that your
   24.52 -            project was successful?
   24.53 -            </hint>
   24.54 -        </question>
   24.55 --->
   24.56 - <answer id="arch-quality">
   24.57 -  <p>
   24.58 -   XXX no answer for arch-quality
   24.59 -  </p>
   24.60 - </answer>
   24.61 -
   24.62 -
   24.63 -
   24.64 -<!--
   24.65 -        <question id="arch-time" when="init">
   24.66 -            What are the time estimates of the work?
   24.67 -            <hint>
   24.68 -            Please express your estimates of how long the design, implementation,
   24.69 -            stabilization are likely to last. How many people will be needed to
   24.70 -            implement this and what is the expected milestone by which the work should be 
   24.71 -            ready?
   24.72 -            </hint>
   24.73 -        </question>
   24.74 --->
   24.75 - <answer id="arch-time">
   24.76 -  <p>
   24.77 -   XXX no answer for arch-time
   24.78 -  </p>
   24.79 - </answer>
   24.80 -
   24.81 -
   24.82 -
   24.83 -<!--
   24.84 -        <question id="arch-usecases" when="init">
   24.85 -            <hint>
   24.86 -                Content of this answer will be displayed as part of page at
   24.87 -                http://www.netbeans.org/download/dev/javadoc/usecases.html 
   24.88 -                You can use tags &lt;usecase name="name&gt; regular html description &lt;/usecase&gt;
   24.89 -                and if you want to use an URL you can prefix if with @TOP@ to begin
   24.90 -                at the root of your javadoc
   24.91 -            </hint>
   24.92 -        
   24.93 -            Describe the main <a href="http://wiki.netbeans.org/API_Design#The_Importance_of_Being_Use_Case_Oriented">
   24.94 -            use cases</a> of the new API. Who will use it under
   24.95 -            what circumstances? What kind of code would typically need to be written
   24.96 -            to use the module?
   24.97 -        </question>
   24.98 --->
   24.99 - <answer id="arch-usecases">
  24.100 -  <p>
  24.101 -   XXX no answer for arch-usecases
  24.102 -  </p>
  24.103 - </answer>
  24.104 -
  24.105 -
  24.106 -
  24.107 -<!--
  24.108 -        <question id="arch-what" when="init">
  24.109 -            What is this project good for?
  24.110 -            <hint>
  24.111 -            Please provide here a few lines describing the project, 
  24.112 -            what problem it should solve, provide links to documentation, 
  24.113 -            specifications, etc.
  24.114 -            </hint>
  24.115 -        </question>
  24.116 --->
  24.117 - <answer id="arch-what">
  24.118 -  <p>
  24.119 -   XXX no answer for arch-what
  24.120 -  </p>
  24.121 - </answer>
  24.122 -
  24.123 -
  24.124 -
  24.125 -<!--
  24.126 -        <question id="arch-where" when="impl">
  24.127 -            Where one can find sources for your module?
  24.128 -            <hint>
  24.129 -                Please provide link to the Hg web client at
  24.130 -                http://hg.netbeans.org/
  24.131 -                or just use tag defaultanswer generate='here'
  24.132 -            </hint>
  24.133 -        </question>
  24.134 --->
  24.135 - <answer id="arch-where">
  24.136 -  <defaultanswer generate='here' />
  24.137 - </answer>
  24.138 -
  24.139 -
  24.140 -
  24.141 -<!--
  24.142 -        <question id="compat-deprecation" when="init">
  24.143 -            How the introduction of your project influences functionality
  24.144 -            provided by previous version of the product?
  24.145 -            <hint>
  24.146 -            If you are planning to deprecate/remove/change any existing APIs,
  24.147 -            list them here accompanied with the reason explaining why you
  24.148 -            are doing so.
  24.149 -            </hint>
  24.150 -        </question>
  24.151 --->
  24.152 - <answer id="compat-deprecation">
  24.153 -  <p>
  24.154 -   XXX no answer for compat-deprecation
  24.155 -  </p>
  24.156 - </answer>
  24.157 -
  24.158 -
  24.159 -
  24.160 -<!--
  24.161 -        <question id="compat-i18n" when="impl">
  24.162 -            Is your module correctly internationalized?
  24.163 -            <hint>
  24.164 -            Correct internationalization means that it obeys instructions 
  24.165 -            at <a href="http://www.netbeans.org/download/dev/javadoc/org-openide-modules/org/openide/modules/doc-files/i18n-branding.html">
  24.166 -            NetBeans I18N pages</a>.
  24.167 -            </hint>
  24.168 -        </question>
  24.169 --->
  24.170 - <answer id="compat-i18n">
  24.171 -  <p>
  24.172 -   XXX no answer for compat-i18n
  24.173 -  </p>
  24.174 - </answer>
  24.175 -
  24.176 -
  24.177 -
  24.178 -<!--
  24.179 -        <question id="compat-standards" when="init">
  24.180 -            Does the module implement or define any standards? Is the 
  24.181 -            implementation exact or does it deviate somehow?
  24.182 -        </question>
  24.183 --->
  24.184 - <answer id="compat-standards">
  24.185 -  <p>
  24.186 -   XXX no answer for compat-standards
  24.187 -  </p>
  24.188 - </answer>
  24.189 -
  24.190 -
  24.191 -
  24.192 -<!--
  24.193 -        <question id="compat-version" when="impl">
  24.194 -            Can your module coexist with earlier and future
  24.195 -            versions of itself? Can you correctly read all old settings? Will future
  24.196 -            versions be able to read your current settings? Can you read
  24.197 -            or politely ignore settings stored by a future version?
  24.198 -            
  24.199 -            <hint>
  24.200 -            Very helpful for reading settings is to store version number
  24.201 -            there, so future versions can decide whether how to read/convert
  24.202 -            the settings and older versions can ignore the new ones.
  24.203 -            </hint>
  24.204 -        </question>
  24.205 --->
  24.206 - <answer id="compat-version">
  24.207 -  <p>
  24.208 -   XXX no answer for compat-version
  24.209 -  </p>
  24.210 - </answer>
  24.211 -
  24.212 -
  24.213 -
  24.214 -<!--
  24.215 -        <question id="dep-jre" when="final">
  24.216 -            Which version of JRE do you need (1.2, 1.3, 1.4, etc.)?
  24.217 -            <hint>
  24.218 -            It is expected that if your module runs on 1.x that it will run 
  24.219 -            on 1.x+1 if no, state that please. Also describe here cases where
  24.220 -            you run different code on different versions of JRE and why.
  24.221 -            </hint>
  24.222 -        </question>
  24.223 --->
  24.224 - <answer id="dep-jre">
  24.225 -  <p>
  24.226 -   XXX no answer for dep-jre
  24.227 -  </p>
  24.228 - </answer>
  24.229 -
  24.230 -
  24.231 -
  24.232 -<!--
  24.233 -        <question id="dep-jrejdk" when="final">
  24.234 -            Do you require the JDK or is the JRE enough?
  24.235 -        </question>
  24.236 --->
  24.237 - <answer id="dep-jrejdk">
  24.238 -  <p>
  24.239 -   XXX no answer for dep-jrejdk
  24.240 -  </p>
  24.241 - </answer>
  24.242 -
  24.243 -
  24.244 -
  24.245 -<!--
  24.246 -        <question id="dep-nb" when="init">
  24.247 -            What other NetBeans projects and modules does this one depend on?
  24.248 -            <hint>
  24.249 -            Depending on other NetBeans projects influnces the ability of
  24.250 -            users of your work to customize their own branded version of
  24.251 -            NetBeans by enabling and disabling some modules. Too
  24.252 -            much dependencies restrict this kind of customization. If that
  24.253 -            is your case, then you may want to split your functionality into
  24.254 -            pieces of autoload, eager and regular modules which can be
  24.255 -            enabled independently. Usually the answer to this question
  24.256 -            is generated from your <code>project.xml</code> file, but
  24.257 -            if it is not guessed correctly, you can suppress it by
  24.258 -            specifying &lt;defaultanswer generate="none"/&gt; and
  24.259 -            write here your own. Please describe such projects as imported APIs using
  24.260 -            the <code>&lt;api name="identification" type="import or export" category="stable" url="where is the description" /&gt;</code>.
  24.261 -            By doing this information gets listed in the summary page of your
  24.262 -            javadoc.
  24.263 -            </hint>
  24.264 -        </question>
  24.265 --->
  24.266 - <answer id="dep-nb">
  24.267 -  <defaultanswer generate='here' />
  24.268 - </answer>
  24.269 -
  24.270 -
  24.271 -
  24.272 -<!--
  24.273 -        <question id="dep-non-nb" when="init">
  24.274 -            What other projects outside NetBeans does this one depend on?
  24.275 -            
  24.276 -            <hint>
  24.277 -            Depending on 3rd party libraries is always problematic,
  24.278 -            especially if they are not open source, as that complicates
  24.279 -            the licensing scheme of NetBeans. Please enumerate your
  24.280 -            external dependencies here, so it is correctly understood since
  24.281 -            the begining what are the legal implications of your project.
  24.282 -            Also please note that
  24.283 -            some non-NetBeans projects are packaged as NetBeans modules
  24.284 -            (see <a href="http://libs.netbeans.org/">libraries</a>) and
  24.285 -            it is preferred to use this approach when more modules may
  24.286 -            depend and share such third-party libraries.
  24.287 -            </hint>
  24.288 -        </question>
  24.289 --->
  24.290 - <answer id="dep-non-nb">
  24.291 -  <p>
  24.292 -   XXX no answer for dep-non-nb
  24.293 -  </p>
  24.294 - </answer>
  24.295 -
  24.296 -
  24.297 -
  24.298 -<!--
  24.299 -        <question id="dep-platform" when="init">
  24.300 -            On which platforms does your module run? Does it run in the same
  24.301 -            way on each?
  24.302 -            <hint>
  24.303 -            If you plan any dependency on OS or any usage of native code,
  24.304 -            please describe why you are doing so and describe how you envision
  24.305 -            to enforce the portability of your code.
  24.306 -            Please note that there is a support for <a href="http://www.netbeans.org/download/dev/javadoc/org-openide-modules/org/openide/modules/doc-files/api.html#how-os-specific">OS conditionally
  24.307 -            enabled modules</a> which together with autoload/eager modules
  24.308 -            can allow you to enable to provide the best OS aware support
  24.309 -            on certain OSes while providing compatibility bridge on the not
  24.310 -            supported ones.
  24.311 -            Also please list the supported
  24.312 -            OSes/HW platforms and mentioned the lovest version of JDK required
  24.313 -            for your project to run on. Also state whether JRE is enough or
  24.314 -            you really need JDK.
  24.315 -            </hint>
  24.316 -        </question>
  24.317 --->
  24.318 - <answer id="dep-platform">
  24.319 -  <p>
  24.320 -   XXX no answer for dep-platform
  24.321 -  </p>
  24.322 - </answer>
  24.323 -
  24.324 -
  24.325 -
  24.326 -<!--
  24.327 -        <question id="deploy-dependencies" when="final">
  24.328 -            What do other modules need to do to declare a dependency on this one,
  24.329 -            in addition to or instead of the normal module dependency declaration
  24.330 -            (e.g. tokens to require)?
  24.331 -            <hint>
  24.332 -                Provide a sample of the actual lines you would add to a module manifest
  24.333 -                to declare a dependency, for example OpenIDE-Module-Requires: some.token.
  24.334 -                If other modules should not depend on this module, or should just use a
  24.335 -                simple regular module dependency, you can just answer "nothing". If you
  24.336 -                intentionally expose a semistable API to clients using implementation
  24.337 -                dependencies, you should mention that here (but there is no need to give
  24.338 -                an example of usage).
  24.339 -            </hint>
  24.340 -        </question>
  24.341 --->
  24.342 - <answer id="deploy-dependencies">
  24.343 -  <p>
  24.344 -   XXX no answer for deploy-dependencies
  24.345 -  </p>
  24.346 - </answer>
  24.347 -
  24.348 -
  24.349 -
  24.350 -<!--
  24.351 -        <question id="deploy-jar" when="impl">
  24.352 -            Do you deploy just module JAR file(s) or other files as well?
  24.353 -            <hint>
  24.354 -            Usually a module consist of one JAR file (perhaps with Class-Path
  24.355 -            extensions) and also a configuration file that enables it. If you
  24.356 -            have any other files, use
  24.357 -            &lt;api group="java.io.File" name="yourname" type="export" category="friend"&gt;...&lt;/api&gt;
  24.358 -            to define the location, name and stability of your files (of course
  24.359 -            changing "yourname" and "friend" to suit your needs).
  24.360 -            
  24.361 -            If it uses more than one JAR, describe where they are located, how
  24.362 -            they refer to each other. 
  24.363 -            If it consist of module JAR(s) and other files, please describe
  24.364 -            what is their purpose, why other files are necessary. Please 
  24.365 -            make sure that installation/uninstallation leaves the system 
  24.366 -            in state as it was before installation.
  24.367 -            </hint>
  24.368 -        </question>
  24.369 --->
  24.370 - <answer id="deploy-jar">
  24.371 -  <p>
  24.372 -   XXX no answer for deploy-jar
  24.373 -  </p>
  24.374 - </answer>
  24.375 -
  24.376 -
  24.377 -
  24.378 -<!--
  24.379 -        <question id="deploy-nbm" when="impl">
  24.380 -            Can you deploy an NBM via the Update Center?
  24.381 -            <hint>
  24.382 -            If not why?
  24.383 -            </hint>
  24.384 -        </question>
  24.385 --->
  24.386 - <answer id="deploy-nbm">
  24.387 -  <p>
  24.388 -   XXX no answer for deploy-nbm
  24.389 -  </p>
  24.390 - </answer>
  24.391 -
  24.392 -
  24.393 -
  24.394 -<!--
  24.395 -        <question id="deploy-packages" when="init">
  24.396 -            Are packages of your module made inaccessible by not declaring them
  24.397 -            public?
  24.398 -            
  24.399 -            <hint>
  24.400 -            By default NetBeans build harness treats all packages are private.
  24.401 -            If you export some of them - either as public or friend packages,
  24.402 -            you should have a reason. If the reason is described elsewhere
  24.403 -            in this document, you can ignore this question.
  24.404 -            </hint>
  24.405 -        </question>
  24.406 --->
  24.407 - <answer id="deploy-packages">
  24.408 -  <p>
  24.409 -   XXX no answer for deploy-packages
  24.410 -  </p>
  24.411 - </answer>
  24.412 -
  24.413 -
  24.414 -
  24.415 -<!--
  24.416 -        <question id="deploy-shared" when="final">
  24.417 -            Do you need to be installed in the shared location only, or in the user directory only,
  24.418 -            or can your module be installed anywhere?
  24.419 -            <hint>
  24.420 -            Installation location shall not matter, if it does explain why.
  24.421 -            Consider also whether <code>InstalledFileLocator</code> can help.
  24.422 -            </hint>
  24.423 -        </question>
  24.424 --->
  24.425 - <answer id="deploy-shared">
  24.426 -  <p>
  24.427 -   XXX no answer for deploy-shared
  24.428 -  </p>
  24.429 - </answer>
  24.430 -
  24.431 -
  24.432 -
  24.433 -<!--
  24.434 -        <question id="exec-ant-tasks" when="impl">
  24.435 -            Do you define or register any ant tasks that other can use?
  24.436 -            
  24.437 -            <hint>
  24.438 -            If you provide an ant task that users can use, you need to be very
  24.439 -            careful about its syntax and behaviour, as it most likely forms an
  24.440 -	          API for end users and as there is a lot of end users, their reaction
  24.441 -            when such API gets broken can be pretty strong.
  24.442 -            </hint>
  24.443 -        </question>
  24.444 --->
  24.445 - <answer id="exec-ant-tasks">
  24.446 -  <p>
  24.447 -   XXX no answer for exec-ant-tasks
  24.448 -  </p>
  24.449 - </answer>
  24.450 -
  24.451 -
  24.452 -
  24.453 -<!--
  24.454 -        <question id="exec-classloader" when="impl">
  24.455 -            Does your code create its own class loader(s)?
  24.456 -            <hint>
  24.457 -            A bit unusual. Please explain why and what for.
  24.458 -            </hint>
  24.459 -        </question>
  24.460 --->
  24.461 - <answer id="exec-classloader">
  24.462 -  <p>
  24.463 -   XXX no answer for exec-classloader
  24.464 -  </p>
  24.465 - </answer>
  24.466 -
  24.467 -
  24.468 -
  24.469 -<!--
  24.470 -        <question id="exec-component" when="impl">
  24.471 -            Is execution of your code influenced by any (string) property
  24.472 -            of any of your components?
  24.473 -            
  24.474 -            <hint>
  24.475 -            Often <code>JComponent.getClientProperty</code>, <code>Action.getValue</code>
  24.476 -            or <code>PropertyDescriptor.getValue</code>, etc. are used to influence
  24.477 -            a behavior of some code. This of course forms an interface that should
  24.478 -            be documented. Also if one depends on some interface that an object
  24.479 -            implements (<code>component instanceof Runnable</code>) that forms an
  24.480 -            API as well.
  24.481 -            </hint>
  24.482 -        </question>
  24.483 --->
  24.484 - <answer id="exec-component">
  24.485 -  <p>
  24.486 -   XXX no answer for exec-component
  24.487 -  </p>
  24.488 - </answer>
  24.489 -
  24.490 -
  24.491 -
  24.492 -<!--
  24.493 -        <question id="exec-introspection" when="impl">
  24.494 -            Does your module use any kind of runtime type information (<code>instanceof</code>,
  24.495 -            work with <code>java.lang.Class</code>, etc.)?
  24.496 -            <hint>
  24.497 -            Check for cases when you have an object of type A and you also
  24.498 -            expect it to (possibly) be of type B and do some special action. That
  24.499 -            should be documented. The same applies on operations in meta-level
  24.500 -            (Class.isInstance(...), Class.isAssignableFrom(...), etc.).
  24.501 -            </hint>
  24.502 -        </question>
  24.503 --->
  24.504 - <answer id="exec-introspection">
  24.505 -  <p>
  24.506 -   XXX no answer for exec-introspection
  24.507 -  </p>
  24.508 - </answer>
  24.509 -
  24.510 -
  24.511 -
  24.512 -<!--
  24.513 -        <question id="exec-privateaccess" when="final">
  24.514 -            Are you aware of any other parts of the system calling some of 
  24.515 -            your methods by reflection?
  24.516 -            <hint>
  24.517 -            If so, describe the "contract" as an API. Likely private or friend one, but
  24.518 -            still API and consider rewrite of it.
  24.519 -            </hint>
  24.520 -        </question>
  24.521 --->
  24.522 - <answer id="exec-privateaccess">
  24.523 -  <p>
  24.524 -   XXX no answer for exec-privateaccess
  24.525 -  </p>
  24.526 - </answer>
  24.527 -
  24.528 -
  24.529 -
  24.530 -<!--
  24.531 -        <question id="exec-process" when="impl">
  24.532 -            Do you execute an external process from your module? How do you ensure
  24.533 -            that the result is the same on different platforms? Do you parse output?
  24.534 -            Do you depend on result code?
  24.535 -            <hint>
  24.536 -            If you feed an input, parse the output please declare that as an API.
  24.537 -            </hint>
  24.538 -        </question>
  24.539 --->
  24.540 - <answer id="exec-process">
  24.541 -  <p>
  24.542 -   XXX no answer for exec-process
  24.543 -  </p>
  24.544 - </answer>
  24.545 -
  24.546 -
  24.547 -
  24.548 -<!--
  24.549 -        <question id="exec-property" when="impl">
  24.550 -            Is execution of your code influenced by any environment or
  24.551 -            Java system (<code>System.getProperty</code>) property?
  24.552 -            On a similar note, is there something interesting that you
  24.553 -            pass to <code>java.util.logging.Logger</code>? Or do you observe
  24.554 -            what others log?
  24.555 -            <hint>
  24.556 -            If there is a property that can change the behavior of your 
  24.557 -            code, somebody will likely use it. You should describe what it does 
  24.558 -            and the <a href="http://wiki.netbeans.org/API_Stability">stability category</a>
  24.559 -            of this API. You may use
  24.560 -            <pre>
  24.561 -                &lt;api type="export" group="property" name="id" category="private" url="http://..."&gt;
  24.562 -                    description of the property, where it is used, what it influence, etc.
  24.563 -                &lt;/api&gt;            
  24.564 -            </pre>
  24.565 -            </hint>
  24.566 -        </question>
  24.567 --->
  24.568 - <answer id="exec-property">
  24.569 -  <p>
  24.570 -   XXX no answer for exec-property
  24.571 -  </p>
  24.572 - </answer>
  24.573 -
  24.574 -
  24.575 -
  24.576 -<!--
  24.577 -        <question id="exec-reflection" when="impl">
  24.578 -            Does your code use Java Reflection to execute other code?
  24.579 -            <hint>
  24.580 -            This usually indicates a missing or insufficient API in the other
  24.581 -            part of the system. If the other side is not aware of your dependency
  24.582 -            this contract can be easily broken.
  24.583 -            </hint>
  24.584 -        </question>
  24.585 --->
  24.586 - <answer id="exec-reflection">
  24.587 -  <p>
  24.588 -   XXX no answer for exec-reflection
  24.589 -  </p>
  24.590 - </answer>
  24.591 -
  24.592 -
  24.593 -
  24.594 -<!--
  24.595 -        <question id="exec-threading" when="init">
  24.596 -            What threading models, if any, does your module adhere to? How the
  24.597 -            project behaves with respect to threading?
  24.598 -            <hint>
  24.599 -                Is your API threadsafe? Can it be accessed from any threads or
  24.600 -                just from some dedicated ones? Any special relation to AWT and
  24.601 -                its Event Dispatch thread? Also
  24.602 -                if your module calls foreign APIs which have a specific threading model,
  24.603 -                indicate how you comply with the requirements for multithreaded access
  24.604 -                (synchronization, mutexes, etc.) applicable to those APIs.
  24.605 -                If your module defines any APIs, or has complex internal structures
  24.606 -                that might be used from multiple threads, declare how you protect
  24.607 -                data against concurrent access, race conditions, deadlocks, etc.,
  24.608 -                and whether such rules are enforced by runtime warnings, errors, assertions, etc.
  24.609 -                Examples: a class might be non-thread-safe (like Java Collections); might
  24.610 -                be fully thread-safe (internal locking); might require access through a mutex
  24.611 -                (and may or may not automatically acquire that mutex on behalf of a client method);
  24.612 -                might be able to run only in the event queue; etc.
  24.613 -                Also describe when any events are fired: synchronously, asynchronously, etc.
  24.614 -                Ideas: <a href="http://core.netbeans.org/proposals/threading/index.html#recommendations">Threading Recommendations</a> (in progress)
  24.615 -            </hint>
  24.616 -        </question>
  24.617 --->
  24.618 - <answer id="exec-threading">
  24.619 -  <p>
  24.620 -   XXX no answer for exec-threading
  24.621 -  </p>
  24.622 - </answer>
  24.623 -
  24.624 -
  24.625 -
  24.626 -<!--
  24.627 -        <question id="format-clipboard" when="impl">
  24.628 -            Which data flavors (if any) does your code read from or insert to
  24.629 -            the clipboard (by access to clipboard on means calling methods on <code>java.awt.datatransfer.Transferable</code>?
  24.630 -            
  24.631 -            <hint>
  24.632 -            Often Node's deal with clipboard by usage of <code>Node.clipboardCopy, Node.clipboardCut and Node.pasteTypes</code>.
  24.633 -            Check your code for overriding these methods.
  24.634 -            </hint>
  24.635 -        </question>
  24.636 --->
  24.637 - <answer id="format-clipboard">
  24.638 -  <p>
  24.639 -   XXX no answer for format-clipboard
  24.640 -  </p>
  24.641 - </answer>
  24.642 -
  24.643 -
  24.644 -
  24.645 -<!--
  24.646 -        <question id="format-dnd" when="impl">
  24.647 -            Which protocols (if any) does your code understand during Drag &amp; Drop?
  24.648 -            <hint>
  24.649 -            Often Node's deal with clipboard by usage of <code>Node.drag, Node.getDropType</code>. 
  24.650 -            Check your code for overriding these methods. Btw. if they are not overridden, they
  24.651 -            by default delegate to <code>Node.clipboardCopy, Node.clipboardCut and Node.pasteTypes</code>.
  24.652 -            </hint>
  24.653 -        </question>
  24.654 --->
  24.655 - <answer id="format-dnd">
  24.656 -  <p>
  24.657 -   XXX no answer for format-dnd
  24.658 -  </p>
  24.659 - </answer>
  24.660 -
  24.661 -
  24.662 -
  24.663 -<!--
  24.664 -        <question id="format-types" when="impl">
  24.665 -            Which protocols and file formats (if any) does your module read or write on disk,
  24.666 -            or transmit or receive over the network? Do you generate an ant build script?
  24.667 -            Can it be edited and modified? 
  24.668 -            
  24.669 -            <hint>
  24.670 -            <p>
  24.671 -            Files can be read and written by other programs, modules and users. If they influence
  24.672 -            your behaviour, make sure you either document the format or claim that it is a private
  24.673 -            api (using the &lt;api&gt; tag). 
  24.674 -            </p>
  24.675 -            
  24.676 -            <p>
  24.677 -            If you generate an ant build file, this is very likely going to be seen by end users and
  24.678 -            they will be attempted to edit it. You should be ready for that and provide here a link
  24.679 -            to documentation that you have for such purposes and also describe how you are going to
  24.680 -            understand such files during next release, when you (very likely) slightly change the 
  24.681 -            format.
  24.682 -            </p>
  24.683 -            </hint>
  24.684 -        </question>
  24.685 --->
  24.686 - <answer id="format-types">
  24.687 -  <p>
  24.688 -   XXX no answer for format-types
  24.689 -  </p>
  24.690 - </answer>
  24.691 -
  24.692 -
  24.693 -
  24.694 -<!--
  24.695 -        <question id="lookup-lookup" when="init">
  24.696 -            Does your module use <code>org.openide.util.Lookup</code>
  24.697 -            or any similar technology to find any components to communicate with? Which ones?
  24.698 -            
  24.699 -            <hint>
  24.700 -            NetBeans is build around a generic registry of services called
  24.701 -            lookup. It is preferable to use it for registration and discovery
  24.702 -            if possible. See
  24.703 -            <a href="http://www.netbeans.org/download/dev/javadoc/org-openide-util/org/openide/util/lookup/doc-files/index.html">
  24.704 -            The Solution to Comunication Between Components
  24.705 -            </a>. If you do not plan to use lookup and insist usage
  24.706 -            of other solution, then please describe why it is not working for
  24.707 -            you.
  24.708 -            <br/>
  24.709 -            When filling the final version of your arch document, please
  24.710 -            describe the interfaces you are searching for, where 
  24.711 -            are defined, whether you are searching for just one or more of them,
  24.712 -            if the order is important, etc. Also classify the stability of such
  24.713 -            API contract. Use &lt;api group=&amp;lookup&amp; /&gt; tag, so
  24.714 -            your information gets listed in the summary page of your javadoc.
  24.715 -            </hint>
  24.716 -        </question>
  24.717 --->
  24.718 - <answer id="lookup-lookup">
  24.719 -  <p>
  24.720 -   XXX no answer for lookup-lookup
  24.721 -  </p>
  24.722 - </answer>
  24.723 -
  24.724 -
  24.725 -
  24.726 -<!--
  24.727 -        <question id="lookup-register" when="final">
  24.728 -            Do you register anything into lookup for other code to find?
  24.729 -            <hint>
  24.730 -            Do you register using layer file or using a declarative annotation such as <code>@ServiceProvider</code>?
  24.731 -            Who is supposed to find your component?
  24.732 -            </hint>
  24.733 -        </question>
  24.734 --->
  24.735 - <answer id="lookup-register">
  24.736 -  <p>
  24.737 -   XXX no answer for lookup-register
  24.738 -  </p>
  24.739 - </answer>
  24.740 -
  24.741 -
  24.742 -
  24.743 -<!--
  24.744 -        <question id="lookup-remove" when="final">
  24.745 -            Do you remove entries of other modules from lookup?
  24.746 -            <hint>
  24.747 -            Why? Of course, that is possible, but it can be dangerous. Is the module
  24.748 -            your are masking resource from aware of what you are doing?
  24.749 -            </hint>
  24.750 -        </question>
  24.751 --->
  24.752 - <answer id="lookup-remove">
  24.753 -  <p>
  24.754 -   XXX no answer for lookup-remove
  24.755 -  </p>
  24.756 - </answer>
  24.757 -
  24.758 -
  24.759 -
  24.760 -<!--
  24.761 -        <question id="perf-exit" when="final">
  24.762 -            Does your module run any code on exit?
  24.763 -        </question>
  24.764 --->
  24.765 - <answer id="perf-exit">
  24.766 -  <p>
  24.767 -   XXX no answer for perf-exit
  24.768 -  </p>
  24.769 - </answer>
  24.770 -
  24.771 -
  24.772 -
  24.773 -<!--
  24.774 -        <question id="perf-huge_dialogs" when="final">
  24.775 -            Does your module contain any dialogs or wizards with a large number of
  24.776 -            GUI controls such as combo boxes, lists, trees, or text areas?
  24.777 -        </question>
  24.778 --->
  24.779 - <answer id="perf-huge_dialogs">
  24.780 -  <p>
  24.781 -   XXX no answer for perf-huge_dialogs
  24.782 -  </p>
  24.783 - </answer>
  24.784 -
  24.785 -
  24.786 -
  24.787 -<!--
  24.788 -        <question id="perf-limit" when="init">
  24.789 -            Are there any hard-coded or practical limits in the number or size of
  24.790 -            elements your code can handle?
  24.791 -            <hint>
  24.792 -                Most of algorithms have increasing memory and speed complexity
  24.793 -                with respect to size of data they operate on. What is the critical
  24.794 -                part of your project that can be seen as a bottleneck with
  24.795 -                respect to speed or required memory? What are the practical
  24.796 -                sizes of data you tested your project with? What is your estimate
  24.797 -                of potential size of data that would cause visible performance
  24.798 -                problems? Is there some kind of check to detect such situation
  24.799 -                and prevent "hard" crashes - for example the CloneableEditorSupport
  24.800 -                checks for size of a file to be opened in editor
  24.801 -                and if it is larger than 1Mb it shows a dialog giving the
  24.802 -                user the right to decide - e.g. to cancel or commit suicide.
  24.803 -            </hint>
  24.804 -        </question>
  24.805 --->
  24.806 - <answer id="perf-limit">
  24.807 -  <p>
  24.808 -   XXX no answer for perf-limit
  24.809 -  </p>
  24.810 - </answer>
  24.811 -
  24.812 -
  24.813 -
  24.814 -<!--
  24.815 -        <question id="perf-mem" when="final">
  24.816 -            How much memory does your component consume? Estimate
  24.817 -            with a relation to the number of windows, etc.
  24.818 -        </question>
  24.819 --->
  24.820 - <answer id="perf-mem">
  24.821 -  <p>
  24.822 -   XXX no answer for perf-mem
  24.823 -  </p>
  24.824 - </answer>
  24.825 -
  24.826 -
  24.827 -
  24.828 -<!--
  24.829 -        <question id="perf-menus" when="final">
  24.830 -            Does your module use dynamically updated context menus, or
  24.831 -            context-sensitive actions with complicated and slow enablement logic?
  24.832 -            <hint>
  24.833 -                If you do a lot of tricks when adding actions to regular or context menus, you can significantly
  24.834 -                slow down display of the menu, even when the user is not using your action. Pay attention to
  24.835 -                actions you add to the main menu bar, and to context menus of foreign nodes or components. If
  24.836 -                the action is conditionally enabled, or changes its display dynamically, you need to check the
  24.837 -                impact on performance. In some cases it may be more appropriate to make a simple action that is
  24.838 -                always enabled but does more detailed checks in a dialog if it is actually run.
  24.839 -            </hint>
  24.840 -        </question>
  24.841 --->
  24.842 - <answer id="perf-menus">
  24.843 -  <p>
  24.844 -   XXX no answer for perf-menus
  24.845 -  </p>
  24.846 - </answer>
  24.847 -
  24.848 -
  24.849 -
  24.850 -<!--
  24.851 -        <question id="perf-progress" when="final">
  24.852 -            Does your module execute any long-running tasks?
  24.853 -            
  24.854 -            <hint>Long running tasks should never block 
  24.855 -            AWT thread as it badly hurts the UI
  24.856 -            <a href="http://performance.netbeans.org/responsiveness/issues.html">
  24.857 -            responsiveness</a>.
  24.858 -            Tasks like connecting over
  24.859 -            network, computing huge amount of data, compilation
  24.860 -            be done asynchronously (for example
  24.861 -            using <code>RequestProcessor</code>), definitively it should 
  24.862 -            not block AWT thread.
  24.863 -            </hint>
  24.864 -        </question>
  24.865 --->
  24.866 - <answer id="perf-progress">
  24.867 -  <p>
  24.868 -   XXX no answer for perf-progress
  24.869 -  </p>
  24.870 - </answer>
  24.871 -
  24.872 -
  24.873 -
  24.874 -<!--
  24.875 -        <question id="perf-scale" when="init">
  24.876 -            Which external criteria influence the performance of your
  24.877 -            program (size of file in editor, number of files in menu, 
  24.878 -            in source directory, etc.) and how well your code scales?
  24.879 -            <hint>
  24.880 -            Please include some estimates, there are other more detailed 
  24.881 -            questions to answer in later phases of implementation. 
  24.882 -            </hint>
  24.883 -        </question>
  24.884 --->
  24.885 - <answer id="perf-scale">
  24.886 -  <p>
  24.887 -   XXX no answer for perf-scale
  24.888 -  </p>
  24.889 - </answer>
  24.890 -
  24.891 -
  24.892 -
  24.893 -<!--
  24.894 -        <question id="perf-spi" when="init">
  24.895 -            How the performance of the plugged in code will be enforced?
  24.896 -            <hint>
  24.897 -            If you allow foreign code to be plugged into your own module, how
  24.898 -            do you enforce that it will behave correctly and quickly and will not
  24.899 -            negatively influence the performance of your own module?
  24.900 -            </hint>
  24.901 -        </question>
  24.902 --->
  24.903 - <answer id="perf-spi">
  24.904 -  <p>
  24.905 -   XXX no answer for perf-spi
  24.906 -  </p>
  24.907 - </answer>
  24.908 -
  24.909 -
  24.910 -
  24.911 -<!--
  24.912 -        <question id="perf-startup" when="final">
  24.913 -            Does your module run any code on startup?
  24.914 -        </question>
  24.915 --->
  24.916 - <answer id="perf-startup">
  24.917 -  <p>
  24.918 -   XXX no answer for perf-startup
  24.919 -  </p>
  24.920 - </answer>
  24.921 -
  24.922 -
  24.923 -
  24.924 -<!--
  24.925 -        <question id="perf-wakeup" when="final">
  24.926 -            Does any piece of your code wake up periodically and do something
  24.927 -            even when the system is otherwise idle (no user interaction)?
  24.928 -        </question>
  24.929 --->
  24.930 - <answer id="perf-wakeup">
  24.931 -  <p>
  24.932 -   XXX no answer for perf-wakeup
  24.933 -  </p>
  24.934 - </answer>
  24.935 -
  24.936 -
  24.937 -
  24.938 -<!--
  24.939 -        <question id="resources-file" when="final">
  24.940 -            Does your module use <code>java.io.File</code> directly?
  24.941 -            
  24.942 -            <hint>
  24.943 -            NetBeans provide a logical wrapper over plain files called 
  24.944 -            <code>org.openide.filesystems.FileObject</code> that
  24.945 -            provides uniform access to such resources and is the preferred
  24.946 -            way that should be used. But of course there can be situations when
  24.947 -            this is not suitable.
  24.948 -            </hint>
  24.949 -        </question>
  24.950 --->
  24.951 - <answer id="resources-file">
  24.952 -  <p>
  24.953 -   XXX no answer for resources-file
  24.954 -  </p>
  24.955 - </answer>
  24.956 -
  24.957 -
  24.958 -
  24.959 -<!--
  24.960 -        <question id="resources-layer" when="final">
  24.961 -            Does your module provide own layer? Does it create any files or
  24.962 -            folders in it? What it is trying to communicate by that and with which 
  24.963 -            components?
  24.964 -            
  24.965 -            <hint>
  24.966 -            NetBeans allows automatic and declarative installation of resources 
  24.967 -            by module layers. Module register files into appropriate places
  24.968 -            and other components use that information to perform their task
  24.969 -            (build menu, toolbar, window layout, list of templates, set of
  24.970 -            options, etc.). 
  24.971 -            </hint>
  24.972 -        </question>
  24.973 --->
  24.974 - <answer id="resources-layer">
  24.975 -  <p>
  24.976 -   XXX no answer for resources-layer
  24.977 -  </p>
  24.978 - </answer>
  24.979 -
  24.980 -
  24.981 -
  24.982 -<!--
  24.983 -        <question id="resources-mask" when="final">
  24.984 -            Does your module mask/hide/override any resources provided by other modules in
  24.985 -            their layers?
  24.986 -            
  24.987 -            <hint>
  24.988 -            If you mask a file provided by another module, you probably depend
  24.989 -            on that and do not want the other module to (for example) change
  24.990 -            the file's name. That module shall thus make that file available as an API
  24.991 -            of some stability category.
  24.992 -            </hint>
  24.993 -        </question>
  24.994 --->
  24.995 - <answer id="resources-mask">
  24.996 -  <p>
  24.997 -   XXX no answer for resources-mask
  24.998 -  </p>
  24.999 - </answer>
 24.1000 -
 24.1001 -
 24.1002 -
 24.1003 -<!--
 24.1004 -        <question id="resources-preferences" when="final">
 24.1005 -            Does your module uses preferences via Preferences API? Does your module use NbPreferences or
 24.1006 -            or regular JDK Preferences ? Does it read, write or both ? 
 24.1007 -            Does it share preferences with other modules ? If so, then why ?
 24.1008 -            <hint>
 24.1009 -                You may use
 24.1010 -                    &lt;api type="export" group="preferences"
 24.1011 -                    name="preference node name" category="private"&gt;
 24.1012 -                    description of individual keys, where it is used, what it
 24.1013 -                    influences, whether the module reads/write it, etc.
 24.1014 -                    &lt;/api&gt;
 24.1015 -                Due to XML ID restrictions, rather than /org/netbeans/modules/foo give the "name" as org.netbeans.modules.foo.
 24.1016 -                Note that if you use NbPreferences this name will then be the same as the code name base of the module.
 24.1017 -            </hint>
 24.1018 -        </question>
 24.1019 --->
 24.1020 - <answer id="resources-preferences">
 24.1021 -  <p>
 24.1022 -   XXX no answer for resources-preferences
 24.1023 -  </p>
 24.1024 - </answer>
 24.1025 -
 24.1026 -
 24.1027 -
 24.1028 -<!--
 24.1029 -        <question id="resources-read" when="final">
 24.1030 -            Does your module read any resources from layers? For what purpose?
 24.1031 -            
 24.1032 -            <hint>
 24.1033 -            As this is some kind of intermodule dependency, it is a kind of API.
 24.1034 -            Please describe it and classify according to 
 24.1035 -            <a href="http://wiki.netbeans.org/API_Design#What_is_an_API.3F">
 24.1036 -            common stability categories</a>.
 24.1037 -            </hint>
 24.1038 -        </question>
 24.1039 --->
 24.1040 - <answer id="resources-read">
 24.1041 -  <p>
 24.1042 -   XXX no answer for resources-read
 24.1043 -  </p>
 24.1044 - </answer>
 24.1045 -
 24.1046 -
 24.1047 -
 24.1048 -<!--
 24.1049 -        <question id="security-grant" when="final">
 24.1050 -            Does your code grant additional rights to some other code?
 24.1051 -            <hint>Avoid using a class loader that adds extra
 24.1052 -            permissions to loaded code unless really necessary.
 24.1053 -            Also note that your API implementation
 24.1054 -            can also expose unneeded permissions to enemy code by
 24.1055 -            calling AccessController.doPrivileged().</hint>
 24.1056 -        </question>
 24.1057 --->
 24.1058 - <answer id="security-grant">
 24.1059 -  <p>
 24.1060 -   XXX no answer for security-grant
 24.1061 -  </p>
 24.1062 - </answer>
 24.1063 -
 24.1064 -
 24.1065 -
 24.1066 -<!--
 24.1067 -        <question id="security-policy" when="final">
 24.1068 -            Does your functionality require modifications to the standard policy file?
 24.1069 -            <hint>Your code might pass control to third-party code not
 24.1070 -            coming from trusted domains. This could be code downloaded over the
 24.1071 -            network or code coming from libraries that are not bundled
 24.1072 -            with NetBeans. Which permissions need to be granted to which domains?</hint>
 24.1073 -        </question>
 24.1074 --->
 24.1075 - <answer id="security-policy">
 24.1076 -  <p>
 24.1077 -   XXX no answer for security-policy
 24.1078 -  </p>
 24.1079 - </answer>
 24.1080 -
 24.1081 -</api-answers>
    25.1 --- a/java.hints/java.hints.test/build.xml	Sun Oct 16 08:01:27 2016 +0200
    25.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.3 @@ -1,8 +0,0 @@
    25.4 -<?xml version="1.0" encoding="UTF-8"?>
    25.5 -<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
    25.6 -<!-- for some information on what you could do (e.g. targets to override). -->
    25.7 -<!-- If you delete this file and reopen the project it will be recreated. -->
    25.8 -<project name="org.netbeans.modules.java.hints.test" default="netbeans" basedir=".">
    25.9 -    <description>Builds, tests, and runs the project org.netbeans.modules.java.hints.test.</description>
   25.10 -    <import file="nbproject/build-impl.xml"/>
   25.11 -</project>
    26.1 --- a/java.hints/java.hints.test/manifest.mf	Sun Oct 16 08:01:27 2016 +0200
    26.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.3 @@ -1,5 +0,0 @@
    26.4 -Manifest-Version: 1.0
    26.5 -OpenIDE-Module: org.netbeans.modules.java.hints.test/1
    26.6 -OpenIDE-Module-Implementation-Version: 1
    26.7 -OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/java/hints/test/Bundle.properties
    26.8 -
    27.1 --- a/java.hints/java.hints.test/nbproject/build-impl.xml	Sun Oct 16 08:01:27 2016 +0200
    27.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.3 @@ -1,45 +0,0 @@
    27.4 -<?xml version="1.0" encoding="UTF-8"?>
    27.5 -<!--
    27.6 -*** GENERATED FROM project.xml - DO NOT EDIT  ***
    27.7 -***         EDIT ../build.xml INSTEAD         ***
    27.8 --->
    27.9 -<project name="org.netbeans.modules.java.hints.test-impl" basedir="..">
   27.10 -    <fail message="Please build using Ant 1.7.1 or higher.">
   27.11 -        <condition>
   27.12 -            <not>
   27.13 -                <antversion atleast="1.7.1"/>
   27.14 -            </not>
   27.15 -        </condition>
   27.16 -    </fail>
   27.17 -    <property file="nbproject/private/suite-private.properties"/>
   27.18 -    <property file="nbproject/suite.properties"/>
   27.19 -    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
   27.20 -    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
   27.21 -    <property file="${suite.dir}/nbproject/platform.properties"/>
   27.22 -    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
   27.23 -        <attribute name="name"/>
   27.24 -        <attribute name="value"/>
   27.25 -        <sequential>
   27.26 -            <property name="@{name}" value="${@{value}}"/>
   27.27 -        </sequential>
   27.28 -    </macrodef>
   27.29 -    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
   27.30 -        <attribute name="property"/>
   27.31 -        <attribute name="value"/>
   27.32 -        <sequential>
   27.33 -            <property name="@{property}" value="@{value}"/>
   27.34 -        </sequential>
   27.35 -    </macrodef>
   27.36 -    <property file="${user.properties.file}"/>
   27.37 -    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
   27.38 -    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
   27.39 -    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
   27.40 -    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
   27.41 -        <condition>
   27.42 -            <not>
   27.43 -                <contains string="${cluster.path.evaluated}" substring="platform"/>
   27.44 -            </not>
   27.45 -        </condition>
   27.46 -    </fail>
   27.47 -    <import file="${harness.dir}/build.xml"/>
   27.48 -</project>
    28.1 --- a/java.hints/java.hints.test/nbproject/genfiles.properties	Sun Oct 16 08:01:27 2016 +0200
    28.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.3 @@ -1,8 +0,0 @@
    28.4 -build.xml.data.CRC32=bdfc486d
    28.5 -build.xml.script.CRC32=fb578ef0
    28.6 -build.xml.stylesheet.CRC32=a56c6a5b@2.70
    28.7 -# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
    28.8 -# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
    28.9 -nbproject/build-impl.xml.data.CRC32=bdfc486d
   28.10 -nbproject/build-impl.xml.script.CRC32=c676886e
   28.11 -nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.70
    29.1 --- a/java.hints/java.hints.test/nbproject/org-netbeans-modules-java-hints-test.sig	Sun Oct 16 08:01:27 2016 +0200
    29.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.3 @@ -1,67 +0,0 @@
    29.4 -#Signature file v4.1
    29.5 -#Version 1.6.1
    29.6 -
    29.7 -CLSS public java.lang.Object
    29.8 -cons public init()
    29.9 -meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
   29.10 -meth protected void finalize() throws java.lang.Throwable
   29.11 -meth public boolean equals(java.lang.Object)
   29.12 -meth public final java.lang.Class<?> getClass()
   29.13 -meth public final void notify()
   29.14 -meth public final void notifyAll()
   29.15 -meth public final void wait() throws java.lang.InterruptedException
   29.16 -meth public final void wait(long) throws java.lang.InterruptedException
   29.17 -meth public final void wait(long,int) throws java.lang.InterruptedException
   29.18 -meth public int hashCode()
   29.19 -meth public java.lang.String toString()
   29.20 -
   29.21 -CLSS public org.netbeans.modules.java.hints.test.api.HintTest
   29.22 -innr public final AppliedFix
   29.23 -innr public final HintOutput
   29.24 -innr public final HintWarning
   29.25 -meth public !varargs org.netbeans.modules.java.hints.test.api.HintTest classpath(java.net.URL[])
   29.26 -meth public org.netbeans.modules.java.hints.test.api.HintTest input(java.lang.String) throws java.lang.Exception
   29.27 -meth public org.netbeans.modules.java.hints.test.api.HintTest input(java.lang.String,boolean) throws java.lang.Exception
   29.28 -meth public org.netbeans.modules.java.hints.test.api.HintTest input(java.lang.String,java.lang.String) throws java.lang.Exception
   29.29 -meth public org.netbeans.modules.java.hints.test.api.HintTest input(java.lang.String,java.lang.String,boolean) throws java.lang.Exception
   29.30 -meth public org.netbeans.modules.java.hints.test.api.HintTest preference(java.lang.String,boolean)
   29.31 -meth public org.netbeans.modules.java.hints.test.api.HintTest preference(java.lang.String,int)
   29.32 -meth public org.netbeans.modules.java.hints.test.api.HintTest preference(java.lang.String,java.lang.String)
   29.33 -meth public org.netbeans.modules.java.hints.test.api.HintTest setCaretMarker(char)
   29.34 -meth public org.netbeans.modules.java.hints.test.api.HintTest sourceLevel(java.lang.String)
   29.35 -meth public org.netbeans.modules.java.hints.test.api.HintTest$HintOutput run(java.lang.Class<?>) throws java.lang.Exception
   29.36 -meth public static org.netbeans.modules.java.hints.test.api.HintTest create() throws java.lang.Exception
   29.37 -supr java.lang.Object
   29.38 -hfds DEBUGGING_HELPER,ERRORS_COMPARATOR,INDEXING_LOGGER,JUNIT_PROPERTIES_FILENAME,JUNIT_PROPERTIES_LOCATION_PROPERTY,NBJUNIT_WORKDIR,bootClassPath,buildRoot,cache,caret,caretMarker,checkCompilable,compileClassPath,log,sourceLevel,sourcePath,sourceRoot,testFile,testPreferences,usedPaths,workDir
   29.39 -hcls DeadlockTask,TempPreferences,TestProxyClassPathProvider,TestSourceForBinaryQuery,TestSourceLevelQueryImplementation
   29.40 -
   29.41 -CLSS public final org.netbeans.modules.java.hints.test.api.HintTest$AppliedFix
   29.42 - outer org.netbeans.modules.java.hints.test.api.HintTest
   29.43 -cons public init(org.netbeans.modules.java.hints.test.api.HintTest)
   29.44 -meth public java.lang.String getOutput() throws java.lang.Exception
   29.45 -meth public java.lang.String getOutput(java.lang.String) throws java.lang.Exception
   29.46 -meth public org.netbeans.modules.java.hints.test.api.HintTest$AppliedFix assertCompilable() throws java.lang.Exception
   29.47 -meth public org.netbeans.modules.java.hints.test.api.HintTest$AppliedFix assertCompilable(java.lang.String) throws java.lang.Exception
   29.48 -meth public org.netbeans.modules.java.hints.test.api.HintTest$AppliedFix assertOutput(java.lang.String) throws java.lang.Exception
   29.49 -meth public org.netbeans.modules.java.hints.test.api.HintTest$AppliedFix assertOutput(java.lang.String,java.lang.String) throws java.lang.Exception
   29.50 -meth public org.netbeans.modules.java.hints.test.api.HintTest$AppliedFix assertVerbatimOutput(java.lang.String) throws java.lang.Exception
   29.51 -meth public org.netbeans.modules.java.hints.test.api.HintTest$AppliedFix assertVerbatimOutput(java.lang.String,java.lang.String) throws java.lang.Exception
   29.52 -supr java.lang.Object
   29.53 -
   29.54 -CLSS public final org.netbeans.modules.java.hints.test.api.HintTest$HintOutput
   29.55 - outer org.netbeans.modules.java.hints.test.api.HintTest
   29.56 -meth public !varargs org.netbeans.modules.java.hints.test.api.HintTest$HintOutput assertContainsWarnings(java.lang.String[])
   29.57 -meth public !varargs org.netbeans.modules.java.hints.test.api.HintTest$HintOutput assertNotContainsWarnings(java.lang.String[])
   29.58 -meth public !varargs org.netbeans.modules.java.hints.test.api.HintTest$HintOutput assertWarnings(java.lang.String[])
   29.59 -meth public org.netbeans.modules.java.hints.test.api.HintTest$HintWarning findWarning(java.lang.String)
   29.60 -supr java.lang.Object
   29.61 -hfds errors
   29.62 -
   29.63 -CLSS public final org.netbeans.modules.java.hints.test.api.HintTest$HintWarning
   29.64 - outer org.netbeans.modules.java.hints.test.api.HintTest
   29.65 -meth public !varargs org.netbeans.modules.java.hints.test.api.HintTest$HintWarning assertFixes(java.lang.String[]) throws java.lang.Exception
   29.66 -meth public org.netbeans.modules.java.hints.test.api.HintTest$AppliedFix applyFix() throws java.lang.Exception
   29.67 -meth public org.netbeans.modules.java.hints.test.api.HintTest$AppliedFix applyFix(java.lang.String) throws java.lang.Exception
   29.68 -supr java.lang.Object
   29.69 -hfds warning
   29.70 -
    30.1 --- a/java.hints/java.hints.test/nbproject/project.properties	Sun Oct 16 08:01:27 2016 +0200
    30.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.3 @@ -1,8 +0,0 @@
    30.4 -is.autoload=true
    30.5 -javac.source=1.7
    30.6 -javac.compilerargs=-Xlint -Xlint:-serial
    30.7 -spec.version.base=2.0.0
    30.8 -javadoc.arch=${basedir}/arch.xml
    30.9 -javadoc.apichanges=${basedir}/apichanges.xml
   30.10 -requires.nb.javac=true
   30.11 -spec.version.base.fatal.warning=false
    31.1 --- a/java.hints/java.hints.test/nbproject/project.xml	Sun Oct 16 08:01:27 2016 +0200
    31.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.3 @@ -1,276 +0,0 @@
    31.4 -<?xml version="1.0" encoding="UTF-8"?>
    31.5 -<project xmlns="http://www.netbeans.org/ns/project/1">
    31.6 -    <type>org.netbeans.modules.apisupport.project</type>
    31.7 -    <configuration>
    31.8 -        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
    31.9 -            <code-name-base>org.netbeans.modules.java.hints.test</code-name-base>
   31.10 -            <suite-component/>
   31.11 -            <module-dependencies>
   31.12 -                <dependency>
   31.13 -                    <code-name-base>org.netbeans.api.annotations.common</code-name-base>
   31.14 -                    <build-prerequisite/>
   31.15 -                    <compile-dependency/>
   31.16 -                    <run-dependency>
   31.17 -                        <release-version>1</release-version>
   31.18 -                        <specification-version>1.13</specification-version>
   31.19 -                    </run-dependency>
   31.20 -                </dependency>
   31.21 -                <dependency>
   31.22 -                    <code-name-base>org.netbeans.api.java</code-name-base>
   31.23 -                    <build-prerequisite/>
   31.24 -                    <compile-dependency/>
   31.25 -                    <run-dependency>
   31.26 -                        <release-version>1</release-version>
   31.27 -                        <specification-version>1.37</specification-version>
   31.28 -                    </run-dependency>
   31.29 -                </dependency>
   31.30 -                <dependency>
   31.31 -                    <code-name-base>org.netbeans.api.java.classpath</code-name-base>
   31.32 -                    <build-prerequisite/>
   31.33 -                    <compile-dependency/>
   31.34 -                    <run-dependency>
   31.35 -                        <release-version>1</release-version>
   31.36 -                        <specification-version>1.32</specification-version>
   31.37 -                    </run-dependency>
   31.38 -                </dependency>
   31.39 -                <dependency>
   31.40 -                    <code-name-base>org.netbeans.api.progress</code-name-base>
   31.41 -                    <build-prerequisite/>
   31.42 -                    <compile-dependency/>
   31.43 -                    <run-dependency>
   31.44 -                        <release-version>1</release-version>
   31.45 -                        <specification-version>1.33</specification-version>
   31.46 -                    </run-dependency>
   31.47 -                </dependency>
   31.48 -                <dependency>
   31.49 -                    <code-name-base>org.netbeans.core.startup</code-name-base>
   31.50 -                    <build-prerequisite/>
   31.51 -                    <compile-dependency/>
   31.52 -                    <run-dependency>
   31.53 -                        <release-version>1</release-version>
   31.54 -                        <specification-version>1.41</specification-version>
   31.55 -                    </run-dependency>
   31.56 -                </dependency>
   31.57 -                <dependency>
   31.58 -                    <code-name-base>org.netbeans.libs.javacapi</code-name-base>
   31.59 -                    <build-prerequisite/>
   31.60 -                    <compile-dependency/>
   31.61 -                    <run-dependency>
   31.62 -                        <specification-version>7.9</specification-version>
   31.63 -                    </run-dependency>
   31.64 -                </dependency>
   31.65 -                <dependency>
   31.66 -                    <code-name-base>org.netbeans.libs.junit4</code-name-base>
   31.67 -                    <build-prerequisite/>
   31.68 -                    <compile-dependency/>
   31.69 -                    <run-dependency>
   31.70 -                        <specification-version>1.13</specification-version>
   31.71 -                    </run-dependency>
   31.72 -                </dependency>
   31.73 -                <dependency>
   31.74 -                    <code-name-base>org.netbeans.modules.code.analysis</code-name-base>
   31.75 -                    <build-prerequisite/>
   31.76 -                    <compile-dependency/>
   31.77 -                    <run-dependency>
   31.78 -                        <release-version>0</release-version>
   31.79 -                        <implementation-version/>
   31.80 -                    </run-dependency>
   31.81 -                </dependency>
   31.82 -                <dependency>
   31.83 -                    <code-name-base>org.netbeans.modules.editor.mimelookup</code-name-base>
   31.84 -                    <build-prerequisite/>
   31.85 -                    <compile-dependency/>
   31.86 -                    <run-dependency>
   31.87 -                        <release-version>1</release-version>
   31.88 -                        <specification-version>1.25</specification-version>
   31.89 -                    </run-dependency>
   31.90 -                </dependency>
   31.91 -                <dependency>
   31.92 -                    <code-name-base>org.netbeans.modules.java.lexer</code-name-base>
   31.93 -                    <build-prerequisite/>
   31.94 -                    <compile-dependency/>
   31.95 -                    <run-dependency>
   31.96 -                        <release-version>1</release-version>
   31.97 -                        <specification-version>1.17</specification-version>
   31.98 -                    </run-dependency>
   31.99 -                </dependency>
  31.100 -                <dependency>
  31.101 -                    <code-name-base>org.netbeans.modules.java.source</code-name-base>
  31.102 -                    <build-prerequisite/>
  31.103 -                    <compile-dependency/>
  31.104 -                    <run-dependency>
  31.105 -                        <implementation-version/>
  31.106 -                    </run-dependency>
  31.107 -                </dependency>
  31.108 -                <dependency>
  31.109 -                    <code-name-base>org.netbeans.modules.java.source.base</code-name-base>
  31.110 -                    <build-prerequisite/>
  31.111 -                    <compile-dependency/>
  31.112 -                    <run-dependency>
  31.113 -                        <implementation-version/>
  31.114 -                    </run-dependency>
  31.115 -                </dependency>
  31.116 -                <dependency>
  31.117 -                    <code-name-base>org.netbeans.modules.lexer</code-name-base>
  31.118 -                    <build-prerequisite/>
  31.119 -                    <compile-dependency/>
  31.120 -                    <run-dependency>
  31.121 -                        <release-version>2</release-version>
  31.122 -                        <specification-version>1.43</specification-version>
  31.123 -                    </run-dependency>
  31.124 -                </dependency>
  31.125 -                <dependency>
  31.126 -                    <code-name-base>org.netbeans.modules.nbjunit</code-name-base>
  31.127 -                    <build-prerequisite/>
  31.128 -                    <compile-dependency/>
  31.129 -                    <run-dependency>
  31.130 -                        <release-version>1</release-version>
  31.131 -                        <specification-version>1.74</specification-version>
  31.132 -                    </run-dependency>
  31.133 -                </dependency>
  31.134 -                <dependency>
  31.135 -                    <code-name-base>org.netbeans.modules.parsing.api</code-name-base>
  31.136 -                    <build-prerequisite/>
  31.137 -                    <compile-dependency/>
  31.138 -                    <run-dependency>
  31.139 -                        <release-version>1</release-version>
  31.140 -                        <implementation-version/>
  31.141 -                    </run-dependency>
  31.142 -                </dependency>
  31.143 -                <dependency>
  31.144 -                    <code-name-base>org.netbeans.modules.parsing.indexing</code-name-base>
  31.145 -                    <build-prerequisite/>
  31.146 -                    <compile-dependency/>
  31.147 -                    <run-dependency>
  31.148 -                        <implementation-version/>
  31.149 -                    </run-dependency>
  31.150 -                </dependency>
  31.151 -                <dependency>
  31.152 -                    <code-name-base>org.netbeans.modules.projectapi</code-name-base>
  31.153 -                    <build-prerequisite/>
  31.154 -                    <compile-dependency/>
  31.155 -                    <run-dependency>
  31.156 -                        <release-version>1</release-version>
  31.157 -                        <specification-version>1.41</specification-version>
  31.158 -                    </run-dependency>
  31.159 -                </dependency>
  31.160 -                <dependency>
  31.161 -                    <code-name-base>org.netbeans.modules.projectuiapi</code-name-base>
  31.162 -                    <build-prerequisite/>
  31.163 -                    <compile-dependency/>
  31.164 -                    <run-dependency>
  31.165 -                        <release-version>1</release-version>
  31.166 -                        <specification-version>1.54</specification-version>
  31.167 -                    </run-dependency>
  31.168 -                </dependency>
  31.169 -                <dependency>
  31.170 -                    <code-name-base>org.netbeans.modules.projectuiapi.base</code-name-base>
  31.171 -                    <build-prerequisite/>
  31.172 -                    <compile-dependency/>
  31.173 -                    <run-dependency>
  31.174 -                        <release-version>1</release-version>
  31.175 -                        <specification-version>1.79.0.9</specification-version>
  31.176 -                    </run-dependency>
  31.177 -                </dependency>
  31.178 -                <dependency>
  31.179 -                    <code-name-base>org.netbeans.modules.refactoring.api</code-name-base>
  31.180 -                    <build-prerequisite/>
  31.181 -                    <compile-dependency/>
  31.182 -                    <run-dependency>
  31.183 -                        <specification-version>1.34</specification-version>
  31.184 -                    </run-dependency>
  31.185 -                </dependency>
  31.186 -                <dependency>
  31.187 -                    <code-name-base>org.netbeans.spi.editor.hints</code-name-base>
  31.188 -                    <build-prerequisite/>
  31.189 -                    <compile-dependency/>
  31.190 -                    <run-dependency>
  31.191 -                        <release-version>0-1</release-version>
  31.192 -                        <specification-version>1.22</specification-version>
  31.193 -                    </run-dependency>
  31.194 -                </dependency>
  31.195 -                <dependency>
  31.196 -                    <code-name-base>org.netbeans.spi.java.hints</code-name-base>
  31.197 -                    <build-prerequisite/>
  31.198 -                    <compile-dependency/>
  31.199 -                    <run-dependency>
  31.200 -                        <implementation-version/>
  31.201 -                    </run-dependency>
  31.202 -                </dependency>
  31.203 -                <dependency>
  31.204 -                    <code-name-base>org.openide.filesystems</code-name-base>
  31.205 -                    <build-prerequisite/>
  31.206 -                    <compile-dependency/>
  31.207 -                    <run-dependency>
  31.208 -                        <specification-version>7.55</specification-version>
  31.209 -                    </run-dependency>
  31.210 -                </dependency>
  31.211 -                <dependency>
  31.212 -                    <code-name-base>org.openide.loaders</code-name-base>
  31.213 -                    <build-prerequisite/>
  31.214 -                    <compile-dependency/>
  31.215 -                    <run-dependency>
  31.216 -                        <specification-version>7.33</specification-version>
  31.217 -                    </run-dependency>
  31.218 -                </dependency>
  31.219 -                <dependency>
  31.220 -                    <code-name-base>org.openide.nodes</code-name-base>
  31.221 -                    <build-prerequisite/>
  31.222 -                    <compile-dependency/>
  31.223 -                    <run-dependency>
  31.224 -                        <specification-version>7.26</specification-version>
  31.225 -                    </run-dependency>
  31.226 -                </dependency>
  31.227 -                <dependency>
  31.228 -                    <code-name-base>org.openide.text</code-name-base>
  31.229 -                    <build-prerequisite/>
  31.230 -                    <compile-dependency/>
  31.231 -                    <run-dependency>
  31.232 -                        <specification-version>6.44</specification-version>
  31.233 -                    </run-dependency>
  31.234 -                </dependency>
  31.235 -                <dependency>
  31.236 -                    <code-name-base>org.openide.util</code-name-base>
  31.237 -                    <build-prerequisite/>
  31.238 -                    <compile-dependency/>
  31.239 -                    <run-dependency>
  31.240 -                        <specification-version>8.20</specification-version>
  31.241 -                    </run-dependency>
  31.242 -                </dependency>
  31.243 -                <dependency>
  31.244 -                    <code-name-base>org.openide.util.lookup</code-name-base>
  31.245 -                    <build-prerequisite/>
  31.246 -                    <compile-dependency/>
  31.247 -                    <run-dependency>
  31.248 -                        <specification-version>8.12</specification-version>
  31.249 -                    </run-dependency>
  31.250 -                </dependency>
  31.251 -                <dependency>
  31.252 -                    <code-name-base>org.openide.util.ui</code-name-base>
  31.253 -                    <build-prerequisite/>
  31.254 -                    <compile-dependency/>
  31.255 -                    <run-dependency>
  31.256 -                        <specification-version>9.3</specification-version>
  31.257 -                    </run-dependency>
  31.258 -                </dependency>
  31.259 -            </module-dependencies>
  31.260 -            <test-dependencies>
  31.261 -                <test-type>
  31.262 -                    <name>unit</name>
  31.263 -                    <test-dependency>
  31.264 -                        <code-name-base>org.netbeans.modules.parsing.nb</code-name-base>
  31.265 -                        <recursive/>
  31.266 -                        <compile-dependency/>
  31.267 -                    </test-dependency>
  31.268 -                    <test-dependency>
  31.269 -                        <code-name-base>org.netbeans.modules.projectapi.nb</code-name-base>
  31.270 -                        <compile-dependency/>
  31.271 -                    </test-dependency>
  31.272 -                </test-type>
  31.273 -            </test-dependencies>
  31.274 -            <public-packages>
  31.275 -                <package>org.netbeans.modules.java.hints.test.api</package>
  31.276 -            </public-packages>
  31.277 -        </data>
  31.278 -    </configuration>
  31.279 -</project>
    32.1 --- a/java.hints/java.hints.test/nbproject/suite.properties	Sun Oct 16 08:01:27 2016 +0200
    32.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.3 @@ -1,1 +0,0 @@
    32.4 -suite.dir=${basedir}/..
    33.1 --- a/java.hints/java.hints.test/src/org/netbeans/modules/java/hints/test/Bundle.properties	Sun Oct 16 08:01:27 2016 +0200
    33.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.3 @@ -1,1 +0,0 @@
    33.4 -OpenIDE-Module-Name=Java Hints Test API
    34.1 --- a/java.hints/java.hints.test/src/org/netbeans/modules/java/hints/test/Utilities.java	Sun Oct 16 08:01:27 2016 +0200
    34.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.3 @@ -1,104 +0,0 @@
    34.4 -/*
    34.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    34.6 - *
    34.7 - * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
    34.8 - *
    34.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   34.10 - * Other names may be trademarks of their respective owners.
   34.11 - *
   34.12 - * The contents of this file are subject to the terms of either the GNU
   34.13 - * General Public License Version 2 only ("GPL") or the Common
   34.14 - * Development and Distribution License("CDDL") (collectively, the
   34.15 - * "License"). You may not use this file except in compliance with the
   34.16 - * License. You can obtain a copy of the License at
   34.17 - * http://www.netbeans.org/cddl-gplv2.html
   34.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   34.19 - * specific language governing permissions and limitations under the
   34.20 - * License.  When distributing the software, include this License Header
   34.21 - * Notice in each file and include the License file at
   34.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   34.23 - * particular file as subject to the "Classpath" exception as provided
   34.24 - * by Oracle in the GPL Version 2 section of the License file that
   34.25 - * accompanied this code. If applicable, add the following below the
   34.26 - * License Header, with the fields enclosed by brackets [] replaced by
   34.27 - * your own identifying information:
   34.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   34.29 - *
   34.30 - * If you wish your version of this file to be governed by only the CDDL
   34.31 - * or only the GPL Version 2, indicate your decision by adding
   34.32 - * "[Contributor] elects to include this software in this distribution
   34.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   34.34 - * single choice of license, a recipient has the option to distribute
   34.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   34.36 - * to extend the choice of license to its licensees as provided above.
   34.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   34.38 - * Version 2 license, then the option applies only if the new code is
   34.39 - * made subject to such option by the copyright holder.
   34.40 - *
   34.41 - * Contributor(s):
   34.42 - *
   34.43 - * Portions Copyrighted 2012 Sun Microsystems, Inc.
   34.44 - */
   34.45 -package org.netbeans.modules.java.hints.test;
   34.46 -
   34.47 -import org.netbeans.api.editor.mimelookup.MimePath;
   34.48 -import org.netbeans.modules.java.source.indexing.JavaCustomIndexer;
   34.49 -import org.netbeans.modules.java.source.parsing.JavacParser;
   34.50 -import org.netbeans.modules.java.source.parsing.JavacParserFactory;
   34.51 -import org.netbeans.spi.editor.mimelookup.MimeDataProvider;
   34.52 -import org.openide.filesystems.FileObject;
   34.53 -import org.openide.filesystems.MIMEResolver;
   34.54 -import org.openide.util.Lookup;
   34.55 -import org.openide.util.lookup.Lookups;
   34.56 -import org.openide.util.lookup.ProxyLookup;
   34.57 -import org.openide.util.lookup.ServiceProvider;
   34.58 -
   34.59 -/**
   34.60 - *
   34.61 - * @author lahvac
   34.62 - */
   34.63 -public class Utilities {
   34.64 -
   34.65 -    @ServiceProvider(service = Lookup.class)
   34.66 -    public static final class TestLookup extends ProxyLookup {
   34.67 -
   34.68 -        public void setLookupsImpl(Lookup... lookups) {
   34.69 -            setLookups(lookups);
   34.70 -        }
   34.71 -
   34.72 -    }
   34.73 -
   34.74 -    @ServiceProvider(service=MimeDataProvider.class)
   34.75 -    public static final class JavacParserProvider implements MimeDataProvider {
   34.76 -
   34.77 -        private Lookup javaLookup = Lookups.fixed(new JavacParserFactory(), new JavaCustomIndexer.Factory());
   34.78 -
   34.79 -        public Lookup getLookup(MimePath mimePath) {
   34.80 -            if (mimePath.getPath().endsWith(JavacParser.MIME_TYPE)) {
   34.81 -                return javaLookup;
   34.82 -            }
   34.83 -
   34.84 -            return Lookup.EMPTY;
   34.85 -        }
   34.86 -
   34.87 -    }
   34.88 -
   34.89 -    @ServiceProvider(service=MIMEResolver.class)
   34.90 -    public static final class JavaMimeResolver extends MIMEResolver {
   34.91 -
   34.92 -        public JavaMimeResolver() {
   34.93 -            super(JavacParser.MIME_TYPE);
   34.94 -        }
   34.95 -
   34.96 -        @Override
   34.97 -        public String findMIMEType(FileObject fo) {
   34.98 -            if ("java".equals(fo.getExt())) {
   34.99 -                return JavacParser.MIME_TYPE;
  34.100 -            }
  34.101 -
  34.102 -            return null;
  34.103 -        }
  34.104 -
  34.105 -    }
  34.106 -
  34.107 -}
    35.1 --- a/java.hints/java.hints.test/src/org/netbeans/modules/java/hints/test/api/HintTest.java	Sun Oct 16 08:01:27 2016 +0200
    35.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.3 @@ -1,1427 +0,0 @@
    35.4 -/*
    35.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    35.6 - *
    35.7 - * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
    35.8 - *
    35.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   35.10 - * Other names may be trademarks of their respective owners.
   35.11 - *
   35.12 - * The contents of this file are subject to the terms of either the GNU
   35.13 - * General Public License Version 2 only ("GPL") or the Common
   35.14 - * Development and Distribution License("CDDL") (collectively, the
   35.15 - * "License"). You may not use this file except in compliance with the
   35.16 - * License. You can obtain a copy of the License at
   35.17 - * http://www.netbeans.org/cddl-gplv2.html
   35.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   35.19 - * specific language governing permissions and limitations under the
   35.20 - * License.  When distributing the software, include this License Header
   35.21 - * Notice in each file and include the License file at
   35.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   35.23 - * particular file as subject to the "Classpath" exception as provided
   35.24 - * by Oracle in the GPL Version 2 section of the License file that
   35.25 - * accompanied this code. If applicable, add the following below the
   35.26 - * License Header, with the fields enclosed by brackets [] replaced by
   35.27 - * your own identifying information:
   35.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   35.29 - *
   35.30 - * If you wish your version of this file to be governed by only the CDDL
   35.31 - * or only the GPL Version 2, indicate your decision by adding
   35.32 - * "[Contributor] elects to include this software in this distribution
   35.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   35.34 - * single choice of license, a recipient has the option to distribute
   35.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   35.36 - * to extend the choice of license to its licensees as provided above.
   35.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   35.38 - * Version 2 license, then the option applies only if the new code is
   35.39 - * made subject to such option by the copyright holder.
   35.40 - *
   35.41 - * Contributor(s):
   35.42 - *
   35.43 - * Portions Copyrighted 2012 Sun Microsystems, Inc.
   35.44 - */
   35.45 -package org.netbeans.modules.java.hints.test.api;
   35.46 -
   35.47 -import com.sun.source.tree.CompilationUnitTree;
   35.48 -import com.sun.source.util.TreePath;
   35.49 -import java.io.File;
   35.50 -import java.io.FileInputStream;
   35.51 -import java.io.IOException;
   35.52 -import java.io.OutputStream;
   35.53 -import java.lang.ref.Reference;
   35.54 -import java.lang.ref.WeakReference;
   35.55 -import java.net.URL;
   35.56 -import java.util.ArrayList;
   35.57 -import java.util.Arrays;
   35.58 -import java.util.Collection;
   35.59 -import java.util.Collections;
   35.60 -import java.util.Comparator;
   35.61 -import java.util.Enumeration;
   35.62 -import java.util.HashMap;
   35.63 -import java.util.HashSet;
   35.64 -import java.util.IdentityHashMap;
   35.65 -import java.util.LinkedList;
   35.66 -import java.util.List;
   35.67 -import java.util.Map;
   35.68 -import java.util.Map.Entry;
   35.69 -import java.util.Properties;
   35.70 -import java.util.Set;
   35.71 -import java.util.concurrent.atomic.AtomicBoolean;
   35.72 -import java.util.logging.Handler;
   35.73 -import java.util.logging.Level;
   35.74 -import java.util.logging.LogRecord;
   35.75 -import java.util.logging.Logger;
   35.76 -import java.util.prefs.AbstractPreferences;
   35.77 -import java.util.prefs.BackingStoreException;
   35.78 -import java.util.prefs.Preferences;
   35.79 -import java.util.regex.Pattern;
   35.80 -import javax.swing.event.ChangeListener;
   35.81 -import javax.swing.text.Document;
   35.82 -import javax.tools.Diagnostic;
   35.83 -import junit.framework.Assert;
   35.84 -import static junit.framework.Assert.assertEquals;
   35.85 -import static junit.framework.Assert.assertFalse;
   35.86 -import static junit.framework.Assert.assertNotNull;
   35.87 -import static junit.framework.Assert.assertNotSame;
   35.88 -import static junit.framework.Assert.assertTrue;
   35.89 -
   35.90 -import org.netbeans.api.editor.mimelookup.MimeLookup;
   35.91 -import org.netbeans.api.java.classpath.ClassPath;
   35.92 -import org.netbeans.api.java.lexer.JavaTokenId;
   35.93 -import org.netbeans.api.java.queries.SourceForBinaryQuery;
   35.94 -import org.netbeans.api.java.source.ClasspathInfo;
   35.95 -import org.netbeans.api.java.source.CompilationController;
   35.96 -import org.netbeans.api.java.source.CompilationInfo;
   35.97 -import org.netbeans.api.java.source.JavaSource;
   35.98 -import org.netbeans.api.java.source.JavaSource.Phase;
   35.99 -import org.netbeans.api.java.source.ModificationResult;
  35.100 -import org.netbeans.api.java.source.ModificationResult.Difference;
  35.101 -import org.netbeans.api.java.source.Task;
  35.102 -import org.netbeans.api.java.source.WorkingCopy;
  35.103 -import org.netbeans.api.lexer.Language;
  35.104 -import org.netbeans.api.project.ui.*;
  35.105 -import org.netbeans.core.startup.Main;
  35.106 -import org.netbeans.junit.NbTestCase;
  35.107 -import org.netbeans.modules.java.JavaDataLoader;
  35.108 -import org.netbeans.modules.java.hints.providers.code.CodeHintProviderImpl;
  35.109 -import org.netbeans.modules.java.hints.providers.code.FSWrapper;
  35.110 -import org.netbeans.modules.java.hints.providers.code.FSWrapper.ClassWrapper;
  35.111 -import org.netbeans.modules.java.hints.providers.spi.HintDescription;
  35.112 -import org.netbeans.modules.java.hints.providers.spi.HintDescription.Worker;
  35.113 -import org.netbeans.modules.java.hints.providers.spi.HintDescriptionFactory;
  35.114 -import org.netbeans.modules.java.hints.providers.spi.HintMetadata;
  35.115 -import org.netbeans.modules.java.hints.providers.spi.HintMetadata.Options;
  35.116 -import org.netbeans.modules.java.hints.spiimpl.JavaFixImpl;
  35.117 -import org.netbeans.modules.java.hints.spiimpl.JavaFixImpl.Accessor;
  35.118 -import org.netbeans.modules.java.hints.spiimpl.MessageImpl;
  35.119 -import org.netbeans.modules.java.hints.spiimpl.SyntheticFix;
  35.120 -import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch;
  35.121 -import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.BatchResult;
  35.122 -import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.Folder;
  35.123 -import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.Resource;
  35.124 -import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.Scope;
  35.125 -import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.VerifiedSpansCallBack;
  35.126 -import org.netbeans.modules.java.hints.spiimpl.batch.BatchUtilities;
  35.127 -import org.netbeans.modules.java.hints.spiimpl.batch.ProgressHandleWrapper;
  35.128 -import org.netbeans.modules.java.hints.spiimpl.batch.Scopes;
  35.129 -import org.netbeans.modules.java.hints.spiimpl.hints.HintsInvoker;
  35.130 -import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings;
  35.131 -import org.netbeans.modules.java.hints.test.Utilities.TestLookup;
  35.132 -import org.netbeans.modules.java.source.JavaSourceAccessor;
  35.133 -import org.netbeans.modules.java.source.TreeLoader;
  35.134 -import org.netbeans.modules.parsing.api.indexing.IndexingManager;
  35.135 -import org.netbeans.modules.parsing.impl.indexing.CacheFolder;
  35.136 -import org.netbeans.modules.parsing.impl.indexing.MimeTypes;
  35.137 -import org.netbeans.modules.refactoring.spi.RefactoringElementImplementation;
  35.138 -import org.netbeans.spi.editor.hints.ErrorDescription;
  35.139 -import org.netbeans.spi.editor.hints.Fix;
  35.140 -import org.netbeans.spi.editor.hints.Severity;
  35.141 -import org.netbeans.spi.java.classpath.ClassPathProvider;
  35.142 -import org.netbeans.spi.java.classpath.support.ClassPathSupport;
  35.143 -import org.netbeans.spi.java.hints.Hint.Kind;
  35.144 -import org.netbeans.spi.java.hints.HintContext;
  35.145 -import org.netbeans.spi.java.hints.JavaFix;
  35.146 -import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation;
  35.147 -import org.netbeans.spi.java.queries.SourceLevelQueryImplementation;
  35.148 -import org.openide.LifecycleManager;
  35.149 -import org.openide.cookies.EditorCookie;
  35.150 -import org.openide.filesystems.FileObject;
  35.151 -import org.openide.filesystems.FileStateInvalidException;
  35.152 -import org.openide.filesystems.FileSystem;
  35.153 -import org.openide.filesystems.FileUtil;
  35.154 -import org.openide.filesystems.MultiFileSystem;
  35.155 -import org.openide.filesystems.Repository;
  35.156 -import org.openide.filesystems.URLMapper;
  35.157 -import org.openide.filesystems.XMLFileSystem;
  35.158 -import org.openide.loaders.DataObject;
  35.159 -import org.openide.loaders.DataObjectNotFoundException;
  35.160 -import org.openide.util.Exceptions;
  35.161 -import org.openide.util.Lookup;
  35.162 -import org.openide.util.NbBundle;
  35.163 -import org.openide.util.lookup.Lookups;
  35.164 -
  35.165 -/**A support class for writing a test for a Java Hint. A test verifying that correct
  35.166 - * warnings are produced should look like:
  35.167 - * <pre>
  35.168 - * HintTest.create()
  35.169 - *         .input("&lt;input Java source code>")
  35.170 - *         .run(&lt;class containg the hint>)
  35.171 - *         .assertWarnings("&lt;required warning(s)>");
  35.172 - * </pre>
  35.173 - *
  35.174 - * Note: when verifying that no warnings are produced in a particular situation,
  35.175 - * do not pass any warnings to the {@code assertWarnings} method.
  35.176 - *
  35.177 - * A test verifying that a hint's transformation is correct:
  35.178 - * <pre>
  35.179 - * HintTest.create()
  35.180 - *         .input("&lt;input Java source code>")
  35.181 - *         .run(&lt;class containg the hint>)
  35.182 - *         .findWarning("&lt;a warning produce by the hint>")
  35.183 - *         .applyFix() //fill apply the only fix in the given ErrorDescription
  35.184 - *         .assertCompilable()
  35.185 - *         .assertOutput("&lt;output Java source code>");
  35.186 - * </pre>
  35.187 - *
  35.188 - * All the tests run under the {@code test} branding, which allows to specify test values
  35.189 - * for bundle keys for warning and fix in {@code Bundle_test.properties}, to isolate the
  35.190 - * test from changes in the production {@code Bundle.properties}.
  35.191 - *
  35.192 - * @author lahvac
  35.193 - */
  35.194 -public class HintTest {
  35.195 -
  35.196 -    private static final Logger INDEXING_LOGGER = /* RepositoryUpdater.UI_LOGGER */ Logger.getLogger("org.netbeans.ui.indexing");
  35.197 -    static {
  35.198 -        INDEXING_LOGGER.setLevel(Level.WARNING);
  35.199 -    }
  35.200 -
  35.201 -    private final File workDir;
  35.202 -    private final FileObject sourceRoot;
  35.203 -    private final FileObject buildRoot;
  35.204 -    private final FileObject cache;
  35.205 -    private final Preferences testPreferences;
  35.206 -    private final HintsSettings hintSettings;
  35.207 -    private final List<FileObject> checkCompilable = new ArrayList<FileObject>();
  35.208 -    private final List<FileObject> testFiles = new ArrayList<FileObject>();
  35.209 -    private String sourceLevel = "1.5";
  35.210 -    private Character caretMarker;
  35.211 -    private FileObject testFile;
  35.212 -    private int caret = -1;
  35.213 -    private ClassPath sourcePath;
  35.214 -    private ClassPath compileClassPath = ClassPathSupport.createClassPath(new URL[0]);
  35.215 -
  35.216 -    private HintTest() throws Exception {
  35.217 -        List<URL> layers = new LinkedList<URL>();
  35.218 -
  35.219 -        for (String layer : new String[] {"META-INF/generated-layer.xml"}) {
  35.220 -            boolean found = false;
  35.221 -
  35.222 -            for (Enumeration<URL> en = Thread.currentThread().getContextClassLoader().getResources(layer); en.hasMoreElements(); ) {
  35.223 -                found = true;
  35.224 -                layers.add(en.nextElement());
  35.225 -            }
  35.226 -
  35.227 -            Assert.assertTrue(layer, found);
  35.228 -        }
  35.229 -
  35.230 -        XMLFileSystem xmlFS = new XMLFileSystem();
  35.231 -        xmlFS.setXmlUrls(layers.toArray(new URL[0]));
  35.232 -
  35.233 -        FileSystem system = new MultiFileSystem(new FileSystem[] {FileUtil.createMemoryFileSystem(), xmlFS});
  35.234 -
  35.235 -        Repository repository = new Repository(system);
  35.236 -
  35.237 -        assertEquals(Lookup.getDefault().getClass().getCanonicalName(), TestLookup.class, Lookup.getDefault().getClass());
  35.238 -
  35.239 -        ((TestLookup) Lookup.getDefault()).setLookupsImpl(
  35.240 -            Lookups.fixed(repository,
  35.241 -                          new TestProxyClassPathProvider(),
  35.242 -                          new TestSourceForBinaryQuery(),
  35.243 -                          new TestSourceLevelQueryImplementation(),
  35.244 -                          JavaDataLoader.findObject(JavaDataLoader.class, true)),
  35.245 -            Lookups.metaInfServices(HintTest.class.getClassLoader()),
  35.246 -            Lookups.singleton(HintTest.class.getClassLoader())
  35.247 -        );
  35.248 -
  35.249 -        Set<String> amt = MimeTypes.getAllMimeTypes();
  35.250 -        if (amt == null) {
  35.251 -            amt = new HashSet<String>();
  35.252 -        } else {
  35.253 -            amt = new HashSet<String>(amt);
  35.254 -        }
  35.255 -        amt.add("text/x-java");
  35.256 -        MimeTypes.setAllMimeTypes(amt);
  35.257 -        org.netbeans.api.project.ui.OpenProjects.getDefault().getOpenProjects();
  35.258 -
  35.259 -        TreeLoader.DISABLE_CONFINEMENT_TEST = true;
  35.260 -        testPreferences = new TempPreferences();
  35.261 -        hintSettings = new HintsSettings() {
  35.262 -            @Override public boolean isEnabled(HintMetadata hint) {
  35.263 -                return true;
  35.264 -            }
  35.265 -            @Override public void setEnabled(HintMetadata hint, boolean value) {
  35.266 -                throw new UnsupportedOperationException("Not supported.");
  35.267 -            }
  35.268 -            @Override public Preferences getHintPreferences(HintMetadata hint) {
  35.269 -                return testPreferences;
  35.270 -            }
  35.271 -            @Override public Severity getSeverity(HintMetadata hint) {
  35.272 -                return hint.severity;
  35.273 -            }
  35.274 -            @Override public void setSeverity(HintMetadata hint, Severity severity) {
  35.275 -                throw new UnsupportedOperationException("Not supported.");
  35.276 -            }
  35.277 -        };
  35.278 -
  35.279 -        workDir = getWorkDir();
  35.280 -        deleteSubFiles(workDir);
  35.281 -        FileUtil.refreshFor(workDir);
  35.282 -
  35.283 -        FileObject wd = FileUtil.toFileObject(workDir);
  35.284 -        
  35.285 -        assertNotNull(wd);
  35.286 -
  35.287 -        sourceRoot = FileUtil.createFolder(wd, "src");
  35.288 -        buildRoot = FileUtil.createFolder(wd, "build");
  35.289 -        cache = FileUtil.createFolder(wd, "cache");
  35.290 -
  35.291 -        CacheFolder.setCacheFolder(cache);
  35.292 -
  35.293 -        NbBundle.setBranding("test");
  35.294 -
  35.295 -        sourcePath = ClassPathSupport.createClassPath(sourceRoot);
  35.296 -        
  35.297 -        Main.initializeURLFactory();
  35.298 -    }
  35.299 -
  35.300 -    /**Bootstraps the test framework.
  35.301 -     *
  35.302 -     * @return the test framework - call more methods on it to set-up a test, then call {@code run} method and assert results.
  35.303 -     */
  35.304 -    public static HintTest create() throws Exception {
  35.305 -        return new HintTest();
  35.306 -    }
  35.307 -
  35.308 -    /**A character to use as a marker of a caret in the input code. The caret position
  35.309 -     * during the run method will be set to the position of this character in the first input file.
  35.310 -     *
  35.311 -     * @param c a caret marker
  35.312 -     * @return itself
  35.313 -     */
  35.314 -    public HintTest setCaretMarker(char c) {
  35.315 -        this.caretMarker = c;
  35.316 -        return this;
  35.317 -    }
  35.318 -
  35.319 -    /**Use the specified {@link java.net.URL}s as compile classpath while parsing
  35.320 -     * the Java input. The {@link java.net.URL}s need to be "folder" {@link java.net.URL}s,
  35.321 -     * ready to be passed to {@link ClassPathSupport#createClassPath(java.net.URL[]) }.
  35.322 -     *
  35.323 -     * @param entries that should become roots of the compile classpath
  35.324 -     * @return itself
  35.325 -     * @see FileUtil#urlForArchiveOrDir(java.io.File)
  35.326 -     * @see FileUtil#getArchiveRoot(java.net.URL)
  35.327 -     */
  35.328 -    public HintTest classpath(URL... entries) {
  35.329 -        compileClassPath = ClassPathSupport.createClassPath(entries);
  35.330 -        return this;
  35.331 -    }
  35.332 -
  35.333 -    /**Create a test file. Equivalent to calling {@code input("test/Test.java", code, true)}.
  35.334 -     *
  35.335 -     * @param code the content of the newly created test file
  35.336 -     * @return itself
  35.337 -     */
  35.338 -    public HintTest input(String code) throws Exception {
  35.339 -        return input("test/Test.java", code, true);
  35.340 -    }
  35.341 -
  35.342 -    /**Create a test file. Equivalent to calling {@code input("test/Test.java", code, compilable)}.
  35.343 -     *
  35.344 -     * @param code the content of the newly created test file
  35.345 -     * @param compilable if true, it will be verified that the file does not contain
  35.346 -     *                   compilation errors before the hint is run on it
  35.347 -     * @return itself
  35.348 -     */
  35.349 -    public HintTest input(String code, boolean compilable) throws Exception {
  35.350 -        return input("test/Test.java", code, compilable);
  35.351 -    }
  35.352 -
  35.353 -    /**Create a test file. Equivalent to calling {@code input(fileName, code, true)}.
  35.354 -     *
  35.355 -     * @param fileName a relative file name of the newly created file from a (automatically created) source root
  35.356 -     * @param code the content of the newly created test file
  35.357 -     * @return itself
  35.358 -     */
  35.359 -    public HintTest input(String fileName, String code) throws Exception {
  35.360 -        return input(fileName, code, true);
  35.361 -    }
  35.362 -    
  35.363 -    /**Create a test file. Any number of files can be created for one test, but the hint
  35.364 -     * will be run only on the first one.
  35.365 -     *
  35.366 -     * @param fileName a relative file name of the newly created file from a (automatically created) source root
  35.367 -     * @param code the content of the newly created test file
  35.368 -     * @param compilable if true, it will be verified that the file does not contain
  35.369 -     *                   compilation errors before the hint is run on it
  35.370 -     * @return itself
  35.371 -     */
  35.372 -    public HintTest input(String fileName, String code, boolean compilable) throws Exception {
  35.373 -        int caret = -1;
  35.374 -
  35.375 -        if (caretMarker != null && testFile == null) {
  35.376 -            caret = code.indexOf(caretMarker);
  35.377 -
  35.378 -            assertNotSame("A caret location must be specified", -1, caret);
  35.379 -
  35.380 -            code = code.substring(0, caret) + code.substring(caret + 1);
  35.381 -        }
  35.382 -
  35.383 -        FileObject file = FileUtil.createData(sourceRoot, fileName);
  35.384 -
  35.385 -        copyStringToFile(file, code);
  35.386 -
  35.387 -        if (compilable) {
  35.388 -            checkCompilable.add(file);
  35.389 -        }
  35.390 -
  35.391 -        if (testFile == null) {
  35.392 -            testFile = file;
  35.393 -            this.caret = caret;
  35.394 -        }
  35.395 -        
  35.396 -        testFiles.add(file);
  35.397 -        
  35.398 -        return this;
  35.399 -    }
  35.400 -
  35.401 -    private void ensureCompilable(FileObject file) throws IOException, AssertionError, IllegalArgumentException {
  35.402 -        CompilationInfo info = parse(file);
  35.403 -
  35.404 -        assertNotNull(info);
  35.405 -
  35.406 -        for (Diagnostic d : info.getDiagnostics()) {
  35.407 -            if (d.getKind() == Diagnostic.Kind.ERROR)
  35.408 -                throw new AssertionError(d.getLineNumber() + ":" + d.getColumnNumber() + " " + d.getMessage(null));
  35.409 -        }
  35.410 -    }
  35.411 -
  35.412 -    /**Sets a source level for all Java files used in this test.
  35.413 -     *
  35.414 -     * @param sourceLevel the source level to use while parsing Java files
  35.415 -     * @return itself
  35.416 -     */
  35.417 -    public HintTest sourceLevel(String sourceLevel) {
  35.418 -        this.sourceLevel = sourceLevel;
  35.419 -        return this;
  35.420 -    }
  35.421 -
  35.422 -    /**Sets a preference that will be visible to the hint.
  35.423 -     *
  35.424 -     * @param preferencesKey a key for the preferences
  35.425 -     * @param value the value to set
  35.426 -     * @return itself
  35.427 -     */
  35.428 -    public HintTest preference(String preferencesKey, String value) {
  35.429 -        this.testPreferences.put(preferencesKey, value);
  35.430 -        return this;
  35.431 -    }
  35.432 -
  35.433 -    /**Sets a preference that will be visible to the hint.
  35.434 -     *
  35.435 -     * @param preferencesKey a key for the preferences
  35.436 -     * @param value the value to set
  35.437 -     * @return itself
  35.438 -     */
  35.439 -    public HintTest preference(String preferencesKey, int value) {
  35.440 -        this.testPreferences.putInt(preferencesKey, value);
  35.441 -        return this;
  35.442 -    }
  35.443 -
  35.444 -    /**Sets a preference that will be visible to the hint.
  35.445 -     *
  35.446 -     * @param preferencesKey a key for the preferences
  35.447 -     * @param value the value to set
  35.448 -     * @return itself
  35.449 -     */
  35.450 -    public HintTest preference(String preferencesKey, boolean value) {
  35.451 -        this.testPreferences.putBoolean(preferencesKey, value);
  35.452 -        return this;
  35.453 -    }
  35.454 -    
  35.455 -    /**Runs the given hint(s) on the first file written by a {@code input} method.
  35.456 -     *
  35.457 -     * @param hint all hints in this class will be run on the file
  35.458 -     * @return a wrapper over the hint output that allows verifying results of the hint
  35.459 -     */
  35.460 -    public HintOutput run(Class<?> hint) throws Exception {
  35.461 -        return run(hint, null);
  35.462 -    }
  35.463 -
  35.464 -    /**Runs the given hint(s) on the first file written by a {@code input} method.
  35.465 -     * Runs only hints with the specified {@code hintCode}. Null hintCode includes
  35.466 -     * all hints from the class
  35.467 -     *
  35.468 -     * @param hint all hints in this class will be run on the file
  35.469 -     * @param hintCode if not {@code null}, only hints with the same id will be run
  35.470 -     * @return a wrapper over the hint output that allows verifying results of the hint
  35.471 -     */
  35.472 -    public HintOutput run(Class<?> hint, String hintCode) throws Exception {
  35.473 -        return runImpl(hint, hintCode, new HintComputer() {
  35.474 -            @Override public Collection<ErrorDescription> computeHints(List<HintDescription> total) throws Exception {
  35.475 -                CompilationInfo info = parse(testFile);
  35.476 -
  35.477 -                assertNotNull(info);
  35.478 -
  35.479 -                List<ErrorDescription> result = new ArrayList<ErrorDescription>();
  35.480 -
  35.481 -                Map<HintDescription, List<ErrorDescription>> errors = computeErrors(info, total, new AtomicBoolean());
  35.482 -
  35.483 -                for (Entry<HintDescription, List<ErrorDescription>> e : errors.entrySet()) {
  35.484 -                    result.addAll(e.getValue());
  35.485 -                }
  35.486 -
  35.487 -                Reference<CompilationInfo> infoRef = new WeakReference<CompilationInfo>(info);
  35.488 -                Reference<CompilationUnitTree> cut = new WeakReference<CompilationUnitTree>(info.getCompilationUnit());
  35.489 -
  35.490 -                info = null;
  35.491 -
  35.492 -                DEBUGGING_HELPER.add(result);
  35.493 -                NbTestCase.assertGC("noone holds CompilationInfo", infoRef);
  35.494 -                NbTestCase.assertGC("noone holds javac", cut);
  35.495 -                DEBUGGING_HELPER.remove(result);
  35.496 -
  35.497 -                return result;
  35.498 -            }
  35.499 -        });
  35.500 -    }
  35.501 -
  35.502 -    private HintOutput runImpl(Class<?> hint, String hintCode, HintComputer doComputeErrors) throws Exception {
  35.503 -        IndexingManager.getDefault().refreshIndexAndWait(sourceRoot.toURL(), null);
  35.504 -        
  35.505 -        for (FileObject file : checkCompilable) {
  35.506 -            ensureCompilable(file);
  35.507 -        }
  35.508 -        
  35.509 -        Map<HintMetadata, Collection<HintDescription>> hints = new HashMap<HintMetadata, Collection<HintDescription>>();
  35.510 -        List<ClassWrapper> found = new ArrayList<ClassWrapper>();
  35.511 -
  35.512 -        for (ClassWrapper w : FSWrapper.listClasses()) {
  35.513 -            if (hint.getCanonicalName().equals(w.getName().replace('$', '.'))) {
  35.514 -                found.add(w);
  35.515 -            }
  35.516 -        }
  35.517 -
  35.518 -        assertFalse(found.isEmpty());
  35.519 -
  35.520 -        for (ClassWrapper w : found) {
  35.521 -            CodeHintProviderImpl.processClass(w, hints);
  35.522 -        }
  35.523 -
  35.524 -        List<HintDescription> total = new LinkedList<HintDescription>();
  35.525 -        final Set<ErrorDescription> requiresJavaFix = Collections.newSetFromMap(new IdentityHashMap<ErrorDescription, Boolean>());
  35.526 -
  35.527 -        for (final Entry<HintMetadata, Collection<HintDescription>> e : hints.entrySet()) {
  35.528 -            if (null != hintCode && !e.getKey().id.equals(hintCode)) {
  35.529 -                continue;
  35.530 -            }
  35.531 -            if (   e.getKey().options.contains(Options.NO_BATCH)
  35.532 -                || e.getKey().options.contains(Options.QUERY)
  35.533 -                || e.getKey().kind == Kind.ACTION) {
  35.534 -                total.addAll(e.getValue());
  35.535 -                continue;
  35.536 -            }
  35.537 -            for (final HintDescription hd : e.getValue()) {
  35.538 -                total.add(HintDescriptionFactory.create()
  35.539 -                                               .setTrigger(hd.getTrigger())
  35.540 -                                               .setMetadata(e.getKey())
  35.541 -                                               .setAdditionalConstraints(hd.getAdditionalConstraints())
  35.542 -                                               .addOptions(hd.getOptions().toArray(new Options[0]))
  35.543 -                                               .setWorker(new Worker() {
  35.544 -                                                    @Override public Collection<? extends ErrorDescription> createErrors(HintContext ctx) {
  35.545 -                                                        Collection<? extends ErrorDescription> errors = hd.getWorker().createErrors(ctx);
  35.546 - 
  35.547 -                                                        if (errors != null) {
  35.548 -                                                            for (ErrorDescription ed : errors) {
  35.549 -                                                                requiresJavaFix.add(ed);
  35.550 -                                                            }
  35.551 -                                                        }
  35.552 -                                                        
  35.553 -                                                        return errors;
  35.554 -                                                     }
  35.555 -                                                })
  35.556 -                                              .produce());
  35.557 -            }
  35.558 -        }
  35.559 -        
  35.560 -        Handler h = new Handler() {
  35.561 -            @Override public void publish(LogRecord record) {
  35.562 -                if (   record.getLevel().intValue() >= Level.WARNING.intValue()
  35.563 -                    && record.getThrown() != null) {
  35.564 -                    throw new IllegalStateException(record.getThrown());
  35.565 -                }
  35.566 -            }
  35.567 -            @Override public void flush() { }
  35.568 -            @Override public void close() throws SecurityException { }
  35.569 -        };
  35.570 -
  35.571 -        Logger log = Logger.getLogger(Exceptions.class.getName());
  35.572 -        log.addHandler(h);
  35.573 -        List<ErrorDescription> result = new ArrayList<ErrorDescription>(doComputeErrors.computeHints(total));
  35.574 -        log.removeHandler(h);
  35.575 -
  35.576 -        Collections.sort(result, ERRORS_COMPARATOR);
  35.577 -        
  35.578 -        return new HintOutput(result, requiresJavaFix);
  35.579 -    }
  35.580 -
  35.581 -    private interface HintComputer {
  35.582 -        public Collection<ErrorDescription> computeHints(List<HintDescription> total) throws Exception;
  35.583 -    }
  35.584 -    
  35.585 -    public HintOutput runGlobal(Class<?> hint) throws Exception {
  35.586 -        return runImpl(hint, null, new HintComputer() {
  35.587 -            @Override public Collection<ErrorDescription> computeHints(List<HintDescription> total) throws Exception {
  35.588 -                final List<ErrorDescription> result = new ArrayList<ErrorDescription>();
  35.589 -                Scope s = Scopes.specifiedFoldersScope(Folder.convert(sourceRoot));
  35.590 -                BatchResult batchResult = BatchSearch.findOccurrences(total, s);
  35.591 -                BatchSearch.getVerifiedSpans(batchResult, new ProgressHandleWrapper(1, 1), new VerifiedSpansCallBack() {
  35.592 -                    @Override public void groupStarted() { }
  35.593 -                    @Override public boolean spansVerified(CompilationController wc, Resource r, Collection<? extends ErrorDescription> hints) throws Exception {
  35.594 -                        result.addAll(hints);
  35.595 -                        return true;
  35.596 -                    }
  35.597 -                    @Override public void groupFinished() { }
  35.598 -                    @Override public void cannotVerifySpan(Resource r) { }
  35.599 -                }, false, new ArrayList<MessageImpl>(), new AtomicBoolean());
  35.600 -
  35.601 -                return result;
  35.602 -            }
  35.603 -        });
  35.604 -    }
  35.605 -    
  35.606 -    //must keep the error descriptions (and their Fixes through them) in a field
  35.607 -    //so that assertGC is able to provide a useful trace of references:
  35.608 -    private static Set<List<ErrorDescription>> DEBUGGING_HELPER = Collections.newSetFromMap(new IdentityHashMap<List<ErrorDescription>, Boolean>());
  35.609 -
  35.610 -    private CompilationInfo parse(FileObject file) throws DataObjectNotFoundException, IllegalArgumentException, IOException {
  35.611 -        DataObject od = DataObject.find(file);
  35.612 -        EditorCookie ec = od.getLookup().lookup(EditorCookie.class);
  35.613 -
  35.614 -        assertNotNull(ec);
  35.615 -
  35.616 -        Document doc = ec.openDocument();
  35.617 -
  35.618 -        doc.putProperty(Language.class, JavaTokenId.language());
  35.619 -        doc.putProperty("mimeType", "text/x-java");
  35.620 -
  35.621 -        JavaSource js = JavaSource.create(ClasspathInfo.create(file), file);
  35.622 -
  35.623 -        assertNotNull("found JavaSource for " + file, js);
  35.624 -
  35.625 -        final DeadlockTask bt = new DeadlockTask(Phase.RESOLVED);
  35.626 -
  35.627 -        js.runUserActionTask(bt, true);
  35.628 -        
  35.629 -        return bt.info;
  35.630 -    }
  35.631 -
  35.632 -    private Map<HintDescription, List<ErrorDescription>> computeErrors(CompilationInfo info, Iterable<? extends HintDescription> hints, AtomicBoolean cancel) {
  35.633 -        return new HintsInvoker(hintSettings, caret, cancel).computeHints(info, new TreePath(info.getCompilationUnit()), hints, new LinkedList<MessageImpl>());
  35.634 -    }
  35.635 -
  35.636 -    FileObject getSourceRoot() {
  35.637 -        return sourceRoot;
  35.638 -    }
  35.639 -
  35.640 -    private static class TempPreferences extends AbstractPreferences {
  35.641 -
  35.642 -        /*private*/Properties properties;
  35.643 -
  35.644 -        private TempPreferences() {
  35.645 -            super(null, "");
  35.646 -        }
  35.647 -
  35.648 -        private  TempPreferences(TempPreferences parent, String name)  {
  35.649 -            super(parent, name);
  35.650 -            newNode = true;
  35.651 -        }
  35.652 -
  35.653 -        protected final String getSpi(String key) {
  35.654 -            return properties().getProperty(key);
  35.655 -        }
  35.656 -
  35.657 -        protected final String[] childrenNamesSpi() throws BackingStoreException {
  35.658 -            return new String[0];
  35.659 -        }
  35.660 -
  35.661 -        protected final String[] keysSpi() throws BackingStoreException {
  35.662 -            return properties().keySet().toArray(new String[0]);
  35.663 -        }
  35.664 -
  35.665 -        protected final void putSpi(String key, String value) {
  35.666 -            properties().put(key,value);
  35.667 -        }
  35.668 -
  35.669 -        protected final void removeSpi(String key) {
  35.670 -            properties().remove(key);
  35.671 -        }
  35.672 -
  35.673 -        protected final void removeNodeSpi() throws BackingStoreException {}
  35.674 -        protected  void flushSpi() throws BackingStoreException {}
  35.675 -        protected void syncSpi() throws BackingStoreException {
  35.676 -            properties().clear();
  35.677 -        }
  35.678 -
  35.679 -        @Override
  35.680 -        public void put(String key, String value) {
  35.681 -            try {
  35.682 -                super.put(key, value);
  35.683 -            } catch (IllegalArgumentException iae) {
  35.684 -                if (iae.getMessage().contains("too long")) {
  35.685 -                    // Not for us!
  35.686 -                    putSpi(key, value);
  35.687 -                } else {
  35.688 -                    throw iae;
  35.689 -                }
  35.690 -            }
  35.691 -        }
  35.692 -
  35.693 -        Properties properties()  {
  35.694 -            if (properties == null) {
  35.695 -                properties = new Properties();
  35.696 -            }
  35.697 -            return properties;
  35.698 -        }
  35.699 -
  35.700 -        protected AbstractPreferences childSpi(String name) {
  35.701 -            return new TempPreferences(this, name);
  35.702 -        }
  35.703 -    }
  35.704 -
  35.705 -    private class TestSourceForBinaryQuery implements SourceForBinaryQueryImplementation {
  35.706 -
  35.707 -        public SourceForBinaryQuery.Result findSourceRoots(URL binaryRoot) {
  35.708 -            FileObject f = URLMapper.findFileObject(binaryRoot);
  35.709 -
  35.710 -            if (buildRoot.equals(f)) {
  35.711 -                return new SourceForBinaryQuery.Result() {
  35.712 -                    public FileObject[] getRoots() {
  35.713 -                        return new FileObject[] {
  35.714 -                            sourceRoot,
  35.715 -                        };
  35.716 -                    }
  35.717 -
  35.718 -                    public void addChangeListener(ChangeListener l) {
  35.719 -                    }
  35.720 -
  35.721 -                    public void removeChangeListener(ChangeListener l) {
  35.722 -                    }
  35.723 -                };
  35.724 -            }
  35.725 -
  35.726 -            return null;
  35.727 -        }
  35.728 -
  35.729 -    }
  35.730 -
  35.731 -    private static List<URL> bootClassPath;
  35.732 -
  35.733 -    private static Logger log = Logger.getLogger(HintTest.class.getName());
  35.734 -
  35.735 -    private static synchronized List<URL> getBootClassPath() {
  35.736 -        if (bootClassPath == null) {
  35.737 -            try {
  35.738 -                String cp = System.getProperty("sun.boot.class.path");
  35.739 -                List<URL> urls = new ArrayList<URL>();
  35.740 -                String[] paths = cp.split(Pattern.quote(System.getProperty("path.separator")));
  35.741 -
  35.742 -                for (String path : paths) {
  35.743 -                    File f = new File(path);
  35.744 -
  35.745 -                    if (!f.canRead())
  35.746 -                        continue;
  35.747 -
  35.748 -                    FileObject fo = FileUtil.toFileObject(f);
  35.749 -
  35.750 -                    if (FileUtil.isArchiveFile(fo)) {
  35.751 -                        fo = FileUtil.getArchiveRoot(fo);
  35.752 -                    }
  35.753 -
  35.754 -                    if (fo != null) {
  35.755 -                        urls.add(fo.getURL());
  35.756 -                    }
  35.757 -                }
  35.758 -
  35.759 -                bootClassPath = urls;
  35.760 -            } catch (FileStateInvalidException e) {
  35.761 -                if (log.isLoggable(Level.SEVERE))
  35.762 -                    log.log(Level.SEVERE, e.getMessage(), e);
  35.763 -            }
  35.764 -        }
  35.765 -
  35.766 -        return bootClassPath;
  35.767 -    }
  35.768 -    
  35.769 -    private class TestProxyClassPathProvider implements ClassPathProvider {
  35.770 -
  35.771 -        public ClassPath findClassPath(FileObject file, String type) {
  35.772 -            try {
  35.773 -            if (ClassPath.BOOT == type) {
  35.774 -                // XXX simpler to use JavaPlatformManager.getDefault().getDefaultPlatform().getBootstrapLibraries()
  35.775 -                return ClassPathSupport.createClassPath(getBootClassPath().toArray(new URL[0]));
  35.776 -            }
  35.777 -
  35.778 -            if (ClassPath.SOURCE == type) {
  35.779 -                return sourcePath;
  35.780 -            }
  35.781 -
  35.782 -            if (ClassPath.COMPILE == type) {
  35.783 -                return compileClassPath;
  35.784 -            }
  35.785 -
  35.786 -            if (ClassPath.EXECUTE == type) {
  35.787 -                return ClassPathSupport.createClassPath(new FileObject[] {
  35.788 -                    buildRoot
  35.789 -                });
  35.790 -            }
  35.791 -            } catch (Exception e) {
  35.792 -                e.printStackTrace();
  35.793 -            }
  35.794 -            return null;
  35.795 -        }
  35.796 -
  35.797 -    }
  35.798 -
  35.799 -    private class TestSourceLevelQueryImplementation implements SourceLevelQueryImplementation {
  35.800 -
  35.801 -        public String getSourceLevel(FileObject javaFile) {
  35.802 -            return sourceLevel;
  35.803 -        }
  35.804 -
  35.805 -    }
  35.806 -
  35.807 -
  35.808 -    private static class DeadlockTask implements Task<CompilationController> {
  35.809 -
  35.810 -        private final Phase phase;
  35.811 -        private CompilationInfo info;
  35.812 -
  35.813 -        public DeadlockTask(Phase phase) {
  35.814 -            assert phase != null;
  35.815 -            this.phase = phase;
  35.816 -        }
  35.817 -
  35.818 -        public void run( CompilationController info ) {
  35.819 -            try {
  35.820 -                info.toPhase(this.phase);
  35.821 -                this.info = info;
  35.822 -            } catch (IOException ioe) {
  35.823 -                if (log.isLoggable(Level.SEVERE))
  35.824 -                    log.log(Level.SEVERE, ioe.getMessage(), ioe);
  35.825 -            }
  35.826 -        }
  35.827 -
  35.828 -    }
  35.829 -
  35.830 -    /**Encapsulated the output of the hint.
  35.831 -     */
  35.832 -    public final class HintOutput {
  35.833 -        
  35.834 -        private final List<ErrorDescription> errors;
  35.835 -        private final Set<ErrorDescription> requiresJavaFix;
  35.836 -
  35.837 -        private HintOutput(List<ErrorDescription> errors, Set<ErrorDescription> requiresJavaFix) {
  35.838 -            this.errors = errors;
  35.839 -            this.requiresJavaFix = requiresJavaFix;
  35.840 -
  35.841 -        }
  35.842 -
  35.843 -        /**Assert that the hint(s) produced the given warnings. The provided strings
  35.844 -         * should match {@code toString()} results of {@link ErrorDescription}s produced
  35.845 -         * by the hint(s).
  35.846 -         *
  35.847 -         * @param warnings expected {@code toString()} results of {@link ErrorDescription}s produced
  35.848 -         *                 by the hint
  35.849 -         * @return itself
  35.850 -         * @throws AssertionError if the given warnings do not match the actual warnings
  35.851 -         */
  35.852 -        public HintOutput assertWarnings(String... warnings) {
  35.853 -            assertEquals("The warnings provided by the hint do not match expected warnings.", Arrays.toString(warnings), errors.toString());
  35.854 -
  35.855 -            return this;
  35.856 -        }
  35.857 -
  35.858 -        /**Assert that the hint(s) produced warnings include the given warnings. The provided strings
  35.859 -         * should match {@code toString()} results of {@link ErrorDescription}s produced
  35.860 -         * by the hint(s).
  35.861 -         *
  35.862 -         * @param warnings expected {@code toString()} results of {@link ErrorDescription}s produced
  35.863 -         *                 by the hint
  35.864 -         * @return itself
  35.865 -         * @throws AssertionError if the given warnings do not match the actual warnings
  35.866 -         */
  35.867 -        public HintOutput assertContainsWarnings(String... warnings) {
  35.868 -            Set<String> goldenSet = new HashSet<String>(Arrays.asList(warnings));
  35.869 -            List<String> errorsNames = new LinkedList<String>();
  35.870 -
  35.871 -            for (ErrorDescription d : errors) {
  35.872 -                goldenSet.remove(d.toString());
  35.873 -                errorsNames.add(d.toString());
  35.874 -            }
  35.875 -            
  35.876 -            assertTrue("The warnings provided by the hint do not contain expected warnings. Provided warnings: " + errorsNames.toString(), goldenSet.isEmpty());
  35.877 -
  35.878 -            return this;
  35.879 -        }
  35.880 -
  35.881 -        /**Assert that the hint(s) produced warnings do not include the given warnings. The provided strings
  35.882 -         * should match {@code toString()} results of {@link ErrorDescription}s produced
  35.883 -         * by the hint(s).
  35.884 -         *
  35.885 -         * @param warnings expected {@code toString()} results of {@link ErrorDescription}s produced
  35.886 -         *                 by the hint
  35.887 -         * @return itself
  35.888 -         * @throws AssertionError if the given warnings do not match the actual warnings
  35.889 -         */
  35.890 -        public HintOutput assertNotContainsWarnings(String... warnings) {
  35.891 -            Set<String> goldenSet = new HashSet<String>(Arrays.asList(warnings));
  35.892 -            List<String> errorsNames = new LinkedList<String>();
  35.893 -
  35.894 -            boolean fail = false;
  35.895 -            for (ErrorDescription d : errors) {
  35.896 -                if (goldenSet.remove(d.getDescription()))
  35.897 -                    fail = true;
  35.898 -                errorsNames.add(d.toString());
  35.899 -            }
  35.900 -            
  35.901 -            assertFalse("The warnings provided by the hint do not exclude expected warnings. Provided warnings: " + errorsNames.toString(), fail);
  35.902 -
  35.903 -            return this;
  35.904 -        }
  35.905 -        
  35.906 -        /**Find a specific warning.
  35.907 -         *
  35.908 -         * @param warning the warning to find - must be equivalent to {@code toString()}
  35.909 -         *                results of the {@link ErrorDescription}.
  35.910 -         * @return a wrapper about the given specific warnings
  35.911 -         * @throws AssertionError if the given warning cannot be found
  35.912 -         */
  35.913 -        public HintWarning findWarning(String warning) {
  35.914 -            ErrorDescription toFix = null;
  35.915 -
  35.916 -            for (ErrorDescription d : errors) {
  35.917 -                if (warning.equals(d.toString())) {
  35.918 -                    toFix = d;
  35.919 -                    break;
  35.920 -                }
  35.921 -            }
  35.922 -
  35.923 -            assertNotNull("Warning: \"" + warning + "\" not found. All ErrorDescriptions: " + errors.toString(), toFix);
  35.924 -
  35.925 -            return new HintWarning(toFix, requiresJavaFix.contains(toFix));
  35.926 -        }
  35.927 -    }
  35.928 -
  35.929 -    /**A wrapper over a single warning.
  35.930 -     */
  35.931 -    public final class HintWarning {
  35.932 -        private final ErrorDescription warning;
  35.933 -        private final boolean requiresJavaFix;
  35.934 -        HintWarning(ErrorDescription warning, boolean requiresJavaFix) {
  35.935 -            this.warning = warning;
  35.936 -            this.requiresJavaFix = requiresJavaFix;
  35.937 -        }
  35.938 -        /**Applies the only fix of the current warning. Fails if the given warning
  35.939 -         * does not have exactly one fix.
  35.940 -         *
  35.941 -         * Note this is a destructive operation - the {@link #run(java.lang.Class)} or {@link #applyFix}
  35.942 -         * cannot be run in the future on any object that follows the chain from the same invocation of {@link #create()}.
  35.943 -         *
  35.944 -         * @return a wrapper over resulting source code
  35.945 -         * @throws AssertionError if there is not one fix for the given {@link ErrorDescription}
  35.946 -         */
  35.947 -        public AppliedFix applyFix() throws Exception {
  35.948 -            return applyFix(true);
  35.949 -        }
  35.950 -
  35.951 -        AppliedFix applyFix(boolean saveAll) throws Exception {
  35.952 -            assertTrue("Must be computed", warning.getFixes().isComputed());
  35.953 -
  35.954 -            List<Fix> fixes = warning.getFixes().getFixes();
  35.955 -
  35.956 -            assertEquals(1, fixes.size());
  35.957 -
  35.958 -            doApplyFix(fixes.get(0));
  35.959 -
  35.960 -            if (saveAll)
  35.961 -                LifecycleManager.getDefault().saveAll();
  35.962 -            
  35.963 -            return new AppliedFix();
  35.964 -        }
  35.965 -        /**Applies the specified fix of the current warning.
  35.966 -         *
  35.967 -         * Note this is a destructive operation - the {@link #run(java.lang.Class)} or {@link #applyFix}
  35.968 -         * cannot be run in the future on any object that follows the chain from the same invocation of {@link #create()}.
  35.969 -         *
  35.970 -         * @param fix {@link Fix#getText() } result of the required fix
  35.971 -         * @return a wrapper over resulting source code
  35.972 -         * @throws AssertionError if the fix cannot be found
  35.973 -         */
  35.974 -        public AppliedFix applyFix(String fix) throws Exception {
  35.975 -            assertTrue("Must be computed", warning.getFixes().isComputed());
  35.976 -
  35.977 -            List<Fix> fixes = warning.getFixes().getFixes();
  35.978 -            List<String> fixNames = new LinkedList<String>();
  35.979 -            Fix toApply = null;
  35.980 -
  35.981 -            for (Fix f : fixes) {
  35.982 -                if (fix.equals(f.getText())) {
  35.983 -                    toApply = f;
  35.984 -                }
  35.985 -
  35.986 -                fixNames.add(f.getText());
  35.987 -            }
  35.988 -
  35.989 -            assertNotNull("Cannot find fix to invoke: " + fixNames.toString(), toApply);
  35.990 -
  35.991 -            doApplyFix(toApply);
  35.992 -            
  35.993 -            LifecycleManager.getDefault().saveAll();
  35.994 -
  35.995 -            return new AppliedFix();
  35.996 -        }
  35.997 -        private void doApplyFix(Fix f) throws Exception {
  35.998 -            Preferences preferences = MimeLookup.getLookup(JavaTokenId.language().mimeType()).lookup(Preferences.class);
  35.999 -            preferences.putBoolean("importInnerClasses", true);
 35.1000 -            try {
 35.1001 -                if (requiresJavaFix) {
 35.1002 -                    assertTrue("The fix must be a JavaFix", f instanceof JavaFixImpl);
 35.1003 -                    
 35.1004 -                    ModificationResult result1 = runJavaFix(((JavaFixImpl) f).jf);
 35.1005 -                    ModificationResult result2 = runJavaFix(((JavaFixImpl) f).jf);
 35.1006 -                    
 35.1007 -                    //ensure the results are the same:
 35.1008 -                    assertEquals("The fix must be repeatable", result1.getModifiedFileObjects(), result2.getModifiedFileObjects());
 35.1009 -                    
 35.1010 -                    for (FileObject file : result1.getModifiedFileObjects()) {
 35.1011 -                        assertEquals("The fix must be repeatable", result1.getResultingSource(file), result2.getResultingSource(file));
 35.1012 -                    }
 35.1013 -                    
 35.1014 -                    result1.commit();
 35.1015 -                } else {
 35.1016 -                    f.implement();
 35.1017 -                }
 35.1018 -            } finally {
 35.1019 -                preferences.remove("importInnerClasses");
 35.1020 -            }
 35.1021 -        }
 35.1022 -        private ModificationResult runJavaFix(final JavaFix jf) throws IOException {
 35.1023 -            FileObject file = Accessor.INSTANCE.getFile(jf);
 35.1024 -            JavaSource js = JavaSource.forFileObject(file);
 35.1025 -            final Map<FileObject, List<Difference>> changes = new HashMap<FileObject, List<Difference>>();
 35.1026 -
 35.1027 -            ModificationResult mr = js.runModificationTask(new Task<WorkingCopy>() {
 35.1028 -                public void run(WorkingCopy wc) throws Exception {
 35.1029 -                    if (wc.toPhase(Phase.RESOLVED).compareTo(Phase.RESOLVED) < 0) {
 35.1030 -                        return;
 35.1031 -                    }
 35.1032 -
 35.1033 -                    Map<FileObject, byte[]> resourceContentChanges = new HashMap<FileObject, byte[]>();
 35.1034 -                    Accessor.INSTANCE.process(jf, wc, true, resourceContentChanges, /*Ignored for now:*/new ArrayList<RefactoringElementImplementation>());
 35.1035 -                    BatchUtilities.addResourceContentChanges(resourceContentChanges, changes);
 35.1036 -                    
 35.1037 -                }
 35.1038 -            });
 35.1039 -            
 35.1040 -            changes.putAll(JavaSourceAccessor.getINSTANCE().getDiffsFromModificationResult(mr));
 35.1041 -            
 35.1042 -            return JavaSourceAccessor.getINSTANCE().createModificationResult(changes, Collections.<Object, int[]>emptyMap());
 35.1043 -        }
 35.1044 -        /**Verifies that the current warning provides the given fixes.
 35.1045 -         *
 35.1046 -         * @param fixes the {@link Fix#getText() } of the expected fixes
 35.1047 -         * @return itself
 35.1048 -         * @throws AssertionError if the expected fixes do not match the provided fixes
 35.1049 -         * @since 1.1
 35.1050 -         */
 35.1051 -        public HintWarning assertFixes(String... expectedFixes) throws Exception {
 35.1052 -            assertTrue("Must be computed", warning.getFixes().isComputed());
 35.1053 -
 35.1054 -            List<String> fixNames = new LinkedList<String>();
 35.1055 -
 35.1056 -            for (Fix f : warning.getFixes().getFixes()) {
 35.1057 -                if (f instanceof SyntheticFix) continue;
 35.1058 -                fixNames.add(f.getText());
 35.1059 -            }
 35.1060 -
 35.1061 -            assertEquals("Fixes for the current warning do not match the expected fixes. All fixes: " + fixNames.toString(), Arrays.asList(expectedFixes), fixNames);
 35.1062 -
 35.1063 -            return this;
 35.1064 -        }
 35.1065 -    }
 35.1066 -
 35.1067 -    /**A wrapper over result after applying a fix.
 35.1068 -     */
 35.1069 -    public final class AppliedFix {
 35.1070 -        /**Require that the result is compilable. Equivalent to {@code assertCompilable("test/Test.java")}
 35.1071 -         *
 35.1072 -         * @return the wrapper itself
 35.1073 -         * @throws AssertionError if the result is not compilable
 35.1074 -         */
 35.1075 -        public AppliedFix assertCompilable() throws Exception {
 35.1076 -            return assertCompilable("test/Test.java");
 35.1077 -        }
 35.1078 -        /**Require that the given resulting file is compilable.
 35.1079 -         *
 35.1080 -         * @param fileName the name of the file that should be verified
 35.1081 -         * @return the wrapper itself
 35.1082 -         * @throws AssertionError if the result is not compilable
 35.1083 -         */
 35.1084 -        public AppliedFix assertCompilable(String fileName) throws Exception {
 35.1085 -            FileObject toCheck = sourceRoot.getFileObject(fileName);
 35.1086 -
 35.1087 -            assertNotNull(toCheck);
 35.1088 -
 35.1089 -            ensureCompilable(toCheck);
 35.1090 -            return this;
 35.1091 -        }
 35.1092 -        /**Verify the content of the resulting file. Equivalent to {@code assertOutput("test/Test.java")}.
 35.1093 -         *
 35.1094 -         * This method will "normalize" whitespaces in the file: generally, all
 35.1095 -         * whitespaces are reduced to a single space both in the given code and
 35.1096 -         * the code read from the file, before the comparison.
 35.1097 -         *
 35.1098 -         * @param code expected content of the resulting file.
 35.1099 -         * @return the wrapper itself
 35.1100 -         * @throws AssertionError if the file does not have the correct content
 35.1101 -         */
 35.1102 -        public AppliedFix assertOutput(String code) throws Exception {
 35.1103 -            return assertOutput("test/Test.java", code);
 35.1104 -        }
 35.1105 -        /**Verify the content of the given resulting file.
 35.1106 -         *
 35.1107 -         * This method will "normalize" whitespaces in the file: generally, all
 35.1108 -         * whitespaces are reduced to a single space both in the given code and
 35.1109 -         * the code read from the file, before the comparison.
 35.1110 -         *
 35.1111 -         * @param fileName the name of the file that should be verified
 35.1112 -         * @param code expected content of the resulting file.
 35.1113 -         * @return the wrapper itself
 35.1114 -         * @throws AssertionError if the file does not have the correct content
 35.1115 -         */
 35.1116 -        public AppliedFix assertOutput(String fileName, String code) throws Exception {
 35.1117 -            FileObject toCheck = sourceRoot.getFileObject(fileName);
 35.1118 -
 35.1119 -            assertNotNull("Required file: " + fileName + " not found", toCheck);
 35.1120 -
 35.1121 -            DataObject toCheckDO = DataObject.find(toCheck);
 35.1122 -            EditorCookie ec = toCheckDO.getLookup().lookup(EditorCookie.class);
 35.1123 -            Document toCheckDocument = ec.openDocument();
 35.1124 -
 35.1125 -            String realCode = toCheckDocument.getText(0, toCheckDocument.getLength());
 35.1126 -
 35.1127 -            //ignore whitespaces:
 35.1128 -            realCode = reduceWhitespaces(realCode);
 35.1129 -
 35.1130 -            assertEquals("The output code does not match the expected code.", reduceWhitespaces(code), realCode);
 35.1131 -
 35.1132 -            return this;
 35.1133 -        }
 35.1134 -        
 35.1135 -        private String reduceWhitespaces(String str) {
 35.1136 -            StringBuilder result = new StringBuilder();
 35.1137 -            int i = 0;
 35.1138 -            boolean wasWhitespace = false;
 35.1139 -            
 35.1140 -            while (i < str.length()) {
 35.1141 -                int codePoint = str.codePointAt(i);
 35.1142 -                
 35.1143 -                if (Character.isWhitespace(codePoint)) {
 35.1144 -                    if (!wasWhitespace) {
 35.1145 -                        result.append(" ");
 35.1146 -                        wasWhitespace = true;
 35.1147 -                    }
 35.1148 -                } else {
 35.1149 -                    result.appendCodePoint(codePoint);
 35.1150 -                    wasWhitespace = false;
 35.1151 -                }
 35.1152 -                i += Character.charCount(codePoint);
 35.1153 -            }
 35.1154 -            
 35.1155 -            return result.toString();
 35.1156 -        }
 35.1157 -        
 35.1158 -        /**Verify the content of the resulting file. Equivalent to {@code assertVerbatimOutput("test/Test.java")}.
 35.1159 -         *
 35.1160 -         * This method will compare the content of the file exactly with the provided
 35.1161 -         * code.
 35.1162 -         *
 35.1163 -         * @param fileName the name of the file that should be verified
 35.1164 -         * @param code expected content of the resulting file.
 35.1165 -         * @return the wrapper itself
 35.1166 -         * @throws AssertionError if the result is not compilable
 35.1167 -         */
 35.1168 -        public AppliedFix assertVerbatimOutput(String code) throws Exception {
 35.1169 -            return assertVerbatimOutput("test/Test.java", code);
 35.1170 -        }
 35.1171 -        /**Verify the content of the given resulting file.
 35.1172 -         *
 35.1173 -         * This method will compare the content of the file exactly with the provided
 35.1174 -         * code.
 35.1175 -         *
 35.1176 -         * @param fileName the name of the file that should be verified
 35.1177 -         * @param code expected content of the resulting file.
 35.1178 -         * @return the wrapper itself
 35.1179 -         * @throws AssertionError if the result is not compilable
 35.1180 -         */
 35.1181 -        public AppliedFix assertVerbatimOutput(String fileName, String code) throws Exception {
 35.1182 -            FileObject toCheck = sourceRoot.getFileObject(fileName);
 35.1183 -
 35.1184 -            assertNotNull(toCheck);
 35.1185 -
 35.1186 -            DataObject toCheckDO = DataObject.find(toCheck);
 35.1187 -            EditorCookie ec = toCheckDO.getLookup().lookup(EditorCookie.class);
 35.1188 -            Document toCheckDocument = ec.openDocument();
 35.1189 -
 35.1190 -            String realCode = toCheckDocument.getText(0, toCheckDocument.getLength());
 35.1191 -
 35.1192 -            assertEquals("The output code does not match the expected code.", code, realCode);
 35.1193 -
 35.1194 -            return this;
 35.1195 -        }
 35.1196 -
 35.1197 -        /**Return code after the fix has been applied.
 35.1198 -         *
 35.1199 -         * @return the code after the fix has been applied
 35.1200 -         */
 35.1201 -        public String getOutput() throws Exception {
 35.1202 -            return getOutput("test/Test.java");
 35.1203 -        }
 35.1204 -
 35.1205 -        /**Return code after the fix has been applied.
 35.1206 -         *
 35.1207 -         * @param fileName file for which the code should be returned
 35.1208 -         * @return the code after the fix has been applied
 35.1209 -         */
 35.1210 -        public String getOutput(String fileName) throws Exception {
 35.1211 -            FileObject toCheck = sourceRoot.getFileObject(fileName);
 35.1212 -
 35.1213 -            assertNotNull(toCheck);
 35.1214 -
 35.1215 -            DataObject toCheckDO = DataObject.find(toCheck);
 35.1216 -            EditorCookie ec = toCheckDO.getLookup().lookup(EditorCookie.class);
 35.1217 -            Document toCheckDocument = ec.openDocument();
 35.1218 -
 35.1219 -            return toCheckDocument.getText(0, toCheckDocument.getLength());
 35.1220 -        }
 35.1221 -    }
 35.1222 -
 35.1223 -    private static final Comparator<ErrorDescription> ERRORS_COMPARATOR = new Comparator<ErrorDescription> () {
 35.1224 -
 35.1225 -        public int compare (ErrorDescription e1, ErrorDescription e2) {
 35.1226 -            return e1.getRange ().getBegin ().getOffset () - e2.getRange ().getBegin ().getOffset ();
 35.1227 -        }
 35.1228 -    };
 35.1229 -
 35.1230 -    static {
 35.1231 -        System.setProperty("org.openide.util.Lookup", TestLookup.class.getName());
 35.1232 -        Assert.assertEquals(TestLookup.class, Lookup.getDefault().getClass());
 35.1233 -    }
 35.1234 -
 35.1235 -    //workdir computation (copied from NbTestCase):
 35.1236 -    private static File getWorkDir() throws IOException {
 35.1237 -        // now we have path, so if not available, create workdir
 35.1238 -        File workdir = FileUtil.normalizeFile(new File(getWorkDirPath()));
 35.1239 -        if (workdir.exists()) {
 35.1240 -            if (!workdir.isDirectory()) {
 35.1241 -                // work dir exists, but is not directory - this should not happen
 35.1242 -                // trow exception
 35.1243 -                throw new IOException("workdir exists, but is not a directory, workdir = " + workdir);
 35.1244 -            } else {
 35.1245 -                // everything looks correctly, return the path
 35.1246 -                return workdir;
 35.1247 -            }
 35.1248 -        } else {
 35.1249 -            // we need to create it
 35.1250 -            boolean result = workdir.mkdirs();
 35.1251 -            if (result == false) {
 35.1252 -                // mkdirs() failed - throw an exception
 35.1253 -                throw new IOException("workdir creation failed: " + workdir);
 35.1254 -            } else {
 35.1255 -                // everything looks ok - return path
 35.1256 -                return workdir;
 35.1257 -            }
 35.1258 -        }
 35.1259 -    }
 35.1260 -
 35.1261 -    private static String getWorkDirPath() {
 35.1262 -        StackTraceElement caller = null;
 35.1263 -        boolean seenItself = false;
 35.1264 -        
 35.1265 -        for (StackTraceElement e : new Exception().getStackTrace()) {
 35.1266 -            if (HintTest.class.getName().equals(e.getClassName())) seenItself = true;
 35.1267 -            if (seenItself && !HintTest.class.getName().equals(e.getClassName())) {
 35.1268 -                caller = e;
 35.1269 -                break;
 35.1270 -            }
 35.1271 -        }
 35.1272 -        
 35.1273 -        String name = caller != null ? caller.getMethodName() : "unknownTest";
 35.1274 -        // start - PerformanceTestCase overrides getName() method and then
 35.1275 -        // name can contain illegal characters
 35.1276 -        String osName = System.getProperty("os.name");
 35.1277 -        if (osName != null && osName.startsWith("Windows")) {
 35.1278 -            char ntfsIllegal[] ={'"','/','\\','?','<','>','|',':'};
 35.1279 -            for (int i=0; i<ntfsIllegal.length; i++) {
 35.1280 -                name = name.replace(ntfsIllegal[i], '~');
 35.1281 -            }
 35.1282 -        }
 35.1283 -        // end
 35.1284 -        
 35.1285 -        final String workDirPath = getWorkDirPathFromManager();
 35.1286 -        
 35.1287 -        // #94319 - shorten workdir path if the following is too long
 35.1288 -        // "Manager.getWorkDirPath()+File.separator+getClass().getName()+File.separator+name"
 35.1289 -        int len1 = workDirPath.length();
 35.1290 -        String clazz = caller != null ? caller.getClassName() : "unknown.Class";
 35.1291 -        int len2 = clazz.length();
 35.1292 -        int len3 = name.length();
 35.1293 -        
 35.1294 -        int tooLong = Integer.getInteger("nbjunit.too.long", 100);
 35.1295 -        if (len1 + len2 + len3 > tooLong) {
 35.1296 -            clazz = abbrevDots(clazz);
 35.1297 -            len2 = clazz.length();
 35.1298 -        }
 35.1299 -
 35.1300 -        if (len1 + len2 + len3 > tooLong) {
 35.1301 -            name = abbrevCapitals(name);
 35.1302 -        }
 35.1303 -        
 35.1304 -        String p = workDirPath + File.separator + clazz + File.separator + name;
 35.1305 -        String realP;
 35.1306 -        
 35.1307 -        for (int i = 0; ; i++) {
 35.1308 -            realP = i == 0 ? p : p + "-" + i;
 35.1309 -            if (usedPaths.add(realP)) {
 35.1310 -                break;
 35.1311 -            }
 35.1312 -        }
 35.1313 -        
 35.1314 -        return realP;
 35.1315 -    }
 35.1316 -
 35.1317 -    private static Set<String> usedPaths = new HashSet<String>();
 35.1318 -    
 35.1319 -    private static String abbrevDots(String dotted) {
 35.1320 -        StringBuilder sb = new StringBuilder();
 35.1321 -        String sep = "";
 35.1322 -        for (String item : dotted.split("\\.")) {
 35.1323 -            sb.append(sep);
 35.1324 -            sb.append(item.charAt(0));
 35.1325 -            sep = ".";
 35.1326 -        }
 35.1327 -        return sb.toString();
 35.1328 -    }
 35.1329 -
 35.1330 -    private static String abbrevCapitals(String name) {
 35.1331 -        if (name.startsWith("test")) {
 35.1332 -            name = name.substring(4);
 35.1333 -        }
 35.1334 -        StringBuilder sb = new StringBuilder();
 35.1335 -        for (int i = 0; i < name.length(); i++) {
 35.1336 -            if (Character.isUpperCase(name.charAt(i))) {
 35.1337 -                sb.append(Character.toLowerCase(name.charAt(i)));
 35.1338 -            }
 35.1339 -        }
 35.1340 -        return sb.toString();
 35.1341 -    }
 35.1342 -
 35.1343 -    private static final String JUNIT_PROPERTIES_FILENAME = "junit.properties";
 35.1344 -    private static final String JUNIT_PROPERTIES_LOCATION_PROPERTY = "junit.properties.file";
 35.1345 -    private static final String NBJUNIT_WORKDIR = "nbjunit.workdir";
 35.1346 -    
 35.1347 -    private static String getWorkDirPathFromManager() {
 35.1348 -        String path = System.getProperty(NBJUNIT_WORKDIR);
 35.1349 -                
 35.1350 -        if (path == null) {            
 35.1351 -            // try to get property from user's settings
 35.1352 -            path = readProperties().getProperty(NBJUNIT_WORKDIR);
 35.1353 -        }
 35.1354 -        if (path != null) {
 35.1355 -            path = path.replace('/', File.separatorChar);
 35.1356 -        } else {
 35.1357 -            // Fallback value, guaranteed to be defined.
 35.1358 -            path = System.getProperty("java.io.tmpdir") + File.separatorChar + "tests-" + System.getProperty("user.name");
 35.1359 -        }
 35.1360 -        return path;
 35.1361 -    }
 35.1362 -
 35.1363 -    private static Properties readProperties() {
 35.1364 -        Properties result = new Properties();
 35.1365 -        try {
 35.1366 -            File propFile = getPreferencesFile();
 35.1367 -            FileInputStream is = new FileInputStream(propFile);
 35.1368 -            try {
 35.1369 -                result.load(is);
 35.1370 -            } finally {
 35.1371 -                is.close();
 35.1372 -            }
 35.1373 -        }  catch (IOException e) {
 35.1374 -        }
 35.1375 -        
 35.1376 -        return result;
 35.1377 -    }
 35.1378 -
 35.1379 -    private static File getPreferencesFile() {
 35.1380 -        String junitPropertiesLocation = System.getProperty(JUNIT_PROPERTIES_LOCATION_PROPERTY);
 35.1381 -        if (junitPropertiesLocation != null) {
 35.1382 -            File propertyFile = new File(junitPropertiesLocation);
 35.1383 -            if (propertyFile.exists()) {
 35.1384 -                return propertyFile;
 35.1385 -            }
 35.1386 -        }
 35.1387 -        // property file was not found - lets fall back to defaults
 35.1388 -        String home= System.getProperty("user.home");
 35.1389 -        return new File(home, JUNIT_PROPERTIES_FILENAME);
 35.1390 -    }
 35.1391 -
 35.1392 -    // private method for deleting a file/directory (and all its subdirectories/files)
 35.1393 -    private static void deleteFile(File file) throws IOException {
 35.1394 -        if (file.isDirectory() && file.equals(file.getCanonicalFile())) {
 35.1395 -            // file is a directory - delete sub files first
 35.1396 -            File files[] = file.listFiles();
 35.1397 -            for (int i = 0; i < files.length; i++) {
 35.1398 -                deleteFile(files[i]);
 35.1399 -            }
 35.1400 -            
 35.1401 -        }
 35.1402 -        // file is a File :-)
 35.1403 -        boolean result = file.delete();
 35.1404 -        if (result == false ) {
 35.1405 -            // a problem has appeared
 35.1406 -            throw new IOException("Cannot delete file, file = "+file.getPath());
 35.1407 -        }
 35.1408 -    }
 35.1409 -    
 35.1410 -    // private method for deleting every subfiles/subdirectories of a file object
 35.1411 -    private static void deleteSubFiles(File file) throws IOException {
 35.1412 -        File files[] = file.getCanonicalFile().listFiles();
 35.1413 -        if (files != null) {
 35.1414 -            for (File f : files) {
 35.1415 -                deleteFile(f);
 35.1416 -            }
 35.1417 -        } else {
 35.1418 -            // probably do nothing - file is not a directory
 35.1419 -        }
 35.1420 -    }
 35.1421 -
 35.1422 -    private static FileObject copyStringToFile (FileObject f, String content) throws Exception {
 35.1423 -        OutputStream os = f.getOutputStream();
 35.1424 -        os.write(content.getBytes("UTF-8"));
 35.1425 -        os.close ();
 35.1426 -
 35.1427 -        return f;
 35.1428 -    }
 35.1429 -
 35.1430 -}
    36.1 --- a/java.hints/java.hints.test/src/org/netbeans/modules/parsing/impl/indexing/MimeTypes.java	Sun Oct 16 08:01:27 2016 +0200
    36.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.3 @@ -1,66 +0,0 @@
    36.4 -/*
    36.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    36.6 - *
    36.7 - * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
    36.8 - *
    36.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   36.10 - * Other names may be trademarks of their respective owners.
   36.11 - *
   36.12 - * The contents of this file are subject to the terms of either the GNU
   36.13 - * General Public License Version 2 only ("GPL") or the Common
   36.14 - * Development and Distribution License("CDDL") (collectively, the
   36.15 - * "License"). You may not use this file except in compliance with the
   36.16 - * License. You can obtain a copy of the License at
   36.17 - * http://www.netbeans.org/cddl-gplv2.html
   36.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   36.19 - * specific language governing permissions and limitations under the
   36.20 - * License.  When distributing the software, include this License Header
   36.21 - * Notice in each file and include the License file at
   36.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   36.23 - * particular file as subject to the "Classpath" exception as provided
   36.24 - * by Oracle in the GPL Version 2 section of the License file that
   36.25 - * accompanied this code. If applicable, add the following below the
   36.26 - * License Header, with the fields enclosed by brackets [] replaced by
   36.27 - * your own identifying information:
   36.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   36.29 - *
   36.30 - * If you wish your version of this file to be governed by only the CDDL
   36.31 - * or only the GPL Version 2, indicate your decision by adding
   36.32 - * "[Contributor] elects to include this software in this distribution
   36.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   36.34 - * single choice of license, a recipient has the option to distribute
   36.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   36.36 - * to extend the choice of license to its licensees as provided above.
   36.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   36.38 - * Version 2 license, then the option applies only if the new code is
   36.39 - * made subject to such option by the copyright holder.
   36.40 - *
   36.41 - * Contributor(s):
   36.42 - *
   36.43 - * Portions Copyrighted 2011 Sun Microsystems, Inc.
   36.44 - */
   36.45 -package org.netbeans.modules.parsing.impl.indexing;
   36.46 -
   36.47 -import java.util.Set;
   36.48 -import org.netbeans.api.annotations.common.CheckForNull;
   36.49 -import org.netbeans.api.annotations.common.NonNull;
   36.50 -import org.openide.util.Parameters;
   36.51 -
   36.52 -/**Not an API!
   36.53 - *
   36.54 - * @author Tomas Zezula
   36.55 - */
   36.56 -public class MimeTypes {
   36.57 -
   36.58 -    private MimeTypes() {}
   36.59 -
   36.60 -    public static void setAllMimeTypes(@NonNull final Set<String> allMimeTypes) {
   36.61 -        Parameters.notNull("allMimeTypes", allMimeTypes);   //NOI18N
   36.62 -        Util.allMimeTypes = allMimeTypes;
   36.63 -    }
   36.64 -
   36.65 -    @CheckForNull
   36.66 -    public static Set<String> getAllMimeTypes() {
   36.67 -        return Util.allMimeTypes;
   36.68 -    }
   36.69 -}
    37.1 --- a/java.hints/java.hints.test/test/unit/src/org/netbeans/modules/java/hints/test/api/HintTestTest.java	Sun Oct 16 08:01:27 2016 +0200
    37.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.3 @@ -1,336 +0,0 @@
    37.4 -/*
    37.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    37.6 - *
    37.7 - * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
    37.8 - *
    37.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   37.10 - * Other names may be trademarks of their respective owners.
   37.11 - *
   37.12 - * The contents of this file are subject to the terms of either the GNU
   37.13 - * General Public License Version 2 only ("GPL") or the Common
   37.14 - * Development and Distribution License("CDDL") (collectively, the
   37.15 - * "License"). You may not use this file except in compliance with the
   37.16 - * License. You can obtain a copy of the License at
   37.17 - * http://www.netbeans.org/cddl-gplv2.html
   37.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   37.19 - * specific language governing permissions and limitations under the
   37.20 - * License.  When distributing the software, include this License Header
   37.21 - * Notice in each file and include the License file at
   37.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   37.23 - * particular file as subject to the "Classpath" exception as provided
   37.24 - * by Oracle in the GPL Version 2 section of the License file that
   37.25 - * accompanied this code. If applicable, add the following below the
   37.26 - * License Header, with the fields enclosed by brackets [] replaced by
   37.27 - * your own identifying information:
   37.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   37.29 - *
   37.30 - * If you wish your version of this file to be governed by only the CDDL
   37.31 - * or only the GPL Version 2, indicate your decision by adding
   37.32 - * "[Contributor] elects to include this software in this distribution
   37.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   37.34 - * single choice of license, a recipient has the option to distribute
   37.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   37.36 - * to extend the choice of license to its licensees as provided above.
   37.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   37.38 - * Version 2 license, then the option applies only if the new code is
   37.39 - * made subject to such option by the copyright holder.
   37.40 - *
   37.41 - * Contributor(s):
   37.42 - *
   37.43 - * Portions Copyrighted 2012 Sun Microsystems, Inc.
   37.44 - */
   37.45 -package org.netbeans.modules.java.hints.test.api;
   37.46 -
   37.47 -import com.sun.source.tree.Tree.Kind;
   37.48 -import com.sun.source.util.TreePath;
   37.49 -import java.io.ByteArrayOutputStream;
   37.50 -import java.io.InputStreamReader;
   37.51 -import java.io.OutputStream;
   37.52 -import java.io.OutputStreamWriter;
   37.53 -import java.io.Reader;
   37.54 -import java.io.Writer;
   37.55 -import javax.swing.text.Document;
   37.56 -import org.junit.Assert;
   37.57 -import org.junit.Test;
   37.58 -import org.netbeans.api.java.source.ClasspathInfo.PathKind;
   37.59 -import org.netbeans.api.java.source.CompilationInfo;
   37.60 -import org.netbeans.api.java.source.JavaSource;
   37.61 -import org.netbeans.spi.editor.hints.ChangeInfo;
   37.62 -import org.netbeans.spi.editor.hints.ErrorDescription;
   37.63 -import org.netbeans.spi.editor.hints.Fix;
   37.64 -import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
   37.65 -import org.netbeans.spi.java.hints.Hint;
   37.66 -import org.netbeans.spi.java.hints.HintContext;
   37.67 -import org.netbeans.spi.java.hints.JavaFix;
   37.68 -import org.netbeans.spi.java.hints.JavaFix.TransformationContext;
   37.69 -import org.netbeans.spi.java.hints.TriggerTreeKind;
   37.70 -import org.openide.LifecycleManager;
   37.71 -import org.openide.cookies.EditorCookie;
   37.72 -import org.openide.filesystems.FileObject;
   37.73 -import org.openide.filesystems.FileUtil;
   37.74 -import org.openide.loaders.DataObject;
   37.75 -
   37.76 -/**
   37.77 - *
   37.78 - * @author lahvac
   37.79 - */
   37.80 -public class HintTestTest {
   37.81 -
   37.82 -    public HintTestTest() {
   37.83 -    }
   37.84 -
   37.85 -    @Test
   37.86 -    public void testNonJavaChanges() throws Exception {
   37.87 -        HintTest.create()
   37.88 -                .input("package test;\n" +
   37.89 -                       "public class Test { }\n")
   37.90 -                .input("test/test.txt", "1\n2\n", false)
   37.91 -                .run(NonJavaChanges.class)
   37.92 -                .findWarning("1:13-1:17:verifier:Test")
   37.93 -                .applyFix()
   37.94 -                .assertVerbatimOutput("test/test.txt", "2\n3\n");
   37.95 -    }
   37.96 -
   37.97 -    @Test
   37.98 -    public void test220070() throws Exception {
   37.99 -        HintTest.create()
  37.100 -                .input("package test;\n" +
  37.101 -                       "public class Test { }\n")
  37.102 -                .input("test/test.txt", "1\n2\n", false)
  37.103 -                .run(NonJavaChanges.class)
  37.104 -                .findWarning("1:13-1:17:verifier:Test")
  37.105 -                .applyFix()
  37.106 -                .assertOutput("test/test.txt", "2\r3\r");
  37.107 -    }
  37.108 -    
  37.109 -    @Test
  37.110 -    public void testNonJavaChangesOpenedInEditor() throws Exception {
  37.111 -        try {
  37.112 -            HintTest ht = HintTest.create()
  37.113 -                                  .input("package test;\n" +
  37.114 -                                         "public class Test { }\n")
  37.115 -                                  .input("test/test.txt", "1\n2\n", false);
  37.116 -            FileObject resource = ht.getSourceRoot().getFileObject("test/test.txt");
  37.117 -            DataObject od = DataObject.find(resource);
  37.118 -            EditorCookie ec = od.getLookup().lookup(EditorCookie.class);
  37.119 -            Document doc = ec.openDocument();
  37.120 -            doc.remove(0, doc.getLength());
  37.121 -            doc.insertString(0, "5\n6\n", null);
  37.122 -            ht.run(NonJavaChanges.class)
  37.123 -              .findWarning("1:13-1:17:verifier:Test")
  37.124 -              .applyFix(false)
  37.125 -              .assertVerbatimOutput("test/test.txt", "6\n7\n");
  37.126 -            Assert.assertEquals("1\n2\n", resource.asText("UTF-8"));
  37.127 -            Assert.assertEquals("6\n7\n", doc.getText(0, doc.getLength()));
  37.128 -        } finally {
  37.129 -            LifecycleManager.getDefault().saveAll();
  37.130 -        }
  37.131 -    }
  37.132 -
  37.133 -    @Hint(displayName="testingNonJavaChanges", description="testingNonJavaChanges", category="test")
  37.134 -    public static final class NonJavaChanges {
  37.135 -        @TriggerTreeKind(Kind.CLASS)
  37.136 -        public static ErrorDescription hint(HintContext ctx) {
  37.137 -            return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), "Test", new TestingNonJavaChangesFix(ctx.getInfo(), ctx.getPath()).toEditorFix());
  37.138 -        }
  37.139 -    }
  37.140 -
  37.141 -    private static final class TestingNonJavaChangesFix extends JavaFix {
  37.142 -
  37.143 -        public TestingNonJavaChangesFix(CompilationInfo info, TreePath tp) {
  37.144 -            super(info, tp);
  37.145 -        }
  37.146 -
  37.147 -        @Override protected String getText() {
  37.148 -            return "Test";
  37.149 -        }
  37.150 -
  37.151 -        @Override protected void performRewrite(TransformationContext ctx) {
  37.152 -            try {
  37.153 -                FileObject resource = ctx.getWorkingCopy().getFileObject().getParent().getFileObject("test.txt");
  37.154 -                Assert.assertNotNull(resource);
  37.155 -                Reader r = new InputStreamReader(ctx.getResourceContent(resource), "UTF-8");
  37.156 -                ByteArrayOutputStream outData = new ByteArrayOutputStream();
  37.157 -                Writer w = new OutputStreamWriter(outData, "UTF-8");
  37.158 -                int read;
  37.159 -
  37.160 -                while ((read = r.read()) != -1) {
  37.161 -                    if (read != '\n') read++;
  37.162 -                    w.write(read);
  37.163 -                }
  37.164 -
  37.165 -                r.close();
  37.166 -                w.close();
  37.167 -
  37.168 -                OutputStream out = ctx.getResourceOutput(resource);
  37.169 -
  37.170 -                out.write(outData.toByteArray());
  37.171 -
  37.172 -                out.close();
  37.173 -            } catch (Exception ex) {
  37.174 -                throw new IllegalStateException(ex);
  37.175 -            }
  37.176 -        }
  37.177 -
  37.178 -    }
  37.179 -
  37.180 -    @Test
  37.181 -    public void testMeaningfullSourcePath() throws Exception {
  37.182 -        HintTest.create()
  37.183 -                .input("package test;\n" +
  37.184 -                       "public class Test { }\n")
  37.185 -                .run(MeaningfullSourcePath.class)
  37.186 -                .assertWarnings();
  37.187 -    }
  37.188 -
  37.189 -    @Hint(displayName="meaningfullSourcePath", description="meaningfullSourcePath", category="test")
  37.190 -    public static final class MeaningfullSourcePath {
  37.191 -        @TriggerTreeKind(Kind.CLASS)
  37.192 -        public static ErrorDescription hint(HintContext ctx) {
  37.193 -            if (ctx.getInfo().getClasspathInfo().getClassPath(PathKind.SOURCE).findOwnerRoot(ctx.getInfo().getFileObject()) == null) {
  37.194 -                return ErrorDescriptionFactory.forTree(ctx, ctx.getPath(), "Broken Source Path");
  37.195 -            }
  37.196 -
  37.197 -            return null;
  37.198 -        }
  37.199 -    }
  37.200 -
  37.201 -    @Test
  37.202 -    public void testCompilationClassPath() throws Exception {
  37.203 -        HintTest.create()
  37.204 -                .input("package test;\n" +
  37.205 -                       "public class Test { }\n")
  37.206 -                .classpath(FileUtil.getArchiveRoot(JavaSource.class.getProtectionDomain().getCodeSource().getLocation()))
  37.207 -                .run(CompilationClassPath.class)
  37.208 -                .assertWarnings();
  37.209 -    }
  37.210 -
  37.211 -    @Hint(displayName="compilationClassPath", description="compilationClassPath", category="test")
  37.212 -    public static final class CompilationClassPath {
  37.213 -        @TriggerTreeKind(Kind.CLASS)
  37.214 -        public static ErrorDescription hint(HintContext ctx) {
  37.215 -            FileObject clazz = ctx.getInfo().getClasspathInfo().getClassPath(PathKind.COMPILE).findResource("org/netbeans/api/java/source/JavaSource.class");
  37.216 -
  37.217 -            if (clazz == null) {
  37.218 -                return ErrorDescriptionFactory.forTree(ctx, ctx.getPath(), "Broken Compilation ClassPath");
  37.219 -            }
  37.220 -
  37.221 -            return null;
  37.222 -        }
  37.223 -    }
  37.224 -
  37.225 -    @Test
  37.226 -    public void testHintThrowsException() throws Exception {
  37.227 -        HintTest ht = HintTest.create()
  37.228 -                              .input("package test;\n" +
  37.229 -                                     "public class Test { }\n");
  37.230 -        try {
  37.231 -            ht.run(HintThrowsException.class);
  37.232 -            Assert.fail("No exception thrown");
  37.233 -        } catch (Exception ex) {
  37.234 -            //ok
  37.235 -            Assert.assertEquals(IllegalStateException.class, ex.getClass());
  37.236 -            Assert.assertNotNull(ex.getCause());
  37.237 -            Assert.assertEquals(NullPointerException.class, ex.getCause().getClass());
  37.238 -            Assert.assertEquals("a", ex.getCause().getMessage());
  37.239 -        }
  37.240 -    }
  37.241 -    
  37.242 -    @Hint(displayName="hintThrowsException", description="hintThrowsException", category="test")
  37.243 -    public static final class HintThrowsException {
  37.244 -        @TriggerTreeKind(Kind.CLASS)
  37.245 -        public static ErrorDescription hint(HintContext ctx) {
  37.246 -            throw new NullPointerException("a");
  37.247 -        }
  37.248 -    }
  37.249 -
  37.250 -    @Test
  37.251 -    public void testNonJavaFix() throws Exception {
  37.252 -        HintTest ht = HintTest.create()
  37.253 -                              .input("package test;\n" +
  37.254 -                                     "public class Test { }\n");
  37.255 -        try {
  37.256 -            ht.run(NonJavaFix.class)
  37.257 -              .findWarning("1:0-1:21:verifier:Test")
  37.258 -              .applyFix();
  37.259 -            Assert.fail("No exception thrown");
  37.260 -        } catch (AssertionError ae) {
  37.261 -            //ok
  37.262 -            Assert.assertEquals("The fix must be a JavaFix", ae.getMessage());
  37.263 -        }
  37.264 -    }
  37.265 -    
  37.266 -    @Hint(displayName="nonJavaFix", description="nonJavaFix", category="test")
  37.267 -    public static final class NonJavaFix {
  37.268 -        @TriggerTreeKind(Kind.CLASS)
  37.269 -        public static ErrorDescription hint(HintContext ctx) {
  37.270 -            return ErrorDescriptionFactory.forTree(ctx, ctx.getPath(), "Test", new Fix() {
  37.271 -                @Override public String getText() {
  37.272 -                    return "Fix";
  37.273 -                }
  37.274 -                @Override public ChangeInfo implement() throws Exception {
  37.275 -                    return null;
  37.276 -                }
  37.277 -            });
  37.278 -        }
  37.279 -    }
  37.280 -    
  37.281 -    @Test
  37.282 -    public void testNotRepeatableJavaFix() throws Exception {
  37.283 -        HintTest ht = HintTest.create()
  37.284 -                              .input("package test;\n" +
  37.285 -                                     "public class Test { }\n");
  37.286 -        try {
  37.287 -            ht.run(NotRepeatableJavaFix.class)
  37.288 -              .findWarning("1:0-1:21:verifier:Test")
  37.289 -              .applyFix();
  37.290 -            Assert.fail("No exception thrown");
  37.291 -        } catch (AssertionError ae) {
  37.292 -            //ok
  37.293 -            Assert.assertTrue(ae.getMessage().startsWith("The fix must be repeatable"));
  37.294 -        }
  37.295 -    }
  37.296 -    
  37.297 -    @Hint(displayName="notRepeatableJavaFix", description="notRepeatableJavaFix", category="test")
  37.298 -    public static final class NotRepeatableJavaFix {
  37.299 -        @TriggerTreeKind(Kind.CLASS)
  37.300 -        public static ErrorDescription hint(HintContext ctx) {
  37.301 -            Fix f = new JavaFix(ctx.getInfo(), ctx.getPath()) {
  37.302 -                private boolean wasRun;
  37.303 -                @Override protected String getText() {
  37.304 -                    return "Fix";
  37.305 -                }
  37.306 -                @Override protected void performRewrite(TransformationContext ctx) throws Exception {
  37.307 -                    if (wasRun) return ;
  37.308 -                    ctx.getWorkingCopy().rewrite(ctx.getPath().getLeaf(), ctx.getWorkingCopy().getTreeMaker().setLabel(ctx.getPath().getLeaf(), "Nue"));
  37.309 -                    wasRun = true;
  37.310 -                }
  37.311 -            }.toEditorFix();
  37.312 -            return ErrorDescriptionFactory.forTree(ctx, ctx.getPath(), "Test", f);
  37.313 -        }
  37.314 -    }
  37.315 -
  37.316 -    public void testSourcePathReady() throws Exception {
  37.317 -        HintTest.create()
  37.318 -                .input("test/Test1.java",
  37.319 -                       "package test;\n" +
  37.320 -                       "public class Test1 {\n" +
  37.321 -                       "    private final Test2 test2 = null;\n" +
  37.322 -                       "}\n")
  37.323 -                .input("test/Test2.java",
  37.324 -                       "package test;\n" +
  37.325 -                       "public class Test2 {\n" +
  37.326 -                       "    private final Test1 test1 = null;\n" +
  37.327 -                       "}\n")
  37.328 -                .runGlobal(NoOp.class)
  37.329 -                .assertWarnings();
  37.330 -    }
  37.331 -
  37.332 -    @Hint(displayName="noOp", description="noOp", category="test")
  37.333 -    public static final class NoOp {
  37.334 -        @TriggerTreeKind(Kind.CLASS)
  37.335 -        public static ErrorDescription hint(HintContext ctx) {
  37.336 -            return null;
  37.337 -        }
  37.338 -    }
  37.339 -}
    38.1 --- a/java.hints/nbproject/build-impl.xml	Sun Oct 16 08:01:27 2016 +0200
    38.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.3 @@ -1,50 +0,0 @@
    38.4 -<?xml version="1.0" encoding="UTF-8"?>
    38.5 -<!--
    38.6 -*** GENERATED FROM project.xml - DO NOT EDIT  ***
    38.7 -***         EDIT ../build.xml INSTEAD         ***
    38.8 --->
    38.9 -<project name="java.hints-impl" basedir=".." xmlns:sproject="http://www.netbeans.org/ns/nb-module-suite-project/1">
   38.10 -    <fail message="Please build using Ant 1.7.1 or higher.">
   38.11 -        <condition>
   38.12 -            <not>
   38.13 -                <antversion atleast="1.7.1"/>
   38.14 -            </not>
   38.15 -        </condition>
   38.16 -    </fail>
   38.17 -    <property file="nbproject/private/platform-private.properties"/>
   38.18 -    <property file="nbproject/platform.properties"/>
   38.19 -    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-suite-project/1">
   38.20 -        <attribute name="name"/>
   38.21 -        <attribute name="value"/>
   38.22 -        <sequential>
   38.23 -            <property name="@{name}" value="${@{value}}"/>
   38.24 -        </sequential>
   38.25 -    </macrodef>
   38.26 -    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-suite-project/1">
   38.27 -        <attribute name="property"/>
   38.28 -        <attribute name="value"/>
   38.29 -        <sequential>
   38.30 -            <property name="@{property}" value="@{value}"/>
   38.31 -        </sequential>
   38.32 -    </macrodef>
   38.33 -    <property file="${user.properties.file}"/>
   38.34 -    <sproject:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir"/>
   38.35 -    <sproject:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir"/>
   38.36 -    <sproject:evalprops property="cluster.path.evaluated" value="${cluster.path}"/>
   38.37 -    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
   38.38 -        <condition>
   38.39 -            <not>
   38.40 -                <contains string="${cluster.path.evaluated}" substring="platform"/>
   38.41 -            </not>
   38.42 -        </condition>
   38.43 -    </fail>
   38.44 -    <ant antfile="nbproject/platform.xml"/>
   38.45 -    <fail message="Cannot find NetBeans build harness. ${line.separator}Check that nbplatform.${nbplatform.active}.netbeans.dest.dir and nbplatform.${nbplatform.active}.harness.dir are defined. ${line.separator}On a developer machine these are normally defined in ${user.properties.file}=${netbeans.user}/build.properties ${line.separator}but for automated builds you should pass these properties to Ant explicitly. ${line.separator}You may instead download the harness and platform: -Dbootstrap.url=.../tasks.jar -Dautoupdate.catalog.url=.../updates.xml">
   38.46 -        <condition>
   38.47 -            <not>
   38.48 -                <available file="${harness.dir}/suite.xml"/>
   38.49 -            </not>
   38.50 -        </condition>
   38.51 -    </fail>
   38.52 -    <import file="${harness.dir}/suite.xml"/>
   38.53 -</project>
    39.1 --- a/java.hints/nbproject/genfiles.properties	Sun Oct 16 08:01:27 2016 +0200
    39.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.3 @@ -1,11 +0,0 @@
    39.4 -build.xml.data.CRC32=85cca5f7
    39.5 -build.xml.script.CRC32=25a1521a
    39.6 -build.xml.stylesheet.CRC32=eaf9f76a@2.58
    39.7 -# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
    39.8 -# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
    39.9 -nbproject/build-impl.xml.data.CRC32=85cca5f7
   39.10 -nbproject/build-impl.xml.script.CRC32=82e0fe0b
   39.11 -nbproject/build-impl.xml.stylesheet.CRC32=0f381476@2.58
   39.12 -nbproject/platform.xml.data.CRC32=85cca5f7
   39.13 -nbproject/platform.xml.script.CRC32=6dcbd131
   39.14 -nbproject/platform.xml.stylesheet.CRC32=4e1f53d4@2.70
    40.1 --- a/java.hints/nbproject/platform.properties	Sun Oct 16 08:01:27 2016 +0200
    40.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.3 @@ -1,19 +0,0 @@
    40.4 -cluster.path=\
    40.5 -    ${nbplatform.active.dir}/apisupport:\
    40.6 -    ${nbplatform.active.dir}/cnd:\
    40.7 -    ${nbplatform.active.dir}/dlight:\
    40.8 -    ${nbplatform.active.dir}/enterprise:\
    40.9 -    ${nbplatform.active.dir}/extide:\
   40.10 -    ${nbplatform.active.dir}/extra:\
   40.11 -    ${nbplatform.active.dir}/harness:\
   40.12 -    ${nbplatform.active.dir}/ide:\
   40.13 -    ${nbplatform.active.dir}/java:\
   40.14 -    ${nbplatform.active.dir}/nb:\
   40.15 -    ${nbplatform.active.dir}/platform:\
   40.16 -    ${nbplatform.active.dir}/profiler:\
   40.17 -    ${nbplatform.active.dir}/webcommon:\
   40.18 -    ${nbplatform.active.dir}/websvccommon:\
   40.19 -    ../remoting/common/build/cluster
   40.20 -extcluster.../remoting/common/build/cluster.javadoc=
   40.21 -extcluster.../remoting/common/build/cluster.sources=
   40.22 -nbplatform.active=default
    41.1 --- a/java.hints/nbproject/platform.xml	Sun Oct 16 08:01:27 2016 +0200
    41.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.3 @@ -1,34 +0,0 @@
    41.4 -<?xml version="1.0" encoding="UTF-8"?>
    41.5 -<project name="platform" default="download" basedir="..">
    41.6 -    <condition property="download.required">
    41.7 -        <and>
    41.8 -            <not>
    41.9 -                <available file="${harness.dir}/suite.xml"/>
   41.10 -            </not>
   41.11 -            <isset property="bootstrap.url"/>
   41.12 -            <isset property="autoupdate.catalog.url"/>
   41.13 -        </and>
   41.14 -    </condition>
   41.15 -    <target name="download" if="download.required">
   41.16 -        <mkdir dir="${harness.dir}"/>
   41.17 -        <pathconvert pathsep="|" property="download.clusters">
   41.18 -            <mapper type="flatten"/>
   41.19 -            <path path="${cluster.path}"/>
   41.20 -        </pathconvert>
   41.21 -        <property name="disabled.modules" value=""/>
   41.22 -        <pathconvert property="module.includes" pathsep="">
   41.23 -            <mapper type="glob" from="${basedir}${file.separator}*" to="(?!^\Q*\E$)"/>
   41.24 -            <path>
   41.25 -                <filelist files="${disabled.modules}" dir="."/>
   41.26 -            </path>
   41.27 -        </pathconvert>
   41.28 -        <echo message="Downloading clusters ${download.clusters}"/>
   41.29 -        <property name="tasks.jar" location="${java.io.tmpdir}/tasks.jar"/>
   41.30 -        <get src="${bootstrap.url}" dest="${tasks.jar}" usetimestamp="true" verbose="true"/>
   41.31 -        <taskdef name="autoupdate" classname="org.netbeans.nbbuild.AutoUpdate" classpath="${tasks.jar}"/>
   41.32 -        <autoupdate installdir="${nbplatform.active.dir}" updatecenter="${autoupdate.catalog.url}">
   41.33 -            <modules includes="${module.includes}.*" clusters="${download.clusters}"/>
   41.34 -            <modules includes="org[.]netbeans[.]modules[.]apisupport[.]harness" clusters="harness"/>
   41.35 -        </autoupdate>
   41.36 -    </target>
   41.37 -</project>
    42.1 --- a/java.hints/nbproject/project.properties	Sun Oct 16 08:01:27 2016 +0200
    42.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.3 @@ -1,7 +0,0 @@
    42.4 -modules=\
    42.5 -    ${project.org.netbeans.spi.java.hints}:\
    42.6 -    ${project.org.netbeans.modules.java.hints.test}:\
    42.7 -    ${project.org.netbeans.modules.jackpot30.hintsimpl}
    42.8 -project.org.netbeans.modules.jackpot30.hintsimpl=hintsimpl
    42.9 -project.org.netbeans.modules.java.hints.test=java.hints.test
   42.10 -project.org.netbeans.spi.java.hints=spi.java.hints
    43.1 --- a/java.hints/nbproject/project.xml	Sun Oct 16 08:01:27 2016 +0200
    43.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.3 @@ -1,9 +0,0 @@
    43.4 -<?xml version="1.0" encoding="UTF-8"?>
    43.5 -<project xmlns="http://www.netbeans.org/ns/project/1">
    43.6 -    <type>org.netbeans.modules.apisupport.project.suite</type>
    43.7 -    <configuration>
    43.8 -        <data xmlns="http://www.netbeans.org/ns/nb-module-suite-project/1">
    43.9 -            <name>java.hints</name>
   43.10 -        </data>
   43.11 -    </configuration>
   43.12 -</project>
    44.1 --- a/java.hints/spi.java.hints/apichanges.xml	Sun Oct 16 08:01:27 2016 +0200
    44.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.3 @@ -1,139 +0,0 @@
    44.4 -<?xml version="1.0" encoding="UTF-8"?>
    44.5 -<!--
    44.6 -DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    44.7 -
    44.8 -Copyright 2012 Oracle and/or its affiliates. All rights reserved.
    44.9 -
   44.10 -Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   44.11 -Other names may be trademarks of their respective owners.
   44.12 -
   44.13 -The contents of this file are subject to the terms of either the GNU
   44.14 -General Public License Version 2 only ("GPL") or the Common
   44.15 -Development and Distribution License("CDDL") (collectively, the
   44.16 -"License"). You may not use this file except in compliance with the
   44.17 -License. You can obtain a copy of the License at
   44.18 -http://www.netbeans.org/cddl-gplv2.html
   44.19 -or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   44.20 -specific language governing permissions and limitations under the
   44.21 -License.  When distributing the software, include this License Header
   44.22 -Notice in each file and include the License file at
   44.23 -nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   44.24 -particular file as subject to the "Classpath" exception as provided
   44.25 -by Oracle in the GPL Version 2 section of the License file that
   44.26 -accompanied this code. If applicable, add the following below the
   44.27 -License Header, with the fields enclosed by brackets [] replaced by
   44.28 -your own identifying information:
   44.29 -"Portions Copyrighted [year] [name of copyright owner]"
   44.30 -
   44.31 -If you wish your version of this file to be governed by only the CDDL
   44.32 -or only the GPL Version 2, indicate your decision by adding
   44.33 -"[Contributor] elects to include this software in this distribution
   44.34 -under the [CDDL or GPL Version 2] license." If you do not indicate a
   44.35 -single choice of license, a recipient has the option to distribute
   44.36 -your version of this file under either the CDDL, the GPL Version 2 or
   44.37 -to extend the choice of license to its licensees as provided above.
   44.38 -However, if you add GPL Version 2 code and therefore, elected the GPL
   44.39 -Version 2 license, then the option applies only if the new code is
   44.40 -made subject to such option by the copyright holder.
   44.41 -
   44.42 -Contributor(s):
   44.43 -
   44.44 -Portions Copyrighted 2012 Sun Microsystems, Inc.
   44.45 --->
   44.46 -<!DOCTYPE apichanges PUBLIC "-//NetBeans//DTD API changes list 1.0//EN" "../nbbuild/javadoctools/apichanges.dtd">
   44.47 -<apichanges>
   44.48 -    <apidefs>
   44.49 -        <apidef name="JavaHintsSPI">Java Hints SPI</apidef>
   44.50 -    </apidefs>
   44.51 -    <changes>
   44.52 -        <change id="ProjectHintsJava">
   44.53 -            <api name="JavaHintsSPI"/>
   44.54 -            <summary>Defining system filesystem folder for per-project Java hints customizers</summary>
   44.55 -            <version major="1" minor="16"/>
   44.56 -            <date day="24" month="4" year="2013"/>
   44.57 -            <author login="jlahoda"/>
   44.58 -            <compatibility addition="yes"/>
   44.59 -            <description>
   44.60 -                <p>
   44.61 -                    Defining <code>Project/hints/java-based</code> folder, where provider for
   44.62 -                    hints customizers for Java-based projects should be stored.
   44.63 -                </p>    
   44.64 -            </description>
   44.65 -<!--            <issue number="227959"/>-->
   44.66 -        </change>
   44.67 -        <change id="IntegerOption">
   44.68 -            <api name="JavaHintsSPI"/>
   44.69 -            <summary>Added support for integer options. Hints can be declared to appear only in inspect &amp; transform</summary>
   44.70 -            <version major="1" minor="14"/>
   44.71 -            <date day="3" month="4" year="2013"/>
   44.72 -            <author login="sdedic"/>
   44.73 -            <compatibility addition="yes"/>
   44.74 -            <description>
   44.75 -                <p>
   44.76 -                    Added declarative support for integer options. <code>@IntegerOption</code> can
   44.77 -                    be used with option name field, similar to <code>@BooleanOption</code>.
   44.78 -                </p>    
   44.79 -                <p>
   44.80 -                    An option was added to <code>Hint.Options</code>, so that hint can declare
   44.81 -                    to be only shown in Inspect &amp; transform dialog. Useful for computation-intensive
   44.82 -                    hints, which should only run on demand.
   44.83 -                </p>    
   44.84 -            </description>
   44.85 -            <class package="org.netbeans.spi.java.hints" name="IntegerOption"/>
   44.86 -            <class package="org.netbeans.spi.java.hints" name="Hint"/>
   44.87 -            <issue number="227822"/>
   44.88 -            <issue number="227959"/>
   44.89 -        </change>
   44.90 -        <change id="ErrorDescriptionFactory.forSpan">
   44.91 -            <api name="JavaHintsSPI"/>
   44.92 -            <summary>Introducing ErrorDescriptionFactory.forSpan.</summary>
   44.93 -            <version major="1" minor="9"/>
   44.94 -            <date day="19" month="12" year="2012"/>
   44.95 -            <author login="jlahoda"/>
   44.96 -            <compatibility addition="yes"/>
   44.97 -            <description>
   44.98 -                <p>
   44.99 -                    Added ErrorDescriptionFactory.forSpan to create the correct
  44.100 -                    Java-enhanced ErrorDescription from a span.
  44.101 -                </p>    
  44.102 -            </description>
  44.103 -            <class package="org.netbeans.spi.java.hints" name="ErrorDescriptionFactory"/>
  44.104 -            <issue number="223723"/>
  44.105 -        </change>
  44.106 -        <change id="TransformationSupport">
  44.107 -            <api name="JavaHintsSPI"/>
  44.108 -            <summary>Added support for using jackpot patterns from other modules (e.g. refactoring).</summary>
  44.109 -            <version major="1" minor="1"/>
  44.110 -            <date day="29" month="3" year="2012"/>
  44.111 -            <author login="jbecicka"/>
  44.112 -            <compatibility addition="yes"/>
  44.113 -            <description>
  44.114 -                <p>
  44.115 -                    Added support for using jackpot patterns from other modules (e.g. refactoring).
  44.116 -                </p>    
  44.117 -            </description>
  44.118 -            <class package="org.netbeans.spi.java.hints.support" name="TransformationSupport"/>
  44.119 -            <issue number="210262"/>
  44.120 -        </change>
  44.121 -    </changes>
  44.122 -    <htmlcontents>
  44.123 -        <head>
  44.124 -            <title>Change History for the Java Hints SPI</title>
  44.125 -            <link rel="stylesheet" href="prose.css" type="text/css"/>
  44.126 -        </head>
  44.127 -        <body>
  44.128 -            <p class="overviewlink">
  44.129 -                <a href="overview-summary.html">Overview</a>
  44.130 -            </p>
  44.131 -            <h1>Introduction</h1>
  44.132 -            <p>This document lists changes made to the Java Hints SPI.</p>
  44.133 -            
  44.134 -            <!-- The actual lists of changes, as summaries and details: -->
  44.135 -            <hr/>
  44.136 -            <standard-changelists module-code-name="$codebase"/>
  44.137 -            
  44.138 -            <hr/>
  44.139 -            <p>@FOOTER@</p>
  44.140 -        </body>
  44.141 -    </htmlcontents>
  44.142 -</apichanges>
    45.1 --- a/java.hints/spi.java.hints/arch.xml	Sun Oct 16 08:01:27 2016 +0200
    45.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.3 @@ -1,1115 +0,0 @@
    45.4 -<?xml version="1.0" encoding="UTF-8"?>
    45.5 -<!DOCTYPE api-answers PUBLIC "-//NetBeans//DTD Arch Answers//EN" "../nbbuild/antsrc/org/netbeans/nbbuild/Arch.dtd" [
    45.6 -  <!ENTITY api-questions SYSTEM "../nbbuild/antsrc/org/netbeans/nbbuild/Arch-api-questions.xml">
    45.7 -]>
    45.8 -
    45.9 -<api-answers
   45.10 -  question-version="1.29"
   45.11 -  author="jlahoda@netbeans.org"
   45.12 ->
   45.13 -
   45.14 -  &api-questions;
   45.15 -
   45.16 -
   45.17 -<!--
   45.18 -        <question id="arch-overall" when="init">
   45.19 -            Describe the overall architecture. 
   45.20 -            <hint>
   45.21 -            What will be API for 
   45.22 -            <a href="http://openide.netbeans.org/tutorial/api-design.html#design.apiandspi">
   45.23 -                clients and what support API</a>? 
   45.24 -            What parts will be pluggable?
   45.25 -            How will plug-ins be registered? Please use <code>&lt;api type="export"/&gt;</code>
   45.26 -            to describe your general APIs and specify their
   45.27 -            <a href="http://openide.netbeans.org/tutorial/api-design.html#category-private">
   45.28 -            stability categories</a>.
   45.29 -            If possible please provide simple diagrams.
   45.30 -            </hint>
   45.31 -        </question>
   45.32 --->
   45.33 - <answer id="arch-overall">
   45.34 -  <p>
   45.35 -   <api type="export" category="devel" group="java" name="spi.java.hints">
   45.36 -       SPI to create custom Java hints, including code smell warnings, productivity tips, etc.
   45.37 -       Please see the Use Cases section for a guide on how to use this SPI.
   45.38 -   </api>
   45.39 -  </p>
   45.40 - </answer>
   45.41 -
   45.42 -
   45.43 -
   45.44 -<!--
   45.45 -        <question id="arch-quality" when="init">
   45.46 -            How will the <a href="http://www.netbeans.org/community/guidelines/q-evangelism.html">quality</a>
   45.47 -            of your code be tested and 
   45.48 -            how are future regressions going to be prevented?
   45.49 -            <hint>
   45.50 -            What kind of testing do
   45.51 -            you want to use? How much functionality, in which areas,
   45.52 -            should be covered by the tests? How you find out that your
   45.53 -            project was successful?
   45.54 -            </hint>
   45.55 -        </question>
   45.56 --->
   45.57 - <answer id="arch-quality">
   45.58 -  <p>
   45.59 -   XXX no answer for arch-quality
   45.60 -  </p>
   45.61 - </answer>
   45.62 -
   45.63 -
   45.64 -
   45.65 -<!--
   45.66 -        <question id="arch-time" when="init">
   45.67 -            What are the time estimates of the work?
   45.68 -            <hint>
   45.69 -            Please express your estimates of how long the design, implementation,
   45.70 -            stabilization are likely to last. How many people will be needed to
   45.71 -            implement this and what is the expected milestone by which the work should be 
   45.72 -            ready?
   45.73 -            </hint>
   45.74 -        </question>
   45.75 --->
   45.76 - <answer id="arch-time">
   45.77 -  <p>
   45.78 -   XXX no answer for arch-time
   45.79 -  </p>
   45.80 - </answer>
   45.81 -
   45.82 -
   45.83 -
   45.84 -<!--
   45.85 -        <question id="arch-usecases" when="init">
   45.86 -            <hint>
   45.87 -                Content of this answer will be displayed as part of page at
   45.88 -                http://www.netbeans.org/download/dev/javadoc/usecases.html 
   45.89 -                You can use tags &lt;usecase name="name&gt; regular html description &lt;/usecase&gt;
   45.90 -                and if you want to use an URL you can prefix if with @TOP@ to begin
   45.91 -                at the root of your javadoc
   45.92 -            </hint>
   45.93 -        
   45.94 -            Describe the main <a href="http://openide.netbeans.org/tutorial/api-design.html#usecase">
   45.95 -            use cases</a> of the new API. Who will use it under
   45.96 -            what circumstances? What kind of code would typically need to be written
   45.97 -            to use the module?
   45.98 -        </question>
   45.99 --->
  45.100 - <answer id="arch-usecases">
  45.101 -  <p>
  45.102 -   <usecase id="creating" name="Creating a new Java Hint">
  45.103 -       Simple way to create a new Java hint is as follows:
  45.104 -       <ul>
  45.105 -           <li>Create a new class, annotate it with the <a href="@TOP@/org/netbeans/spi/java/hints/Hint.html">@Hint</a>
  45.106 -           annotation to it.</li>
  45.107 -           <li>Create a <code>public static ErrorDescription hint(HintContext ctx) {}</code> method in the
  45.108 -           class. Annotate the method either with the <a href="@TOP@/org/netbeans/spi/java/hints/TriggerPattern.html">@TriggerPattern</a>
  45.109 -           annotation (strongly recommended), or with the <a href="@TOP@/org/netbeans/spi/java/hints/TriggerTreeKind.html">@TriggerTreeKind</a>.
  45.110 -           This method will be called when for parts of the code that match the given pattern, of for trees of the specified kinds.</li>
  45.111 -           <li>Perform whatever checks necessary to find out whether a warning should be produced at the given place, and produce the ErrorDescription if needed.</li>
  45.112 -       </ul>
  45.113 -       <br/>
  45.114 -       Tips:
  45.115 -       <ul>
  45.116 -           <li>Always use the java.hints' <a href="@TOP@/org/netbeans/spi/java/hints/ErrorDescriptionFactory.html">ErrorDescriptionFactory</a> to produce the resulting ErrorDescription.</li>
  45.117 -           <li>Never try to produce a custom suppress warnings "fix". Specify suppress warnings keys in the @Hint annotation.</li>
  45.118 -           <li>If an automated transformation is to be prodived from your hint, subclass <a href="@TOP@/org/netbeans/spi/java/hints/JavaFix.html">JavaFix</a> and
  45.119 -               use its <code>toEditorFix()</code> method to get the <code>Fix</code>, if the transformation is going to be used inside Inspect&amp;Transform.
  45.120 -           </li>
  45.121 -           <li>The name of the method is arbitrary, one hint can consist of more that one "triggered" method.</li>
  45.122 -       </ul>
  45.123 -   </usecase>
  45.124 -   <usecase id="no-class" name="Creating a new Java Hint Without a Class">
  45.125 -       For simple hints, it is possible to annotate the hint method with the <a href="@TOP@/org/netbeans/spi/java/hints/Hint.html">@Hint</a> annotation.
  45.126 -       The hint then consists of this sole method. Any number of such hints may be created in a single class.
  45.127 -   </usecase>
  45.128 -   <usecase id="testing" name="Creating a Tests for the Newly Created Java Hint">
  45.129 -       Creating automated tests for the hints is simple: create a test class, and use
  45.130 -       <a href="@TOP@/../org-netbeans-modules-java-hints-test/org/netbeans/modules/java/hints/test/api/HintTest.html">HintTest</a>
  45.131 -       to setup the test, run the hint and verify that its outcomes are correct.
  45.132 -       The tests automatically run with <code>test</code> branding, so create <code>Bundle_test.properties</code>, and add
  45.133 -       bundle keys into it for ErrorDescription and Fix display names, to isolate the test from changes in the production
  45.134 -       <code>Bundle.properties</code>.
  45.135 -   </usecase>
  45.136 -   <usecase id="adding-options" name="Adding options to a Java Hint">
  45.137 -       To add a simple boolean option to your hint, use <a href="@TOP@/org/netbeans/spi/java/hints/BooleanOption.html">@BooleanOption</a>.
  45.138 -   </usecase>
  45.139 -  </p>
  45.140 - </answer>
  45.141 -
  45.142 -
  45.143 -
  45.144 -<!--
  45.145 -        <question id="arch-what" when="init">
  45.146 -            What is this project good for?
  45.147 -            <hint>
  45.148 -            Please provide here a few lines describing the project, 
  45.149 -            what problem it should solve, provide links to documentation, 
  45.150 -            specifications, etc.
  45.151 -            </hint>
  45.152 -        </question>
  45.153 --->
  45.154 - <answer id="arch-what">
  45.155 -  <p>
  45.156 -   XXX no answer for arch-what
  45.157 -  </p>
  45.158 - </answer>
  45.159 -
  45.160 -
  45.161 -
  45.162 -<!--
  45.163 -        <question id="arch-where" when="impl">
  45.164 -            Where one can find sources for your module?
  45.165 -            <hint>
  45.166 -                Please provide link to the Hg web client at
  45.167 -                http://hg.netbeans.org/
  45.168 -                or just use tag defaultanswer generate='here'
  45.169 -            </hint>
  45.170 -        </question>
  45.171 --->
  45.172 - <answer id="arch-where">
  45.173 -  <defaultanswer generate='here' />
  45.174 - </answer>
  45.175 -
  45.176 -
  45.177 -
  45.178 -<!--
  45.179 -        <question id="compat-deprecation" when="init">
  45.180 -            How the introduction of your project influences functionality
  45.181 -            provided by previous version of the product?
  45.182 -            <hint>
  45.183 -            If you are planning to deprecate/remove/change any existing APIs,
  45.184 -            list them here accompanied with the reason explaining why you
  45.185 -            are doing so.
  45.186 -            </hint>
  45.187 -        </question>
  45.188 --->
  45.189 - <answer id="compat-deprecation">
  45.190 -  <p>
  45.191 -   XXX no answer for compat-deprecation
  45.192 -  </p>
  45.193 - </answer>
  45.194 -
  45.195 -
  45.196 -
  45.197 -<!--
  45.198 -        <question id="compat-i18n" when="impl">
  45.199 -            Is your module correctly internationalized?
  45.200 -            <hint>
  45.201 -            Correct internationalization means that it obeys instructions 
  45.202 -            at <a href="http://www.netbeans.org/download/dev/javadoc/org-openide-modules/org/openide/modules/doc-files/i18n-branding.html">
  45.203 -            NetBeans I18N pages</a>.
  45.204 -            </hint>
  45.205 -        </question>
  45.206 --->
  45.207 - <answer id="compat-i18n">
  45.208 -  <p>
  45.209 -   XXX no answer for compat-i18n
  45.210 -  </p>
  45.211 - </answer>
  45.212 -
  45.213 -
  45.214 -
  45.215 -<!--
  45.216 -        <question id="compat-standards" when="init">
  45.217 -            Does the module implement or define any standards? Is the 
  45.218 -            implementation exact or does it deviate somehow?
  45.219 -        </question>
  45.220 --->
  45.221 - <answer id="compat-standards">
  45.222 -  <p>
  45.223 -   XXX no answer for compat-standards
  45.224 -  </p>
  45.225 - </answer>
  45.226 -
  45.227 -
  45.228 -
  45.229 -<!--
  45.230 -        <question id="compat-version" when="impl">
  45.231 -            Can your module coexist with earlier and future
  45.232 -            versions of itself? Can you correctly read all old settings? Will future
  45.233 -            versions be able to read your current settings? Can you read
  45.234 -            or politely ignore settings stored by a future version?
  45.235 -            
  45.236 -            <hint>
  45.237 -            Very helpful for reading settings is to store version number
  45.238 -            there, so future versions can decide whether how to read/convert
  45.239 -            the settings and older versions can ignore the new ones.
  45.240 -            </hint>
  45.241 -        </question>
  45.242 --->
  45.243 - <answer id="compat-version">
  45.244 -  <p>
  45.245 -   XXX no answer for compat-version
  45.246 -  </p>
  45.247 - </answer>
  45.248 -
  45.249 -
  45.250 -
  45.251 -<!--
  45.252 -        <question id="dep-jre" when="final">
  45.253 -            Which version of JRE do you need (1.2, 1.3, 1.4, etc.)?
  45.254 -            <hint>
  45.255 -            It is expected that if your module runs on 1.x that it will run 
  45.256 -            on 1.x+1 if no, state that please. Also describe here cases where
  45.257 -            you run different code on different versions of JRE and why.
  45.258 -            </hint>
  45.259 -        </question>
  45.260 --->
  45.261 - <answer id="dep-jre">
  45.262 -  <p>
  45.263 -   XXX no answer for dep-jre
  45.264 -  </p>
  45.265 - </answer>
  45.266 -
  45.267 -
  45.268 -
  45.269 -<!--
  45.270 -        <question id="dep-jrejdk" when="final">
  45.271 -            Do you require the JDK or is the JRE enough?
  45.272 -        </question>
  45.273 --->
  45.274 - <answer id="dep-jrejdk">
  45.275 -  <p>
  45.276 -   XXX no answer for dep-jrejdk
  45.277 -  </p>
  45.278 - </answer>
  45.279 -
  45.280 -
  45.281 -
  45.282 -<!--
  45.283 -        <question id="dep-nb" when="init">
  45.284 -            What other NetBeans projects and modules does this one depend on?
  45.285 -            <hint>
  45.286 -            Depending on other NetBeans projects influnces the ability of
  45.287 -            users of your work to customize their own branded version of
  45.288 -            NetBeans by enabling and disabling some modules. Too
  45.289 -            much dependencies restrict this kind of customization. If that
  45.290 -            is your case, then you may want to split your functionality into
  45.291 -            pieces of autoload, eager and regular modules which can be
  45.292 -            enabled independently. Usually the answer to this question
  45.293 -            is generated from your <code>project.xml</code> file, but
  45.294 -            if it is not guessed correctly, you can suppress it by
  45.295 -            specifying &lt;defaultanswer generate="none"/&gt; and
  45.296 -            write here your own. Please describe such projects as imported APIs using
  45.297 -            the <code>&lt;api name="identification" type="import or export" category="stable" url="where is the description" /&gt;</code>.
  45.298 -            By doing this information gets listed in the summary page of your
  45.299 -            javadoc.
  45.300 -            </hint>
  45.301 -        </question>
  45.302 --->
  45.303 - <answer id="dep-nb">
  45.304 -  <defaultanswer generate='here' />
  45.305 - </answer>
  45.306 -
  45.307 -
  45.308 -
  45.309 -<!--
  45.310 -        <question id="dep-non-nb" when="init">
  45.311 -            What other projects outside NetBeans does this one depend on?
  45.312 -            
  45.313 -            <hint>
  45.314 -            Depending on 3rd party libraries is always problematic,
  45.315 -            especially if they are not open source, as that complicates
  45.316 -            the licensing scheme of NetBeans. Please enumerate your
  45.317 -            external dependencies here, so it is correctly understood since
  45.318 -            the begining what are the legal implications of your project.
  45.319 -            Also please note that
  45.320 -            some non-NetBeans projects are packaged as NetBeans modules
  45.321 -            (see <a href="http://libs.netbeans.org/">libraries</a>) and
  45.322 -            it is preferred to use this approach when more modules may
  45.323 -            depend and share such third-party libraries.
  45.324 -            </hint>
  45.325 -        </question>
  45.326 --->
  45.327 - <answer id="dep-non-nb">
  45.328 -  <p>
  45.329 -   XXX no answer for dep-non-nb
  45.330 -  </p>
  45.331 - </answer>
  45.332 -
  45.333 -
  45.334 -
  45.335 -<!--
  45.336 -        <question id="dep-platform" when="init">
  45.337 -            On which platforms does your module run? Does it run in the same
  45.338 -            way on each?
  45.339 -            <hint>
  45.340 -            If you plan any dependency on OS or any usage of native code,
  45.341 -            please describe why you are doing so and describe how you envision
  45.342 -            to enforce the portability of your code.
  45.343 -            Please note that there is a support for <a href="http://www.netbeans.org/download/dev/javadoc/org-openide-modules/org/openide/modules/doc-files/api.html#how-os-specific">OS conditionally
  45.344 -            enabled modules</a> which together with autoload/eager modules
  45.345 -            can allow you to enable to provide the best OS aware support
  45.346 -            on certain OSes while providing compatibility bridge on the not
  45.347 -            supported ones.
  45.348 -            Also please list the supported
  45.349 -            OSes/HW platforms and mentioned the lovest version of JDK required
  45.350 -            for your project to run on. Also state whether JRE is enough or
  45.351 -            you really need JDK.
  45.352 -            </hint>
  45.353 -        </question>
  45.354 --->
  45.355 - <answer id="dep-platform">
  45.356 -  <p>
  45.357 -   XXX no answer for dep-platform
  45.358 -  </p>
  45.359 - </answer>
  45.360 -
  45.361 -
  45.362 -
  45.363 -<!--
  45.364 -        <question id="deploy-dependencies" when="final">
  45.365 -            What do other modules need to do to declare a dependency on this one,
  45.366 -            in addition to or instead of the normal module dependency declaration
  45.367 -            (e.g. tokens to require)?
  45.368 -            <hint>
  45.369 -                Provide a sample of the actual lines you would add to a module manifest
  45.370 -                to declare a dependency, for example OpenIDE-Module-Requires: some.token.
  45.371 -                If other modules should not depend on this module, or should just use a
  45.372 -                simple regular module dependency, you can just answer "nothing". If you
  45.373 -                intentionally expose a semistable API to clients using implementation
  45.374 -                dependencies, you should mention that here (but there is no need to give
  45.375 -                an example of usage).
  45.376 -            </hint>
  45.377 -        </question>
  45.378 --->
  45.379 - <answer id="deploy-dependencies">
  45.380 -  <p>
  45.381 -   XXX no answer for deploy-dependencies
  45.382 -  </p>
  45.383 - </answer>
  45.384 -
  45.385 -
  45.386 -
  45.387 -<!--
  45.388 -        <question id="deploy-jar" when="impl">
  45.389 -            Do you deploy just module JAR file(s) or other files as well?
  45.390 -            <hint>
  45.391 -            Usually a module consist of one JAR file (perhaps with Class-Path
  45.392 -            extensions) and also a configuration file that enables it. If you
  45.393 -            have any other files, use
  45.394 -            &lt;api group="java.io.File" name="yourname" type="export" category="friend"&gt;...&lt;/api&gt;
  45.395 -            to define the location, name and stability of your files (of course
  45.396 -            changing "yourname" and "friend" to suit your needs).
  45.397 -            
  45.398 -            If it uses more than one JAR, describe where they are located, how
  45.399 -            they refer to each other. 
  45.400 -            If it consist of module JAR(s) and other files, please describe
  45.401 -            what is their purpose, why other files are necessary. Please 
  45.402 -            make sure that installation/uninstallation leaves the system 
  45.403 -            in state as it was before installation.
  45.404 -            </hint>
  45.405 -        </question>
  45.406 --->
  45.407 - <answer id="deploy-jar">
  45.408 -  <p>
  45.409 -   XXX no answer for deploy-jar
  45.410 -  </p>
  45.411 - </answer>
  45.412 -
  45.413 -
  45.414 -
  45.415 -<!--
  45.416 -        <question id="deploy-nbm" when="impl">
  45.417 -            Can you deploy an NBM via the Update Center?
  45.418 -            <hint>
  45.419 -            If not why?
  45.420 -            </hint>
  45.421 -        </question>
  45.422 --->
  45.423 - <answer id="deploy-nbm">
  45.424 -  <p>
  45.425 -   XXX no answer for deploy-nbm
  45.426 -  </p>
  45.427 - </answer>
  45.428 -
  45.429 -
  45.430 -
  45.431 -<!--
  45.432 -        <question id="deploy-packages" when="init">
  45.433 -            Are packages of your module made inaccessible by not declaring them
  45.434 -            public?
  45.435 -            
  45.436 -            <hint>
  45.437 -            By default NetBeans build harness treats all packages are private.
  45.438 -            If you export some of them - either as public or friend packages,
  45.439 -            you should have a reason. If the reason is described elsewhere
  45.440 -            in this document, you can ignore this question.
  45.441 -            </hint>
  45.442 -        </question>
  45.443 --->
  45.444 - <answer id="deploy-packages">
  45.445 -  <p>
  45.446 -   XXX no answer for deploy-packages
  45.447 -  </p>
  45.448 - </answer>
  45.449 -
  45.450 -
  45.451 -
  45.452 -<!--
  45.453 -        <question id="deploy-shared" when="final">
  45.454 -            Do you need to be installed in the shared location only, or in the user directory only,
  45.455 -            or can your module be installed anywhere?
  45.456 -            <hint>
  45.457 -            Installation location shall not matter, if it does explain why.
  45.458 -            Consider also whether <code>InstalledFileLocator</code> can help.
  45.459 -            </hint>
  45.460 -        </question>
  45.461 --->
  45.462 - <answer id="deploy-shared">
  45.463 -  <p>
  45.464 -   XXX no answer for deploy-shared
  45.465 -  </p>
  45.466 - </answer>
  45.467 -
  45.468 -
  45.469 -
  45.470 -<!--
  45.471 -        <question id="exec-ant-tasks" when="impl">
  45.472 -            Do you define or register any ant tasks that other can use?
  45.473 -            
  45.474 -            <hint>
  45.475 -            If you provide an ant task that users can use, you need to be very
  45.476 -            careful about its syntax and behaviour, as it most likely forms an
  45.477 -	          API for end users and as there is a lot of end users, their reaction
  45.478 -            when such API gets broken can be pretty strong.
  45.479 -            </hint>
  45.480 -        </question>
  45.481 --->
  45.482 - <answer id="exec-ant-tasks">
  45.483 -  <p>
  45.484 -   XXX no answer for exec-ant-tasks
  45.485 -  </p>
  45.486 - </answer>
  45.487 -
  45.488 -
  45.489 -
  45.490 -<!--
  45.491 -        <question id="exec-classloader" when="impl">
  45.492 -            Does your code create its own class loader(s)?
  45.493 -            <hint>
  45.494 -            A bit unusual. Please explain why and what for.
  45.495 -            </hint>
  45.496 -        </question>
  45.497 --->
  45.498 - <answer id="exec-classloader">
  45.499 -  <p>
  45.500 -   XXX no answer for exec-classloader
  45.501 -  </p>
  45.502 - </answer>
  45.503 -
  45.504 -
  45.505 -
  45.506 -<!--
  45.507 -        <question id="exec-component" when="impl">
  45.508 -            Is execution of your code influenced by any (string) property
  45.509 -            of any of your components?
  45.510 -            
  45.511 -            <hint>
  45.512 -            Often <code>JComponent.getClientProperty</code>, <code>Action.getValue</code>
  45.513 -            or <code>PropertyDescriptor.getValue</code>, etc. are used to influence
  45.514 -            a behavior of some code. This of course forms an interface that should
  45.515 -            be documented. Also if one depends on some interface that an object
  45.516 -            implements (<code>component instanceof Runnable</code>) that forms an
  45.517 -            API as well.
  45.518 -            </hint>
  45.519 -        </question>
  45.520 --->
  45.521 - <answer id="exec-component">
  45.522 -  <p>
  45.523 -   XXX no answer for exec-component
  45.524 -  </p>
  45.525 - </answer>
  45.526 -
  45.527 -
  45.528 -
  45.529 -<!--
  45.530 -        <question id="exec-introspection" when="impl">
  45.531 -            Does your module use any kind of runtime type information (<code>instanceof</code>,
  45.532 -            work with <code>java.lang.Class</code>, etc.)?
  45.533 -            <hint>
  45.534 -            Check for cases when you have an object of type A and you also
  45.535 -            expect it to (possibly) be of type B and do some special action. That
  45.536 -            should be documented. The same applies on operations in meta-level
  45.537 -            (Class.isInstance(...), Class.isAssignableFrom(...), etc.).
  45.538 -            </hint>
  45.539 -        </question>
  45.540 --->
  45.541 - <answer id="exec-introspection">
  45.542 -  <p>
  45.543 -   XXX no answer for exec-introspection
  45.544 -  </p>
  45.545 - </answer>
  45.546 -
  45.547 -
  45.548 -
  45.549 -<!--
  45.550 -        <question id="exec-privateaccess" when="final">
  45.551 -            Are you aware of any other parts of the system calling some of 
  45.552 -            your methods by reflection?
  45.553 -            <hint>
  45.554 -            If so, describe the "contract" as an API. Likely private or friend one, but
  45.555 -            still API and consider rewrite of it.
  45.556 -            </hint>
  45.557 -        </question>
  45.558 --->
  45.559 - <answer id="exec-privateaccess">
  45.560 -  <p>
  45.561 -   XXX no answer for exec-privateaccess
  45.562 -  </p>
  45.563 - </answer>
  45.564 -
  45.565 -
  45.566 -
  45.567 -<!--
  45.568 -        <question id="exec-process" when="impl">
  45.569 -            Do you execute an external process from your module? How do you ensure
  45.570 -            that the result is the same on different platforms? Do you parse output?
  45.571 -            Do you depend on result code?
  45.572 -            <hint>
  45.573 -            If you feed an input, parse the output please declare that as an API.
  45.574 -            </hint>
  45.575 -        </question>
  45.576 --->
  45.577 - <answer id="exec-process">
  45.578 -  <p>
  45.579 -   XXX no answer for exec-process
  45.580 -  </p>
  45.581 - </answer>
  45.582 -
  45.583 -
  45.584 -
  45.585 -<!--
  45.586 -        <question id="exec-property" when="impl">
  45.587 -            Is execution of your code influenced by any environment or
  45.588 -            Java system (<code>System.getProperty</code>) property?
  45.589 -            On a similar note, is there something interesting that you
  45.590 -            pass to <code>java.util.logging.Logger</code>? Or do you observe
  45.591 -            what others log?
  45.592 -            <hint>
  45.593 -            If there is a property that can change the behavior of your 
  45.594 -            code, somebody will likely use it. You should describe what it does 
  45.595 -            and the <a href="http://openide.netbeans.org/tutorial/api-design.html#life">stability category</a>
  45.596 -            of this API. You may use
  45.597 -            <pre>
  45.598 -                &lt;api type="export" group="property" name="id" category="private" url="http://..."&gt;
  45.599 -                    description of the property, where it is used, what it influence, etc.
  45.600 -                &lt;/api&gt;            
  45.601 -            </pre>
  45.602 -            </hint>
  45.603 -        </question>
  45.604 --->
  45.605 - <answer id="exec-property">
  45.606 -  <p>
  45.607 -   XXX no answer for exec-property
  45.608 -  </p>
  45.609 - </answer>
  45.610 -
  45.611 -
  45.612 -
  45.613 -<!--
  45.614 -        <question id="exec-reflection" when="impl">
  45.615 -            Does your code use Java Reflection to execute other code?
  45.616 -            <hint>
  45.617 -            This usually indicates a missing or insufficient API in the other
  45.618 -            part of the system. If the other side is not aware of your dependency
  45.619 -            this contract can be easily broken.
  45.620 -            </hint>
  45.621 -        </question>
  45.622 --->
  45.623 - <answer id="exec-reflection">
  45.624 -  <p>
  45.625 -   XXX no answer for exec-reflection
  45.626 -  </p>
  45.627 - </answer>
  45.628 -
  45.629 -
  45.630 -
  45.631 -<!--
  45.632 -        <question id="exec-threading" when="init">
  45.633 -            What threading models, if any, does your module adhere to? How the
  45.634 -            project behaves with respect to threading?
  45.635 -            <hint>
  45.636 -                Is your API threadsafe? Can it be accessed from any threads or
  45.637 -                just from some dedicated ones? Any special relation to AWT and
  45.638 -                its Event Dispatch thread? Also
  45.639 -                if your module calls foreign APIs which have a specific threading model,
  45.640 -                indicate how you comply with the requirements for multithreaded access
  45.641 -                (synchronization, mutexes, etc.) applicable to those APIs.
  45.642 -                If your module defines any APIs, or has complex internal structures
  45.643 -                that might be used from multiple threads, declare how you protect
  45.644 -                data against concurrent access, race conditions, deadlocks, etc.,
  45.645 -                and whether such rules are enforced by runtime warnings, errors, assertions, etc.
  45.646 -                Examples: a class might be non-thread-safe (like Java Collections); might
  45.647 -                be fully thread-safe (internal locking); might require access through a mutex
  45.648 -                (and may or may not automatically acquire that mutex on behalf of a client method);
  45.649 -                might be able to run only in the event queue; etc.
  45.650 -                Also describe when any events are fired: synchronously, asynchronously, etc.
  45.651 -                Ideas: <a href="http://core.netbeans.org/proposals/threading/index.html#recommendations">Threading Recommendations</a> (in progress)
  45.652 -            </hint>
  45.653 -        </question>
  45.654 --->
  45.655 - <answer id="exec-threading">
  45.656 -  <p>
  45.657 -   XXX no answer for exec-threading
  45.658 -  </p>
  45.659 - </answer>
  45.660 -
  45.661 -
  45.662 -
  45.663 -<!--
  45.664 -        <question id="format-clipboard" when="impl">
  45.665 -            Which data flavors (if any) does your code read from or insert to
  45.666 -            the clipboard (by access to clipboard on means calling methods on <code>java.awt.datatransfer.Transferable</code>?
  45.667 -            
  45.668 -            <hint>
  45.669 -            Often Node's deal with clipboard by usage of <code>Node.clipboardCopy, Node.clipboardCut and Node.pasteTypes</code>.
  45.670 -            Check your code for overriding these methods.
  45.671 -            </hint>
  45.672 -        </question>
  45.673 --->
  45.674 - <answer id="format-clipboard">
  45.675 -  <p>
  45.676 -   XXX no answer for format-clipboard
  45.677 -  </p>
  45.678 - </answer>
  45.679 -
  45.680 -
  45.681 -
  45.682 -<!--
  45.683 -        <question id="format-dnd" when="impl">
  45.684 -            Which protocols (if any) does your code understand during Drag &amp; Drop?
  45.685 -            <hint>
  45.686 -            Often Node's deal with clipboard by usage of <code>Node.drag, Node.getDropType</code>. 
  45.687 -            Check your code for overriding these methods. Btw. if they are not overridden, they
  45.688 -            by default delegate to <code>Node.clipboardCopy, Node.clipboardCut and Node.pasteTypes</code>.
  45.689 -            </hint>
  45.690 -        </question>
  45.691 --->
  45.692 - <answer id="format-dnd">
  45.693 -  <p>
  45.694 -   XXX no answer for format-dnd
  45.695 -  </p>
  45.696 - </answer>
  45.697 -
  45.698 -
  45.699 -
  45.700 -<!--
  45.701 -        <question id="format-types" when="impl">
  45.702 -            Which protocols and file formats (if any) does your module read or write on disk,
  45.703 -            or transmit or receive over the network? Do you generate an ant build script?
  45.704 -            Can it be edited and modified? 
  45.705 -            
  45.706 -            <hint>
  45.707 -            <p>
  45.708 -            Files can be read and written by other programs, modules and users. If they influence
  45.709 -            your behaviour, make sure you either document the format or claim that it is a private
  45.710 -            api (using the &lt;api&gt; tag). 
  45.711 -            </p>
  45.712 -            
  45.713 -            <p>
  45.714 -            If you generate an ant build file, this is very likely going to be seen by end users and
  45.715 -            they will be attempted to edit it. You should be ready for that and provide here a link
  45.716 -            to documentation that you have for such purposes and also describe how you are going to
  45.717 -            understand such files during next release, when you (very likely) slightly change the 
  45.718 -            format.
  45.719 -            </p>
  45.720 -            </hint>
  45.721 -        </question>
  45.722 --->
  45.723 - <answer id="format-types">
  45.724 -  <p>
  45.725 -   XXX no answer for format-types
  45.726 -  </p>
  45.727 - </answer>
  45.728 -
  45.729 -
  45.730 -
  45.731 -<!--
  45.732 -        <question id="lookup-lookup" when="init">
  45.733 -            Does your module use <code>org.openide.util.Lookup</code>
  45.734 -            or any similar technology to find any components to communicate with? Which ones?
  45.735 -            
  45.736 -            <hint>
  45.737 -            NetBeans is build around a generic registry of services called
  45.738 -            lookup. It is preferable to use it for registration and discovery
  45.739 -            if possible. See
  45.740 -            <a href="http://www.netbeans.org/download/dev/javadoc/org-openide-util/org/openide/util/lookup/doc-files/index.html">
  45.741 -            The Solution to Comunication Between Components
  45.742 -            </a>. If you do not plan to use lookup and insist usage
  45.743 -            of other solution, then please describe why it is not working for
  45.744 -            you.
  45.745 -            <br/>
  45.746 -            When filling the final version of your arch document, please
  45.747 -            describe the interfaces you are searching for, where 
  45.748 -            are defined, whether you are searching for just one or more of them,
  45.749 -            if the order is important, etc. Also classify the stability of such
  45.750 -            API contract. Use &lt;api group=&amp;lookup&amp; /&gt; tag, so
  45.751 -            your information gets listed in the summary page of your javadoc.
  45.752 -            </hint>
  45.753 -        </question>
  45.754 --->
  45.755 - <answer id="lookup-lookup">
  45.756 -  <p>
  45.757 -   XXX no answer for lookup-lookup
  45.758 -  </p>
  45.759 - </answer>
  45.760 -
  45.761 -
  45.762 -
  45.763 -<!--
  45.764 -        <question id="lookup-register" when="final">
  45.765 -            Do you register anything into lookup for other code to find?
  45.766 -            <hint>
  45.767 -            Do you register using layer file or using a declarative annotation such as <code>@ServiceProvider</code>?
  45.768 -            Who is supposed to find your component?
  45.769 -            </hint>
  45.770 -        </question>
  45.771 --->
  45.772 - <answer id="lookup-register">
  45.773 -  <p>
  45.774 -   XXX no answer for lookup-register
  45.775 -  </p>
  45.776 - </answer>
  45.777 -
  45.778 -
  45.779 -
  45.780 -<!--
  45.781 -        <question id="lookup-remove" when="final">
  45.782 -            Do you remove entries of other modules from lookup?
  45.783 -            <hint>
  45.784 -            Why? Of course, that is possible, but it can be dangerous. Is the module
  45.785 -            your are masking resource from aware of what you are doing?
  45.786 -            </hint>
  45.787 -        </question>
  45.788 --->
  45.789 - <answer id="lookup-remove">
  45.790 -  <p>
  45.791 -   XXX no answer for lookup-remove
  45.792 -  </p>
  45.793 - </answer>
  45.794 -
  45.795 -
  45.796 -
  45.797 -<!--
  45.798 -        <question id="perf-exit" when="final">
  45.799 -            Does your module run any code on exit?
  45.800 -        </question>
  45.801 --->
  45.802 - <answer id="perf-exit">
  45.803 -  <p>
  45.804 -   XXX no answer for perf-exit
  45.805 -  </p>
  45.806 - </answer>
  45.807 -
  45.808 -
  45.809 -
  45.810 -<!--
  45.811 -        <question id="perf-huge_dialogs" when="final">
  45.812 -            Does your module contain any dialogs or wizards with a large number of
  45.813 -            GUI controls such as combo boxes, lists, trees, or text areas?
  45.814 -        </question>
  45.815 --->
  45.816 - <answer id="perf-huge_dialogs">
  45.817 -  <p>
  45.818 -   XXX no answer for perf-huge_dialogs
  45.819 -  </p>
  45.820 - </answer>
  45.821 -
  45.822 -
  45.823 -
  45.824 -<!--
  45.825 -        <question id="perf-limit" when="init">
  45.826 -            Are there any hard-coded or practical limits in the number or size of
  45.827 -            elements your code can handle?
  45.828 -            <hint>
  45.829 -                Most of algorithms have increasing memory and speed complexity
  45.830 -                with respect to size of data they operate on. What is the critical
  45.831 -                part of your project that can be seen as a bottleneck with
  45.832 -                respect to speed or required memory? What are the practical
  45.833 -                sizes of data you tested your project with? What is your estimate
  45.834 -                of potential size of data that would cause visible performance
  45.835 -                problems? Is there some kind of check to detect such situation
  45.836 -                and prevent "hard" crashes - for example the CloneableEditorSupport
  45.837 -                checks for size of a file to be opened in editor
  45.838 -                and if it is larger than 1Mb it shows a dialog giving the
  45.839 -                user the right to decide - e.g. to cancel or commit suicide.
  45.840 -            </hint>
  45.841 -        </question>
  45.842 --->
  45.843 - <answer id="perf-limit">
  45.844 -  <p>
  45.845 -   XXX no answer for perf-limit
  45.846 -  </p>
  45.847 - </answer>
  45.848 -
  45.849 -
  45.850 -
  45.851 -<!--
  45.852 -        <question id="perf-mem" when="final">
  45.853 -            How much memory does your component consume? Estimate
  45.854 -            with a relation to the number of windows, etc.
  45.855 -        </question>
  45.856 --->
  45.857 - <answer id="perf-mem">
  45.858 -  <p>
  45.859 -   XXX no answer for perf-mem
  45.860 -  </p>
  45.861 - </answer>
  45.862 -
  45.863 -
  45.864 -
  45.865 -<!--
  45.866 -        <question id="perf-menus" when="final">
  45.867 -            Does your module use dynamically updated context menus, or
  45.868 -            context-sensitive actions with complicated and slow enablement logic?
  45.869 -            <hint>
  45.870 -                If you do a lot of tricks when adding actions to regular or context menus, you can significantly
  45.871 -                slow down display of the menu, even when the user is not using your action. Pay attention to
  45.872 -                actions you add to the main menu bar, and to context menus of foreign nodes or components. If
  45.873 -                the action is conditionally enabled, or changes its display dynamically, you need to check the
  45.874 -                impact on performance. In some cases it may be more appropriate to make a simple action that is
  45.875 -                always enabled but does more detailed checks in a dialog if it is actually run.
  45.876 -            </hint>
  45.877 -        </question>
  45.878 --->
  45.879 - <answer id="perf-menus">
  45.880 -  <p>
  45.881 -   XXX no answer for perf-menus
  45.882 -  </p>
  45.883 - </answer>
  45.884 -
  45.885 -
  45.886 -
  45.887 -<!--
  45.888 -        <question id="perf-progress" when="final">
  45.889 -            Does your module execute any long-running tasks?
  45.890 -            
  45.891 -            <hint>Long running tasks should never block 
  45.892 -            AWT thread as it badly hurts the UI
  45.893 -            <a href="http://performance.netbeans.org/responsiveness/issues.html">
  45.894 -            responsiveness</a>.
  45.895 -            Tasks like connecting over
  45.896 -            network, computing huge amount of data, compilation
  45.897 -            be done asynchronously (for example
  45.898 -            using <code>RequestProcessor</code>), definitively it should 
  45.899 -            not block AWT thread.
  45.900 -            </hint>
  45.901 -        </question>
  45.902 --->
  45.903 - <answer id="perf-progress">
  45.904 -  <p>
  45.905 -   XXX no answer for perf-progress
  45.906 -  </p>
  45.907 - </answer>
  45.908 -
  45.909 -
  45.910 -
  45.911 -<!--
  45.912 -        <question id="perf-scale" when="init">
  45.913 -            Which external criteria influence the performance of your
  45.914 -            program (size of file in editor, number of files in menu, 
  45.915 -            in source directory, etc.) and how well your code scales?
  45.916 -            <hint>
  45.917 -            Please include some estimates, there are other more detailed 
  45.918 -            questions to answer in later phases of implementation. 
  45.919 -            </hint>
  45.920 -        </question>
  45.921 --->
  45.922 - <answer id="perf-scale">
  45.923 -  <p>
  45.924 -   XXX no answer for perf-scale
  45.925 -  </p>
  45.926 - </answer>
  45.927 -
  45.928 -
  45.929 -
  45.930 -<!--
  45.931 -        <question id="perf-spi" when="init">
  45.932 -            How the performance of the plugged in code will be enforced?
  45.933 -            <hint>
  45.934 -            If you allow foreign code to be plugged into your own module, how
  45.935 -            do you enforce that it will behave correctly and quickly and will not
  45.936 -            negatively influence the performance of your own module?
  45.937 -            </hint>
  45.938 -        </question>
  45.939 --->
  45.940 - <answer id="perf-spi">
  45.941 -  <p>
  45.942 -   XXX no answer for perf-spi
  45.943 -  </p>
  45.944 - </answer>
  45.945 -
  45.946 -
  45.947 -
  45.948 -<!--
  45.949 -        <question id="perf-startup" when="final">
  45.950 -            Does your module run any code on startup?
  45.951 -        </question>
  45.952 --->
  45.953 - <answer id="perf-startup">
  45.954 -  <p>
  45.955 -   XXX no answer for perf-startup
  45.956 -  </p>
  45.957 - </answer>
  45.958 -
  45.959 -
  45.960 -
  45.961 -<!--
  45.962 -        <question id="perf-wakeup" when="final">
  45.963 -            Does any piece of your code wake up periodically and do something
  45.964 -            even when the system is otherwise idle (no user interaction)?
  45.965 -        </question>
  45.966 --->
  45.967 - <answer id="perf-wakeup">
  45.968 -  <p>
  45.969 -   XXX no answer for perf-wakeup
  45.970 -  </p>
  45.971 - </answer>
  45.972 -
  45.973 -
  45.974 -
  45.975 -<!--
  45.976 -        <question id="resources-file" when="final">
  45.977 -            Does your module use <code>java.io.File</code> directly?
  45.978 -            
  45.979 -            <hint>
  45.980 -            NetBeans provide a logical wrapper over plain files called 
  45.981 -            <code>org.openide.filesystems.FileObject</code> that
  45.982 -            provides uniform access to such resources and is the preferred
  45.983 -            way that should be used. But of course there can be situations when
  45.984 -            this is not suitable.
  45.985 -            </hint>
  45.986 -        </question>
  45.987 --->
  45.988 - <answer id="resources-file">
  45.989 -  <p>
  45.990 -   XXX no answer for resources-file
  45.991 -  </p>
  45.992 - </answer>
  45.993 -
  45.994 -
  45.995 -
  45.996 -<!--
  45.997 -        <question id="resources-layer" when="final">
  45.998 -            Does your module provide own layer? Does it create any files or
  45.999 -            folders in it? What it is trying to communicate by that and with which 
 45.1000 -            components?
 45.1001 -            
 45.1002 -            <hint>
 45.1003 -            NetBeans allows automatic and declarative installation of resources 
 45.1004 -            by module layers. Module register files into appropriate places
 45.1005 -            and other components use that information to perform their task
 45.1006 -            (build menu, toolbar, window layout, list of templates, set of
 45.1007 -            options, etc.). 
 45.1008 -            </hint>
 45.1009 -        </question>
 45.1010 --->
 45.1011 - <answer id="resources-layer">
 45.1012 -  <p>
 45.1013 -   XXX no answer for resources-layer
 45.1014 -  </p>
 45.1015 - </answer>
 45.1016 -
 45.1017 -
 45.1018 -
 45.1019 -<!--
 45.1020 -        <question id="resources-mask" when="final">
 45.1021 -            Does your module mask/hide/override any resources provided by other modules in
 45.1022 -            their layers?
 45.1023 -            
 45.1024 -            <hint>
 45.1025 -            If you mask a file provided by another module, you probably depend
 45.1026 -            on that and do not want the other module to (for example) change
 45.1027 -            the file's name. That module shall thus make that file available as an API
 45.1028 -            of some stability category.
 45.1029 -            </hint>
 45.1030 -        </question>
 45.1031 --->
 45.1032 - <answer id="resources-mask">
 45.1033 -  <p>
 45.1034 -   XXX no answer for resources-mask
 45.1035 -  </p>
 45.1036 - </answer>
 45.1037 -
 45.1038 -
 45.1039 -
 45.1040 -<!--
 45.1041 -        <question id="resources-preferences" when="final">
 45.1042 -            Does your module uses preferences via Preferences API? Does your module use NbPreferences or
 45.1043 -            or regular JDK Preferences ? Does it read, write or both ? 
 45.1044 -            Does it share preferences with other modules ? If so, then why ?
 45.1045 -            <hint>
 45.1046 -                You may use
 45.1047 -                    &lt;api type="export" group="preferences"
 45.1048 -                    name="preference node name" category="private"&gt;
 45.1049 -                    description of individual keys, where it is used, what it
 45.1050 -                    influences, whether the module reads/write it, etc.
 45.1051 -                    &lt;/api&gt;
 45.1052 -                Due to XML ID restrictions, rather than /org/netbeans/modules/foo give the "name" as org.netbeans.modules.foo.
 45.1053 -                Note that if you use NbPreferences this name will then be the same as the code name base of the module.
 45.1054 -            </hint>
 45.1055 -        </question>
 45.1056 --->
 45.1057 - <answer id="resources-preferences">
 45.1058 -  <p>
 45.1059 -   XXX no answer for resources-preferences
 45.1060 -  </p>
 45.1061 - </answer>
 45.1062 -
 45.1063 -
 45.1064 -
 45.1065 -<!--
 45.1066 -        <question id="resources-read" when="final">
 45.1067 -            Does your module read any resources from layers? For what purpose?
 45.1068 -            
 45.1069 -            <hint>
 45.1070 -            As this is some kind of intermodule dependency, it is a kind of API.
 45.1071 -            Please describe it and classify according to 
 45.1072 -            <a href="http://openide.netbeans.org/tutorial/api-design.html#categories">
 45.1073 -            common stability categories</a>.
 45.1074 -            </hint>
 45.1075 -        </question>
 45.1076 --->
 45.1077 - <answer id="resources-read">
 45.1078 -  <p>
 45.1079 -   XXX no answer for resources-read
 45.1080 -  </p>
 45.1081 - </answer>
 45.1082 -
 45.1083 -
 45.1084 -
 45.1085 -<!--
 45.1086 -        <question id="security-grant" when="final">
 45.1087 -            Does your code grant additional rights to some other code?
 45.1088 -            <hint>Avoid using a class loader that adds extra
 45.1089 -            permissions to loaded code unless really necessary.
 45.1090 -            Also note that your API implementation
 45.1091 -            can also expose unneeded permissions to enemy code by
 45.1092 -            calling AccessController.doPrivileged().</hint>
 45.1093 -        </question>
 45.1094 --->
 45.1095 - <answer id="security-grant">
 45.1096 -  <p>
 45.1097 -   XXX no answer for security-grant
 45.1098 -  </p>
 45.1099 - </answer>
 45.1100 -
 45.1101 -
 45.1102 -
 45.1103 -<!--
 45.1104 -        <question id="security-policy" when="final">
 45.1105 -            Does your functionality require modifications to the standard policy file?
 45.1106 -            <hint>Your code might pass control to third-party code not
 45.1107 -            coming from trusted domains. This could be code downloaded over the
 45.1108 -            network or code coming from libraries that are not bundled
 45.1109 -            with NetBeans. Which permissions need to be granted to which domains?</hint>
 45.1110 -        </question>
 45.1111 --->
 45.1112 - <answer id="security-policy">
 45.1113 -  <p>
 45.1114 -   XXX no answer for security-policy
 45.1115 -  </p>
 45.1116 - </answer>
 45.1117 -
 45.1118 -</api-answers>
    46.1 --- a/java.hints/spi.java.hints/build.xml	Sun Oct 16 08:01:27 2016 +0200
    46.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.3 @@ -1,8 +0,0 @@
    46.4 -<?xml version="1.0" encoding="UTF-8"?>
    46.5 -<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
    46.6 -<!-- for some information on what you could do (e.g. targets to override). -->
    46.7 -<!-- If you delete this file and reopen the project it will be recreated. -->
    46.8 -<project name="org.netbeans.spi.java.hints" default="netbeans" basedir=".">
    46.9 -    <description>Builds, tests, and runs the project org.netbeans.spi.java.hints.</description>
   46.10 -    <import file="nbproject/build-impl.xml"/>
   46.11 -</project>
    47.1 --- a/java.hints/spi.java.hints/manifest.mf	Sun Oct 16 08:01:27 2016 +0200
    47.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.3 @@ -1,5 +0,0 @@
    47.4 -Manifest-Version: 1.0
    47.5 -OpenIDE-Module: org.netbeans.spi.java.hints
    47.6 -OpenIDE-Module-Implementation-Version: 11
    47.7 -OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/java/hints/spiimpl/Bundle.properties
    47.8 -
    48.1 --- a/java.hints/spi.java.hints/nbproject/build-impl.xml	Sun Oct 16 08:01:27 2016 +0200
    48.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.3 @@ -1,45 +0,0 @@
    48.4 -<?xml version="1.0" encoding="UTF-8"?>
    48.5 -<!--
    48.6 -*** GENERATED FROM project.xml - DO NOT EDIT  ***
    48.7 -***         EDIT ../build.xml INSTEAD         ***
    48.8 --->
    48.9 -<project name="org.netbeans.spi.java.hints-impl" basedir="..">
   48.10 -    <fail message="Please build using Ant 1.7.1 or higher.">
   48.11 -        <condition>
   48.12 -            <not>
   48.13 -                <antversion atleast="1.7.1"/>
   48.14 -            </not>
   48.15 -        </condition>
   48.16 -    </fail>
   48.17 -    <property file="nbproject/private/suite-private.properties"/>
   48.18 -    <property file="nbproject/suite.properties"/>
   48.19 -    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
   48.20 -    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
   48.21 -    <property file="${suite.dir}/nbproject/platform.properties"/>
   48.22 -    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
   48.23 -        <attribute name="name"/>
   48.24 -        <attribute name="value"/>
   48.25 -        <sequential>
   48.26 -            <property name="@{name}" value="${@{value}}"/>
   48.27 -        </sequential>
   48.28 -    </macrodef>
   48.29 -    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
   48.30 -        <attribute name="property"/>
   48.31 -        <attribute name="value"/>
   48.32 -        <sequential>
   48.33 -            <property name="@{property}" value="@{value}"/>
   48.34 -        </sequential>
   48.35 -    </macrodef>
   48.36 -    <property file="${user.properties.file}"/>
   48.37 -    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
   48.38 -    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
   48.39 -    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
   48.40 -    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
   48.41 -        <condition>
   48.42 -            <not>
   48.43 -                <contains string="${cluster.path.evaluated}" substring="platform"/>
   48.44 -            </not>
   48.45 -        </condition>
   48.46 -    </fail>
   48.47 -    <import file="${harness.dir}/build.xml"/>
   48.48 -</project>
    49.1 --- a/java.hints/spi.java.hints/nbproject/genfiles.properties	Sun Oct 16 08:01:27 2016 +0200
    49.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.3 @@ -1,8 +0,0 @@
    49.4 -build.xml.data.CRC32=1b4fb019
    49.5 -build.xml.script.CRC32=caab83d9
    49.6 -build.xml.stylesheet.CRC32=a56c6a5b@2.70
    49.7 -# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
    49.8 -# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
    49.9 -nbproject/build-impl.xml.data.CRC32=1b4fb019
   49.10 -nbproject/build-impl.xml.script.CRC32=7438bc77
   49.11 -nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.70
    50.1 --- a/java.hints/spi.java.hints/nbproject/org-netbeans-spi-java-hints.sig	Sun Oct 16 08:01:27 2016 +0200
    50.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    50.3 @@ -1,276 +0,0 @@
    50.4 -#Signature file v4.1
    50.5 -#Version 1.10.1
    50.6 -
    50.7 -CLSS public abstract interface java.io.Serializable
    50.8 -
    50.9 -CLSS public abstract interface java.lang.Comparable<%0 extends java.lang.Object>
   50.10 -meth public abstract int compareTo({java.lang.Comparable%0})
   50.11 -
   50.12 -CLSS public abstract java.lang.Enum<%0 extends java.lang.Enum<{java.lang.Enum%0}>>
   50.13 -cons protected init(java.lang.String,int)
   50.14 -intf java.io.Serializable
   50.15 -intf java.lang.Comparable<{java.lang.Enum%0}>
   50.16 -meth protected final java.lang.Object clone() throws java.lang.CloneNotSupportedException
   50.17 -meth protected final void finalize()
   50.18 -meth public final boolean equals(java.lang.Object)
   50.19 -meth public final int compareTo({java.lang.Enum%0})
   50.20 -meth public final int hashCode()
   50.21 -meth public final int ordinal()
   50.22 -meth public final java.lang.Class<{java.lang.Enum%0}> getDeclaringClass()
   50.23 -meth public final java.lang.String name()
   50.24 -meth public java.lang.String toString()
   50.25 -meth public static <%0 extends java.lang.Enum<{%%0}>> {%%0} valueOf(java.lang.Class<{%%0}>,java.lang.String)
   50.26 -supr java.lang.Object
   50.27 -hfds name,ordinal
   50.28 -
   50.29 -CLSS public java.lang.Object
   50.30 -cons public init()
   50.31 -meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
   50.32 -meth protected void finalize() throws java.lang.Throwable
   50.33 -meth public boolean equals(java.lang.Object)
   50.34 -meth public final java.lang.Class<?> getClass()
   50.35 -meth public final void notify()
   50.36 -meth public final void notifyAll()
   50.37 -meth public final void wait() throws java.lang.InterruptedException
   50.38 -meth public final void wait(long) throws java.lang.InterruptedException
   50.39 -meth public final void wait(long,int) throws java.lang.InterruptedException
   50.40 -meth public int hashCode()
   50.41 -meth public java.lang.String toString()
   50.42 -
   50.43 -CLSS public abstract interface java.lang.annotation.Annotation
   50.44 -meth public abstract boolean equals(java.lang.Object)
   50.45 -meth public abstract int hashCode()
   50.46 -meth public abstract java.lang.Class<? extends java.lang.annotation.Annotation> annotationType()
   50.47 -meth public abstract java.lang.String toString()
   50.48 -
   50.49 -CLSS public abstract interface !annotation java.lang.annotation.Documented
   50.50 - anno 0 java.lang.annotation.Documented()
   50.51 - anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=RUNTIME)
   50.52 - anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[ANNOTATION_TYPE])
   50.53 -intf java.lang.annotation.Annotation
   50.54 -
   50.55 -CLSS public abstract interface !annotation java.lang.annotation.Retention
   50.56 - anno 0 java.lang.annotation.Documented()
   50.57 - anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=RUNTIME)
   50.58 - anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[ANNOTATION_TYPE])
   50.59 -intf java.lang.annotation.Annotation
   50.60 -meth public abstract java.lang.annotation.RetentionPolicy value()
   50.61 -
   50.62 -CLSS public abstract interface !annotation java.lang.annotation.Target
   50.63 - anno 0 java.lang.annotation.Documented()
   50.64 - anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=RUNTIME)
   50.65 - anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[ANNOTATION_TYPE])
   50.66 -intf java.lang.annotation.Annotation
   50.67 -meth public abstract java.lang.annotation.ElementType[] value()
   50.68 -
   50.69 -CLSS public abstract interface !annotation org.netbeans.spi.java.hints.BooleanOption
   50.70 - anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=SOURCE)
   50.71 - anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[FIELD])
   50.72 -intf java.lang.annotation.Annotation
   50.73 -meth public abstract boolean defaultValue()
   50.74 -meth public abstract java.lang.String displayName()
   50.75 -meth public abstract java.lang.String tooltip()
   50.76 -
   50.77 -CLSS public abstract interface !annotation org.netbeans.spi.java.hints.ConstraintVariableType
   50.78 - anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[])
   50.79 -intf java.lang.annotation.Annotation
   50.80 -meth public abstract java.lang.String type()
   50.81 -meth public abstract java.lang.String variable()
   50.82 -
   50.83 -CLSS public abstract interface org.netbeans.spi.java.hints.CustomizerProvider
   50.84 -meth public abstract javax.swing.JComponent getCustomizer(java.util.prefs.Preferences)
   50.85 - anno 0 org.netbeans.api.annotations.common.NonNull()
   50.86 - anno 1 org.netbeans.api.annotations.common.NonNull()
   50.87 -
   50.88 -CLSS public org.netbeans.spi.java.hints.ErrorDescriptionFactory
   50.89 -meth public !varargs static org.netbeans.spi.editor.hints.ErrorDescription forName(org.netbeans.spi.java.hints.HintContext,com.sun.source.tree.Tree,java.lang.String,org.netbeans.spi.editor.hints.Fix[])
   50.90 -meth public !varargs static org.netbeans.spi.editor.hints.ErrorDescription forName(org.netbeans.spi.java.hints.HintContext,com.sun.source.util.TreePath,java.lang.String,org.netbeans.spi.editor.hints.Fix[])
   50.91 -meth public !varargs static org.netbeans.spi.editor.hints.ErrorDescription forSpan(org.netbeans.spi.java.hints.HintContext,int,int,java.lang.String,org.netbeans.spi.editor.hints.Fix[])
   50.92 -meth public !varargs static org.netbeans.spi.editor.hints.ErrorDescription forTree(org.netbeans.spi.java.hints.HintContext,com.sun.source.tree.Tree,java.lang.String,org.netbeans.spi.editor.hints.Fix[])
   50.93 -meth public !varargs static org.netbeans.spi.editor.hints.ErrorDescription forTree(org.netbeans.spi.java.hints.HintContext,com.sun.source.util.TreePath,java.lang.String,org.netbeans.spi.editor.hints.Fix[])
   50.94 -supr java.lang.Object
   50.95 -hfds DECLARATION
   50.96 -hcls DisableConfigure,FixImpl,InspectFix,TopLevelConfigureFix
   50.97 -
   50.98 -CLSS public abstract interface !annotation org.netbeans.spi.java.hints.Hint
   50.99 - anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=SOURCE)
  50.100 - anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[TYPE, METHOD])
  50.101 -innr public final static !enum Kind
  50.102 -innr public final static !enum Options
  50.103 -intf java.lang.annotation.Annotation
  50.104 -meth public abstract !hasdefault boolean enabled()
  50.105 -meth public abstract !hasdefault java.lang.Class<? extends org.netbeans.spi.java.hints.CustomizerProvider> customizerProvider()
  50.106 -meth public abstract !hasdefault java.lang.String id()
  50.107 -meth public abstract !hasdefault java.lang.String[] suppressWarnings()
  50.108 -meth public abstract !hasdefault org.netbeans.spi.editor.hints.Severity severity()
  50.109 -meth public abstract !hasdefault org.netbeans.spi.java.hints.Hint$Kind hintKind()
  50.110 -meth public abstract !hasdefault org.netbeans.spi.java.hints.Hint$Options[] options()
  50.111 -meth public abstract java.lang.String category()
  50.112 -meth public abstract java.lang.String description()
  50.113 -meth public abstract java.lang.String displayName()
  50.114 -
  50.115 -CLSS public final static !enum org.netbeans.spi.java.hints.Hint$Kind
  50.116 - outer org.netbeans.spi.java.hints.Hint
  50.117 -fld public final static org.netbeans.spi.java.hints.Hint$Kind ACTION
  50.118 -fld public final static org.netbeans.spi.java.hints.Hint$Kind INSPECTION
  50.119 -meth public static org.netbeans.spi.java.hints.Hint$Kind valueOf(java.lang.String)
  50.120 -meth public static org.netbeans.spi.java.hints.Hint$Kind[] values()
  50.121 -supr java.lang.Enum<org.netbeans.spi.java.hints.Hint$Kind>
  50.122 -
  50.123 -CLSS public final static !enum org.netbeans.spi.java.hints.Hint$Options
  50.124 - outer org.netbeans.spi.java.hints.Hint
  50.125 -fld public final static org.netbeans.spi.java.hints.Hint$Options NO_BATCH
  50.126 -fld public final static org.netbeans.spi.java.hints.Hint$Options QUERY
  50.127 -meth public static org.netbeans.spi.java.hints.Hint$Options valueOf(java.lang.String)
  50.128 -meth public static org.netbeans.spi.java.hints.Hint$Options[] values()
  50.129 -supr java.lang.Enum<org.netbeans.spi.java.hints.Hint$Options>
  50.130 -
  50.131 -CLSS public org.netbeans.spi.java.hints.HintContext
  50.132 -innr public final static !enum MessageKind
  50.133 -meth public boolean isBulkMode()
  50.134 -meth public boolean isCanceled()
  50.135 -meth public com.sun.source.util.TreePath getPath()
  50.136 -meth public int getCaretLocation()
  50.137 -meth public java.util.Map<java.lang.String,com.sun.source.util.TreePath> getVariables()
  50.138 -meth public java.util.Map<java.lang.String,java.lang.String> getVariableNames()
  50.139 -meth public java.util.Map<java.lang.String,java.util.Collection<? extends com.sun.source.util.TreePath>> getMultiVariables()
  50.140 -meth public java.util.Map<java.lang.String,javax.lang.model.type.TypeMirror> getConstraints()
  50.141 -meth public java.util.prefs.Preferences getPreferences()
  50.142 -meth public org.netbeans.api.java.source.CompilationInfo getInfo()
  50.143 -meth public org.netbeans.spi.editor.hints.Severity getSeverity()
  50.144 -meth public void reportMessage(org.netbeans.spi.java.hints.HintContext$MessageKind,java.lang.String)
  50.145 -supr java.lang.Object
  50.146 -hfds bulkMode,cancel,caret,constraints,info,messages,metadata,multiVariables,path,preferences,severity,variableNames,variables
  50.147 -
  50.148 -CLSS public final static !enum org.netbeans.spi.java.hints.HintContext$MessageKind
  50.149 - outer org.netbeans.spi.java.hints.HintContext
  50.150 -fld public final static org.netbeans.spi.java.hints.HintContext$MessageKind ERROR
  50.151 -fld public final static org.netbeans.spi.java.hints.HintContext$MessageKind WARNING
  50.152 -meth public static org.netbeans.spi.java.hints.HintContext$MessageKind valueOf(java.lang.String)
  50.153 -meth public static org.netbeans.spi.java.hints.HintContext$MessageKind[] values()
  50.154 -supr java.lang.Enum<org.netbeans.spi.java.hints.HintContext$MessageKind>
  50.155 -
  50.156 -CLSS public final !enum org.netbeans.spi.java.hints.HintSeverity
  50.157 -fld public final static org.netbeans.spi.java.hints.HintSeverity CURRENT_LINE_WARNING
  50.158 -fld public final static org.netbeans.spi.java.hints.HintSeverity ERROR
  50.159 -fld public final static org.netbeans.spi.java.hints.HintSeverity WARNING
  50.160 -meth public org.netbeans.spi.editor.hints.Severity toEditorSeverity()
  50.161 -meth public static org.netbeans.spi.java.hints.HintSeverity valueOf(java.lang.String)
  50.162 -meth public static org.netbeans.spi.java.hints.HintSeverity[] values()
  50.163 -supr java.lang.Enum<org.netbeans.spi.java.hints.HintSeverity>
  50.164 -
  50.165 -CLSS public abstract org.netbeans.spi.java.hints.JavaFix
  50.166 -cons protected init(org.netbeans.api.java.source.CompilationInfo,com.sun.source.util.TreePath)
  50.167 - anno 1 org.netbeans.api.annotations.common.NonNull()
  50.168 - anno 2 org.netbeans.api.annotations.common.NonNull()
  50.169 -cons protected init(org.netbeans.api.java.source.TreePathHandle)
  50.170 - anno 1 org.netbeans.api.annotations.common.NonNull()
  50.171 -innr public final static TransformationContext
  50.172 -meth protected abstract java.lang.String getText()
  50.173 - anno 0 org.netbeans.api.annotations.common.NonNull()
  50.174 -meth protected abstract void performRewrite(org.netbeans.spi.java.hints.JavaFix$TransformationContext) throws java.lang.Exception
  50.175 - anno 1 org.netbeans.api.annotations.common.NonNull()
  50.176 -meth public final org.netbeans.spi.editor.hints.Fix toEditorFix()
  50.177 -supr java.lang.Object
  50.178 -hfds LOG,handle,options
  50.179 -
  50.180 -CLSS public final static org.netbeans.spi.java.hints.JavaFix$TransformationContext
  50.181 - outer org.netbeans.spi.java.hints.JavaFix
  50.182 -meth public com.sun.source.util.TreePath getPath()
  50.183 - anno 0 org.netbeans.api.annotations.common.NonNull()
  50.184 -meth public java.io.InputStream getResourceContent(org.openide.filesystems.FileObject) throws java.io.IOException
  50.185 - anno 0 org.netbeans.api.annotations.common.NonNull()
  50.186 - anno 1 org.netbeans.api.annotations.common.NonNull()
  50.187 -meth public java.io.OutputStream getResourceOutput(org.openide.filesystems.FileObject) throws java.io.IOException
  50.188 - anno 0 org.netbeans.api.annotations.common.NonNull()
  50.189 - anno 1 org.netbeans.api.annotations.common.NonNull()
  50.190 -meth public org.netbeans.api.java.source.WorkingCopy getWorkingCopy()
  50.191 - anno 0 org.netbeans.api.annotations.common.NonNull()
  50.192 -supr java.lang.Object
  50.193 -hfds canShowUI,fileChanges,path,resourceContentChanges,workingCopy
  50.194 -
  50.195 -CLSS public org.netbeans.spi.java.hints.JavaFixUtilities
  50.196 -cons public init()
  50.197 -meth public static boolean requiresParenthesis(com.sun.source.tree.Tree,com.sun.source.tree.Tree,com.sun.source.tree.Tree)
  50.198 -meth public static org.netbeans.spi.editor.hints.Fix removeFromParent(org.netbeans.spi.java.hints.HintContext,java.lang.String,com.sun.source.util.TreePath)
  50.199 -meth public static org.netbeans.spi.editor.hints.Fix rewriteFix(org.netbeans.spi.java.hints.HintContext,java.lang.String,com.sun.source.util.TreePath,java.lang.String)
  50.200 -supr java.lang.Object
  50.201 -hfds NUMBER_LITERAL_KINDS,OPERATOR_PRIORITIES,SPEC_VERSION
  50.202 -hcls JavaFixRealImpl,MoveFile,RemoveFromParent,ReplaceParameters
  50.203 -
  50.204 -CLSS public org.netbeans.spi.java.hints.MatcherUtilities
  50.205 -cons public init()
  50.206 -meth public static boolean matches(org.netbeans.spi.java.hints.HintContext,com.sun.source.util.TreePath,java.lang.String)
  50.207 - anno 1 org.netbeans.api.annotations.common.NonNull()
  50.208 - anno 2 org.netbeans.api.annotations.common.NonNull()
  50.209 - anno 3 org.netbeans.api.annotations.common.NonNull()
  50.210 -meth public static boolean matches(org.netbeans.spi.java.hints.HintContext,com.sun.source.util.TreePath,java.lang.String,boolean)
  50.211 - anno 1 org.netbeans.api.annotations.common.NonNull()
  50.212 - anno 2 org.netbeans.api.annotations.common.NonNull()
  50.213 - anno 3 org.netbeans.api.annotations.common.NonNull()
  50.214 -meth public static boolean matches(org.netbeans.spi.java.hints.HintContext,com.sun.source.util.TreePath,java.lang.String,java.util.Map<java.lang.String,com.sun.source.util.TreePath>,java.util.Map<java.lang.String,java.util.Collection<? extends com.sun.source.util.TreePath>>,java.util.Map<java.lang.String,java.lang.String>)
  50.215 - anno 1 org.netbeans.api.annotations.common.NonNull()
  50.216 - anno 2 org.netbeans.api.annotations.common.NonNull()
  50.217 - anno 3 org.netbeans.api.annotations.common.NonNull()
  50.218 -meth public static boolean matches(org.netbeans.spi.java.hints.HintContext,java.util.Collection<? extends com.sun.source.util.TreePath>,java.lang.String,java.util.Map<java.lang.String,com.sun.source.util.TreePath>,java.util.Map<java.lang.String,java.util.Collection<? extends com.sun.source.util.TreePath>>,java.util.Map<java.lang.String,java.lang.String>)
  50.219 - anno 1 org.netbeans.api.annotations.common.NonNull()
  50.220 - anno 2 org.netbeans.api.annotations.common.NonNull()
  50.221 - anno 3 org.netbeans.api.annotations.common.NonNull()
  50.222 -supr java.lang.Object
  50.223 -
  50.224 -CLSS public abstract interface !annotation org.netbeans.spi.java.hints.TriggerPattern
  50.225 - anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=SOURCE)
  50.226 - anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[METHOD])
  50.227 -intf java.lang.annotation.Annotation
  50.228 -meth public abstract !hasdefault org.netbeans.spi.java.hints.ConstraintVariableType[] constraints()
  50.229 -meth public abstract java.lang.String value()
  50.230 -
  50.231 -CLSS public abstract interface !annotation org.netbeans.spi.java.hints.TriggerPatterns
  50.232 - anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=SOURCE)
  50.233 - anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[METHOD])
  50.234 -intf java.lang.annotation.Annotation
  50.235 -meth public abstract org.netbeans.spi.java.hints.TriggerPattern[] value()
  50.236 -
  50.237 -CLSS public abstract interface !annotation org.netbeans.spi.java.hints.TriggerTreeKind
  50.238 - anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=SOURCE)
  50.239 - anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[METHOD])
  50.240 -intf java.lang.annotation.Annotation
  50.241 -meth public abstract com.sun.source.tree.Tree$Kind[] value()
  50.242 -
  50.243 -CLSS public abstract interface !annotation org.netbeans.spi.java.hints.UseOptions
  50.244 - anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=SOURCE)
  50.245 - anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[METHOD])
  50.246 -intf java.lang.annotation.Annotation
  50.247 -meth public abstract java.lang.String[] value()
  50.248 -
  50.249 -CLSS public final org.netbeans.spi.java.hints.support.FixFactory
  50.250 -meth public final static org.netbeans.spi.editor.hints.Fix addModifiersFix(org.netbeans.api.java.source.CompilationInfo,com.sun.source.util.TreePath,java.util.Set<javax.lang.model.element.Modifier>,java.lang.String)
  50.251 -meth public final static org.netbeans.spi.editor.hints.Fix changeModifiersFix(org.netbeans.api.java.source.CompilationInfo,com.sun.source.util.TreePath,java.util.Set<javax.lang.model.element.Modifier>,java.util.Set<javax.lang.model.element.Modifier>,java.lang.String)
  50.252 -meth public final static org.netbeans.spi.editor.hints.Fix removeModifiersFix(org.netbeans.api.java.source.CompilationInfo,com.sun.source.util.TreePath,java.util.Set<javax.lang.model.element.Modifier>,java.lang.String)
  50.253 -supr java.lang.Object
  50.254 -hcls ChangeModifiersFixImpl
  50.255 -
  50.256 -CLSS public final org.netbeans.spi.java.hints.support.TransformationSupport
  50.257 -innr public abstract interface static Transformer
  50.258 -meth public java.util.Collection<? extends org.netbeans.api.java.source.ModificationResult> processAllProjects()
  50.259 - anno 0 org.netbeans.api.annotations.common.NonNull()
  50.260 -meth public org.netbeans.spi.java.hints.support.TransformationSupport setCancel(java.util.concurrent.atomic.AtomicBoolean)
  50.261 - anno 0 org.netbeans.api.annotations.common.NonNull()
  50.262 - anno 1 org.netbeans.api.annotations.common.NonNull()
  50.263 -meth public static org.netbeans.spi.java.hints.support.TransformationSupport create(java.lang.String)
  50.264 - anno 0 org.netbeans.api.annotations.common.NonNull()
  50.265 - anno 1 org.netbeans.api.annotations.common.NonNull()
  50.266 -meth public static org.netbeans.spi.java.hints.support.TransformationSupport create(java.lang.String,org.netbeans.spi.java.hints.support.TransformationSupport$Transformer)
  50.267 - anno 0 org.netbeans.api.annotations.common.NonNull()
  50.268 - anno 1 org.netbeans.api.annotations.common.NonNull()
  50.269 - anno 2 org.netbeans.api.annotations.common.NonNull()
  50.270 -meth public void transformTreePath(org.netbeans.api.java.source.WorkingCopy,com.sun.source.util.TreePath)
  50.271 - anno 1 org.netbeans.api.annotations.common.NonNull()
  50.272 - anno 2 org.netbeans.api.annotations.common.NonNull()
  50.273 -supr java.lang.Object
  50.274 -hfds cancel,jackpotPattern,transformer
  50.275 -
  50.276 -CLSS public abstract interface static org.netbeans.spi.java.hints.support.TransformationSupport$Transformer
  50.277 - outer org.netbeans.spi.java.hints.support.TransformationSupport
  50.278 -meth public abstract void transform(org.netbeans.api.java.source.WorkingCopy,org.netbeans.api.java.source.matching.Occurrence)
  50.279 -
    51.1 --- a/java.hints/spi.java.hints/nbproject/project.properties	Sun Oct 16 08:01:27 2016 +0200
    51.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    51.3 @@ -1,7 +0,0 @@
    51.4 -is.autoload=true
    51.5 -javac.source=1.7
    51.6 -javac.compilerargs=-Xlint -Xlint:-serial
    51.7 -spec.version.base=2.0.0
    51.8 -requires.nb.javac=true
    51.9 -javadoc.arch=${basedir}/arch.xml
   51.10 -javadoc.apichanges=${basedir}/apichanges.xml
    52.1 --- a/java.hints/spi.java.hints/nbproject/project.xml	Sun Oct 16 08:01:27 2016 +0200
    52.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    52.3 @@ -1,480 +0,0 @@
    52.4 -<?xml version="1.0" encoding="UTF-8"?>
    52.5 -<project xmlns="http://www.netbeans.org/ns/project/1">
    52.6 -    <type>org.netbeans.modules.apisupport.project</type>
    52.7 -    <configuration>
    52.8 -        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
    52.9 -            <code-name-base>org.netbeans.spi.java.hints</code-name-base>
   52.10 -            <suite-component/>
   52.11 -            <module-dependencies>
   52.12 -                <dependency>
   52.13 -                    <code-name-base>org.netbeans.api.annotations.common</code-name-base>
   52.14 -                    <build-prerequisite/>
   52.15 -                    <compile-dependency/>
   52.16 -                    <run-dependency>
   52.17 -                        <release-version>1</release-version>
   52.18 -                        <specification-version>1.4</specification-version>
   52.19 -                    </run-dependency>
   52.20 -                </dependency>
   52.21 -                <dependency>
   52.22 -                    <code-name-base>org.netbeans.api.java</code-name-base>
   52.23 -                    <build-prerequisite/>
   52.24 -                    <compile-dependency/>
   52.25 -                    <run-dependency>
   52.26 -                        <release-version>1</release-version>
   52.27 -                        <specification-version>1.18</specification-version>
   52.28 -                    </run-dependency>
   52.29 -                </dependency>
   52.30 -                <dependency>
   52.31 -                    <code-name-base>org.netbeans.api.java.classpath</code-name-base>
   52.32 -                    <build-prerequisite/>
   52.33 -                    <compile-dependency/>
   52.34 -                    <run-dependency>
   52.35 -                        <release-version>1</release-version>
   52.36 -                        <specification-version>1.24</specification-version>
   52.37 -                    </run-dependency>
   52.38 -                </dependency>
   52.39 -                <dependency>
   52.40 -                    <code-name-base>org.netbeans.api.progress</code-name-base>
   52.41 -                    <build-prerequisite/>
   52.42 -                    <compile-dependency/>
   52.43 -                    <run-dependency>
   52.44 -                        <release-version>1</release-version>
   52.45 -                        <specification-version>1.16</specification-version>
   52.46 -                    </run-dependency>
   52.47 -                </dependency>
   52.48 -                <dependency>
   52.49 -                    <code-name-base>org.netbeans.api.progress.nb</code-name-base>
   52.50 -                    <build-prerequisite/>
   52.51 -                    <compile-dependency/>
   52.52 -                    <run-dependency>
   52.53 -                        <specification-version>1.45</specification-version>
   52.54 -                    </run-dependency>
   52.55 -                </dependency>
   52.56 -                <dependency>
   52.57 -                    <code-name-base>org.netbeans.lib.nbjavac</code-name-base>
   52.58 -                    <build-prerequisite/>
   52.59 -                    <compile-dependency/>
   52.60 -                    <run-dependency>
   52.61 -                        <implementation-version/>
   52.62 -                    </run-dependency>
   52.63 -                </dependency>
   52.64 -                <dependency>
   52.65 -                    <code-name-base>org.netbeans.libs.javacapi</code-name-base>
   52.66 -                    <build-prerequisite/>
   52.67 -                    <compile-dependency/>
   52.68 -                    <run-dependency>
   52.69 -                        <specification-version>8.0</specification-version>
   52.70 -                    </run-dependency>
   52.71 -                </dependency>
   52.72 -                <dependency>
   52.73 -                    <code-name-base>org.netbeans.libs.javacimpl</code-name-base>
   52.74 -                    <build-prerequisite/>
   52.75 -                    <compile-dependency/>
   52.76 -                    <run-dependency>
   52.77 -                        <release-version>1</release-version>
   52.78 -                        <implementation-version/>
   52.79 -                    </run-dependency>
   52.80 -                </dependency>
   52.81 -                <dependency>
   52.82 -                    <code-name-base>org.netbeans.libs.lucene</code-name-base>
   52.83 -                    <build-prerequisite/>
   52.84 -                    <compile-dependency/>
   52.85 -                    <run-dependency>
   52.86 -                        <release-version>3</release-version>
   52.87 -                        <specification-version>3.0</specification-version>
   52.88 -                    </run-dependency>
   52.89 -                </dependency>
   52.90 -                <dependency>
   52.91 -                    <code-name-base>org.netbeans.modules.code.analysis</code-name-base>
   52.92 -                    <build-prerequisite/>
   52.93 -                    <compile-dependency/>
   52.94 -                    <run-dependency>
   52.95 -                        <release-version>0</release-version>
   52.96 -                        <specification-version>1.8</specification-version>
   52.97 -                    </run-dependency>
   52.98 -                </dependency>
   52.99 -                <dependency>
  52.100 -                    <code-name-base>org.netbeans.modules.editor</code-name-base>
  52.101 -                    <build-prerequisite/>
  52.102 -                    <compile-dependency/>
  52.103 -                    <run-dependency>
  52.104 -                        <release-version>3</release-version>
  52.105 -                        <specification-version>1.53</specification-version>
  52.106 -                    </run-dependency>
  52.107 -                </dependency>
  52.108 -                <dependency>
  52.109 -                    <code-name-base>org.netbeans.modules.editor.errorstripe.api</code-name-base>
  52.110 -                    <build-prerequisite/>
  52.111 -                    <compile-dependency/>
  52.112 -                    <run-dependency>
  52.113 -                        <release-version>1</release-version>
  52.114 -                        <specification-version>2.3</specification-version>
  52.115 -                    </run-dependency>
  52.116 -                </dependency>
  52.117 -                <dependency>
  52.118 -                    <code-name-base>org.netbeans.modules.editor.lib</code-name-base>
  52.119 -                    <build-prerequisite/>
  52.120 -                    <compile-dependency/>
  52.121 -                    <run-dependency>
  52.122 -                        <release-version>3</release-version>
  52.123 -                        <specification-version>3.1</specification-version>
  52.124 -                    </run-dependency>
  52.125 -                </dependency>
  52.126 -                <dependency>
  52.127 -                    <code-name-base>org.netbeans.modules.editor.lib2</code-name-base>
  52.128 -                    <build-prerequisite/>
  52.129 -                    <compile-dependency/>
  52.130 -                    <run-dependency>
  52.131 -                        <release-version>1</release-version>
  52.132 -                        <specification-version>1.8</specification-version>
  52.133 -                    </run-dependency>
  52.134 -                </dependency>
  52.135 -                <dependency>
  52.136 -                    <code-name-base>org.netbeans.modules.editor.mimelookup</code-name-base>
  52.137 -                    <build-prerequisite/>
  52.138 -                    <compile-dependency/>
  52.139 -                    <run-dependency>
  52.140 -                        <release-version>1</release-version>
  52.141 -                        <specification-version>1.15</specification-version>
  52.142 -                    </run-dependency>
  52.143 -                </dependency>
  52.144 -                <dependency>
  52.145 -                    <code-name-base>org.netbeans.modules.editor.settings</code-name-base>
  52.146 -                    <build-prerequisite/>
  52.147 -                    <compile-dependency/>
  52.148 -                    <run-dependency>
  52.149 -                        <release-version>1</release-version>
  52.150 -                        <specification-version>1.28</specification-version>
  52.151 -                    </run-dependency>
  52.152 -                </dependency>
  52.153 -                <dependency>
  52.154 -                    <code-name-base>org.netbeans.modules.editor.util</code-name-base>
  52.155 -                    <build-prerequisite/>
  52.156 -                    <compile-dependency/>
  52.157 -                    <run-dependency>
  52.158 -                        <release-version>1</release-version>
  52.159 -                        <specification-version>1.33</specification-version>
  52.160 -                    </run-dependency>
  52.161 -                </dependency>
  52.162 -                <dependency>
  52.163 -                    <code-name-base>org.netbeans.modules.java.lexer</code-name-base>
  52.164 -                    <build-prerequisite/>
  52.165 -                    <compile-dependency/>
  52.166 -                    <run-dependency>
  52.167 -                        <release-version>1</release-version>
  52.168 -                        <specification-version>1.0</specification-version>
  52.169 -                    </run-dependency>
  52.170 -                </dependency>
  52.171 -                <dependency>
  52.172 -                    <code-name-base>org.netbeans.modules.java.platform</code-name-base>
  52.173 -                    <build-prerequisite/>
  52.174 -                    <compile-dependency/>
  52.175 -                    <run-dependency>
  52.176 -                        <release-version>1</release-version>
  52.177 -                        <specification-version>1.16</specification-version>
  52.178 -                    </run-dependency>
  52.179 -                </dependency>
  52.180 -                <dependency>
  52.181 -                    <code-name-base>org.netbeans.modules.java.project</code-name-base>
  52.182 -                    <build-prerequisite/>
  52.183 -                    <compile-dependency/>
  52.184 -                    <run-dependency>
  52.185 -                        <release-version>1</release-version>
  52.186 -                        <specification-version>1.41</specification-version>
  52.187 -                    </run-dependency>
  52.188 -                </dependency>
  52.189 -                <dependency>
  52.190 -                    <code-name-base>org.netbeans.modules.java.source</code-name-base>
  52.191 -                    <build-prerequisite/>
  52.192 -                    <compile-dependency/>
  52.193 -                    <run-dependency>
  52.194 -                        <implementation-version/>
  52.195 -                    </run-dependency>
  52.196 -                </dependency>
  52.197 -                <dependency>
  52.198 -                    <code-name-base>org.netbeans.modules.java.source.base</code-name-base>
  52.199 -                    <build-prerequisite/>
  52.200 -                    <compile-dependency/>
  52.201 -                    <run-dependency>
  52.202 -                        <implementation-version/>
  52.203 -                    </run-dependency>
  52.204 -                </dependency>
  52.205 -                <dependency>
  52.206 -                    <code-name-base>org.netbeans.modules.lexer</code-name-base>
  52.207 -                    <build-prerequisite/>
  52.208 -                    <compile-dependency/>
  52.209 -                    <run-dependency>
  52.210 -                        <release-version>2</release-version>
  52.211 -                        <specification-version>1.25</specification-version>
  52.212 -                    </run-dependency>
  52.213 -                </dependency>
  52.214 -                <dependency>
  52.215 -                    <code-name-base>org.netbeans.modules.options.api</code-name-base>
  52.216 -                    <build-prerequisite/>
  52.217 -                    <compile-dependency/>
  52.218 -                    <run-dependency>
  52.219 -                        <release-version>1</release-version>
  52.220 -                        <specification-version>1.5</specification-version>
  52.221 -                    </run-dependency>
  52.222 -                </dependency>
  52.223 -                <dependency>
  52.224 -                    <code-name-base>org.netbeans.modules.options.editor</code-name-base>
  52.225 -                    <build-prerequisite/>
  52.226 -                    <compile-dependency/>
  52.227 -                    <run-dependency>
  52.228 -                        <release-version>1</release-version>
  52.229 -                        <specification-version>1.28</specification-version>
  52.230 -                    </run-dependency>
  52.231 -                </dependency>
  52.232 -                <dependency>
  52.233 -                    <code-name-base>org.netbeans.modules.parsing.api</code-name-base>
  52.234 -                    <build-prerequisite/>
  52.235 -                    <compile-dependency/>
  52.236 -                    <run-dependency>
  52.237 -                        <release-version>1</release-version>
  52.238 -                        <implementation-version/>
  52.239 -                    </run-dependency>
  52.240 -                </dependency>
  52.241 -                <dependency>
  52.242 -                    <code-name-base>org.netbeans.modules.projectapi</code-name-base>
  52.243 -                    <build-prerequisite/>
  52.244 -                    <compile-dependency/>
  52.245 -                    <run-dependency>
  52.246 -                        <release-version>1</release-version>
  52.247 -                        <specification-version>1.42</specification-version>
  52.248 -                    </run-dependency>
  52.249 -                </dependency>
  52.250 -                <dependency>
  52.251 -                    <code-name-base>org.netbeans.modules.queries</code-name-base>
  52.252 -                    <build-prerequisite/>
  52.253 -                    <compile-dependency/>
  52.254 -                    <run-dependency>
  52.255 -                        <release-version>1</release-version>
  52.256 -                        <specification-version>1.18</specification-version>
  52.257 -                    </run-dependency>
  52.258 -                </dependency>
  52.259 -                <dependency>
  52.260 -                    <code-name-base>org.netbeans.modules.refactoring.api</code-name-base>
  52.261 -                    <build-prerequisite/>
  52.262 -                    <compile-dependency/>
  52.263 -                    <run-dependency>
  52.264 -                        <specification-version>1.23</specification-version>
  52.265 -                    </run-dependency>
  52.266 -                </dependency>
  52.267 -                <dependency>
  52.268 -                    <code-name-base>org.netbeans.spi.editor.hints</code-name-base>
  52.269 -                    <build-prerequisite/>
  52.270 -                    <compile-dependency/>
  52.271 -                    <run-dependency>
  52.272 -                        <release-version>0-1</release-version>
  52.273 -                        <specification-version>1.22</specification-version>
  52.274 -                    </run-dependency>
  52.275 -                </dependency>
  52.276 -                <dependency>
  52.277 -                    <code-name-base>org.openide.actions</code-name-base>
  52.278 -                    <build-prerequisite/>
  52.279 -                    <compile-dependency/>
  52.280 -                    <run-dependency>
  52.281 -                        <specification-version>6.15</specification-version>
  52.282 -                    </run-dependency>
  52.283 -                </dependency>
  52.284 -                <dependency>
  52.285 -                    <code-name-base>org.openide.awt</code-name-base>
  52.286 -                    <build-prerequisite/>
  52.287 -                    <compile-dependency/>
  52.288 -                    <run-dependency>
  52.289 -                        <specification-version>6.10</specification-version>
  52.290 -                    </run-dependency>
  52.291 -                </dependency>
  52.292 -                <dependency>
  52.293 -                    <code-name-base>org.openide.dialogs</code-name-base>
  52.294 -                    <build-prerequisite/>
  52.295 -                    <compile-dependency/>
  52.296 -                    <run-dependency>
  52.297 -                        <specification-version>7.0</specification-version>
  52.298 -                    </run-dependency>
  52.299 -                </dependency>
  52.300 -                <dependency>
  52.301 -                    <code-name-base>org.openide.explorer</code-name-base>
  52.302 -                    <build-prerequisite/>
  52.303 -                    <compile-dependency/>
  52.304 -                    <run-dependency>
  52.305 -                        <specification-version>6.22</specification-version>
  52.306 -                    </run-dependency>
  52.307 -                </dependency>
  52.308 -                <dependency>
  52.309 -                    <code-name-base>org.openide.filesystems</code-name-base>
  52.310 -                    <build-prerequisite/>
  52.311 -                    <compile-dependency/>
  52.312 -                    <run-dependency>
  52.313 -                        <specification-version>7.19</specification-version>
  52.314 -                    </run-dependency>
  52.315 -                </dependency>
  52.316 -                <dependency>
  52.317 -                    <code-name-base>org.openide.loaders</code-name-base>
  52.318 -                    <build-prerequisite/>
  52.319 -                    <compile-dependency/>
  52.320 -                    <run-dependency/>
  52.321 -                </dependency>
  52.322 -                <dependency>
  52.323 -                    <code-name-base>org.openide.modules</code-name-base>
  52.324 -                    <build-prerequisite/>
  52.325 -                    <compile-dependency/>
  52.326 -                    <run-dependency>
  52.327 -                        <specification-version>7.3</specification-version>
  52.328 -                    </run-dependency>
  52.329 -                </dependency>
  52.330 -                <dependency>
  52.331 -                    <code-name-base>org.openide.nodes</code-name-base>
  52.332 -                    <build-prerequisite/>
  52.333 -                    <compile-dependency/>
  52.334 -                    <run-dependency>
  52.335 -                        <specification-version>6.2</specification-version>
  52.336 -                    </run-dependency>
  52.337 -                </dependency>
  52.338 -                <dependency>
  52.339 -                    <code-name-base>org.openide.text</code-name-base>
  52.340 -                    <build-prerequisite/>
  52.341 -                    <compile-dependency/>
  52.342 -                    <run-dependency>
  52.343 -                        <specification-version>6.16</specification-version>
  52.344 -                    </run-dependency>
  52.345 -                </dependency>
  52.346 -                <dependency>
  52.347 -                    <code-name-base>org.openide.util</code-name-base>
  52.348 -                    <build-prerequisite/>
  52.349 -                    <compile-dependency/>
  52.350 -                    <run-dependency>
  52.351 -                        <specification-version>8.32</specification-version>
  52.352 -                    </run-dependency>
  52.353 -                </dependency>
  52.354 -                <dependency>
  52.355 -                    <code-name-base>org.openide.util.lookup</code-name-base>
  52.356 -                    <build-prerequisite/>
  52.357 -                    <compile-dependency/>
  52.358 -                    <run-dependency>
  52.359 -                        <specification-version>8.0</specification-version>
  52.360 -                    </run-dependency>
  52.361 -                </dependency>
  52.362 -                <dependency>
  52.363 -                    <code-name-base>org.openide.windows</code-name-base>
  52.364 -                    <build-prerequisite/>
  52.365 -                    <compile-dependency/>
  52.366 -                    <run-dependency>
  52.367 -                        <specification-version>6.16</specification-version>
  52.368 -                    </run-dependency>
  52.369 -                </dependency>
  52.370 -            </module-dependencies>
  52.371 -            <test-dependencies>
  52.372 -                <test-type>
  52.373 -                    <name>unit</name>
  52.374 -                    <test-dependency>
  52.375 -                        <code-name-base>org.netbeans.core</code-name-base>
  52.376 -                        <compile-dependency/>
  52.377 -                    </test-dependency>
  52.378 -                    <test-dependency>
  52.379 -                        <code-name-base>org.netbeans.insane</code-name-base>
  52.380 -                        <compile-dependency/>
  52.381 -                    </test-dependency>
  52.382 -                    <test-dependency>
  52.383 -                        <code-name-base>org.netbeans.libs.freemarker</code-name-base>
  52.384 -                        <recursive/>
  52.385 -                        <compile-dependency/>
  52.386 -                    </test-dependency>
  52.387 -                    <test-dependency>
  52.388 -                        <code-name-base>org.netbeans.libs.junit4</code-name-base>
  52.389 -                        <compile-dependency/>
  52.390 -                    </test-dependency>
  52.391 -                    <test-dependency>
  52.392 -                        <code-name-base>org.netbeans.modules.classfile</code-name-base>
  52.393 -                    </test-dependency>
  52.394 -                    <test-dependency>
  52.395 -                        <code-name-base>org.netbeans.modules.defaults</code-name-base>
  52.396 -                    </test-dependency>
  52.397 -                    <test-dependency>
  52.398 -                        <code-name-base>org.netbeans.modules.editor</code-name-base>
  52.399 -                        <test/>
  52.400 -                    </test-dependency>
  52.401 -                    <test-dependency>
  52.402 -                        <code-name-base>org.netbeans.modules.editor.mimelookup</code-name-base>
  52.403 -                        <compile-dependency/>
  52.404 -                        <test/>
  52.405 -                    </test-dependency>
  52.406 -                    <test-dependency>
  52.407 -                        <code-name-base>org.netbeans.modules.editor.settings</code-name-base>
  52.408 -                    </test-dependency>
  52.409 -                    <test-dependency>
  52.410 -                        <code-name-base>org.netbeans.modules.editor.settings.storage</code-name-base>
  52.411 -                    </test-dependency>
  52.412 -                    <test-dependency>
  52.413 -                        <code-name-base>org.netbeans.modules.editor.util</code-name-base>
  52.414 -                    </test-dependency>
  52.415 -                    <test-dependency>
  52.416 -                        <code-name-base>org.netbeans.modules.jackpot30.test.borrowed</code-name-base>
  52.417 -                        <compile-dependency/>
  52.418 -                    </test-dependency>
  52.419 -                    <test-dependency>
  52.420 -                        <code-name-base>org.netbeans.modules.java.editor</code-name-base>
  52.421 -                        <recursive/>
  52.422 -                        <compile-dependency/>
  52.423 -                    </test-dependency>
  52.424 -                    <test-dependency>
  52.425 -                        <code-name-base>org.netbeans.modules.java.hints</code-name-base>
  52.426 -                        <compile-dependency/>
  52.427 -                    </test-dependency>
  52.428 -                    <test-dependency>
  52.429 -                        <code-name-base>org.netbeans.modules.java.hints.declarative</code-name-base>
  52.430 -                        <compile-dependency/>
  52.431 -                    </test-dependency>
  52.432 -                    <test-dependency>
  52.433 -                        <code-name-base>org.netbeans.modules.java.source</code-name-base>
  52.434 -                        <compile-dependency/>
  52.435 -                        <test/>
  52.436 -                    </test-dependency>
  52.437 -                    <test-dependency>
  52.438 -                        <code-name-base>org.netbeans.modules.masterfs</code-name-base>
  52.439 -                    </test-dependency>
  52.440 -                    <test-dependency>
  52.441 -                        <code-name-base>org.netbeans.modules.nbjunit</code-name-base>
  52.442 -                        <compile-dependency/>
  52.443 -                    </test-dependency>
  52.444 -                    <test-dependency>
  52.445 -                        <code-name-base>org.netbeans.modules.parsing.api</code-name-base>
  52.446 -                        <compile-dependency/>
  52.447 -                        <test/>
  52.448 -                    </test-dependency>
  52.449 -                    <test-dependency>
  52.450 -                        <code-name-base>org.netbeans.modules.parsing.nb</code-name-base>
  52.451 -                        <compile-dependency/>
  52.452 -                    </test-dependency>
  52.453 -                    <test-dependency>
  52.454 -                        <code-name-base>org.netbeans.modules.progress.ui</code-name-base>
  52.455 -                    </test-dependency>
  52.456 -                    <test-dependency>
  52.457 -                        <code-name-base>org.netbeans.modules.projectapi.nb</code-name-base>
  52.458 -                        <compile-dependency/>
  52.459 -                    </test-dependency>
  52.460 -                    <test-dependency>
  52.461 -                        <code-name-base>org.netbeans.modules.projectui</code-name-base>
  52.462 -                    </test-dependency>
  52.463 -                    <test-dependency>
  52.464 -                        <code-name-base>org.openide.util</code-name-base>
  52.465 -                        <compile-dependency/>
  52.466 -                        <test/>
  52.467 -                    </test-dependency>
  52.468 -                    <test-dependency>
  52.469 -                        <code-name-base>org.openide.util.lookup</code-name-base>
  52.470 -                        <compile-dependency/>
  52.471 -                        <test/>
  52.472 -                    </test-dependency>
  52.473 -                </test-type>
  52.474 -            </test-dependencies>
  52.475 -            <public-packages>
  52.476 -                <package>org.netbeans.spi.java.hints</package>
  52.477 -                <package>org.netbeans.spi.java.hints.annotations</package>
  52.478 -                <package>org.netbeans.spi.java.hints.matching</package>
  52.479 -                <package>org.netbeans.spi.java.hints.support</package>
  52.480 -            </public-packages>
  52.481 -        </data>
  52.482 -    </configuration>
  52.483 -</project>
    53.1 --- a/java.hints/spi.java.hints/nbproject/suite.properties	Sun Oct 16 08:01:27 2016 +0200
    53.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    53.3 @@ -1,1 +0,0 @@
    53.4 -suite.dir=${basedir}/..
    54.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/jackpot/spi/Bundle.properties	Sun Oct 16 08:01:27 2016 +0200
    54.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.3 @@ -1,42 +0,0 @@
    54.4 -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    54.5 -#
    54.6 -# Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
    54.7 -#
    54.8 -# Oracle and Java are registered trademarks of Oracle and/or its affiliates.
    54.9 -# Other names may be trademarks of their respective owners.
   54.10 -#
   54.11 -# The contents of this file are subject to the terms of either the GNU
   54.12 -# General Public License Version 2 only ("GPL") or the Common
   54.13 -# Development and Distribution License("CDDL") (collectively, the
   54.14 -# "License"). You may not use this file except in compliance with the
   54.15 -# License. You can obtain a copy of the License at
   54.16 -# http://www.netbeans.org/cddl-gplv2.html
   54.17 -# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   54.18 -# specific language governing permissions and limitations under the
   54.19 -# License.  When distributing the software, include this License Header
   54.20 -# Notice in each file and include the License file at
   54.21 -# nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   54.22 -# particular file as subject to the "Classpath" exception as provided
   54.23 -# by Oracle in the GPL Version 2 section of the License file that
   54.24 -# accompanied this code. If applicable, add the following below the
   54.25 -# License Header, with the fields enclosed by brackets [] replaced by
   54.26 -# your own identifying information:
   54.27 -# "Portions Copyrighted [year] [name of copyright owner]"
   54.28 -#
   54.29 -# Contributor(s):
   54.30 -#
   54.31 -# The Original Software is NetBeans. The Initial Developer of the Original
   54.32 -# Software is Sun Microsystems, Inc. Portions Copyright 2008-2009 Sun
   54.33 -# Microsystems, Inc. All Rights Reserved.
   54.34 -#
   54.35 -# If you wish your version of this file to be governed by only the CDDL
   54.36 -# or only the GPL Version 2, indicate your decision by adding
   54.37 -# "[Contributor] elects to include this software in this distribution
   54.38 -# under the [CDDL or GPL Version 2] license." If you do not indicate a
   54.39 -# single choice of license, a recipient has the option to distribute
   54.40 -# your version of this file under either the CDDL, the GPL Version 2 or
   54.41 -# to extend the choice of license to its licensees as provided above.
   54.42 -# However, if you add GPL Version 2 code and therefore, elected the GPL
   54.43 -# Version 2 license, then the option applies only if the new code is
   54.44 -# made subject to such option by the copyright holder.
   54.45 -LBL_UpdateDependencyQuestion=Update dependency on module {0} to specification version {1}?
   54.46 \ No newline at end of file
    55.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/jackpot/spi/HintsRunner.java	Sun Oct 16 08:01:27 2016 +0200
    55.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    55.3 @@ -1,69 +0,0 @@
    55.4 -/*
    55.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    55.6 - *
    55.7 - * Copyright 2009-2010 Oracle and/or its affiliates. All rights reserved.
    55.8 - *
    55.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   55.10 - * Other names may be trademarks of their respective owners.
   55.11 - *
   55.12 - * The contents of this file are subject to the terms of either the GNU
   55.13 - * General Public License Version 2 only ("GPL") or the Common
   55.14 - * Development and Distribution License("CDDL") (collectively, the
   55.15 - * "License"). You may not use this file except in compliance with the
   55.16 - * License. You can obtain a copy of the License at
   55.17 - * http://www.netbeans.org/cddl-gplv2.html
   55.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   55.19 - * specific language governing permissions and limitations under the
   55.20 - * License.  When distributing the software, include this License Header
   55.21 - * Notice in each file and include the License file at
   55.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   55.23 - * particular file as subject to the "Classpath" exception as provided
   55.24 - * by Oracle in the GPL Version 2 section of the License file that
   55.25 - * accompanied this code. If applicable, add the following below the
   55.26 - * License Header, with the fields enclosed by brackets [] replaced by
   55.27 - * your own identifying information:
   55.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   55.29 - *
   55.30 - * If you wish your version of this file to be governed by only the CDDL
   55.31 - * or only the GPL Version 2, indicate your decision by adding
   55.32 - * "[Contributor] elects to include this software in this distribution
   55.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   55.34 - * single choice of license, a recipient has the option to distribute
   55.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   55.36 - * to extend the choice of license to its licensees as provided above.
   55.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   55.38 - * Version 2 license, then the option applies only if the new code is
   55.39 - * made subject to such option by the copyright holder.
   55.40 - *
   55.41 - * Contributor(s):
   55.42 - *
   55.43 - * Portions Copyrighted 2009-2010 Sun Microsystems, Inc.
   55.44 - */
   55.45 -
   55.46 -package org.netbeans.modules.java.hints.jackpot.spi;
   55.47 -
   55.48 -import org.netbeans.modules.java.hints.providers.spi.HintDescription;
   55.49 -import com.sun.source.util.TreePath;
   55.50 -import java.util.LinkedList;
   55.51 -import java.util.List;
   55.52 -import java.util.Map;
   55.53 -import java.util.concurrent.atomic.AtomicBoolean;
   55.54 -import org.netbeans.api.annotations.common.CheckForNull;
   55.55 -import org.netbeans.api.java.source.CompilationInfo;
   55.56 -import org.netbeans.modules.java.hints.spiimpl.MessageImpl;
   55.57 -import org.netbeans.modules.java.hints.spiimpl.hints.HintsInvoker;
   55.58 -import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings;
   55.59 -import org.netbeans.spi.editor.hints.ErrorDescription;
   55.60 -
   55.61 -/**XXX: probably unused
   55.62 - *
   55.63 - * @author lahvac
   55.64 - */
   55.65 -public class HintsRunner {
   55.66 -
   55.67 -    @CheckForNull
   55.68 -    public static Map<HintDescription, List<ErrorDescription>> computeErrors(CompilationInfo info, Iterable<? extends HintDescription> hints, AtomicBoolean cancel) {
   55.69 -        return new HintsInvoker(HintsSettings.getSettingsFor(info.getFileObject()), cancel).computeHints(info, new TreePath(info.getCompilationUnit()), hints, new LinkedList<MessageImpl>());
   55.70 -    }
   55.71 -
   55.72 -}
    56.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/jackpot/spi/PatternConvertor.java	Sun Oct 16 08:01:27 2016 +0200
    56.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    56.3 @@ -1,113 +0,0 @@
    56.4 -/*
    56.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    56.6 - *
    56.7 - * Copyright 2009-2011 Sun Microsystems, Inc. All rights reserved.
    56.8 - *
    56.9 - * The contents of this file are subject to the terms of either the GNU
   56.10 - * General Public License Version 2 only ("GPL") or the Common
   56.11 - * Development and Distribution License("CDDL") (collectively, the
   56.12 - * "License"). You may not use this file except in compliance with the
   56.13 - * License. You can obtain a copy of the License at
   56.14 - * http://www.netbeans.org/cddl-gplv2.html
   56.15 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   56.16 - * specific language governing permissions and limitations under the
   56.17 - * License.  When distributing the software, include this License Header
   56.18 - * Notice in each file and include the License file at
   56.19 - * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
   56.20 - * particular file as subject to the "Classpath" exception as provided
   56.21 - * by Sun in the GPL Version 2 section of the License file that
   56.22 - * accompanied this code. If applicable, add the following below the
   56.23 - * License Header, with the fields enclosed by brackets [] replaced by
   56.24 - * your own identifying information:
   56.25 - * "Portions Copyrighted [year] [name of copyright owner]"
   56.26 - *
   56.27 - * If you wish your version of this file to be governed by only the CDDL
   56.28 - * or only the GPL Version 2, indicate your decision by adding
   56.29 - * "[Contributor] elects to include this software in this distribution
   56.30 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   56.31 - * single choice of license, a recipient has the option to distribute
   56.32 - * your version of this file under either the CDDL, the GPL Version 2 or
   56.33 - * to extend the choice of license to its licensees as provided above.
   56.34 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   56.35 - * Version 2 license, then the option applies only if the new code is
   56.36 - * made subject to such option by the copyright holder.
   56.37 - *
   56.38 - * Contributor(s):
   56.39 - *
   56.40 - * Portions Copyrighted 2009-2011 Sun Microsystems, Inc.
   56.41 - */
   56.42 -
   56.43 -package org.netbeans.modules.java.hints.jackpot.spi;
   56.44 -
   56.45 -import org.netbeans.modules.java.hints.providers.spi.HintDescriptionFactory;
   56.46 -import org.netbeans.spi.java.hints.HintContext;
   56.47 -import java.util.ArrayList;
   56.48 -import java.util.Collection;
   56.49 -import java.util.Collections;
   56.50 -import org.netbeans.api.annotations.common.CheckForNull;
   56.51 -import org.netbeans.api.annotations.common.NonNull;
   56.52 -import org.netbeans.modules.java.hints.providers.spi.HintDescription.Worker;
   56.53 -import org.netbeans.modules.java.hints.providers.spi.Trigger.PatternDescription;
   56.54 -import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
   56.55 -import org.netbeans.spi.editor.hints.ErrorDescription;
   56.56 -import org.netbeans.modules.java.hints.providers.spi.HintDescription;
   56.57 -import org.openide.util.Lookup;
   56.58 -
   56.59 -/**XXX: big hack?
   56.60 - *
   56.61 - * @author lahvac
   56.62 - */
   56.63 -public abstract class PatternConvertor {
   56.64 -
   56.65 -    protected abstract @CheckForNull Iterable<? extends HintDescription> parseString(@NonNull String code);
   56.66 -
   56.67 -    public static @CheckForNull Iterable<? extends HintDescription> create(@NonNull String code) {
   56.68 -        Collection<String> patterns = new ArrayList<String>();
   56.69 -        
   56.70 -        //XXX:
   56.71 -        if (code.contains(";;")) {
   56.72 -            PatternConvertor c = Lookup.getDefault().lookup(PatternConvertor.class);
   56.73 -
   56.74 -            if (c != null) {
   56.75 -                return c.parseString(code);
   56.76 -            }
   56.77 -
   56.78 -            for (String s : code.split(";;")) {
   56.79 -                s = s.trim();
   56.80 -                if (s.isEmpty()) {
   56.81 -                    continue;
   56.82 -                }
   56.83 -                
   56.84 -                patterns.add(s);
   56.85 -            }
   56.86 -        } else {
   56.87 -            patterns.add(code);
   56.88 -        }
   56.89 -
   56.90 -        Collection<HintDescription> result = new ArrayList<HintDescription>(patterns.size());
   56.91 -
   56.92 -        for (String pattern : patterns) {
   56.93 -            PatternDescription pd = PatternDescription.create(pattern, Collections.<String, String>emptyMap());
   56.94 -
   56.95 -            HintDescription desc = HintDescriptionFactory.create()
   56.96 -    //                                                     .setDisplayName("Pattern Matches")
   56.97 -                                                         .setTrigger(pd)
   56.98 -                                                         .setWorker(new WorkerImpl())
   56.99 -                                                         .produce();
  56.100 -            
  56.101 -            result.add(desc);
  56.102 -        }
  56.103 -
  56.104 -        return result;
  56.105 -    }
  56.106 -
  56.107 -    private static final class WorkerImpl implements Worker {
  56.108 -
  56.109 -        public Collection<? extends ErrorDescription> createErrors(HintContext ctx) {
  56.110 -            ErrorDescription ed = ErrorDescriptionFactory.forTree(ctx, ctx.getPath(), "Found pattern occurrence");
  56.111 -
  56.112 -            return Collections.singleton(ed);
  56.113 -        }
  56.114 -        
  56.115 -    }
  56.116 -}
    57.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/jackpot/spi/ProjectDependencyUpgrader.java	Sun Oct 16 08:01:27 2016 +0200
    57.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    57.3 @@ -1,64 +0,0 @@
    57.4 -/*
    57.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    57.6 - *
    57.7 - * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
    57.8 - *
    57.9 - * The contents of this file are subject to the terms of either the GNU
   57.10 - * General Public License Version 2 only ("GPL") or the Common
   57.11 - * Development and Distribution License("CDDL") (collectively, the
   57.12 - * "License"). You may not use this file except in compliance with the
   57.13 - * License. You can obtain a copy of the License at
   57.14 - * http://www.netbeans.org/cddl-gplv2.html
   57.15 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   57.16 - * specific language governing permissions and limitations under the
   57.17 - * License.  When distributing the software, include this License Header
   57.18 - * Notice in each file and include the License file at
   57.19 - * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
   57.20 - * particular file as subject to the "Classpath" exception as provided
   57.21 - * by Sun in the GPL Version 2 section of the License file that
   57.22 - * accompanied this code. If applicable, add the following below the
   57.23 - * License Header, with the fields enclosed by brackets [] replaced by
   57.24 - * your own identifying information:
   57.25 - * "Portions Copyrighted [year] [name of copyright owner]"
   57.26 - *
   57.27 - * If you wish your version of this file to be governed by only the CDDL
   57.28 - * or only the GPL Version 2, indicate your decision by adding
   57.29 - * "[Contributor] elects to include this software in this distribution
   57.30 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   57.31 - * single choice of license, a recipient has the option to distribute
   57.32 - * your version of this file under either the CDDL, the GPL Version 2 or
   57.33 - * to extend the choice of license to its licensees as provided above.
   57.34 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   57.35 - * Version 2 license, then the option applies only if the new code is
   57.36 - * made subject to such option by the copyright holder.
   57.37 - *
   57.38 - * Contributor(s):
   57.39 - *
   57.40 - * Portions Copyrighted 2010 Sun Microsystems, Inc.
   57.41 - */
   57.42 -package org.netbeans.modules.java.hints.jackpot.spi;
   57.43 -
   57.44 -import org.netbeans.api.project.Project;
   57.45 -import org.openide.DialogDisplayer;
   57.46 -import org.openide.NotifyDescriptor;
   57.47 -import org.openide.filesystems.FileObject;
   57.48 -import org.openide.modules.SpecificationVersion;
   57.49 -
   57.50 -/**
   57.51 - *
   57.52 - * @author lahvac
   57.53 - */
   57.54 -public abstract class ProjectDependencyUpgrader {
   57.55 -
   57.56 -    public abstract boolean ensureDependency(Project p, FileObject dep, SpecificationVersion spec, boolean canShowUI);
   57.57 -    public abstract boolean ensureDependency(Project p, String specification, boolean b);
   57.58 -
   57.59 -    protected final boolean showDependencyUpgradeDialog(Project p, String dep, SpecificationVersion currentDependency, SpecificationVersion spec, boolean newDepenency, boolean canShowUI) {
   57.60 -        if (!canShowUI) return true;
   57.61 -        
   57.62 -        NotifyDescriptor nd = new NotifyDescriptor.Confirmation("New version: " + spec, "Update spec version.", NotifyDescriptor.YES_NO_OPTION);
   57.63 -
   57.64 -        return DialogDisplayer.getDefault().notify(nd) == NotifyDescriptor.YES_OPTION;
   57.65 -    }
   57.66 -
   57.67 -}
    58.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/code/CodeHintProviderImpl.java	Sun Oct 16 08:01:27 2016 +0200
    58.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    58.3 @@ -1,475 +0,0 @@
    58.4 -/*
    58.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    58.6 - *
    58.7 - * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
    58.8 - *
    58.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   58.10 - * Other names may be trademarks of their respective owners.
   58.11 - *
   58.12 - * The contents of this file are subject to the terms of either the GNU
   58.13 - * General Public License Version 2 only ("GPL") or the Common
   58.14 - * Development and Distribution License("CDDL") (collectively, the
   58.15 - * "License"). You may not use this file except in compliance with the
   58.16 - * License. You can obtain a copy of the License at
   58.17 - * http://www.netbeans.org/cddl-gplv2.html
   58.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   58.19 - * specific language governing permissions and limitations under the
   58.20 - * License.  When distributing the software, include this License Header
   58.21 - * Notice in each file and include the License file at
   58.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   58.23 - * particular file as subject to the "Classpath" exception as provided
   58.24 - * by Oracle in the GPL Version 2 section of the License file that
   58.25 - * accompanied this code. If applicable, add the following below the
   58.26 - * License Header, with the fields enclosed by brackets [] replaced by
   58.27 - * your own identifying information:
   58.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   58.29 - *
   58.30 - * If you wish your version of this file to be governed by only the CDDL
   58.31 - * or only the GPL Version 2, indicate your decision by adding
   58.32 - * "[Contributor] elects to include this software in this distribution
   58.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   58.34 - * single choice of license, a recipient has the option to distribute
   58.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   58.36 - * to extend the choice of license to its licensees as provided above.
   58.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   58.38 - * Version 2 license, then the option applies only if the new code is
   58.39 - * made subject to such option by the copyright holder.
   58.40 - *
   58.41 - * Contributor(s):
   58.42 - *
   58.43 - * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
   58.44 - */
   58.45 -
   58.46 -package org.netbeans.modules.java.hints.providers.code;
   58.47 -
   58.48 -import com.sun.source.tree.Tree.Kind;
   58.49 -import java.lang.annotation.Annotation;
   58.50 -import java.lang.reflect.InvocationTargetException;
   58.51 -import java.lang.reflect.Method;
   58.52 -import java.util.ArrayList;
   58.53 -import java.util.Arrays;
   58.54 -import java.util.Collection;
   58.55 -import java.util.Collections;
   58.56 -import java.util.EnumSet;
   58.57 -import java.util.HashMap;
   58.58 -import java.util.HashSet;
   58.59 -import java.util.LinkedList;
   58.60 -import java.util.List;
   58.61 -import java.util.Map;
   58.62 -import java.util.Set;
   58.63 -import java.util.concurrent.atomic.AtomicReference;
   58.64 -import java.util.logging.Level;
   58.65 -import java.util.logging.Logger;
   58.66 -import java.util.prefs.Preferences;
   58.67 -import javax.swing.JComponent;
   58.68 -import javax.swing.JPanel;
   58.69 -import org.netbeans.modules.java.hints.providers.code.FSWrapper.ClassWrapper;
   58.70 -import org.netbeans.modules.java.hints.providers.code.FSWrapper.FieldWrapper;
   58.71 -import org.netbeans.modules.java.hints.providers.code.FSWrapper.MethodWrapper;
   58.72 -import org.netbeans.modules.java.hints.providers.code.ReflectiveCustomizerProvider.OptionDescriptor;
   58.73 -import org.netbeans.spi.java.hints.CustomizerProvider;
   58.74 -import org.netbeans.modules.java.hints.providers.spi.HintDescription;
   58.75 -import org.netbeans.modules.java.hints.providers.spi.HintDescription.Worker;
   58.76 -import org.netbeans.modules.java.hints.providers.spi.HintDescriptionFactory;
   58.77 -import org.netbeans.modules.java.hints.providers.spi.HintMetadata;
   58.78 -import org.netbeans.modules.java.hints.providers.spi.HintMetadata.Options;
   58.79 -import org.netbeans.modules.java.hints.providers.spi.HintProvider;
   58.80 -import org.netbeans.modules.java.hints.providers.spi.Trigger.DecisionTrigger;
   58.81 -import org.netbeans.modules.java.hints.providers.spi.Trigger.Kinds;
   58.82 -import org.netbeans.modules.java.hints.providers.spi.Trigger.PatternDescription;
   58.83 -import org.netbeans.spi.editor.hints.ErrorDescription;
   58.84 -import org.netbeans.spi.editor.hints.Severity;
   58.85 -import org.netbeans.spi.java.hints.BooleanOption;
   58.86 -import org.netbeans.spi.java.hints.ConstraintVariableType;
   58.87 -import org.netbeans.spi.java.hints.Hint;
   58.88 -import org.netbeans.spi.java.hints.IntegerOption;
   58.89 -import org.netbeans.spi.java.hints.TriggerDecision;
   58.90 -import org.netbeans.spi.java.hints.TriggerPattern;
   58.91 -import org.netbeans.spi.java.hints.TriggerPatterns;
   58.92 -import org.netbeans.spi.java.hints.TriggerTreeKind;
   58.93 -import org.netbeans.spi.java.hints.UseOptions;
   58.94 -import org.openide.util.Exceptions;
   58.95 -import org.openide.util.Lookup;
   58.96 -import org.openide.util.NbCollections;
   58.97 -import org.openide.util.lookup.ServiceProvider;
   58.98 -
   58.99 -/**
  58.100 - *
  58.101 - * @author lahvac
  58.102 - */
  58.103 -@ServiceProvider(service=HintProvider.class)
  58.104 -public class CodeHintProviderImpl implements HintProvider {
  58.105 -
  58.106 -    private static final Logger LOG = Logger.getLogger(WorkerImpl.class.getName());
  58.107 -    
  58.108 -    public Map<HintMetadata, ? extends Collection<? extends HintDescription>> computeHints() {
  58.109 -        return computeHints(findLoader(), "META-INF/nb-hints/hints");
  58.110 -    }
  58.111 -
  58.112 -    private Map<HintMetadata, ? extends Collection<? extends HintDescription>> computeHints(ClassLoader l, String path) {
  58.113 -        Map<HintMetadata, Collection<HintDescription>> result = new HashMap<HintMetadata, Collection<HintDescription>>();
  58.114 -        
  58.115 -        for (ClassWrapper c : FSWrapper.listClasses()) {
  58.116 -            try {
  58.117 -                processClass(c, result);
  58.118 -            } catch (ThreadDeath td) {
  58.119 -                throw td;
  58.120 -            } catch (Throwable t) {
  58.121 -                Exceptions.printStackTrace(t);
  58.122 -            }
  58.123 -        }
  58.124 -
  58.125 -        return result;
  58.126 -    }
  58.127 -
  58.128 -    static ClassLoader findLoader() {
  58.129 -        ClassLoader l = Lookup.getDefault().lookup(ClassLoader.class);
  58.130 -
  58.131 -        if (l == null) {
  58.132 -            return CodeHintProviderImpl.class.getClassLoader();
  58.133 -        }
  58.134 -
  58.135 -        return l;
  58.136 -    }
  58.137 -
  58.138 -    public static void processClass(ClassWrapper clazz, Map<HintMetadata, Collection<HintDescription>> result) throws SecurityException {
  58.139 -        Hint metadata = clazz.getAnnotation(Hint.class);
  58.140 -        HintMetadata hm;
  58.141 -        
  58.142 -        if (metadata != null) {
  58.143 -            String id = metadata.id();
  58.144 -
  58.145 -            if (id == null || id.length() == 0) {
  58.146 -                id = clazz.getName();
  58.147 -            }
  58.148 -            hm = fromAnnotation(id, clazz, null, metadata);
  58.149 -        } else {
  58.150 -            hm = null;
  58.151 -        }
  58.152 -        
  58.153 -        for (MethodWrapper m : clazz.getMethods()) {
  58.154 -            Hint localMetadataAnnotation = m.getAnnotation(Hint.class);
  58.155 -            HintMetadata localMetadata;
  58.156 -
  58.157 -            if (localMetadataAnnotation != null) {
  58.158 -                String localID = localMetadataAnnotation.id();
  58.159 -
  58.160 -                if (localID == null || localID.length() == 0) {
  58.161 -                    localID = clazz.getName() + "." + m.getName();
  58.162 -                }
  58.163 -
  58.164 -                localMetadata = fromAnnotation(localID, clazz, m, localMetadataAnnotation);
  58.165 -            } else {
  58.166 -                localMetadata = hm;
  58.167 -            }
  58.168 -
  58.169 -            if (localMetadata != null) {
  58.170 -                processMethod(result, m, localMetadata);
  58.171 -            }
  58.172 -        }
  58.173 -    }
  58.174 -
  58.175 -    private static HintMetadata fromAnnotation(String id, ClassWrapper clazz, MethodWrapper method, Hint metadata) {
  58.176 -        HintMetadata hm = HintMetadata.Builder.create(id)
  58.177 -                                              .setDescription(metadata.displayName(), metadata.description())
  58.178 -                                              .setCategory(metadata.category())
  58.179 -                                              .setEnabled(metadata.enabled())
  58.180 -                                              .setSeverity(metadata.severity())
  58.181 -                                              .setKind(metadata.hintKind())
  58.182 -                                              .setCustomizerProvider(createCustomizerProvider(clazz, method, id, metadata))
  58.183 -                                              .addSuppressWarnings(metadata.suppressWarnings())
  58.184 -                                              .addOptions(Options.fromHintOptions(metadata.options()).toArray(new Options[0]))
  58.185 -                                              .build();
  58.186 -        return hm;
  58.187 -    }
  58.188 -
  58.189 -    private static CustomizerProvider createCustomizerProvider(ClassWrapper clazz, MethodWrapper method, String id, Hint hint) {
  58.190 -        Class<? extends CustomizerProvider> customizerClass = hint.customizerProvider();
  58.191 -
  58.192 -        if (customizerClass != CustomizerProvider.class) {
  58.193 -            return new DelegatingCustomizerProvider(customizerClass);
  58.194 -        }
  58.195 -
  58.196 -        Set<String> allowedOptions = null;
  58.197 -
  58.198 -        if (method != null) {
  58.199 -            UseOptions useOptions = method.getAnnotation(UseOptions.class);
  58.200 -
  58.201 -            if (useOptions == null) return null;
  58.202 -
  58.203 -            allowedOptions = new HashSet<String>(Arrays.asList(useOptions.value()));
  58.204 -        }
  58.205 -
  58.206 -        List<OptionDescriptor> declarativeOptions = new ArrayList<OptionDescriptor>();
  58.207 -
  58.208 -        for (FieldWrapper fw : clazz.getFields()) {
  58.209 -            BooleanOption option = fw.getAnnotation(BooleanOption.class);
  58.210 -            IntegerOption iOption = fw.getAnnotation(IntegerOption.class);
  58.211 -            
  58.212 -            String key = fw.getConstantValue();
  58.213 -
  58.214 -            if (key == null) continue;
  58.215 -            if (allowedOptions != null && !allowedOptions.contains(key)) continue;
  58.216 -            
  58.217 -            Object defValue;
  58.218 -            String displayName;
  58.219 -            String tooltip;
  58.220 -            if (option != null) {
  58.221 -                defValue = option.defaultValue();
  58.222 -                displayName = option.displayName();
  58.223 -                tooltip = option.tooltip();
  58.224 -            } else if (iOption != null) {
  58.225 -                defValue = iOption.defaultValue();
  58.226 -                displayName = iOption.displayName();
  58.227 -                tooltip = iOption.tooltip();
  58.228 -            } else {
  58.229 -                return null;
  58.230 -            }
  58.231 -            
  58.232 -            declarativeOptions.add(
  58.233 -                new OptionDescriptor(
  58.234 -                    key, 
  58.235 -                    defValue,
  58.236 -                    displayName,
  58.237 -                    tooltip,
  58.238 -                    option != null ? option : iOption)
  58.239 -            );
  58.240 -        }
  58.241 -
  58.242 -        return !declarativeOptions.isEmpty() ? new ReflectiveCustomizerProvider(clazz.getName(), id, declarativeOptions) : null;
  58.243 -    }
  58.244 -    
  58.245 -    static void processMethod(Map<HintMetadata, Collection<HintDescription>> hints, MethodWrapper m, HintMetadata metadata) {
  58.246 -        //XXX: combinations of TriggerTreeKind and TriggerPattern?
  58.247 -        processTreeKindHint(hints, m, metadata);
  58.248 -        processPatternHint(hints, m, metadata);
  58.249 -        processDecisionHint(hints, m, metadata);
  58.250 -    }
  58.251 -    
  58.252 -    private static void processTreeKindHint(Map<HintMetadata, Collection<HintDescription>> hints, MethodWrapper m, HintMetadata metadata) {
  58.253 -        TriggerTreeKind kindTrigger = m.getAnnotation(TriggerTreeKind.class);
  58.254 -
  58.255 -        if (kindTrigger == null) {
  58.256 -            return ;
  58.257 -        }
  58.258 -
  58.259 -        Worker w = new WorkerImpl(m.getClazz().getName(), m.getName());
  58.260 -
  58.261 -        Set<Kind> kinds = EnumSet.noneOf(Kind.class);
  58.262 -        
  58.263 -        kinds.addAll(Arrays.asList(kindTrigger.value()));
  58.264 -
  58.265 -        addHint(hints, metadata, HintDescriptionFactory.create()
  58.266 -                                                       .setTrigger(new Kinds(kinds))
  58.267 -                                                       .setWorker(w)
  58.268 -                                                       .setMetadata(metadata)
  58.269 -                                                       .produce());
  58.270 -    }
  58.271 -    
  58.272 -    private static void processPatternHint(Map<HintMetadata, Collection<HintDescription>> hints, MethodWrapper m, HintMetadata metadata) {
  58.273 -        TriggerPattern patternTrigger = m.getAnnotation(TriggerPattern.class);
  58.274 -
  58.275 -        if (patternTrigger != null) {
  58.276 -            processPatternHint(hints, patternTrigger, m, metadata);
  58.277 -            return ;
  58.278 -        }
  58.279 -
  58.280 -        TriggerPatterns patternTriggers = m.getAnnotation(TriggerPatterns.class);
  58.281 -
  58.282 -        if (patternTriggers != null) {
  58.283 -            for (TriggerPattern pattern : patternTriggers.value()) {
  58.284 -                processPatternHint(hints, pattern, m, metadata);
  58.285 -            }
  58.286 -            return ;
  58.287 -        }
  58.288 -    }
  58.289 -
  58.290 -    private static void processPatternHint(Map<HintMetadata, Collection<HintDescription>> hints, TriggerPattern patternTrigger, MethodWrapper m, HintMetadata metadata) {
  58.291 -        String pattern = patternTrigger.value();
  58.292 -        Map<String, String> constraints = new HashMap<String, String>();
  58.293 -
  58.294 -        for (ConstraintVariableType c : patternTrigger.constraints()) {
  58.295 -            constraints.put(c.variable(), c.type());
  58.296 -        }
  58.297 -
  58.298 -        PatternDescription pd = PatternDescription.create(pattern, constraints);
  58.299 -
  58.300 -        addHint(hints, metadata, HintDescriptionFactory.create()
  58.301 -                                                       .setTrigger(pd)
  58.302 -                                                       .setWorker(new WorkerImpl(m.getClazz().getName(), m.getName()))
  58.303 -                                                       .setMetadata(metadata)
  58.304 -                                                       .produce());
  58.305 -    }
  58.306 -
  58.307 -    private static void processDecisionHint(Map<HintMetadata, Collection<HintDescription>> hints, MethodWrapper m, HintMetadata metadata) {
  58.308 -        TriggerDecision decisionTrigger = m.getAnnotation(TriggerDecision.class);
  58.309 -
  58.310 -        if (decisionTrigger == null) {
  58.311 -            return ;
  58.312 -        }
  58.313 -
  58.314 -        Worker w = new WorkerImpl(m.getClazz().getName(), m.getName());
  58.315 -
  58.316 -        addHint(hints, metadata, HintDescriptionFactory.create()
  58.317 -                                                       .setTrigger(new DecisionTrigger(decisionTrigger.value()))
  58.318 -                                                       .setWorker(w)
  58.319 -                                                       .setMetadata(metadata)
  58.320 -                                                       .produce());
  58.321 -    }
  58.322 -    
  58.323 -    private static void addHint(Map<HintMetadata, Collection<HintDescription>> hints, HintMetadata metadata, HintDescription hint) {
  58.324 -        Collection<HintDescription> list = hints.get(metadata);
  58.325 -
  58.326 -        if (list == null) {
  58.327 -            hints.put(metadata, list = new LinkedList<HintDescription>());
  58.328 -        }
  58.329 -
  58.330 -        list.add(hint);
  58.331 -    }
  58.332 -
  58.333 -    //accessed by tests:
  58.334 -    static final class WorkerImpl implements Worker {
  58.335 -
  58.336 -        private final String className;
  58.337 -        private final String methodName;
  58.338 -
  58.339 -        public WorkerImpl(String className, String methodName) {
  58.340 -            this.className = className;
  58.341 -            this.methodName = methodName;
  58.342 -        }
  58.343 -
  58.344 -        private final AtomicReference<Method> methodRef = new AtomicReference<Method>();
  58.345 -
  58.346 -        public Collection<? extends ErrorDescription> createErrors(org.netbeans.spi.java.hints.HintContext ctx) {
  58.347 -            try {
  58.348 -                Method method = methodRef.get();
  58.349 -
  58.350 -                if (method == null) {
  58.351 -                    methodRef.set(method = getMethod());
  58.352 -                }
  58.353 -                
  58.354 -                Object result = method.invoke(null, ctx);
  58.355 -
  58.356 -                if (result == null) {
  58.357 -                    return null;
  58.358 -                }
  58.359 -
  58.360 -                if (result instanceof Iterable) {
  58.361 -                    List<ErrorDescription> out = new LinkedList<ErrorDescription>();
  58.362 -
  58.363 -                    for (ErrorDescription ed : NbCollections.iterable(NbCollections.checkedIteratorByFilter(((Iterable) result).iterator(), ErrorDescription.class, false))) {
  58.364 -                        out.add(ed);
  58.365 -                    }
  58.366 -
  58.367 -                    return out;
  58.368 -                }
  58.369 -
  58.370 -                if (result instanceof ErrorDescription) {
  58.371 -                    return Collections.singletonList((ErrorDescription) result);
  58.372 -                }
  58.373 -
  58.374 -                //XXX: log if result was ignored...
  58.375 -            } catch (IllegalAccessException ex) {
  58.376 -                Exceptions.printStackTrace(ex);
  58.377 -            } catch (IllegalArgumentException ex) {
  58.378 -                Exceptions.printStackTrace(ex);
  58.379 -            } catch (ClassNotFoundException ex) {
  58.380 -                Exceptions.printStackTrace(ex);
  58.381 -            } catch (NoSuchMethodException ex) {
  58.382 -                Exceptions.printStackTrace(ex);
  58.383 -            } catch (InvocationTargetException ex) {
  58.384 -                LOG.log(Level.INFO, className + "." + methodName, ex);
  58.385 -                //so that the exceptions are categorized better:
  58.386 -                Exceptions.printStackTrace(ex.getCause());
  58.387 -            }
  58.388 -
  58.389 -            return null;
  58.390 -        }
  58.391 -
  58.392 -        //used by tests:
  58.393 -        Method getMethod() throws NoSuchMethodException, ClassNotFoundException {
  58.394 -            return FSWrapper.resolveMethod(className, methodName);
  58.395 -        }
  58.396 -
  58.397 -    }
  58.398 -
  58.399 -    private static final class EmptyHintMetadataDescription implements Hint {
  58.400 -
  58.401 -        public String id() {
  58.402 -            return "";
  58.403 -        }
  58.404 -
  58.405 -        public String category() {
  58.406 -            return "general";
  58.407 -        }
  58.408 -
  58.409 -        public boolean enabled() {
  58.410 -            return true;
  58.411 -        }
  58.412 -
  58.413 -        public Severity severity() {
  58.414 -            return Severity.VERIFIER;
  58.415 -        }
  58.416 -
  58.417 -        private static final String[] EMPTY_SW = new String[0];
  58.418 -        
  58.419 -        public String[] suppressWarnings() {
  58.420 -            return EMPTY_SW;
  58.421 -        }
  58.422 -
  58.423 -        public Class<? extends Annotation> annotationType() {
  58.424 -            return Hint.class;
  58.425 -        }
  58.426 -
  58.427 -        public Class<? extends CustomizerProvider> customizerProvider() {
  58.428 -            return CustomizerProvider.class;
  58.429 -        }
  58.430 -
  58.431 -        public Kind hintKind() {
  58.432 -            return Kind.INSPECTION;
  58.433 -        }
  58.434 -
  58.435 -        private static final Options[] EMPTY_OPTIONS = new Options[0];
  58.436 -
  58.437 -        public Options[] options() {
  58.438 -            return EMPTY_OPTIONS;
  58.439 -        }
  58.440 -
  58.441 -        @Override public String displayName() {
  58.442 -            return "";
  58.443 -        }
  58.444 -
  58.445 -        @Override public String description() {
  58.446 -            return "";
  58.447 -        }
  58.448 -
  58.449 -    }
  58.450 -
  58.451 -    private static final class DelegatingCustomizerProvider implements CustomizerProvider {
  58.452 -
  58.453 -        private final Class<? extends CustomizerProvider> component;
  58.454 -
  58.455 -        public DelegatingCustomizerProvider(Class<? extends CustomizerProvider> component) {
  58.456 -            this.component = component;
  58.457 -        }
  58.458 -
  58.459 -        @Override
  58.460 -        public JComponent getCustomizer(Preferences prefs) {
  58.461 -            try {
  58.462 -                return component.newInstance().getCustomizer(prefs);
  58.463 -            } catch (SecurityException ex) {
  58.464 -                Exceptions.printStackTrace(ex);
  58.465 -            } catch (InstantiationException ex) {
  58.466 -                Exceptions.printStackTrace(ex);
  58.467 -            } catch (IllegalAccessException ex) {
  58.468 -                Exceptions.printStackTrace(ex);
  58.469 -            } catch (IllegalArgumentException ex) {
  58.470 -                Exceptions.printStackTrace(ex);
  58.471 -            }
  58.472 -
  58.473 -            return new JPanel();
  58.474 -        }
  58.475 -
  58.476 -    }
  58.477 -
  58.478 -}
    59.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/code/FSWrapper.java	Sun Oct 16 08:01:27 2016 +0200
    59.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    59.3 @@ -1,319 +0,0 @@
    59.4 -/*
    59.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    59.6 - *
    59.7 - * Copyright 2010-2011 Oracle and/or its affiliates. All rights reserved.
    59.8 - *
    59.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   59.10 - * Other names may be trademarks of their respective owners.
   59.11 - *
   59.12 - * The contents of this file are subject to the terms of either the GNU
   59.13 - * General Public License Version 2 only ("GPL") or the Common
   59.14 - * Development and Distribution License("CDDL") (collectively, the
   59.15 - * "License"). You may not use this file except in compliance with the
   59.16 - * License. You can obtain a copy of the License at
   59.17 - * http://www.netbeans.org/cddl-gplv2.html
   59.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   59.19 - * specific language governing permissions and limitations under the
   59.20 - * License.  When distributing the software, include this License Header
   59.21 - * Notice in each file and include the License file at
   59.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   59.23 - * particular file as subject to the "Classpath" exception as provided
   59.24 - * by Oracle in the GPL Version 2 section of the License file that
   59.25 - * accompanied this code. If applicable, add the following below the
   59.26 - * License Header, with the fields enclosed by brackets [] replaced by
   59.27 - * your own identifying information:
   59.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   59.29 - *
   59.30 - * If you wish your version of this file to be governed by only the CDDL
   59.31 - * or only the GPL Version 2, indicate your decision by adding
   59.32 - * "[Contributor] elects to include this software in this distribution
   59.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   59.34 - * single choice of license, a recipient has the option to distribute
   59.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   59.36 - * to extend the choice of license to its licensees as provided above.
   59.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   59.38 - * Version 2 license, then the option applies only if the new code is
   59.39 - * made subject to such option by the copyright holder.
   59.40 - *
   59.41 - * Contributor(s):
   59.42 - *
   59.43 - * Portions Copyrighted 2010-2011 Sun Microsystems, Inc.
   59.44 - */
   59.45 -
   59.46 -package org.netbeans.modules.java.hints.providers.code;
   59.47 -
   59.48 -import java.lang.annotation.Annotation;
   59.49 -import java.lang.reflect.Array;
   59.50 -import java.lang.reflect.InvocationHandler;
   59.51 -import java.lang.reflect.Method;
   59.52 -import java.lang.reflect.Proxy;
   59.53 -import java.util.HashMap;
   59.54 -import java.util.LinkedList;
   59.55 -import java.util.List;
   59.56 -import java.util.Map;
   59.57 -import java.util.logging.Level;
   59.58 -import java.util.logging.Logger;
   59.59 -import org.netbeans.spi.java.hints.HintContext;
   59.60 -import org.openide.filesystems.FileObject;
   59.61 -import org.openide.filesystems.FileUtil;
   59.62 -import org.openide.util.Exceptions;
   59.63 -
   59.64 -/**
   59.65 - *
   59.66 - * @author lahvac
   59.67 - */
   59.68 -public class FSWrapper {
   59.69 -
   59.70 -    public static Iterable<? extends ClassWrapper> listClasses() {
   59.71 -        ClassLoader loader = FSWrapper.class.getClassLoader();
   59.72 -
   59.73 -        if (loader == null) {
   59.74 -            loader = ClassLoader.getSystemClassLoader();
   59.75 -        }
   59.76 -
   59.77 -        List<ClassWrapper> result = new LinkedList<ClassWrapper>();
   59.78 -        FileObject main = FileUtil.getConfigFile("org-netbeans-modules-java-hints/code-hints/");
   59.79 -
   59.80 -        if (main != null) {
   59.81 -            for (FileObject c : main.getChildren()) {
   59.82 -                result.add(new ClassWrapper(loader, c));
   59.83 -            }
   59.84 -        }
   59.85 -
   59.86 -        return result;
   59.87 -    }
   59.88 -
   59.89 -    public static Method resolveMethod(String className, String methodName) throws NoSuchMethodException, ClassNotFoundException {
   59.90 -        Class<?> clazz = CodeHintProviderImpl.findLoader().loadClass(className);
   59.91 -
   59.92 -        return clazz.getDeclaredMethod(methodName, HintContext.class);
   59.93 -    }
   59.94 -
   59.95 -    public static class AnnotatableWrapper {
   59.96 -        protected final ClassLoader loader;
   59.97 -        protected final FileObject folder;
   59.98 -        protected AnnotatableWrapper(ClassLoader loader, FileObject folder) {
   59.99 -            this.loader = loader;
  59.100 -            this.folder = folder;
  59.101 -        }
  59.102 -
  59.103 -        private final Map<Class<? extends Annotation>, Annotation> annotations = new HashMap<Class<? extends Annotation>, Annotation>();
  59.104 -
  59.105 -        public synchronized <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
  59.106 -            if (!this.annotations.containsKey(annotationClass)) {
  59.107 -                FileObject f = folder.getFileObject(annotationClass.getName().replace('.', '-') + ".annotation");
  59.108 -                T result = null;
  59.109 -
  59.110 -                if (f != null) {
  59.111 -                    try {
  59.112 -                        Annotation a = loadAnnotation(loader, f);
  59.113 -
  59.114 -                        result = annotationClass.cast(a);
  59.115 -                    } catch (ClassNotFoundException ex) {
  59.116 -                        Exceptions.printStackTrace(ex);
  59.117 -                    }
  59.118 -                }
  59.119 -
  59.120 -                this.annotations.put(annotationClass, result);
  59.121 -            }
  59.122 -
  59.123 -            return annotationClass.cast(this.annotations.get(annotationClass));
  59.124 -        }
  59.125 -    }
  59.126 -
  59.127 -    public static class ClassWrapper extends AnnotatableWrapper {
  59.128 -        private final String className;
  59.129 -        public ClassWrapper(ClassLoader loader, FileObject folder) {
  59.130 -            super(loader, folder);
  59.131 -            className = folder.getName().replace('-', '.');
  59.132 -        }
  59.133 -
  59.134 -        private Iterable<? extends MethodWrapper> methods;
  59.135 -
  59.136 -        public synchronized Iterable<? extends MethodWrapper> getMethods() {
  59.137 -            if (this.methods == null) {
  59.138 -                List<MethodWrapper> methods = new LinkedList<MethodWrapper>();
  59.139 -
  59.140 -                for (FileObject c : folder.getChildren()) {
  59.141 -                    if (c.getExt().equals("method")) {
  59.142 -                        methods.add(new MethodWrapper(loader, c, this));
  59.143 -                    }
  59.144 -                }
  59.145 -
  59.146 -                this.methods = methods;
  59.147 -            }
  59.148 -
  59.149 -            return this.methods;
  59.150 -        }
  59.151 -
  59.152 -        private Iterable<? extends FieldWrapper> fields;
  59.153 -
  59.154 -        public synchronized Iterable<? extends FieldWrapper> getFields() {
  59.155 -            if (this.fields == null) {
  59.156 -                List<FieldWrapper> fields = new LinkedList<FieldWrapper>();
  59.157 -
  59.158 -                for (FileObject c : folder.getChildren()) {
  59.159 -                    if (c.getExt().equals("field")) {
  59.160 -                        fields.add(new FieldWrapper(loader, c, this));
  59.161 -                    }
  59.162 -                }
  59.163 -
  59.164 -                this.fields = fields;
  59.165 -            }
  59.166 -
  59.167 -            return this.fields;
  59.168 -        }
  59.169 -
  59.170 -        public String getName() {
  59.171 -            return className;
  59.172 -        }
  59.173 -
  59.174 -        private Class<?> clazz;
  59.175 -        public synchronized Class<?> getDeclaredClass() {
  59.176 -            if (clazz != null) {
  59.177 -                return clazz;
  59.178 -            }
  59.179 -
  59.180 -            try {
  59.181 -                return this.clazz = loader.loadClass(className);
  59.182 -            } catch (ClassNotFoundException ex) {
  59.183 -                Exceptions.printStackTrace(ex);
  59.184 -            }
  59.185 -
  59.186 -            return null; //XXX
  59.187 -        }
  59.188 -    }
  59.189 -
  59.190 -    public static class MethodWrapper extends AnnotatableWrapper {
  59.191 -        private final ClassWrapper clazz;
  59.192 -        public MethodWrapper(ClassLoader loader, FileObject folder, ClassWrapper clazz) {
  59.193 -            super(loader, folder);
  59.194 -            this.clazz = clazz;
  59.195 -        }
  59.196 -
  59.197 -        ClassWrapper getClazz() {
  59.198 -            return clazz;
  59.199 -        }
  59.200 -        
  59.201 -        String getName() {
  59.202 -            return folder.getName();
  59.203 -        }
  59.204 -    }
  59.205 -
  59.206 -    public static class FieldWrapper extends AnnotatableWrapper {
  59.207 -        private final ClassWrapper clazz;
  59.208 -        public FieldWrapper(ClassLoader loader, FileObject folder, ClassWrapper clazz) {
  59.209 -            super(loader, folder);
  59.210 -            this.clazz = clazz;
  59.211 -        }
  59.212 -
  59.213 -        ClassWrapper getClazz() {
  59.214 -            return clazz;
  59.215 -        }
  59.216 -
  59.217 -        String getName() {
  59.218 -            return folder.getName();
  59.219 -        }
  59.220 -
  59.221 -        String getConstantValue() {
  59.222 -            Object constantValue = folder.getAttribute("constantValue");
  59.223 -
  59.224 -            if (constantValue instanceof String) {
  59.225 -                return (String) constantValue;
  59.226 -            }
  59.227 -
  59.228 -            return null;
  59.229 -        }
  59.230 -    }
  59.231 -
  59.232 -    private static final Object MARKER = new Object();
  59.233 -    
  59.234 -    private static Object computeAttributeValue(ClassLoader loader, FileObject folder, String attributeName, Class<?> returnType, Object defaulValue) throws ClassNotFoundException {
  59.235 -        Object result = folder.getAttribute(attributeName);
  59.236 -
  59.237 -        if (result == null) {
  59.238 -            FileObject embedded = folder.getFileObject(attributeName);
  59.239 -
  59.240 -            if (embedded == null) {
  59.241 -                result = defaulValue;
  59.242 -            } else {
  59.243 -                if (returnType.isArray()) {
  59.244 -                    List<Object> items = new LinkedList<Object>();
  59.245 -                    int c = 0;
  59.246 -
  59.247 -                    while (true) {
  59.248 -                        Object val = computeAttributeValue(loader, embedded, "item" + c, returnType.getComponentType(), MARKER);
  59.249 -
  59.250 -                        if (val == MARKER) {
  59.251 -                            break;
  59.252 -                        }
  59.253 -
  59.254 -                        items.add(val);
  59.255 -                        c++;
  59.256 -                    }
  59.257 -
  59.258 -                    Object res = Array.newInstance(returnType.getComponentType(), items.size());
  59.259 -                    int ci = 0;
  59.260 -
  59.261 -                    for (Object i : items) {
  59.262 -                        Array.set(res, ci++, i);
  59.263 -                    }
  59.264 -
  59.265 -                    result = res;
  59.266 -                } else if (returnType.isAnnotation()) {
  59.267 -                    result = loadAnnotation(loader, embedded.getChildren()[0]);
  59.268 -                }
  59.269 -            }
  59.270 -        } else {
  59.271 -            if (returnType.isEnum()) {
  59.272 -                String fqn = (String) result;
  59.273 -                int lastDot = fqn.lastIndexOf('.');
  59.274 -                Class<? extends Enum> enumClass = (Class<? extends Enum>) loader.loadClass(fqn.substring(0, lastDot));
  59.275 -
  59.276 -                result = Enum.valueOf(enumClass, fqn.substring(lastDot + 1));
  59.277 -            } else if (returnType == Class.class) {
  59.278 -                String fqn = (String) result;
  59.279 -
  59.280 -                try {
  59.281 -                    result = loader.loadClass(fqn);
  59.282 -                } catch (ClassNotFoundException ex) {
  59.283 -                    Logger.getLogger(FSWrapper.class.getName()).log(Level.FINE, null, ex);
  59.284 -                    result = CodeHintProviderImpl.findLoader().loadClass(fqn);
  59.285 -                }
  59.286 -            }
  59.287 -        }
  59.288 -
  59.289 -        return result;
  59.290 -    }
  59.291 -
  59.292 -    
  59.293 -    private static <T extends Annotation> T loadAnnotation(ClassLoader l, FileObject annotationFolder) throws ClassNotFoundException {
  59.294 -        Class<?> clazz = l.loadClass(annotationFolder.getName().replace('-', '.'));
  59.295 -
  59.296 -        return (T) Proxy.newProxyInstance(l, new Class[] {clazz}, new InvocationHandlerImpl(l, annotationFolder));
  59.297 -    }
  59.298 -    
  59.299 -    private static final class InvocationHandlerImpl implements InvocationHandler {
  59.300 -
  59.301 -        private final ClassLoader loader;
  59.302 -        private final FileObject folder;
  59.303 -        private final Map<String, Object> attributes = new HashMap<String, Object>();
  59.304 -
  59.305 -        public InvocationHandlerImpl(ClassLoader loader, FileObject folder) {
  59.306 -            this.loader = loader;
  59.307 -            this.folder = folder;
  59.308 -        }
  59.309 -
  59.310 -        public synchronized Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  59.311 -            if (!attributes.containsKey(method.getName())) {
  59.312 -                Object result = computeAttributeValue(loader, folder, method.getName(), method.getReturnType(), method.getDefaultValue());
  59.313 -
  59.314 -                attributes.put(method.getName(), result);
  59.315 -            }
  59.316 -
  59.317 -            return attributes.get(method.getName());
  59.318 -        }
  59.319 -
  59.320 -    }
  59.321 -
  59.322 -}
    60.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/code/ReflectiveCustomizerProvider.java	Sun Oct 16 08:01:27 2016 +0200
    60.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    60.3 @@ -1,261 +0,0 @@
    60.4 -/*
    60.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    60.6 - *
    60.7 - * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
    60.8 - *
    60.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   60.10 - * Other names may be trademarks of their respective owners.
   60.11 - *
   60.12 - * The contents of this file are subject to the terms of either the GNU
   60.13 - * General Public License Version 2 only ("GPL") or the Common
   60.14 - * Development and Distribution License("CDDL") (collectively, the
   60.15 - * "License"). You may not use this file except in compliance with the
   60.16 - * License. You can obtain a copy of the License at
   60.17 - * http://www.netbeans.org/cddl-gplv2.html
   60.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   60.19 - * specific language governing permissions and limitations under the
   60.20 - * License.  When distributing the software, include this License Header
   60.21 - * Notice in each file and include the License file at
   60.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   60.23 - * particular file as subject to the "Classpath" exception as provided
   60.24 - * by Oracle in the GPL Version 2 section of the License file that
   60.25 - * accompanied this code. If applicable, add the following below the
   60.26 - * License Header, with the fields enclosed by brackets [] replaced by
   60.27 - * your own identifying information:
   60.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   60.29 - *
   60.30 - * If you wish your version of this file to be governed by only the CDDL
   60.31 - * or only the GPL Version 2, indicate your decision by adding
   60.32 - * "[Contributor] elects to include this software in this distribution
   60.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   60.34 - * single choice of license, a recipient has the option to distribute
   60.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   60.36 - * to extend the choice of license to its licensees as provided above.
   60.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   60.38 - * Version 2 license, then the option applies only if the new code is
   60.39 - * made subject to such option by the copyright holder.
   60.40 - *
   60.41 - * Contributor(s):
   60.42 - *
   60.43 - * Portions Copyrighted 2012 Sun Microsystems, Inc.
   60.44 - */
   60.45 -package org.netbeans.modules.java.hints.providers.code;
   60.46 -
   60.47 -import java.awt.GridBagConstraints;
   60.48 -import java.awt.GridBagLayout;
   60.49 -import java.awt.Insets;
   60.50 -import java.awt.event.ActionEvent;
   60.51 -import java.awt.event.ActionListener;
   60.52 -import java.util.List;
   60.53 -import java.util.prefs.Preferences;
   60.54 -import javax.swing.JCheckBox;
   60.55 -import javax.swing.JComponent;
   60.56 -import javax.swing.JFormattedTextField;
   60.57 -import javax.swing.JLabel;
   60.58 -import javax.swing.JPanel;
   60.59 -import javax.swing.JSpinner;
   60.60 -import javax.swing.SpinnerNumberModel;
   60.61 -import javax.swing.event.ChangeEvent;
   60.62 -import javax.swing.event.ChangeListener;
   60.63 -import javax.swing.text.NumberFormatter;
   60.64 -import org.netbeans.spi.java.hints.BooleanOption;
   60.65 -import org.netbeans.spi.java.hints.CustomizerProvider;
   60.66 -import org.netbeans.spi.java.hints.IntegerOption;
   60.67 -import org.openide.util.Exceptions;
   60.68 -
   60.69 -/**
   60.70 - *
   60.71 - * @author lahvac
   60.72 - */
   60.73 -public class ReflectiveCustomizerProvider implements CustomizerProvider {
   60.74 -    private final String hintClassName;
   60.75 -    private final String hintId;
   60.76 -    private final List<OptionDescriptor> options;
   60.77 -
   60.78 -    public ReflectiveCustomizerProvider(String hintClassName, String hintId, List<OptionDescriptor> options) {
   60.79 -        this.hintClassName = hintClassName;
   60.80 -        this.hintId = hintId;
   60.81 -        this.options = options;
   60.82 -    }
   60.83 -
   60.84 -    @Override
   60.85 -    public JComponent getCustomizer(Preferences prefs) {
   60.86 -        return new CustomizerImpl(prefs, hintClassName, hintId, options);
   60.87 -    }
   60.88 -
   60.89 -    private static final class CustomizerImpl extends JPanel {
   60.90 -        private int row;
   60.91 -        
   60.92 -        public CustomizerImpl(Preferences prefs, String hintClassName, String hintId, List<OptionDescriptor> options) {
   60.93 -            try {
   60.94 -                setLayout(new GridBagLayout());
   60.95 -                row = 0;
   60.96 -                
   60.97 -                for (OptionDescriptor option : options) {
   60.98 -                    if (option.parameters instanceof IntegerOption) {
   60.99 -                        createIntegerOption(option, prefs);
  60.100 -                    }
  60.101 -                }
  60.102 -
  60.103 -                for (OptionDescriptor option : options) {
  60.104 -                    if (option.parameters instanceof BooleanOption) {
  60.105 -                        createBooleanOption(option, prefs);
  60.106 -                    }
  60.107 -                }
  60.108 -
  60.109 -                GridBagConstraints constraints = new GridBagConstraints();
  60.110 -
  60.111 -                constraints.anchor = GridBagConstraints.NORTHWEST;
  60.112 -                constraints.fill = GridBagConstraints.BOTH;
  60.113 -                constraints.gridheight = 1;
  60.114 -                constraints.gridwidth = GridBagConstraints.REMAINDER;
  60.115 -                constraints.gridx = 0;
  60.116 -                constraints.gridy = row++;
  60.117 -                constraints.weightx = 1;
  60.118 -                constraints.weighty = 1;
  60.119 -
  60.120 -                add(new JPanel(), constraints);
  60.121 -            } catch (IllegalArgumentException ex) {
  60.122 -                Exceptions.printStackTrace(ex);
  60.123 -            } catch (SecurityException ex) {
  60.124 -                Exceptions.printStackTrace(ex);
  60.125 -            }
  60.126 -        }
  60.127 -        
  60.128 -        private void createIntegerOption(OptionDescriptor option, Preferences prefs) {
  60.129 -            IntegerOption iopt = (IntegerOption)option.parameters;
  60.130 -            JLabel l = new JLabel();
  60.131 -            org.openide.awt.Mnemonics.setLocalizedText(l, option.displayName + ":");
  60.132 -            
  60.133 -            GridBagConstraints constraints = new GridBagConstraints();
  60.134 -            constraints.anchor = GridBagConstraints.WEST;
  60.135 -            constraints.fill = GridBagConstraints.NONE;
  60.136 -            constraints.gridheight = 1;
  60.137 -            constraints.gridwidth = 1;
  60.138 -            constraints.gridx = 0;
  60.139 -            constraints.gridy = row;
  60.140 -            constraints.weightx = 0;
  60.141 -            constraints.weighty = 0;
  60.142 -            constraints.insets = new Insets(0, 0, 0, 8);
  60.143 -            
  60.144 -            add(l, constraints);
  60.145 -            
  60.146 -            JComponent field;
  60.147 -            int val = prefs.getInt(option.preferencesKey, ((Integer)option.defaultValue).intValue());
  60.148 -            if (iopt.step() > 0) {
  60.149 -                val = Math.min(iopt.maxValue(), Math.max(iopt.minValue(), val));
  60.150 -                JSpinner spinner = new JSpinner(
  60.151 -                        new SpinnerNumberModel(val, iopt.minValue(), iopt.maxValue(), iopt.step()));
  60.152 -                spinner.addChangeListener(new ActionListenerImpl(option.preferencesKey, prefs));
  60.153 -                field = spinner;
  60.154 -            } else {
  60.155 -                NumberFormatter nf = new NumberFormatter();
  60.156 -                nf.setValueClass(Integer.class);
  60.157 -                nf.setMaximum(iopt.maxValue());
  60.158 -                nf.setMinimum(iopt.minValue());
  60.159 -                JFormattedTextField formatted = new JFormattedTextField(nf);
  60.160 -                field = formatted;
  60.161 -            }
  60.162 -            if (option.tooltip != null && !option.tooltip.isEmpty()) {
  60.163 -                field.setToolTipText(option.tooltip);
  60.164 -            }
  60.165 -            constraints = new GridBagConstraints();
  60.166 -            constraints.anchor = GridBagConstraints.WEST;
  60.167 -            constraints.fill = GridBagConstraints.HORIZONTAL;
  60.168 -            constraints.gridheight = 1;
  60.169 -            constraints.gridwidth = 1;
  60.170 -            constraints.gridx = 1;
  60.171 -            constraints.gridy = row;
  60.172 -            constraints.weightx = 0;
  60.173 -            constraints.weighty = 0;
  60.174 -            
  60.175 -            add(field, constraints);
  60.176 -
  60.177 -            constraints = new GridBagConstraints();
  60.178 -            constraints.anchor = GridBagConstraints.WEST;
  60.179 -            constraints.fill = GridBagConstraints.HORIZONTAL;
  60.180 -            constraints.gridheight = 1;
  60.181 -            constraints.gridwidth = GridBagConstraints.REMAINDER;
  60.182 -            constraints.gridx = 2;
  60.183 -            constraints.gridy = row++;
  60.184 -            constraints.weightx = 1;
  60.185 -            constraints.weighty = 0;
  60.186 -            
  60.187 -            add(new JPanel(), constraints);
  60.188 -        }
  60.189 -        
  60.190 -        private JComponent createBooleanOption(OptionDescriptor option, Preferences prefs)  {
  60.191 -            JCheckBox checkBox = new JCheckBox();
  60.192 -
  60.193 -            org.openide.awt.Mnemonics.setLocalizedText(checkBox, option.displayName);
  60.194 -            checkBox.setToolTipText(option.tooltip);
  60.195 -            checkBox.addActionListener(new ActionListenerImpl(option.preferencesKey, prefs));
  60.196 -
  60.197 -            checkBox.setSelected(prefs.getBoolean(option.preferencesKey, 
  60.198 -                    Boolean.TRUE == option.defaultValue));
  60.199 -            GridBagConstraints constraints = new GridBagConstraints();
  60.200 -
  60.201 -            constraints.anchor = GridBagConstraints.WEST;
  60.202 -            constraints.fill = GridBagConstraints.NONE;
  60.203 -            constraints.gridheight = 1;
  60.204 -            constraints.gridwidth = 2;
  60.205 -            constraints.gridx = 0;
  60.206 -            constraints.gridy = row++;
  60.207 -            constraints.weightx = 0;
  60.208 -            constraints.weighty = 0;
  60.209 -
  60.210 -            add(checkBox, constraints);
  60.211 -            return checkBox;
  60.212 -        }
  60.213 -                
  60.214 -        
  60.215 -        private static final class ActionListenerImpl implements ActionListener, ChangeListener {
  60.216 -            private final String key;
  60.217 -            private final Preferences prefs;
  60.218 -
  60.219 -            public ActionListenerImpl(String key, Preferences prefs) {
  60.220 -                this.key = key;
  60.221 -                this.prefs = prefs;
  60.222 -            }
  60.223 -
  60.224 -            @Override
  60.225 -            public void actionPerformed(ActionEvent e) {
  60.226 -                JCheckBox checkBox = ((JCheckBox)e.getSource());
  60.227 -                prefs.putBoolean(key, checkBox.isSelected());
  60.228 -            }
  60.229 -
  60.230 -            @Override
  60.231 -            public void stateChanged(ChangeEvent e) {
  60.232 -                Integer i = (Integer)((JSpinner)e.getSource()).getValue();
  60.233 -                prefs.putInt(key, i);
  60.234 -            }
  60.235 -
  60.236 -        }
  60.237 -        
  60.238 -    }
  60.239 -
  60.240 -    public static final class OptionDescriptor {
  60.241 -        public final String preferencesKey;
  60.242 -        public final Object defaultValue;
  60.243 -        public final String displayName;
  60.244 -        public final String tooltip;
  60.245 -        /**
  60.246 -         * The original Annotation object, type-specific parameters.
  60.247 -         */
  60.248 -        public final Object parameters;
  60.249 -
  60.250 -        public OptionDescriptor(
  60.251 -                String preferencesKey, 
  60.252 -                Object defaultValue, 
  60.253 -                String displayName, String tooltip, 
  60.254 -                Object parameters) {
  60.255 -            this.preferencesKey = preferencesKey;
  60.256 -            this.defaultValue = defaultValue;
  60.257 -            this.displayName = displayName;
  60.258 -            this.tooltip = tooltip;
  60.259 -            this.parameters = parameters;
  60.260 -        }
  60.261 -
  60.262 -    }
  60.263 -
  60.264 -}
    61.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/ClassPathBasedHintProvider.java	Sun Oct 16 08:01:27 2016 +0200
    61.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    61.3 @@ -1,57 +0,0 @@
    61.4 -/*
    61.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    61.6 - *
    61.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
    61.8 - *
    61.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   61.10 - * Other names may be trademarks of their respective owners.
   61.11 - *
   61.12 - * The contents of this file are subject to the terms of either the GNU
   61.13 - * General Public License Version 2 only ("GPL") or the Common
   61.14 - * Development and Distribution License("CDDL") (collectively, the
   61.15 - * "License"). You may not use this file except in compliance with the
   61.16 - * License. You can obtain a copy of the License at
   61.17 - * http://www.netbeans.org/cddl-gplv2.html
   61.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   61.19 - * specific language governing permissions and limitations under the
   61.20 - * License.  When distributing the software, include this License Header
   61.21 - * Notice in each file and include the License file at
   61.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   61.23 - * particular file as subject to the "Classpath" exception as provided
   61.24 - * by Oracle in the GPL Version 2 section of the License file that
   61.25 - * accompanied this code. If applicable, add the following below the
   61.26 - * License Header, with the fields enclosed by brackets [] replaced by
   61.27 - * your own identifying information:
   61.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   61.29 - *
   61.30 - * If you wish your version of this file to be governed by only the CDDL
   61.31 - * or only the GPL Version 2, indicate your decision by adding
   61.32 - * "[Contributor] elects to include this software in this distribution
   61.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   61.34 - * single choice of license, a recipient has the option to distribute
   61.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   61.36 - * to extend the choice of license to its licensees as provided above.
   61.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   61.38 - * Version 2 license, then the option applies only if the new code is
   61.39 - * made subject to such option by the copyright holder.
   61.40 - *
   61.41 - * Contributor(s):
   61.42 - *
   61.43 - * Portions Copyrighted 2009 Sun Microsystems, Inc.
   61.44 - */
   61.45 -
   61.46 -package org.netbeans.modules.java.hints.providers.spi;
   61.47 -
   61.48 -import java.util.Collection;
   61.49 -import org.netbeans.api.java.classpath.ClassPath;
   61.50 -import org.netbeans.modules.java.hints.providers.spi.HintDescription;
   61.51 -
   61.52 -/**
   61.53 - * XXX: this is another ugly hack!
   61.54 - * @author lahvac
   61.55 - */
   61.56 -public interface ClassPathBasedHintProvider {
   61.57 -
   61.58 -    public Collection<? extends HintDescription> computeHints(ClassPath cp);
   61.59 -
   61.60 -}
    62.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/ElementBasedHintProvider.java	Sun Oct 16 08:01:27 2016 +0200
    62.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    62.3 @@ -1,57 +0,0 @@
    62.4 -/*
    62.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    62.6 - *
    62.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
    62.8 - *
    62.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   62.10 - * Other names may be trademarks of their respective owners.
   62.11 - *
   62.12 - * The contents of this file are subject to the terms of either the GNU
   62.13 - * General Public License Version 2 only ("GPL") or the Common
   62.14 - * Development and Distribution License("CDDL") (collectively, the
   62.15 - * "License"). You may not use this file except in compliance with the
   62.16 - * License. You can obtain a copy of the License at
   62.17 - * http://www.netbeans.org/cddl-gplv2.html
   62.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   62.19 - * specific language governing permissions and limitations under the
   62.20 - * License.  When distributing the software, include this License Header
   62.21 - * Notice in each file and include the License file at
   62.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   62.23 - * particular file as subject to the "Classpath" exception as provided
   62.24 - * by Oracle in the GPL Version 2 section of the License file that
   62.25 - * accompanied this code. If applicable, add the following below the
   62.26 - * License Header, with the fields enclosed by brackets [] replaced by
   62.27 - * your own identifying information:
   62.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   62.29 - *
   62.30 - * If you wish your version of this file to be governed by only the CDDL
   62.31 - * or only the GPL Version 2, indicate your decision by adding
   62.32 - * "[Contributor] elects to include this software in this distribution
   62.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   62.34 - * single choice of license, a recipient has the option to distribute
   62.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   62.36 - * to extend the choice of license to its licensees as provided above.
   62.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   62.38 - * Version 2 license, then the option applies only if the new code is
   62.39 - * made subject to such option by the copyright holder.
   62.40 - *
   62.41 - * Contributor(s):
   62.42 - *
   62.43 - * Portions Copyrighted 2009 Sun Microsystems, Inc.
   62.44 - */
   62.45 -
   62.46 -package org.netbeans.modules.java.hints.providers.spi;
   62.47 -
   62.48 -import java.util.Collection;
   62.49 -import org.netbeans.api.java.source.CompilationInfo;
   62.50 -import org.netbeans.modules.java.hints.providers.spi.HintDescription;
   62.51 -
   62.52 -/**
   62.53 - * XXX: this is an ugly hack!
   62.54 - * @author lahvac
   62.55 - */
   62.56 -public interface ElementBasedHintProvider {
   62.57 -
   62.58 -    public Collection<? extends HintDescription> computeHints(CompilationInfo info);
   62.59 -
   62.60 -}
    63.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/HintDescription.java	Sun Oct 16 08:01:27 2016 +0200
    63.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    63.3 @@ -1,127 +0,0 @@
    63.4 -/*
    63.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    63.6 - *
    63.7 - * Copyright 2009-2010 Oracle and/or its affiliates. All rights reserved.
    63.8 - *
    63.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   63.10 - * Other names may be trademarks of their respective owners.
   63.11 - *
   63.12 - * The contents of this file are subject to the terms of either the GNU
   63.13 - * General Public License Version 2 only ("GPL") or the Common
   63.14 - * Development and Distribution License("CDDL") (collectively, the
   63.15 - * "License"). You may not use this file except in compliance with the
   63.16 - * License. You can obtain a copy of the License at
   63.17 - * http://www.netbeans.org/cddl-gplv2.html
   63.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   63.19 - * specific language governing permissions and limitations under the
   63.20 - * License.  When distributing the software, include this License Header
   63.21 - * Notice in each file and include the License file at
   63.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   63.23 - * particular file as subject to the "Classpath" exception as provided
   63.24 - * by Oracle in the GPL Version 2 section of the License file that
   63.25 - * accompanied this code. If applicable, add the following below the
   63.26 - * License Header, with the fields enclosed by brackets [] replaced by
   63.27 - * your own identifying information:
   63.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   63.29 - *
   63.30 - * If you wish your version of this file to be governed by only the CDDL
   63.31 - * or only the GPL Version 2, indicate your decision by adding
   63.32 - * "[Contributor] elects to include this software in this distribution
   63.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   63.34 - * single choice of license, a recipient has the option to distribute
   63.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   63.36 - * to extend the choice of license to its licensees as provided above.
   63.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   63.38 - * Version 2 license, then the option applies only if the new code is
   63.39 - * made subject to such option by the copyright holder.
   63.40 - *
   63.41 - * Contributor(s):
   63.42 - *
   63.43 - * Portions Copyrighted 2009-2010 Sun Microsystems, Inc.
   63.44 - */
   63.45 -
   63.46 -package org.netbeans.modules.java.hints.providers.spi;
   63.47 -
   63.48 -import java.util.Collection;
   63.49 -import java.util.Collections;
   63.50 -import java.util.HashSet;
   63.51 -import java.util.Set;
   63.52 -import org.netbeans.modules.java.hints.providers.spi.HintMetadata.Options;
   63.53 -import org.netbeans.spi.editor.hints.ErrorDescription;
   63.54 -import org.netbeans.spi.java.hints.HintContext;
   63.55 -
   63.56 -/**
   63.57 - *
   63.58 - * @author Jan Lahoda
   63.59 - */
   63.60 -public final class HintDescription {
   63.61 -
   63.62 -    private final HintMetadata metadata;
   63.63 -    private final Trigger trigger;
   63.64 -    private final Worker worker;
   63.65 -    private final AdditionalQueryConstraints additionalConstraints;
   63.66 -    private final String hintText;
   63.67 -    private final Set<Options> options;
   63.68 -
   63.69 -    private HintDescription(HintMetadata metadata, Trigger trigger, Worker worker, AdditionalQueryConstraints additionalConstraints, String hintText, Set<Options> options) {
   63.70 -        this.metadata = metadata;
   63.71 -        this.trigger = trigger;
   63.72 -        this.worker = worker;
   63.73 -        this.additionalConstraints = additionalConstraints;
   63.74 -        this.hintText = hintText;
   63.75 -        this.options = options;
   63.76 -    }
   63.77 -
   63.78 -    static HintDescription create(HintMetadata metadata, Trigger trigger, Worker worker, AdditionalQueryConstraints additionalConstraints, String hintText, Set<Options> options) {
   63.79 -        return new HintDescription(metadata, trigger, worker, additionalConstraints, hintText, options);
   63.80 -    }
   63.81 -
   63.82 -    @Override
   63.83 -    public String toString() {
   63.84 -        return "[HintDescription:" + trigger + "]";
   63.85 -    }
   63.86 -
   63.87 -    public AdditionalQueryConstraints getAdditionalConstraints() {
   63.88 -        return additionalConstraints;
   63.89 -    }
   63.90 -
   63.91 -    public String getHintText() {
   63.92 -        return hintText;
   63.93 -    }
   63.94 -
   63.95 -    public HintMetadata getMetadata() {
   63.96 -        return metadata;
   63.97 -    }
   63.98 -
   63.99 -    public Trigger getTrigger() {
  63.100 -        return trigger;
  63.101 -    }
  63.102 -
  63.103 -    public Worker getWorker() {
  63.104 -        return worker;
  63.105 -    }
  63.106 -
  63.107 -    public Set<Options> getOptions() {
  63.108 -        return options;
  63.109 -    }
  63.110 -
  63.111 -    public static interface Worker {
  63.112 -
  63.113 -        public Collection<? extends ErrorDescription> createErrors(HintContext ctx);
  63.114 -
  63.115 -    }
  63.116 -
  63.117 -    public static final class AdditionalQueryConstraints {
  63.118 -        public final Set<String> requiredErasedTypes;
  63.119 -
  63.120 -        public AdditionalQueryConstraints(Set<String> requiredErasedTypes) {
  63.121 -            this.requiredErasedTypes = Collections.unmodifiableSet(new HashSet<String>(requiredErasedTypes));
  63.122 -        }
  63.123 -
  63.124 -        private static final AdditionalQueryConstraints EMPTY = new AdditionalQueryConstraints(Collections.<String>emptySet());
  63.125 -        public static AdditionalQueryConstraints empty() {
  63.126 -            return EMPTY;
  63.127 -        }
  63.128 -    }
  63.129 -
  63.130 -}
    64.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/HintDescriptionFactory.java	Sun Oct 16 08:01:27 2016 +0200
    64.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    64.3 @@ -1,127 +0,0 @@
    64.4 -/*
    64.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    64.6 - *
    64.7 - * Copyright 2009-2010 Oracle and/or its affiliates. All rights reserved.
    64.8 - *
    64.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   64.10 - * Other names may be trademarks of their respective owners.
   64.11 - *
   64.12 - * The contents of this file are subject to the terms of either the GNU
   64.13 - * General Public License Version 2 only ("GPL") or the Common
   64.14 - * Development and Distribution License("CDDL") (collectively, the
   64.15 - * "License"). You may not use this file except in compliance with the
   64.16 - * License. You can obtain a copy of the License at
   64.17 - * http://www.netbeans.org/cddl-gplv2.html
   64.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   64.19 - * specific language governing permissions and limitations under the
   64.20 - * License.  When distributing the software, include this License Header
   64.21 - * Notice in each file and include the License file at
   64.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   64.23 - * particular file as subject to the "Classpath" exception as provided
   64.24 - * by Oracle in the GPL Version 2 section of the License file that
   64.25 - * accompanied this code. If applicable, add the following below the
   64.26 - * License Header, with the fields enclosed by brackets [] replaced by
   64.27 - * your own identifying information:
   64.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   64.29 - *
   64.30 - * If you wish your version of this file to be governed by only the CDDL
   64.31 - * or only the GPL Version 2, indicate your decision by adding
   64.32 - * "[Contributor] elects to include this software in this distribution
   64.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   64.34 - * single choice of license, a recipient has the option to distribute
   64.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   64.36 - * to extend the choice of license to its licensees as provided above.
   64.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   64.38 - * Version 2 license, then the option applies only if the new code is
   64.39 - * made subject to such option by the copyright holder.
   64.40 - *
   64.41 - * Contributor(s):
   64.42 - *
   64.43 - * Portions Copyrighted 2009-2010 Sun Microsystems, Inc.
   64.44 - */
   64.45 -
   64.46 -package org.netbeans.modules.java.hints.providers.spi;
   64.47 -
   64.48 -import java.util.Arrays;
   64.49 -import java.util.Collections;
   64.50 -import java.util.EnumSet;
   64.51 -import java.util.Set;
   64.52 -import org.netbeans.api.annotations.common.NonNull;
   64.53 -import org.netbeans.modules.java.hints.providers.spi.HintDescription.AdditionalQueryConstraints;
   64.54 -import org.netbeans.modules.java.hints.providers.spi.HintDescription.Worker;
   64.55 -import org.netbeans.modules.java.hints.providers.spi.HintMetadata.Options;
   64.56 -
   64.57 -/**
   64.58 - *
   64.59 - * @author lahvac
   64.60 - */
   64.61 -public class HintDescriptionFactory {
   64.62 -
   64.63 -    private       HintMetadata metadata;
   64.64 -    private       Trigger trigger;
   64.65 -    private       Worker worker;
   64.66 -    private       AdditionalQueryConstraints additionalConstraints;
   64.67 -    private       String hintText;
   64.68 -    private       Set<Options> options;
   64.69 -    private       boolean finished;
   64.70 -
   64.71 -    private HintDescriptionFactory() {
   64.72 -    }
   64.73 -
   64.74 -    public static HintDescriptionFactory create() {
   64.75 -        return new HintDescriptionFactory();
   64.76 -    }
   64.77 -
   64.78 -    /**TODO: move to create?
   64.79 -     *
   64.80 -     * @param metadata
   64.81 -     * @return
   64.82 -     */
   64.83 -    public HintDescriptionFactory setMetadata(HintMetadata metadata) {
   64.84 -        this.metadata = metadata;
   64.85 -        return this;
   64.86 -    }
   64.87 -
   64.88 -    public HintDescriptionFactory setTrigger(Trigger trigger) {
   64.89 -        if (this.trigger != null) {
   64.90 -            throw new IllegalStateException(this.trigger.toString());
   64.91 -        }
   64.92 -
   64.93 -        this.trigger = trigger;
   64.94 -        return this;
   64.95 -    }
   64.96 -
   64.97 -    public HintDescriptionFactory setWorker(Worker worker) {
   64.98 -        this.worker = worker;
   64.99 -        return this;
  64.100 -    }
  64.101 -
  64.102 -    public HintDescriptionFactory setAdditionalConstraints(AdditionalQueryConstraints additionalConstraints) {
  64.103 -        this.additionalConstraints = additionalConstraints;
  64.104 -        return this;
  64.105 -    }
  64.106 -
  64.107 -    public HintDescriptionFactory setHintText(@NonNull String hintText) {
  64.108 -        this.hintText = hintText;
  64.109 -        return this;
  64.110 -    }
  64.111 -
  64.112 -    public HintDescriptionFactory addOptions(Options... options) {
  64.113 -        if (this.options == null) {
  64.114 -            this.options = EnumSet.noneOf(Options.class);
  64.115 -        }
  64.116 -        this.options.addAll(Arrays.asList(options));
  64.117 -        return this;
  64.118 -    }
  64.119 -        
  64.120 -    public HintDescription produce() {
  64.121 -        if (metadata == null) {
  64.122 -            metadata = HintMetadata.Builder.create("no-id").addOptions(Options.NON_GUI).build();
  64.123 -        }
  64.124 -        if (this.additionalConstraints == null) {
  64.125 -            this.additionalConstraints = AdditionalQueryConstraints.empty();
  64.126 -        }
  64.127 -        return HintDescription.create(metadata, trigger, worker, additionalConstraints, hintText, options != null ? options : Collections.<Options>emptySet());
  64.128 -    }
  64.129 -    
  64.130 -}
    65.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/HintMetadata.java	Sun Oct 16 08:01:27 2016 +0200
    65.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    65.3 @@ -1,224 +0,0 @@
    65.4 -/*
    65.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    65.6 - *
    65.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
    65.8 - *
    65.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   65.10 - * Other names may be trademarks of their respective owners.
   65.11 - *
   65.12 - * The contents of this file are subject to the terms of either the GNU
   65.13 - * General Public License Version 2 only ("GPL") or the Common
   65.14 - * Development and Distribution License("CDDL") (collectively, the
   65.15 - * "License"). You may not use this file except in compliance with the
   65.16 - * License. You can obtain a copy of the License at
   65.17 - * http://www.netbeans.org/cddl-gplv2.html
   65.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   65.19 - * specific language governing permissions and limitations under the
   65.20 - * License.  When distributing the software, include this License Header
   65.21 - * Notice in each file and include the License file at
   65.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   65.23 - * particular file as subject to the "Classpath" exception as provided
   65.24 - * by Oracle in the GPL Version 2 section of the License file that
   65.25 - * accompanied this code. If applicable, add the following below the
   65.26 - * License Header, with the fields enclosed by brackets [] replaced by
   65.27 - * your own identifying information:
   65.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   65.29 - *
   65.30 - * If you wish your version of this file to be governed by only the CDDL
   65.31 - * or only the GPL Version 2, indicate your decision by adding
   65.32 - * "[Contributor] elects to include this software in this distribution
   65.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   65.34 - * single choice of license, a recipient has the option to distribute
   65.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   65.36 - * to extend the choice of license to its licensees as provided above.
   65.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   65.38 - * Version 2 license, then the option applies only if the new code is
   65.39 - * made subject to such option by the copyright holder.
   65.40 - *
   65.41 - * Contributor(s):
   65.42 - *
   65.43 - * Portions Copyrighted 2010 Sun Microsystems, Inc.
   65.44 - */
   65.45 -
   65.46 -package org.netbeans.modules.java.hints.providers.spi;
   65.47 -
   65.48 -import java.util.ArrayList;
   65.49 -import java.util.Arrays;
   65.50 -import java.util.Collection;
   65.51 -import java.util.EnumSet;
   65.52 -import java.util.HashSet;
   65.53 -import java.util.MissingResourceException;
   65.54 -import java.util.ResourceBundle;
   65.55 -import java.util.Set;
   65.56 -import java.util.logging.Level;
   65.57 -import java.util.logging.Logger;
   65.58 -import org.netbeans.spi.editor.hints.Severity;
   65.59 -import org.netbeans.spi.java.hints.CustomizerProvider;
   65.60 -import org.netbeans.spi.java.hints.Hint;
   65.61 -import org.openide.util.NbBundle;
   65.62 -
   65.63 -/**
   65.64 - *
   65.65 - * @author lahvac
   65.66 - */
   65.67 -public class HintMetadata {
   65.68 -
   65.69 -    public final String id;
   65.70 -    public final String displayName;
   65.71 -    public final String description;
   65.72 -    public final String category;
   65.73 -    public final boolean enabled;
   65.74 -    public final Hint.Kind kind;
   65.75 -    public final Severity severity;
   65.76 -    public final Collection<? extends String> suppressWarnings;
   65.77 -    public final CustomizerProvider customizer;
   65.78 -    public final boolean showInTaskList = false;
   65.79 -    public final Set<Options> options;
   65.80 -
   65.81 -    HintMetadata(String id, String displayName, String description, String category, boolean enabled, Hint.Kind kind, Severity severity, Collection<? extends String> suppressWarnings, CustomizerProvider customizer, Set<Options> options) {
   65.82 -        this.id = id;
   65.83 -        this.displayName = displayName;
   65.84 -        this.description = description;
   65.85 -        this.category = category;
   65.86 -        this.enabled = enabled;
   65.87 -        this.kind = kind;
   65.88 -        this.severity = severity;
   65.89 -        this.suppressWarnings = suppressWarnings;
   65.90 -        this.customizer = customizer;
   65.91 -        this.options = options;
   65.92 -    }
   65.93 -
   65.94 -    @Override
   65.95 -    public String toString() {
   65.96 -        return this.displayName;
   65.97 -    }
   65.98 -
   65.99 -    private static String lookup(ResourceBundle bundle, String key, String def) {
  65.100 -        try {
  65.101 -            return bundle != null ? bundle.getString(key) : def;
  65.102 -        } catch (MissingResourceException mre) {
  65.103 -            Logger.getLogger(HintMetadata.class.getName()).log(Level.FINE, null, mre);
  65.104 -            return def;
  65.105 -        }
  65.106 -    }
  65.107 -
  65.108 -    public static final class Builder {
  65.109 -        private final String id;
  65.110 -        private String displayName;
  65.111 -        private String description;
  65.112 -        private String category;
  65.113 -        private boolean enabled;
  65.114 -        private Hint.Kind kind;
  65.115 -        private Severity severity;
  65.116 -        private final Collection<String> suppressWarnings = new ArrayList<String>();
  65.117 -        private CustomizerProvider customizer;
  65.118 -        private final Set<Options> options = EnumSet.noneOf(Options.class);
  65.119 -
  65.120 -        private Builder(String id) {
  65.121 -            this.id = id;
  65.122 -            this.displayName = "";
  65.123 -            this.description = "";
  65.124 -            this.category = "";
  65.125 -            this.enabled = true;
  65.126 -            this.kind = Hint.Kind.INSPECTION;
  65.127 -            this.severity = Severity.VERIFIER;
  65.128 -        }
  65.129 -
  65.130 -        public static Builder create(String id) {
  65.131 -            return new Builder(id);
  65.132 -        }
  65.133 -
  65.134 -        public Builder setDescription(String displayName, String description) {
  65.135 -            this.displayName = displayName;
  65.136 -            this.description = description;
  65.137 -            return this;
  65.138 -        }
  65.139 -
  65.140 -        public Builder setBundle(ResourceBundle bundle) {
  65.141 -            return setBundle(bundle, null, null);
  65.142 -        }
  65.143 -
  65.144 -        public Builder setBundle(ResourceBundle bundle, String fallbackDisplayName, String fallbackDescription) {
  65.145 -            if (fallbackDisplayName == null) fallbackDisplayName = "No Display Name";
  65.146 -            if (fallbackDescription == null) fallbackDescription = "No Description";
  65.147 -            
  65.148 -            this.displayName = lookup(bundle, "DN_" + id.replace('$', '.'), fallbackDisplayName);
  65.149 -            this.description = lookup(bundle, "DESC_" + id.replace('$', '.'), fallbackDescription);
  65.150 -            return this;
  65.151 -        }
  65.152 -
  65.153 -        public Builder setBundle(String bundleForFQN) {
  65.154 -            ResourceBundle bundle;
  65.155 -
  65.156 -            try {
  65.157 -                int lastDot = bundleForFQN.lastIndexOf('.');
  65.158 -
  65.159 -                assert lastDot >= 0;
  65.160 -
  65.161 -                bundle = NbBundle.getBundle(bundleForFQN.substring(0, lastDot + 1) + "Bundle");
  65.162 -            } catch (MissingResourceException mre) {
  65.163 -                Logger.getLogger(HintMetadata.class.getName()).log(Level.FINE, null, mre);
  65.164 -                bundle = null;
  65.165 -            }
  65.166 -            return setBundle(bundle);
  65.167 -        }
  65.168 -
  65.169 -        public Builder setCategory(String category) {
  65.170 -            this.category = category;
  65.171 -            return this;
  65.172 -        }
  65.173 -
  65.174 -        public Builder setEnabled(boolean enabled) {
  65.175 -            this.enabled = enabled;
  65.176 -            return this;
  65.177 -        }
  65.178 -
  65.179 -        public Builder setKind(Hint.Kind kind) {
  65.180 -            this.kind = kind;
  65.181 -            return this;
  65.182 -        }
  65.183 -
  65.184 -        public Builder setSeverity(Severity severity) {
  65.185 -            this.severity = severity;
  65.186 -            return this;
  65.187 -        }
  65.188 -
  65.189 -
  65.190 -        public Builder addSuppressWarnings(String... keys) {
  65.191 -            this.suppressWarnings.addAll(Arrays.asList(keys));
  65.192 -            return this;
  65.193 -        }
  65.194 -
  65.195 -        public Builder setCustomizerProvider(CustomizerProvider customizer) {
  65.196 -            this.customizer = customizer;
  65.197 -            return this;
  65.198 -        }
  65.199 -
  65.200 -        public Builder addOptions(Options... options) {
  65.201 -            this.options.addAll(Arrays.asList(options));
  65.202 -            return this;
  65.203 -        }
  65.204 -
  65.205 -        public HintMetadata build() {
  65.206 -            return new HintMetadata(id, displayName, description, category, enabled, kind, severity, suppressWarnings, customizer, options);
  65.207 -        }
  65.208 -
  65.209 -    }
  65.210 -
  65.211 -    public enum Options {
  65.212 -        NON_GUI,
  65.213 -        QUERY,
  65.214 -        NO_BATCH,
  65.215 -        HEAVY;
  65.216 -
  65.217 -        public static Set<Options> fromHintOptions(Hint.Options... options) {
  65.218 -            Set<Options> result = new HashSet<Options>();
  65.219 -
  65.220 -            for (Hint.Options opt : options) {
  65.221 -                result.add(valueOf(opt.name()));
  65.222 -            }
  65.223 -
  65.224 -            return result;
  65.225 -        }
  65.226 -    }
  65.227 -}
    66.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/HintProvider.java	Sun Oct 16 08:01:27 2016 +0200
    66.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    66.3 @@ -1,54 +0,0 @@
    66.4 -/*
    66.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    66.6 - *
    66.7 - * Copyright 2009-2010 Oracle and/or its affiliates. All rights reserved.
    66.8 - *
    66.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   66.10 - * Other names may be trademarks of their respective owners.
   66.11 - *
   66.12 - * The contents of this file are subject to the terms of either the GNU
   66.13 - * General Public License Version 2 only ("GPL") or the Common
   66.14 - * Development and Distribution License("CDDL") (collectively, the
   66.15 - * "License"). You may not use this file except in compliance with the
   66.16 - * License. You can obtain a copy of the License at
   66.17 - * http://www.netbeans.org/cddl-gplv2.html
   66.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   66.19 - * specific language governing permissions and limitations under the
   66.20 - * License.  When distributing the software, include this License Header
   66.21 - * Notice in each file and include the License file at
   66.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   66.23 - * particular file as subject to the "Classpath" exception as provided
   66.24 - * by Oracle in the GPL Version 2 section of the License file that
   66.25 - * accompanied this code. If applicable, add the following below the
   66.26 - * License Header, with the fields enclosed by brackets [] replaced by
   66.27 - * your own identifying information:
   66.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   66.29 - *
   66.30 - * If you wish your version of this file to be governed by only the CDDL
   66.31 - * or only the GPL Version 2, indicate your decision by adding
   66.32 - * "[Contributor] elects to include this software in this distribution
   66.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   66.34 - * single choice of license, a recipient has the option to distribute
   66.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   66.36 - * to extend the choice of license to its licensees as provided above.
   66.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   66.38 - * Version 2 license, then the option applies only if the new code is
   66.39 - * made subject to such option by the copyright holder.
   66.40 - *
   66.41 - * Contributor(s):
   66.42 - *
   66.43 - * Portions Copyrighted 2009-2010 Sun Microsystems, Inc.
   66.44 - */
   66.45 -
   66.46 -package org.netbeans.modules.java.hints.providers.spi;
   66.47 -
   66.48 -import java.util.Collection;
   66.49 -import java.util.Map;
   66.50 -import org.netbeans.modules.java.hints.providers.spi.HintDescription;
   66.51 -import org.netbeans.modules.java.hints.providers.spi.HintMetadata;
   66.52 -
   66.53 -public interface HintProvider {
   66.54 -
   66.55 -    public Map<HintMetadata, ? extends Collection<? extends HintDescription>> computeHints();
   66.56 -
   66.57 -}
    67.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/PositionRefresherHelper.java	Sun Oct 16 08:01:27 2016 +0200
    67.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    67.3 @@ -1,105 +0,0 @@
    67.4 -/*
    67.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    67.6 - *
    67.7 - * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
    67.8 - *
    67.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   67.10 - * Other names may be trademarks of their respective owners.
   67.11 - *
   67.12 - * The contents of this file are subject to the terms of either the GNU
   67.13 - * General Public License Version 2 only ("GPL") or the Common
   67.14 - * Development and Distribution License("CDDL") (collectively, the
   67.15 - * "License"). You may not use this file except in compliance with the
   67.16 - * License. You can obtain a copy of the License at
   67.17 - * http://www.netbeans.org/cddl-gplv2.html
   67.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   67.19 - * specific language governing permissions and limitations under the
   67.20 - * License.  When distributing the software, include this License Header
   67.21 - * Notice in each file and include the License file at
   67.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   67.23 - * particular file as subject to the "Classpath" exception as provided
   67.24 - * by Oracle in the GPL Version 2 section of the License file that
   67.25 - * accompanied this code. If applicable, add the following below the
   67.26 - * License Header, with the fields enclosed by brackets [] replaced by
   67.27 - * your own identifying information:
   67.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   67.29 - *
   67.30 - * If you wish your version of this file to be governed by only the CDDL
   67.31 - * or only the GPL Version 2, indicate your decision by adding
   67.32 - * "[Contributor] elects to include this software in this distribution
   67.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   67.34 - * single choice of license, a recipient has the option to distribute
   67.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   67.36 - * to extend the choice of license to its licensees as provided above.
   67.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   67.38 - * Version 2 license, then the option applies only if the new code is
   67.39 - * made subject to such option by the copyright holder.
   67.40 - *
   67.41 - * Contributor(s):
   67.42 - *
   67.43 - * Portions Copyrighted 2012 Sun Microsystems, Inc.
   67.44 - */
   67.45 -package org.netbeans.modules.java.hints.providers.spi;
   67.46 -
   67.47 -import java.util.List;
   67.48 -import javax.swing.text.Document;
   67.49 -import org.netbeans.api.annotations.common.CheckForNull;
   67.50 -import org.netbeans.api.java.source.CompilationInfo;
   67.51 -import org.netbeans.lib.editor.util.swing.DocumentUtilities;
   67.52 -import org.netbeans.spi.editor.hints.Context;
   67.53 -import org.netbeans.spi.editor.hints.ErrorDescription;
   67.54 -import org.netbeans.modules.java.hints.providers.spi.PositionRefresherHelper.DocumentVersion;
   67.55 -
   67.56 -/**TODO: should be public?
   67.57 - *
   67.58 - * @author lahvac
   67.59 - */
   67.60 -public abstract class PositionRefresherHelper<V extends DocumentVersion> {
   67.61 -
   67.62 -    private final Object documentKey = new Object();
   67.63 -    private final String key;
   67.64 -
   67.65 -    protected PositionRefresherHelper(String key) {
   67.66 -        this.key = key;
   67.67 -    }
   67.68 -
   67.69 -    protected abstract boolean isUpToDate(Context context, Document doc, V oldVersion);
   67.70 -    /**XXX: should be protected*/public abstract @CheckForNull List<ErrorDescription> getErrorDescriptionsAt(CompilationInfo info, Context context, Document doc) throws Exception;
   67.71 -
   67.72 -    protected final void setVersion(Document doc, V version) {
   67.73 -        if (doc != null) {
   67.74 -            doc.putProperty(documentKey, version);
   67.75 -        }
   67.76 -    }
   67.77 -
   67.78 -    protected @CheckForNull V getUpToDateDocumentVersion(Context context, Document doc) {
   67.79 -        V oldVersion = (V) doc.getProperty(documentKey);
   67.80 -
   67.81 -        if (oldVersion == null) return null;
   67.82 -
   67.83 -        if (((DocumentVersion) oldVersion).version != DocumentUtilities.getDocumentVersion(doc)) return null;
   67.84 -        
   67.85 -        return oldVersion;
   67.86 -    }
   67.87 -    
   67.88 -    /**XXX*/ public boolean upToDateCheck(Context context, Document doc) {
   67.89 -        V oldVersion = getUpToDateDocumentVersion(context, doc);
   67.90 -
   67.91 -        if (oldVersion == null) return false;
   67.92 -
   67.93 -        return isUpToDate(context, doc, oldVersion);
   67.94 -    }
   67.95 -
   67.96 -    /**XXX*/ public String getKey() {
   67.97 -        return key;
   67.98 -    }
   67.99 -
  67.100 -    public static class DocumentVersion {
  67.101 -        private final long version;
  67.102 -
  67.103 -        public DocumentVersion(Document doc) {
  67.104 -            this.version = doc != null ? DocumentUtilities.getDocumentVersion(doc) : 0;
  67.105 -        }
  67.106 -
  67.107 -    }
  67.108 -}
    68.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/Trigger.java	Sun Oct 16 08:01:27 2016 +0200
    68.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    68.3 @@ -1,171 +0,0 @@
    68.4 -/*
    68.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    68.6 - *
    68.7 - * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
    68.8 - *
    68.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   68.10 - * Other names may be trademarks of their respective owners.
   68.11 - *
   68.12 - * The contents of this file are subject to the terms of either the GNU
   68.13 - * General Public License Version 2 only ("GPL") or the Common
   68.14 - * Development and Distribution License("CDDL") (collectively, the
   68.15 - * "License"). You may not use this file except in compliance with the
   68.16 - * License. You can obtain a copy of the License at
   68.17 - * http://www.netbeans.org/cddl-gplv2.html
   68.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   68.19 - * specific language governing permissions and limitations under the
   68.20 - * License.  When distributing the software, include this License Header
   68.21 - * Notice in each file and include the License file at
   68.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   68.23 - * particular file as subject to the "Classpath" exception as provided
   68.24 - * by Oracle in the GPL Version 2 section of the License file that
   68.25 - * accompanied this code. If applicable, add the following below the
   68.26 - * License Header, with the fields enclosed by brackets [] replaced by
   68.27 - * your own identifying information:
   68.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   68.29 - *
   68.30 - * If you wish your version of this file to be governed by only the CDDL
   68.31 - * or only the GPL Version 2, indicate your decision by adding
   68.32 - * "[Contributor] elects to include this software in this distribution
   68.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   68.34 - * single choice of license, a recipient has the option to distribute
   68.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   68.36 - * to extend the choice of license to its licensees as provided above.
   68.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   68.38 - * Version 2 license, then the option applies only if the new code is
   68.39 - * made subject to such option by the copyright holder.
   68.40 - *
   68.41 - * Contributor(s):
   68.42 - *
   68.43 - * Portions Copyrighted 2011 Sun Microsystems, Inc.
   68.44 - */
   68.45 -package org.netbeans.modules.java.hints.providers.spi;
   68.46 -
   68.47 -import com.sun.source.tree.Tree.Kind;
   68.48 -import java.util.Arrays;
   68.49 -import java.util.Map;
   68.50 -import java.util.Set;
   68.51 -import org.netbeans.api.java.source.matching.Pattern;
   68.52 -import org.netbeans.spi.java.hints.Decision;
   68.53 -import org.openide.util.Parameters;
   68.54 -
   68.55 -/**A base class for triggers.
   68.56 - *
   68.57 - * @author lahvac
   68.58 - */
   68.59 -public abstract class Trigger {
   68.60 -
   68.61 -    Trigger() {}
   68.62 -
   68.63 -    /**Invoke the given hint's worker on the specified {@link Tree.Kind}(s).
   68.64 -     *
   68.65 -     */
   68.66 -    public static final class Kinds extends Trigger {
   68.67 -        private final Set<Kind> kinds;
   68.68 -
   68.69 -        /**Create the trigger for the specified set of {@link Tree.Kind}s.
   68.70 -         *
   68.71 -         * @param kinds on which the hint's worker should be invoked.
   68.72 -         */
   68.73 -        public Kinds(Set<Kind> kinds) {
   68.74 -            this.kinds = kinds;
   68.75 -        }
   68.76 -
   68.77 -        public Iterable<? extends Kind> getKinds() {
   68.78 -            return kinds;
   68.79 -        }
   68.80 -
   68.81 -        @Override
   68.82 -        public String toString() {
   68.83 -            return kinds.toString();
   68.84 -        }
   68.85 -    }
   68.86 -
   68.87 -    /**Invoke the hint's worker on tree nodes that match the given pattern.
   68.88 -     *
   68.89 -     */
   68.90 -    public static final class PatternDescription extends Trigger {
   68.91 -
   68.92 -        private final String pattern;
   68.93 -        private final Map<String, String> constraints;
   68.94 -        private final Iterable<? extends String> imports;
   68.95 -
   68.96 -        private PatternDescription(String pattern, Map<String, String> constraints, String... imports) {
   68.97 -            this.pattern = pattern;
   68.98 -            this.constraints = constraints;
   68.99 -            this.imports = Arrays.asList(imports);
  68.100 -        }
  68.101 -
  68.102 -        /** Create the trigger to invoke the hint's worker on tree nodes that match the given pattern.
  68.103 -         *
  68.104 -         * @param pattern which will be interpreted as a pattern with free variables ({@link Pattern#createPatternWithFreeVariables(com.sun.source.util.TreePath, java.util.Map) }.
  68.105 -         * @param constraints are expected to be mapping from a free variable name to the expected type.
  68.106 -         * @param XXX: document the imports
  68.107 -         * @return the created trigger.
  68.108 -         */
  68.109 -        public static PatternDescription create(String pattern, Map<String, String> constraints, String... imports) {
  68.110 -            Parameters.notNull("pattern", pattern);
  68.111 -            Parameters.notNull("constraints", constraints);
  68.112 -            Parameters.notNull("imports", imports);
  68.113 -
  68.114 -            return new PatternDescription(pattern, constraints, imports);
  68.115 -        }
  68.116 -
  68.117 -        @Override
  68.118 -        public boolean equals(Object obj) {
  68.119 -            if (obj == null) {
  68.120 -                return false;
  68.121 -            }
  68.122 -            if (getClass() != obj.getClass()) {
  68.123 -                return false;
  68.124 -            }
  68.125 -            final PatternDescription other = (PatternDescription) obj;
  68.126 -            if ((this.pattern == null) ? (other.pattern != null) : !this.pattern.equals(other.pattern)) {
  68.127 -                return false;
  68.128 -            }
  68.129 -            if (this.constraints != other.constraints && (this.constraints == null || !this.constraints.equals(other.constraints))) {
  68.130 -                return false;
  68.131 -            }
  68.132 -            return true;
  68.133 -        }
  68.134 -
  68.135 -        @Override
  68.136 -        public int hashCode() {
  68.137 -            int hash = 7;
  68.138 -            hash = 71 * hash + (this.pattern != null ? this.pattern.hashCode() : 0);
  68.139 -            hash = 71 * hash + (this.constraints != null ? this.constraints.hashCode() : 0);
  68.140 -            return hash;
  68.141 -        }
  68.142 -
  68.143 -        public String getPattern() {
  68.144 -            return pattern;
  68.145 -        }
  68.146 -
  68.147 -        public Map<String, String> getConstraints() {
  68.148 -            return constraints;
  68.149 -        }
  68.150 -
  68.151 -        public Iterable<? extends String> getImports() {
  68.152 -            return imports;
  68.153 -        }
  68.154 -
  68.155 -        @Override
  68.156 -        public String toString() {
  68.157 -            return pattern;
  68.158 -        }
  68.159 -
  68.160 -    }
  68.161 -    
  68.162 -    public static final class DecisionTrigger extends Trigger {
  68.163 -        private final Class<? extends Decision> decisionClass;
  68.164 -
  68.165 -        public DecisionTrigger(Class<? extends Decision> decisionClass) {
  68.166 -            this.decisionClass = decisionClass;
  68.167 -        }
  68.168 -
  68.169 -        public Class<? extends Decision> getDecisionClass() {
  68.170 -            return decisionClass;
  68.171 -        }
  68.172 -    }
  68.173 -
  68.174 -}
    69.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/Bundle.properties	Sun Oct 16 08:01:27 2016 +0200
    69.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    69.3 @@ -1,4 +0,0 @@
    69.4 -OpenIDE-Module-Name=Java Hints SPI
    69.5 -
    69.6 -#refresh hints
    69.7 -Refresh_hints=Refresh Hints
    70.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/Hacks.java	Sun Oct 16 08:01:27 2016 +0200
    70.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    70.3 @@ -1,219 +0,0 @@
    70.4 -/*
    70.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    70.6 - *
    70.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
    70.8 - *
    70.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   70.10 - * Other names may be trademarks of their respective owners.
   70.11 - *
   70.12 - * The contents of this file are subject to the terms of either the GNU
   70.13 - * General Public License Version 2 only ("GPL") or the Common
   70.14 - * Development and Distribution License("CDDL") (collectively, the
   70.15 - * "License"). You may not use this file except in compliance with the
   70.16 - * License. You can obtain a copy of the License at
   70.17 - * http://www.netbeans.org/cddl-gplv2.html
   70.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   70.19 - * specific language governing permissions and limitations under the
   70.20 - * License.  When distributing the software, include this License Header
   70.21 - * Notice in each file and include the License file at
   70.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   70.23 - * particular file as subject to the "Classpath" exception as provided
   70.24 - * by Oracle in the GPL Version 2 section of the License file that
   70.25 - * accompanied this code. If applicable, add the following below the
   70.26 - * License Header, with the fields enclosed by brackets [] replaced by
   70.27 - * your own identifying information:
   70.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   70.29 - *
   70.30 - * If you wish your version of this file to be governed by only the CDDL
   70.31 - * or only the GPL Version 2, indicate your decision by adding
   70.32 - * "[Contributor] elects to include this software in this distribution
   70.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   70.34 - * single choice of license, a recipient has the option to distribute
   70.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   70.36 - * to extend the choice of license to its licensees as provided above.
   70.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   70.38 - * Version 2 license, then the option applies only if the new code is
   70.39 - * made subject to such option by the copyright holder.
   70.40 - *
   70.41 - * Contributor(s):
   70.42 - *
   70.43 - * Portions Copyrighted 2009 Sun Microsystems, Inc.
   70.44 - */
   70.45 -
   70.46 -package org.netbeans.modules.java.hints.spiimpl;
   70.47 -
   70.48 -import com.sun.source.tree.BlockTree;
   70.49 -import com.sun.source.tree.CompilationUnitTree;
   70.50 -import com.sun.source.tree.MethodTree;
   70.51 -import com.sun.source.tree.Scope;
   70.52 -import com.sun.source.tree.Tree;
   70.53 -import com.sun.source.util.TreePath;
   70.54 -import com.sun.source.util.TreePathScanner;
   70.55 -import com.sun.tools.javac.api.JavacTaskImpl;
   70.56 -import com.sun.tools.javac.code.Symbol.ClassSymbol;
   70.57 -import com.sun.tools.javac.comp.AttrContext;
   70.58 -import com.sun.tools.javac.comp.Enter;
   70.59 -import com.sun.tools.javac.comp.Env;
   70.60 -import com.sun.tools.javac.main.JavaCompiler;
   70.61 -import com.sun.tools.javac.tree.JCTree;
   70.62 -import com.sun.tools.javac.tree.JCTree.JCErroneous;
   70.63 -import com.sun.tools.javac.util.Context;
   70.64 -import com.sun.tools.javac.util.Log;
   70.65 -import java.io.File;
   70.66 -import java.io.IOException;
   70.67 -import javax.lang.model.element.Element;
   70.68 -import javax.lang.model.element.TypeElement;
   70.69 -import javax.lang.model.element.VariableElement;
   70.70 -import javax.lang.model.type.TypeMirror;
   70.71 -import javax.tools.JavaFileObject;
   70.72 -import org.netbeans.api.annotations.common.CheckForNull;
   70.73 -import org.netbeans.api.annotations.common.NonNull;
   70.74 -import org.netbeans.api.java.source.CompilationInfo;
   70.75 -import org.netbeans.api.java.source.TreeUtilities;
   70.76 -import org.netbeans.modules.java.hints.providers.spi.HintMetadata;
   70.77 -import org.netbeans.modules.java.source.JavaSourceAccessor;
   70.78 -import org.netbeans.modules.java.source.parsing.FileObjects;
   70.79 -import org.openide.util.Exceptions;
   70.80 -
   70.81 -/**
   70.82 - *
   70.83 - * @author lahvac
   70.84 - */
   70.85 -public class Hacks {
   70.86 -
   70.87 -    //XXX: copied from Utilities, for declarative hints, different import management:
   70.88 -    private static long inc;
   70.89 -
   70.90 -    public static Scope constructScope(CompilationInfo info, String... importedClasses) {
   70.91 -        StringBuilder clazz = new StringBuilder();
   70.92 -
   70.93 -        clazz.append("package $$;\n");
   70.94 -
   70.95 -        for (String i : importedClasses) {
   70.96 -            clazz.append("import ").append(i).append(";\n");
   70.97 -        }
   70.98 -
   70.99 -        clazz.append("public class $").append(inc++).append("{");
  70.100 -
  70.101 -        clazz.append("private void test() {\n");
  70.102 -        clazz.append("}\n");
  70.103 -        clazz.append("}\n");
  70.104 -
  70.105 -        JavacTaskImpl jti = JavaSourceAccessor.getINSTANCE().getJavacTask(info);
  70.106 -        Context context = jti.getContext();
  70.107 -
  70.108 -        JavaCompiler jc = JavaCompiler.instance(context);
  70.109 -        Log.instance(context).nerrors = 0;
  70.110 -
  70.111 -        JavaFileObject jfo = FileObjects.memoryFileObject("$$", "$", new File("/tmp/t.java").toURI(), System.currentTimeMillis(), clazz.toString());
  70.112 -        boolean oldSkipAPs = jc.skipAnnotationProcessing;
  70.113 -
  70.114 -        try {
  70.115 -            jc.skipAnnotationProcessing = true;
  70.116 -
  70.117 -            Iterable<? extends CompilationUnitTree> parsed = jti.parse(jfo);
  70.118 -            CompilationUnitTree cut = parsed.iterator().next();
  70.119 -
  70.120 -            jti.analyze(jti.enter(parsed));
  70.121 -
  70.122 -            return new ScannerImpl().scan(cut, info);
  70.123 -        } catch (IOException ex) {
  70.124 -            Exceptions.printStackTrace(ex);
  70.125 -            return null;
  70.126 -        } finally {
  70.127 -            jc.skipAnnotationProcessing = oldSkipAPs;
  70.128 -        }
  70.129 -    }
  70.130 -
  70.131 -    private static final class ScannerImpl extends TreePathScanner<Scope, CompilationInfo> {
  70.132 -
  70.133 -        @Override
  70.134 -        public Scope visitBlock(BlockTree node, CompilationInfo p) {
  70.135 -            return p.getTrees().getScope(getCurrentPath());
  70.136 -        }
  70.137 -
  70.138 -        @Override
  70.139 -        public Scope visitMethod(MethodTree node, CompilationInfo p) {
  70.140 -            if (node.getReturnType() == null) {
  70.141 -                return null;
  70.142 -            }
  70.143 -            return super.visitMethod(node, p);
  70.144 -        }
  70.145 -
  70.146 -        @Override
  70.147 -        public Scope reduce(Scope r1, Scope r2) {
  70.148 -            return r1 != null ? r1 : r2;
  70.149 -        }
  70.150 -
  70.151 -    }
  70.152 -
  70.153 -
  70.154 -    public static Tree createRenameTree(@NonNull Tree originalTree, @NonNull String newName) {
  70.155 -        return new RenameTree(originalTree, newName);
  70.156 -    }
  70.157 -
  70.158 -    public static final class RenameTree extends JCErroneous {
  70.159 -
  70.160 -        public final Tree originalTree;
  70.161 -        public final String newName;
  70.162 -
  70.163 -        public RenameTree(@NonNull Tree originalTree, @NonNull String newName) {
  70.164 -            super(com.sun.tools.javac.util.List.<JCTree>nil());
  70.165 -            this.originalTree = originalTree;
  70.166 -            this.newName = newName;
  70.167 -        }
  70.168 -
  70.169 -    }
  70.170 -
  70.171 -    public static @CheckForNull TypeMirror parseFQNType(@NonNull CompilationInfo info, @NonNull String spec) {
  70.172 -        if (spec.length() == 0) {
  70.173 -            return null;
  70.174 -        }
  70.175 -        
  70.176 -        TypeElement jlObject = info.getElements().getTypeElement("java.lang.Object");
  70.177 -        
  70.178 -        //XXX:
  70.179 -        TypeElement scope;
  70.180 -
  70.181 -        if (info.getTopLevelElements().isEmpty()) {
  70.182 -            scope = jlObject;
  70.183 -        } else {
  70.184 -            scope = info.getTopLevelElements().iterator().next();
  70.185 -        }
  70.186 -        //XXX end
  70.187 -        
  70.188 -        return info.getTreeUtilities().parseType(spec, /*XXX: jlObject*/scope);
  70.189 -    }
  70.190 -
  70.191 -    public static VariableElement attributeThis(CompilationInfo info, TreePath tp) {
  70.192 -        //XXX:
  70.193 -        while (tp != null) {
  70.194 -            if (TreeUtilities.CLASS_TREE_KINDS.contains(tp.getLeaf().getKind())) {
  70.195 -                Element currentElement = info.getTrees().getElement(tp);
  70.196 -
  70.197 -                if (currentElement == null || !(currentElement instanceof ClassSymbol)) return null;
  70.198 -
  70.199 -                Enter enter = Enter.instance(JavaSourceAccessor.getINSTANCE().getJavacTask(info).getContext());
  70.200 -                Env<AttrContext> env = enter.getEnv((ClassSymbol) currentElement);
  70.201 -
  70.202 -                if (env == null) return null;
  70.203 -
  70.204 -                for (Element el : env.info.getLocalElements()) {
  70.205 -                    if (el.getSimpleName().contentEquals("this")) {
  70.206 -                        return (VariableElement) el;
  70.207 -                    }
  70.208 -                }
  70.209 -
  70.210 -                return null;
  70.211 -            }
  70.212 -
  70.213 -            tp = tp.getParentPath();
  70.214 -        }
  70.215 -
  70.216 -        return null;
  70.217 -    }
  70.218 -    
  70.219 -    public static interface InspectAndTransformOpener {
  70.220 -        public void openIAT(HintMetadata hm);
  70.221 -    }
  70.222 -}
    71.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/JackpotTrees.java	Sun Oct 16 08:01:27 2016 +0200
    71.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    71.3 @@ -1,246 +0,0 @@
    71.4 -/*
    71.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    71.6 - *
    71.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
    71.8 - *
    71.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   71.10 - * Other names may be trademarks of their respective owners.
   71.11 - *
   71.12 - * The contents of this file are subject to the terms of either the GNU
   71.13 - * General Public License Version 2 only ("GPL") or the Common
   71.14 - * Development and Distribution License("CDDL") (collectively, the
   71.15 - * "License"). You may not use this file except in compliance with the
   71.16 - * License. You can obtain a copy of the License at
   71.17 - * http://www.netbeans.org/cddl-gplv2.html
   71.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   71.19 - * specific language governing permissions and limitations under the
   71.20 - * License.  When distributing the software, include this License Header
   71.21 - * Notice in each file and include the License file at
   71.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   71.23 - * particular file as subject to the "Classpath" exception as provided
   71.24 - * by Oracle in the GPL Version 2 section of the License file that
   71.25 - * accompanied this code. If applicable, add the following below the
   71.26 - * License Header, with the fields enclosed by brackets [] replaced by
   71.27 - * your own identifying information:
   71.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   71.29 - *
   71.30 - * If you wish your version of this file to be governed by only the CDDL
   71.31 - * or only the GPL Version 2, indicate your decision by adding
   71.32 - * "[Contributor] elects to include this software in this distribution
   71.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   71.34 - * single choice of license, a recipient has the option to distribute
   71.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   71.36 - * to extend the choice of license to its licensees as provided above.
   71.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   71.38 - * Version 2 license, then the option applies only if the new code is
   71.39 - * made subject to such option by the copyright holder.
   71.40 - *
   71.41 - * Contributor(s):
   71.42 - *
   71.43 - * Portions Copyrighted 2010 Sun Microsystems, Inc.
   71.44 - */
   71.45 -
   71.46 -package org.netbeans.modules.java.hints.spiimpl;
   71.47 -
   71.48 -import com.sun.source.tree.IdentifierTree;
   71.49 -import com.sun.source.tree.TreeVisitor;
   71.50 -import com.sun.tools.javac.code.Symbol.VarSymbol;
   71.51 -import com.sun.tools.javac.code.Symtab;
   71.52 -import com.sun.tools.javac.tree.JCTree;
   71.53 -import com.sun.tools.javac.tree.JCTree.JCAnnotation;
   71.54 -import com.sun.tools.javac.tree.JCTree.JCBlock;
   71.55 -import com.sun.tools.javac.tree.JCTree.JCCase;
   71.56 -import com.sun.tools.javac.tree.JCTree.JCCatch;
   71.57 -import com.sun.tools.javac.tree.JCTree.JCModifiers;
   71.58 -import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
   71.59 -import com.sun.tools.javac.tree.TreeMaker;
   71.60 -import com.sun.tools.javac.util.Context;
   71.61 -import com.sun.tools.javac.util.List;
   71.62 -import com.sun.tools.javac.util.Name;
   71.63 -
   71.64 -
   71.65 -/**
   71.66 - *
   71.67 - * @author lahvac
   71.68 - */
   71.69 -public class JackpotTrees {
   71.70 -    public static class AnnotationWildcard extends JCAnnotation implements IdentifierTree {
   71.71 -
   71.72 -        private final Name ident;
   71.73 -        private final JCIdent jcIdent;
   71.74 -
   71.75 -        public AnnotationWildcard(Name ident, JCIdent jcIdent) {
   71.76 -            super(Tag.ANNOTATION, jcIdent, List.<JCExpression>nil());
   71.77 -            this.ident = ident;
   71.78 -            this.jcIdent = jcIdent;
   71.79 -        }
   71.80 -
   71.81 -        public Name getName() {
   71.82 -            return ident;
   71.83 -        }
   71.84 -
   71.85 -        @Override
   71.86 -        public Kind getKind() {
   71.87 -            return Kind.IDENTIFIER;
   71.88 -        }
   71.89 -
   71.90 -        @Override
   71.91 -        public void accept(Visitor v) {
   71.92 -            v.visitIdent(jcIdent);
   71.93 -        }
   71.94 -
   71.95 -        @Override
   71.96 -        public <R, D> R accept(TreeVisitor<R, D> v, D d) {
   71.97 -            return v.visitIdentifier(this, d);
   71.98 -        }
   71.99 -
  71.100 -        @Override
  71.101 -        public String toString() {
  71.102 -            return ident.toString();
  71.103 -        }
  71.104 -
  71.105 -    }
  71.106 -    
  71.107 -    public static class CatchWildcard extends JCCatch implements IdentifierTree {
  71.108 -
  71.109 -        private final Name ident;
  71.110 -        private final JCIdent jcIdent;
  71.111 -
  71.112 -        public CatchWildcard(Context ctx, Name ident, JCIdent jcIdent) {
  71.113 -            super(new FakeVariable(ctx, ident, jcIdent), TreeMaker.instance(ctx).Block(0, List.<JCStatement>nil()));
  71.114 -            this.ident = ident;
  71.115 -            this.jcIdent = jcIdent;
  71.116 -        }
  71.117 -
  71.118 -        public Name getName() {
  71.119 -            return ident;
  71.120 -        }
  71.121 -
  71.122 -        @Override
  71.123 -        public Kind getKind() {
  71.124 -            return Kind.IDENTIFIER;
  71.125 -        }
  71.126 -
  71.127 -        @Override
  71.128 -        public void accept(Visitor v) {
  71.129 -            v.visitIdent(jcIdent);
  71.130 -        }
  71.131 -
  71.132 -        @Override
  71.133 -        public <R, D> R accept(TreeVisitor<R, D> v, D d) {
  71.134 -            return v.visitIdentifier(this, d);
  71.135 -        }
  71.136 -
  71.137 -        @Override
  71.138 -        public String toString() {
  71.139 -            return "catch " + ident.toString();
  71.140 -        }
  71.141 -
  71.142 -    }
  71.143 -    
  71.144 -    public static class VariableWildcard extends FakeVariable implements IdentifierTree {
  71.145 -
  71.146 -        private final Name ident;
  71.147 -
  71.148 -        public VariableWildcard(Context ctx, Name ident, JCIdent jcIdent) {
  71.149 -            super(ctx, ident, jcIdent);
  71.150 -            this.ident = ident;
  71.151 -        }
  71.152 -
  71.153 -        public Name getName() {
  71.154 -            return ident;
  71.155 -        }
  71.156 -
  71.157 -        @Override
  71.158 -        public Kind getKind() {
  71.159 -            return Kind.IDENTIFIER;
  71.160 -        }
  71.161 -
  71.162 -        @Override
  71.163 -        public <R, D> R accept(TreeVisitor<R, D> v, D d) {
  71.164 -            return v.visitIdentifier(this, d);
  71.165 -        }
  71.166 -
  71.167 -        @Override
  71.168 -        public String toString() {
  71.169 -            return ident.toString();
  71.170 -        }
  71.171 -    }
  71.172 -
  71.173 -    private static class FakeVariable extends JCVariableDecl {
  71.174 -        
  71.175 -        private final JCIdent jcIdent;
  71.176 -
  71.177 -        public FakeVariable(Context ctx, Name ident, JCIdent jcIdent) {
  71.178 -            super(new FakeModifiers(), ident, createType(ctx), null, null);
  71.179 -            this.sym = new VarSymbol(0, name, type, Symtab.instance(ctx).errSymbol);
  71.180 -            this.type = vartype.type;
  71.181 -            this.jcIdent = jcIdent;
  71.182 -        }
  71.183 -
  71.184 -        private static JCErroneous createType(Context ctx) {
  71.185 -            JCErroneous err = new JCErroneous(List.<JCTree>nil()) {};
  71.186 -
  71.187 -            err.type = Symtab.instance(ctx).errType;
  71.188 -
  71.189 -            return err;
  71.190 -        }
  71.191 -
  71.192 -        @Override
  71.193 -        public void accept(Visitor v) {
  71.194 -            v.visitIdent(jcIdent);
  71.195 -        }
  71.196 -
  71.197 -    }
  71.198 -
  71.199 -    private static class FakeModifiers extends JCModifiers {
  71.200 -        public FakeModifiers() {
  71.201 -            super(0, List.<JCAnnotation>nil());
  71.202 -        }
  71.203 -    }
  71.204 -
  71.205 -    public static class CaseWildcard extends JCCase implements IdentifierTree {
  71.206 -
  71.207 -        private final Name ident;
  71.208 -        private final JCIdent jcIdent;
  71.209 -
  71.210 -        public CaseWildcard(Context ctx, Name ident, JCIdent jcIdent) {
  71.211 -            super(jcIdent, List.<JCStatement>nil());
  71.212 -            this.ident = ident;
  71.213 -            this.jcIdent = jcIdent;
  71.214 -        }
  71.215 -
  71.216 -        public Name getName() {
  71.217 -            return ident;
  71.218 -        }
  71.219 -
  71.220 -        @Override
  71.221 -        public Kind getKind() {
  71.222 -            return Kind.IDENTIFIER;
  71.223 -        }
  71.224 -
  71.225 -        @Override
  71.226 -        public void accept(Visitor v) {
  71.227 -            v.visitIdent(jcIdent);
  71.228 -        }
  71.229 -
  71.230 -        @Override
  71.231 -        public <R, D> R accept(TreeVisitor<R, D> v, D d) {
  71.232 -            return v.visitIdentifier(this, d);
  71.233 -        }
  71.234 -
  71.235 -        @Override
  71.236 -        public String toString() {
  71.237 -            return "case " + ident.toString();
  71.238 -        }
  71.239 -
  71.240 -    }
  71.241 -    
  71.242 -    public static class FakeBlock extends JCBlock {
  71.243 -
  71.244 -        public FakeBlock(long flags, List<JCStatement> stats) {
  71.245 -            super(flags, stats);
  71.246 -        }
  71.247 -        
  71.248 -    }
  71.249 -}
    72.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/JavaFixImpl.java	Sun Oct 16 08:01:27 2016 +0200
    72.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    72.3 @@ -1,146 +0,0 @@
    72.4 -/*
    72.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    72.6 - *
    72.7 - * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
    72.8 - *
    72.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   72.10 - * Other names may be trademarks of their respective owners.
   72.11 - *
   72.12 - * The contents of this file are subject to the terms of either the GNU
   72.13 - * General Public License Version 2 only ("GPL") or the Common
   72.14 - * Development and Distribution License("CDDL") (collectively, the
   72.15 - * "License"). You may not use this file except in compliance with the
   72.16 - * License. You can obtain a copy of the License at
   72.17 - * http://www.netbeans.org/cddl-gplv2.html
   72.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   72.19 - * specific language governing permissions and limitations under the
   72.20 - * License.  When distributing the software, include this License Header
   72.21 - * Notice in each file and include the License file at
   72.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   72.23 - * particular file as subject to the "Classpath" exception as provided
   72.24 - * by Oracle in the GPL Version 2 section of the License file that
   72.25 - * accompanied this code. If applicable, add the following below the
   72.26 - * License Header, with the fields enclosed by brackets [] replaced by
   72.27 - * your own identifying information:
   72.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   72.29 - *
   72.30 - * If you wish your version of this file to be governed by only the CDDL
   72.31 - * or only the GPL Version 2, indicate your decision by adding
   72.32 - * "[Contributor] elects to include this software in this distribution
   72.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   72.34 - * single choice of license, a recipient has the option to distribute
   72.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   72.36 - * to extend the choice of license to its licensees as provided above.
   72.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   72.38 - * Version 2 license, then the option applies only if the new code is
   72.39 - * made subject to such option by the copyright holder.
   72.40 - *
   72.41 - * Contributor(s):
   72.42 - *
   72.43 - * Portions Copyrighted 2008-2009 Sun Microsystems, Inc.
   72.44 - */
   72.45 -
   72.46 -package org.netbeans.modules.java.hints.spiimpl;
   72.47 -
   72.48 -import com.sun.source.util.TreePath;
   72.49 -import java.util.ArrayList;
   72.50 -import java.util.Collection;
   72.51 -import java.util.Collections;
   72.52 -import java.util.HashMap;
   72.53 -import java.util.IdentityHashMap;
   72.54 -import java.util.List;
   72.55 -import java.util.Map;
   72.56 -import java.util.Set;
   72.57 -import javax.lang.model.type.TypeMirror;
   72.58 -import org.netbeans.api.java.source.CompilationInfo;
   72.59 -import org.netbeans.api.java.source.JavaSource;
   72.60 -import org.netbeans.api.java.source.JavaSource.Phase;
   72.61 -import org.netbeans.api.java.source.ModificationResult.Difference;
   72.62 -import org.netbeans.api.java.source.Task;
   72.63 -import org.netbeans.api.java.source.WorkingCopy;
   72.64 -import org.netbeans.api.project.Project;
   72.65 -import org.netbeans.modules.java.hints.spiimpl.batch.BatchUtilities;
   72.66 -import org.netbeans.modules.java.source.JavaSourceAccessor;
   72.67 -import org.netbeans.modules.refactoring.spi.RefactoringElementImplementation;
   72.68 -import org.netbeans.spi.editor.hints.ChangeInfo;
   72.69 -import org.netbeans.spi.editor.hints.Fix;
   72.70 -import org.netbeans.spi.java.hints.HintContext;
   72.71 -import org.netbeans.spi.java.hints.JavaFix;
   72.72 -import org.openide.filesystems.FileObject;
   72.73 -import org.openide.util.Exceptions;
   72.74 -
   72.75 -/**TODO: move to better package
   72.76 - *
   72.77 - * @author Jan Lahoda
   72.78 - */
   72.79 -public final class JavaFixImpl implements Fix {
   72.80 -
   72.81 -    public final JavaFix jf;
   72.82 -
   72.83 -    public JavaFixImpl(JavaFix jf) {
   72.84 -        this.jf = jf;
   72.85 -    }
   72.86 -
   72.87 -    public String getText() {
   72.88 -        return Accessor.INSTANCE.getText(jf);
   72.89 -    }
   72.90 -
   72.91 -    public ChangeInfo implement() throws Exception {
   72.92 -        FileObject file = Accessor.INSTANCE.getFile(jf);
   72.93 -        
   72.94 -        BatchUtilities.fixDependencies(file, Collections.singletonList(jf), new IdentityHashMap<Project, Set<String>>());
   72.95 -
   72.96 -        JavaSource js = JavaSource.forFileObject(file);
   72.97 -
   72.98 -        js.runModificationTask(new Task<WorkingCopy>() {
   72.99 -            public void run(WorkingCopy wc) throws Exception {
  72.100 -                if (wc.toPhase(Phase.RESOLVED).compareTo(Phase.RESOLVED) < 0) {
  72.101 -                    return;
  72.102 -                }
  72.103 -
  72.104 -                Map<FileObject, byte[]> resourceContentChanges = new HashMap<FileObject, byte[]>();
  72.105 -                Accessor.INSTANCE.process(jf, wc, true, resourceContentChanges, /*Ignored in editor:*/new ArrayList<RefactoringElementImplementation>());
  72.106 -                Map<FileObject, List<Difference>> resourceContentDiffs = new HashMap<FileObject, List<Difference>>();
  72.107 -                BatchUtilities.addResourceContentChanges(resourceContentChanges, resourceContentDiffs);
  72.108 -                JavaSourceAccessor.getINSTANCE().createModificationResult(resourceContentDiffs, Collections.<Object, int[]>emptyMap()).commit();
  72.109 -            }
  72.110 -        }).commit();
  72.111 -
  72.112 -        return null;
  72.113 -    }
  72.114 -
  72.115 -    @Override
  72.116 -    public boolean equals(Object obj) {
  72.117 -        if (obj instanceof JavaFixImpl) {
  72.118 -            return jf.equals(((JavaFixImpl)obj).jf);
  72.119 -        }
  72.120 -        return super.equals(obj);
  72.121 -    }
  72.122 -
  72.123 -    @Override
  72.124 -    public int hashCode() {
  72.125 -        return jf.hashCode();
  72.126 -    }
  72.127 -
  72.128 -    public static abstract class Accessor {
  72.129 -
  72.130 -        static {
  72.131 -            try {
  72.132 -                Class.forName(JavaFix.class.getCanonicalName(), true, JavaFix.class.getClassLoader());
  72.133 -            } catch (ClassNotFoundException ex) {
  72.134 -                Exceptions.printStackTrace(ex);
  72.135 -            }
  72.136 -        }
  72.137 -        
  72.138 -        public static Accessor INSTANCE;
  72.139 -
  72.140 -        public abstract String getText(JavaFix jf);
  72.141 -        public abstract ChangeInfo process(JavaFix jf, WorkingCopy wc, boolean canShowUI, Map<FileObject, byte[]> resourceContent, Collection<? super RefactoringElementImplementation> fileChanges) throws Exception;
  72.142 -        public abstract FileObject getFile(JavaFix jf);
  72.143 -        public abstract Map<String, String> getOptions(JavaFix jf);
  72.144 -        public abstract Fix rewriteFix(CompilationInfo info, String displayName, TreePath what, final String to, Map<String, TreePath> parameters, Map<String, Collection<? extends TreePath>> parametersMulti, final Map<String, String> parameterNames, Map<String, TypeMirror> constraints, Map<String, String> options, String... imports);
  72.145 -        public abstract Fix createSuppressWarningsFix(CompilationInfo compilationInfo, TreePath treePath, String... keys);
  72.146 -        public abstract List<Fix> createSuppressWarnings(CompilationInfo compilationInfo, TreePath treePath, String... keys);
  72.147 -        public abstract List<Fix> resolveDefaultFixes(HintContext ctx, Fix... provided);
  72.148 -    }
  72.149 -}
    73.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/JavaHintsPositionRefresher.java	Sun Oct 16 08:01:27 2016 +0200
    73.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    73.3 @@ -1,161 +0,0 @@
    73.4 -/*
    73.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    73.6 - *
    73.7 - * Copyright 2009-2010 Oracle and/or its affiliates. All rights reserved.
    73.8 - *
    73.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   73.10 - * Other names may be trademarks of their respective owners.
   73.11 - *
   73.12 - * The contents of this file are subject to the terms of either the GNU
   73.13 - * General Public License Version 2 only ("GPL") or the Common
   73.14 - * Development and Distribution License("CDDL") (collectively, the
   73.15 - * "License"). You may not use this file except in compliance with the
   73.16 - * License. You can obtain a copy of the License at
   73.17 - * http://www.netbeans.org/cddl-gplv2.html
   73.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   73.19 - * specific language governing permissions and limitations under the
   73.20 - * License.  When distributing the software, include this License Header
   73.21 - * Notice in each file and include the License file at
   73.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   73.23 - * particular file as subject to the "Classpath" exception as provided
   73.24 - * by Oracle in the GPL Version 2 section of the License file that
   73.25 - * accompanied this code. If applicable, add the following below the
   73.26 - * License Header, with the fields enclosed by brackets [] replaced by
   73.27 - * your own identifying information:
   73.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   73.29 - *
   73.30 - * If you wish your version of this file to be governed by only the CDDL
   73.31 - * or only the GPL Version 2, indicate your decision by adding
   73.32 - * "[Contributor] elects to include this software in this distribution
   73.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   73.34 - * single choice of license, a recipient has the option to distribute
   73.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   73.36 - * to extend the choice of license to its licensees as provided above.
   73.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   73.38 - * Version 2 license, then the option applies only if the new code is
   73.39 - * made subject to such option by the copyright holder.
   73.40 - *
   73.41 - * Contributor(s):
   73.42 - *
   73.43 - * Portions Copyrighted 2009-2010 Sun Microsystems, Inc.
   73.44 - */
   73.45 -
   73.46 -package org.netbeans.modules.java.hints.spiimpl;
   73.47 -
   73.48 -import java.io.IOException;
   73.49 -import java.util.ArrayList;
   73.50 -import java.util.Collections;
   73.51 -import java.util.HashMap;
   73.52 -import java.util.Iterator;
   73.53 -import java.util.List;
   73.54 -import java.util.Map;
   73.55 -import java.util.logging.Level;
   73.56 -import java.util.logging.Logger;
   73.57 -import javax.swing.text.Document;
   73.58 -import org.netbeans.api.editor.mimelookup.MimeLookup;
   73.59 -import org.netbeans.api.editor.mimelookup.MimeRegistration;
   73.60 -import org.netbeans.api.java.source.CompilationController;
   73.61 -import org.netbeans.api.java.source.JavaSource;
   73.62 -import org.netbeans.api.java.source.JavaSource.Phase;
   73.63 -import org.netbeans.api.java.source.Task;
   73.64 -import org.netbeans.api.progress.ProgressUtils;
   73.65 -import org.netbeans.spi.editor.hints.Context;
   73.66 -import org.netbeans.spi.editor.hints.ErrorDescription;
   73.67 -import org.netbeans.spi.editor.hints.PositionRefresher;
   73.68 -import org.netbeans.modules.java.hints.providers.spi.PositionRefresherHelper;
   73.69 -import org.openide.util.Exceptions;
   73.70 -import org.openide.util.NbBundle;
   73.71 -
   73.72 -/**
   73.73 - * Refreshes all Java Hints on current line upon Alt-Enter or mouseclick
   73.74 - * @author Max Sauer
   73.75 - */
   73.76 -@MimeRegistration(mimeType="text/x-java", service=PositionRefresher.class)
   73.77 -public class JavaHintsPositionRefresher implements PositionRefresher {
   73.78 -
   73.79 -    private static final Logger LOG = Logger.getLogger(JavaHintsPositionRefresher.class.getName());
   73.80 -
   73.81 -    @Override
   73.82 -    public Map<String, List<ErrorDescription>> getErrorDescriptionsAt(final Context context, final Document doc) {
   73.83 -        final List<PositionRefresherHelper> refreshers = new ArrayList<PositionRefresherHelper>(MimeLookup.getLookup("text/x-java").lookupAll(PositionRefresherHelper.class));
   73.84 -
   73.85 -        for (Iterator<PositionRefresherHelper> it = refreshers.iterator(); it.hasNext();) {
   73.86 -            PositionRefresherHelper h = it.next();
   73.87 -
   73.88 -            if (h.upToDateCheck(context, doc)) {
   73.89 -                LOG.log(Level.FINE, "Not computing warnings for {0}, results are up-to-date.", h.getKey());
   73.90 -                it.remove();
   73.91 -            } else {
   73.92 -                LOG.log(Level.FINE, "Will compute warnings for {0}, results not up-to-date.", h.getKey());
   73.93 -            }
   73.94 -        }
   73.95 -
   73.96 -        if (refreshers.isEmpty()) return Collections.emptyMap();
   73.97 -        
   73.98 -        final JavaSource js = JavaSource.forDocument(doc);
   73.99 -
  73.100 -        if (js == null) {
  73.101 -            LOG.log(Level.FINE, "No JavaSource associated to: {0}", new Object[] {doc, doc.getProperty(Document.StreamDescriptionProperty)});
  73.102 -            return Collections.emptyMap();
  73.103 -        }
  73.104 -
  73.105 -        final Map<String, List<ErrorDescription>> eds = new HashMap<String, List<ErrorDescription>>();
  73.106 -
  73.107 -        Runnable r = new Runnable() {
  73.108 -
  73.109 -            public void run() {
  73.110 -                try {
  73.111 -                    js.runUserActionTask(new RefreshTask(eds, refreshers, context, doc), true);
  73.112 -                } catch (IOException ex) {
  73.113 -                    Exceptions.printStackTrace(ex);
  73.114 -                }
  73.115 -            }
  73.116 -        };
  73.117 -        
  73.118 -        ProgressUtils.runOffEventDispatchThread(r, NbBundle.getMessage(JavaHintsPositionRefresher.class, "Refresh_hints"), context.getCancel(), false); // NOI18N
  73.119 -
  73.120 -        return eds;
  73.121 -    }
  73.122 -
  73.123 -
  73.124 -    private class RefreshTask implements Task<CompilationController> {
  73.125 -
  73.126 -        private final Map<String, List<ErrorDescription>> eds;
  73.127 -        private final List<PositionRefresherHelper> refreshers;
  73.128 -        private final Context ctx;
  73.129 -        private final Document doc;
  73.130 -
  73.131 -        public RefreshTask(Map<String, List<ErrorDescription>> eds, List<PositionRefresherHelper> refreshers, Context ctx, Document doc) {
  73.132 -            this.eds = eds;
  73.133 -            this.refreshers = refreshers;
  73.134 -            this.ctx = ctx;
  73.135 -            this.doc = doc;
  73.136 -        }
  73.137 -
  73.138 -        public void run(CompilationController controller) throws Exception {
  73.139 -            if (controller.toPhase(JavaSource.Phase.RESOLVED).compareTo(Phase.RESOLVED) < 0) {
  73.140 -                return ;
  73.141 -            }
  73.142 -
  73.143 -            Document doc = controller.getDocument();
  73.144 -
  73.145 -            if (doc == null) {
  73.146 -                return;
  73.147 -            }
  73.148 -
  73.149 -            for (PositionRefresherHelper h : refreshers) {
  73.150 -                if (ctx.isCanceled()) {
  73.151 -                    return;
  73.152 -                }
  73.153 -                
  73.154 -                List errors = h.getErrorDescriptionsAt(controller, ctx, doc);
  73.155 -                
  73.156 -                if (errors == null) continue;
  73.157 -                
  73.158 -                eds.put(h.getKey(), errors);
  73.159 -            }
  73.160 -        }
  73.161 -        
  73.162 -    }
  73.163 -
  73.164 -}
    74.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/MessageImpl.java	Sun Oct 16 08:01:27 2016 +0200
    74.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    74.3 @@ -1,61 +0,0 @@
    74.4 -/*
    74.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    74.6 - *
    74.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
    74.8 - *
    74.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   74.10 - * Other names may be trademarks of their respective owners.
   74.11 - *
   74.12 - * The contents of this file are subject to the terms of either the GNU
   74.13 - * General Public License Version 2 only ("GPL") or the Common
   74.14 - * Development and Distribution License("CDDL") (collectively, the
   74.15 - * "License"). You may not use this file except in compliance with the
   74.16 - * License. You can obtain a copy of the License at
   74.17 - * http://www.netbeans.org/cddl-gplv2.html
   74.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   74.19 - * specific language governing permissions and limitations under the
   74.20 - * License.  When distributing the software, include this License Header
   74.21 - * Notice in each file and include the License file at
   74.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   74.23 - * particular file as subject to the "Classpath" exception as provided
   74.24 - * by Oracle in the GPL Version 2 section of the License file that
   74.25 - * accompanied this code. If applicable, add the following below the
   74.26 - * License Header, with the fields enclosed by brackets [] replaced by
   74.27 - * your own identifying information:
   74.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   74.29 - *
   74.30 - * If you wish your version of this file to be governed by only the CDDL
   74.31 - * or only the GPL Version 2, indicate your decision by adding
   74.32 - * "[Contributor] elects to include this software in this distribution
   74.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   74.34 - * single choice of license, a recipient has the option to distribute
   74.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   74.36 - * to extend the choice of license to its licensees as provided above.
   74.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   74.38 - * Version 2 license, then the option applies only if the new code is
   74.39 - * made subject to such option by the copyright holder.
   74.40 - *
   74.41 - * Contributor(s):
   74.42 - *
   74.43 - * Portions Copyrighted 2009 Sun Microsystems, Inc.
   74.44 - */
   74.45 -
   74.46 -package org.netbeans.modules.java.hints.spiimpl;
   74.47 -
   74.48 -import org.netbeans.spi.java.hints.HintContext.MessageKind;
   74.49 -
   74.50 -/**
   74.51 - *
   74.52 - * @author lahvacc
   74.53 - */
   74.54 -public class MessageImpl {
   74.55 -
   74.56 -    public final MessageKind kind;
   74.57 -    public final String text;
   74.58 -
   74.59 -    public MessageImpl(MessageKind kind, String text) {
   74.60 -        this.kind = kind;
   74.61 -        this.text = text;
   74.62 -    }
   74.63 -
   74.64 -}
    75.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/RulesManager.java	Sun Oct 16 08:01:27 2016 +0200
    75.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    75.3 @@ -1,68 +0,0 @@
    75.4 -/*
    75.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    75.6 - *
    75.7 - * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
    75.8 - *
    75.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   75.10 - * Other names may be trademarks of their respective owners.
   75.11 - *
   75.12 - * The contents of this file are subject to the terms of either the GNU
   75.13 - * General Public License Version 2 only ("GPL") or the Common
   75.14 - * Development and Distribution License("CDDL") (collectively, the
   75.15 - * "License"). You may not use this file except in compliance with the
   75.16 - * License. You can obtain a copy of the License at
   75.17 - * http://www.netbeans.org/cddl-gplv2.html
   75.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   75.19 - * specific language governing permissions and limitations under the
   75.20 - * License.  When distributing the software, include this License Header
   75.21 - * Notice in each file and include the License file at
   75.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   75.23 - * particular file as subject to the "Classpath" exception as provided
   75.24 - * by Oracle in the GPL Version 2 section of the License file that
   75.25 - * accompanied this code. If applicable, add the following below the
   75.26 - * License Header, with the fields enclosed by brackets [] replaced by
   75.27 - * your own identifying information:
   75.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   75.29 - *
   75.30 - * If you wish your version of this file to be governed by only the CDDL
   75.31 - * or only the GPL Version 2, indicate your decision by adding
   75.32 - * "[Contributor] elects to include this software in this distribution
   75.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   75.34 - * single choice of license, a recipient has the option to distribute
   75.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   75.36 - * to extend the choice of license to its licensees as provided above.
   75.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   75.38 - * Version 2 license, then the option applies only if the new code is
   75.39 - * made subject to such option by the copyright holder.
   75.40 - *
   75.41 - * Contributor(s):
   75.42 - *
   75.43 - * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
   75.44 - */
   75.45 -
   75.46 -package org.netbeans.modules.java.hints.spiimpl;
   75.47 -
   75.48 -import java.util.Collection;
   75.49 -import java.util.Map;
   75.50 -import java.util.concurrent.atomic.AtomicBoolean;
   75.51 -import org.netbeans.api.annotations.common.NullAllowed;
   75.52 -import org.netbeans.api.java.classpath.ClassPath;
   75.53 -import org.netbeans.api.java.source.CompilationInfo;
   75.54 -import org.netbeans.modules.java.hints.providers.spi.HintDescription;
   75.55 -import org.netbeans.modules.java.hints.providers.spi.HintMetadata;
   75.56 -import org.openide.util.Lookup;
   75.57 -
   75.58 -/**
   75.59 - *
   75.60 - * @author lahvac
   75.61 - */
   75.62 -public abstract class RulesManager {
   75.63 -
   75.64 -    public static RulesManager getInstance() {
   75.65 -        return Lookup.getDefault().lookup(RulesManager.class);
   75.66 -    }
   75.67 -
   75.68 -    public abstract Map<HintMetadata, ? extends Collection<? extends HintDescription>> readHints(@NullAllowed CompilationInfo info, @NullAllowed Collection<? extends ClassPath> from, @NullAllowed AtomicBoolean cancel);
   75.69 -    public abstract void reload(); //XXX
   75.70 -    
   75.71 -}
    76.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/RulesManagerImpl.java	Sun Oct 16 08:01:27 2016 +0200
    76.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    76.3 @@ -1,140 +0,0 @@
    76.4 -/*
    76.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    76.6 - *
    76.7 - * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
    76.8 - *
    76.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   76.10 - * Other names may be trademarks of their respective owners.
   76.11 - *
   76.12 - * The contents of this file are subject to the terms of either the GNU
   76.13 - * General Public License Version 2 only ("GPL") or the Common
   76.14 - * Development and Distribution License("CDDL") (collectively, the
   76.15 - * "License"). You may not use this file except in compliance with the
   76.16 - * License. You can obtain a copy of the License at
   76.17 - * http://www.netbeans.org/cddl-gplv2.html
   76.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   76.19 - * specific language governing permissions and limitations under the
   76.20 - * License.  When distributing the software, include this License Header
   76.21 - * Notice in each file and include the License file at
   76.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   76.23 - * particular file as subject to the "Classpath" exception as provided
   76.24 - * by Oracle in the GPL Version 2 section of the License file that
   76.25 - * accompanied this code. If applicable, add the following below the
   76.26 - * License Header, with the fields enclosed by brackets [] replaced by
   76.27 - * your own identifying information:
   76.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   76.29 - *
   76.30 - * If you wish your version of this file to be governed by only the CDDL
   76.31 - * or only the GPL Version 2, indicate your decision by adding
   76.32 - * "[Contributor] elects to include this software in this distribution
   76.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   76.34 - * single choice of license, a recipient has the option to distribute
   76.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   76.36 - * to extend the choice of license to its licensees as provided above.
   76.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   76.38 - * Version 2 license, then the option applies only if the new code is
   76.39 - * made subject to such option by the copyright holder.
   76.40 - *
   76.41 - * Contributor(s):
   76.42 - *
   76.43 - * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
   76.44 - */
   76.45 -
   76.46 -package org.netbeans.modules.java.hints.spiimpl;
   76.47 -
   76.48 -import java.util.ArrayList;
   76.49 -import java.util.Collection;
   76.50 -import java.util.Collections;
   76.51 -import java.util.HashMap;
   76.52 -import java.util.LinkedList;
   76.53 -import java.util.Map;
   76.54 -import java.util.Map.Entry;
   76.55 -import java.util.concurrent.atomic.AtomicBoolean;
   76.56 -import org.netbeans.api.java.classpath.ClassPath;
   76.57 -import org.netbeans.api.java.source.ClasspathInfo;
   76.58 -import org.netbeans.api.java.source.ClasspathInfo.PathKind;
   76.59 -import org.netbeans.api.java.source.CompilationInfo;
   76.60 -import org.netbeans.modules.java.hints.providers.spi.HintDescription;
   76.61 -import org.netbeans.modules.java.hints.providers.spi.HintMetadata;
   76.62 -import org.netbeans.modules.java.hints.providers.spi.ClassPathBasedHintProvider;
   76.63 -import org.netbeans.modules.java.hints.providers.spi.ElementBasedHintProvider;
   76.64 -import org.netbeans.modules.java.hints.providers.spi.HintProvider;
   76.65 -import org.netbeans.spi.java.classpath.support.ClassPathSupport;
   76.66 -import org.openide.util.Lookup;
   76.67 -import org.openide.util.lookup.ServiceProvider;
   76.68 -
   76.69 -/**
   76.70 - *
   76.71 - * @author lahvac
   76.72 - */
   76.73 -@ServiceProvider(service=RulesManager.class)
   76.74 -public class RulesManagerImpl extends RulesManager {
   76.75 -
   76.76 -    private final Map<HintMetadata, Collection<HintDescription>> globalHints = new HashMap<HintMetadata, Collection<HintDescription>>();
   76.77 -
   76.78 -    public RulesManagerImpl() {
   76.79 -        reload();
   76.80 -    }
   76.81 -    
   76.82 -    @Override
   76.83 -    public void reload() {
   76.84 -        globalHints.clear();
   76.85 -
   76.86 -        for (HintProvider p : Lookup.getDefault().lookupAll(HintProvider.class)) {
   76.87 -            Map<HintMetadata, ? extends Collection<? extends HintDescription>> pHints = p.computeHints();
   76.88 -
   76.89 -            if (pHints != null) {
   76.90 -                for (Entry<HintMetadata, ? extends Collection<? extends HintDescription>> e : pHints.entrySet()) {
   76.91 -                    globalHints.put(e.getKey(), new ArrayList<HintDescription>(e.getValue()));
   76.92 -                }
   76.93 -            }
   76.94 -        }
   76.95 -    }
   76.96 -
   76.97 -    @Override
   76.98 -    public Map<HintMetadata, ? extends Collection<? extends HintDescription>> readHints(CompilationInfo info, Collection<? extends ClassPath> from, AtomicBoolean cancel) {
   76.99 -        Map<HintMetadata, Collection<HintDescription>> result = new HashMap<HintMetadata, Collection<HintDescription>>(globalHints);
  76.100 -
  76.101 -        if (info != null) {
  76.102 -            for (ElementBasedHintProvider provider : Lookup.getDefault().lookupAll(ElementBasedHintProvider.class)) {
  76.103 -                sortByMetadata(provider.computeHints(info), result);
  76.104 -            }
  76.105 -        }
  76.106 -
  76.107 -        if (from == null) {
  76.108 -            if (info != null) {
  76.109 -                ClasspathInfo cpInfo = info.getClasspathInfo();
  76.110 -                LinkedList<ClassPath> cps = new LinkedList<ClassPath>();
  76.111 -
  76.112 -                cps.add(cpInfo.getClassPath(PathKind.BOOT));
  76.113 -                cps.add(cpInfo.getClassPath(PathKind.COMPILE));
  76.114 -                cps.add(cpInfo.getClassPath(PathKind.SOURCE));
  76.115 -
  76.116 -                from = cps;
  76.117 -            } else {
  76.118 -                from = Collections.emptyList();
  76.119 -            }
  76.120 -        }
  76.121 -
  76.122 -        ClassPath compound = ClassPathSupport.createProxyClassPath(from.toArray(new ClassPath[0]));
  76.123 -
  76.124 -        for (ClassPathBasedHintProvider p : Lookup.getDefault().lookupAll(ClassPathBasedHintProvider.class)) {
  76.125 -            sortByMetadata(p.computeHints(compound), result);
  76.126 -        }
  76.127 -
  76.128 -        return result;
  76.129 -    }
  76.130 -
  76.131 -    public static void sortByMetadata(Collection<? extends HintDescription> listedHints, Map<HintMetadata, Collection<HintDescription>> into) {
  76.132 -        for (HintDescription hd : listedHints) {
  76.133 -            Collection<HintDescription> h = into.get(hd.getMetadata());
  76.134 -
  76.135 -            if (h == null) {
  76.136 -                into.put(hd.getMetadata(), h = new ArrayList<HintDescription>());
  76.137 -            }
  76.138 -
  76.139 -            h.add(hd);
  76.140 -        }
  76.141 -    }
  76.142 -
  76.143 -}
    77.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/SPIAccessor.java	Sun Oct 16 08:01:27 2016 +0200
    77.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    77.3 @@ -1,86 +0,0 @@
    77.4 -/*
    77.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    77.6 - *
    77.7 - * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
    77.8 - *
    77.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   77.10 - * Other names may be trademarks of their respective owners.
   77.11 - *
   77.12 - * The contents of this file are subject to the terms of either the GNU
   77.13 - * General Public License Version 2 only ("GPL") or the Common
   77.14 - * Development and Distribution License("CDDL") (collectively, the
   77.15 - * "License"). You may not use this file except in compliance with the
   77.16 - * License. You can obtain a copy of the License at
   77.17 - * http://www.netbeans.org/cddl-gplv2.html
   77.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   77.19 - * specific language governing permissions and limitations under the
   77.20 - * License.  When distributing the software, include this License Header
   77.21 - * Notice in each file and include the License file at
   77.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   77.23 - * particular file as subject to the "Classpath" exception as provided
   77.24 - * by Oracle in the GPL Version 2 section of the License file that
   77.25 - * accompanied this code. If applicable, add the following below the
   77.26 - * License Header, with the fields enclosed by brackets [] replaced by
   77.27 - * your own identifying information:
   77.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   77.29 - *
   77.30 - * If you wish your version of this file to be governed by only the CDDL
   77.31 - * or only the GPL Version 2, indicate your decision by adding
   77.32 - * "[Contributor] elects to include this software in this distribution
   77.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   77.34 - * single choice of license, a recipient has the option to distribute
   77.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   77.36 - * to extend the choice of license to its licensees as provided above.
   77.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   77.38 - * Version 2 license, then the option applies only if the new code is
   77.39 - * made subject to such option by the copyright holder.
   77.40 - *
   77.41 - * Contributor(s):
   77.42 - *
   77.43 - * Portions Copyrighted 2012 Sun Microsystems, Inc.
   77.44 - */
   77.45 -package org.netbeans.modules.java.hints.spiimpl;
   77.46 -
   77.47 -import com.sun.source.util.TreePath;
   77.48 -import java.util.Collection;
   77.49 -import java.util.Map;
   77.50 -import java.util.concurrent.atomic.AtomicBoolean;
   77.51 -import javax.lang.model.type.TypeMirror;
   77.52 -import org.netbeans.api.java.source.CompilationInfo;
   77.53 -import org.netbeans.modules.java.hints.providers.spi.HintMetadata;
   77.54 -import org.netbeans.modules.java.hints.spiimpl.hints.GlobalProcessingContext;
   77.55 -import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings;
   77.56 -import org.netbeans.spi.java.hints.HintContext;
   77.57 -import org.openide.util.Exceptions;
   77.58 -
   77.59 -/**
   77.60 - *
   77.61 - * @author lahvac
   77.62 - */
   77.63 -public abstract class SPIAccessor {
   77.64 -
   77.65 -    private static volatile SPIAccessor accessor;
   77.66 -
   77.67 -    public static synchronized SPIAccessor getINSTANCE() {
   77.68 -        if (accessor == null) {
   77.69 -            try {
   77.70 -                Class.forName(HintContext.class.getName(), true, HintContext.class.getClassLoader());
   77.71 -                assert accessor != null;
   77.72 -            } catch (ClassNotFoundException e) {
   77.73 -                Exceptions.printStackTrace(e);
   77.74 -            }
   77.75 -        }
   77.76 -        return accessor;
   77.77 -    }
   77.78 -
   77.79 -    public static void setINSTANCE(SPIAccessor instance) {
   77.80 -        assert instance != null;
   77.81 -        accessor = instance;
   77.82 -    }
   77.83 -
   77.84 -    public abstract HintContext createHintContext(CompilationInfo info, HintsSettings settings, HintMetadata metadata, GlobalProcessingContext globalContext, TreePath path, Map<String, TreePath> variables, Map<String, Collection<? extends TreePath>> multiVariables, Map<String, String> variableNames, Map<String, TypeMirror> constraints, Collection<? super MessageImpl> problems, boolean bulkMode, AtomicBoolean cancel, int caret);
   77.85 -    public abstract HintContext createHintContext(CompilationInfo info, HintsSettings settings, HintMetadata metadata, GlobalProcessingContext globalContext, TreePath path, Map<String, TreePath> variables, Map<String, Collection<? extends TreePath>> multiVariables, Map<String, String> variableNames);
   77.86 -    public abstract HintMetadata getHintMetadata(HintContext ctx);
   77.87 -    public abstract HintsSettings getHintSettings(HintContext ctx);
   77.88 -
   77.89 -}
    78.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/SyntheticFix.java	Sun Oct 16 08:01:27 2016 +0200
    78.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    78.3 @@ -1,46 +0,0 @@
    78.4 -/*
    78.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    78.6 - *
    78.7 - * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
    78.8 - *
    78.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   78.10 - * Other names may be trademarks of their respective owners.
   78.11 - *
   78.12 - * The contents of this file are subject to the terms of either the GNU
   78.13 - * General Public License Version 2 only ("GPL") or the Common Development and
   78.14 - * Distribution License("CDDL") (collectively, the "License"). You may not use
   78.15 - * this file except in compliance with the License. You can obtain a copy of
   78.16 - * the License at http://www.netbeans.org/cddl-gplv2.html or
   78.17 - * nbbuild/licenses/CDDL-GPL-2-CP. See the License for the specific language
   78.18 - * governing permissions and limitations under the License. When distributing
   78.19 - * the software, include this License Header Notice in each file and include
   78.20 - * the License file at nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
   78.21 - * particular file as subject to the "Classpath" exception as provided by
   78.22 - * Oracle in the GPL Version 2 section of the License file that accompanied
   78.23 - * this code. If applicable, add the following below the License Header, with
   78.24 - * the fields enclosed by brackets [] replaced by your own identifying
   78.25 - * information: "Portions Copyrighted [year] [name of copyright owner]"
   78.26 - *
   78.27 - * If you wish your version of this file to be governed by only the CDDL or
   78.28 - * only the GPL Version 2, indicate your decision by adding "[Contributor]
   78.29 - * elects to include this software in this distribution under the [CDDL or GPL
   78.30 - * Version 2] license." If you do not indicate a single choice of license, a
   78.31 - * recipient has the option to distribute your version of this file under
   78.32 - * either the CDDL, the GPL Version 2 or to extend the choice of license to its
   78.33 - * licensees as provided above. However, if you add GPL Version 2 code and
   78.34 - * therefore, elected the GPL Version 2 license, then the option applies only
   78.35 - * if the new code is made subject to such option by the copyright holder.
   78.36 - *
   78.37 - * Contributor(s):
   78.38 - *
   78.39 - * Portions Copyrighted 2011 Sun Microsystems, Inc.
   78.40 - */
   78.41 -package org.netbeans.modules.java.hints.spiimpl;
   78.42 -
   78.43 -/**
   78.44 - *
   78.45 - * @author lahvac
   78.46 - */
   78.47 -public interface SyntheticFix {
   78.48 -
   78.49 -}
    79.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/Utilities.java	Sun Oct 16 08:01:27 2016 +0200
    79.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    79.3 @@ -1,1554 +0,0 @@
    79.4 -/*
    79.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    79.6 - *
    79.7 - * Copyright 2008-2010 Sun Microsystems, Inc. All rights reserved.
    79.8 - *
    79.9 - * The contents of this file are subject to the terms of either the GNU
   79.10 - * General Public License Version 2 only ("GPL") or the Common
   79.11 - * Development and Distribution License("CDDL") (collectively, the
   79.12 - * "License"). You may not use this file except in compliance with the
   79.13 - * License. You can obtain a copy of the License at
   79.14 - * http://www.netbeans.org/cddl-gplv2.html
   79.15 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   79.16 - * specific language governing permissions and limitations under the
   79.17 - * License.  When distributing the software, include this License Header
   79.18 - * Notice in each file and include the License file at
   79.19 - * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
   79.20 - * particular file as subject to the "Classpath" exception as provided
   79.21 - * by Sun in the GPL Version 2 section of the License file that
   79.22 - * accompanied this code. If applicable, add the following below the
   79.23 - * License Header, with the fields enclosed by brackets [] replaced by
   79.24 - * your own identifying information:
   79.25 - * "Portions Copyrighted [year] [name of copyright owner]"
   79.26 - *
   79.27 - * If you wish your version of this file to be governed by only the CDDL
   79.28 - * or only the GPL Version 2, indicate your decision by adding
   79.29 - * "[Contributor] elects to include this software in this distribution
   79.30 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   79.31 - * single choice of license, a recipient has the option to distribute
   79.32 - * your version of this file under either the CDDL, the GPL Version 2 or
   79.33 - * to extend the choice of license to its licensees as provided above.
   79.34 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   79.35 - * Version 2 license, then the option applies only if the new code is
   79.36 - * made subject to such option by the copyright holder.
   79.37 - *
   79.38 - * Contributor(s):
   79.39 - *
   79.40 - * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
   79.41 - */
   79.42 -
   79.43 -package org.netbeans.modules.java.hints.spiimpl;
   79.44 -
   79.45 -import com.sun.source.tree.AnnotationTree;
   79.46 -import com.sun.source.tree.AssignmentTree;
   79.47 -import com.sun.source.tree.BlockTree;
   79.48 -import com.sun.source.tree.ClassTree;
   79.49 -import com.sun.source.tree.CompilationUnitTree;
   79.50 -import com.sun.source.tree.ExpressionStatementTree;
   79.51 -import com.sun.source.tree.ExpressionTree;
   79.52 -import com.sun.source.tree.IdentifierTree;
   79.53 -import com.sun.source.tree.ImportTree;
   79.54 -import com.sun.source.tree.LiteralTree;
   79.55 -import com.sun.source.tree.MemberSelectTree;
   79.56 -import com.sun.source.tree.MethodInvocationTree;
   79.57 -import com.sun.source.tree.MethodTree;
   79.58 -import com.sun.source.tree.ModifiersTree;
   79.59 -import com.sun.source.tree.NewArrayTree;
   79.60 -import com.sun.source.tree.NewClassTree;
   79.61 -import com.sun.source.tree.Scope;
   79.62 -import com.sun.source.tree.StatementTree;
   79.63 -import com.sun.source.tree.SwitchTree;
   79.64 -import com.sun.source.tree.Tree;
   79.65 -import com.sun.source.tree.Tree.Kind;
   79.66 -import com.sun.source.tree.TypeParameterTree;
   79.67 -import com.sun.source.tree.VariableTree;
   79.68 -import com.sun.source.util.SourcePositions;
   79.69 -import com.sun.source.util.TreePath;
   79.70 -import com.sun.source.util.TreePathScanner;
   79.71 -import com.sun.source.util.TreeScanner;
   79.72 -import com.sun.source.util.Trees;
   79.73 -import com.sun.tools.javac.api.JavacScope;
   79.74 -import com.sun.tools.javac.api.JavacTaskImpl;
   79.75 -import com.sun.tools.javac.api.JavacTrees;
   79.76 -import com.sun.tools.javac.code.Flags;
   79.77 -import com.sun.tools.javac.code.Symtab;
   79.78 -import com.sun.tools.javac.code.Type;
   79.79 -import com.sun.tools.javac.comp.Attr;
   79.80 -import com.sun.tools.javac.comp.AttrContext;
   79.81 -import com.sun.tools.javac.comp.Env;
   79.82 -import com.sun.tools.javac.comp.Todo;
   79.83 -import com.sun.tools.javac.main.JavaCompiler;
   79.84 -import com.sun.tools.javac.parser.JavacParser;
   79.85 -import com.sun.tools.javac.parser.Lexer;
   79.86 -import com.sun.tools.javac.parser.Parser;
   79.87 -import com.sun.tools.javac.parser.ParserFactory;
   79.88 -import com.sun.tools.javac.parser.Scanner;
   79.89 -import com.sun.tools.javac.parser.ScannerFactory;
   79.90 -import com.sun.tools.javac.parser.Tokens.Token;
   79.91 -import com.sun.tools.javac.parser.Tokens.TokenKind;
   79.92 -import com.sun.tools.javac.tree.JCTree;
   79.93 -import com.sun.tools.javac.tree.JCTree.JCCase;
   79.94 -import com.sun.tools.javac.tree.JCTree.JCCatch;
   79.95 -import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
   79.96 -import com.sun.tools.javac.tree.JCTree.JCExpression;
   79.97 -import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
   79.98 -import com.sun.tools.javac.tree.JCTree.JCIdent;
   79.99 -import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
  79.100 -import com.sun.tools.javac.tree.JCTree.JCModifiers;
  79.101 -import com.sun.tools.javac.tree.JCTree.JCStatement;
  79.102 -import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
  79.103 -import com.sun.tools.javac.util.Context;
  79.104 -import com.sun.tools.javac.util.JCDiagnostic;
  79.105 -import com.sun.tools.javac.util.ListBuffer;
  79.106 -import com.sun.tools.javac.util.Log;
  79.107 -import com.sun.tools.javac.util.Names;
  79.108 -import com.sun.tools.javadoc.Messager;
  79.109 -import java.io.File;
  79.110 -import java.io.IOException;
  79.111 -import java.net.URI;
  79.112 -import java.nio.CharBuffer;
  79.113 -import java.util.Arrays;
  79.114 -import java.util.Collection;
  79.115 -import java.util.Collections;
  79.116 -import java.util.EnumSet;
  79.117 -import java.util.HashMap;
  79.118 -import java.util.HashSet;
  79.119 -import java.util.Iterator;
  79.120 -import java.util.LinkedList;
  79.121 -import java.util.List;
  79.122 -import java.util.Locale;
  79.123 -import java.util.Map;
  79.124 -import java.util.Map.Entry;
  79.125 -import java.util.Set;
  79.126 -import java.util.concurrent.atomic.AtomicBoolean;
  79.127 -import javax.lang.model.element.AnnotationMirror;
  79.128 -import javax.lang.model.element.AnnotationValue;
  79.129 -import javax.lang.model.element.AnnotationValueVisitor;
  79.130 -import javax.lang.model.element.Element;
  79.131 -import javax.lang.model.element.ElementKind;
  79.132 -import javax.lang.model.element.ExecutableElement;
  79.133 -import javax.lang.model.element.Modifier;
  79.134 -import javax.lang.model.element.Name;
  79.135 -import javax.lang.model.element.TypeElement;
  79.136 -import javax.lang.model.element.VariableElement;
  79.137 -import javax.lang.model.type.TypeKind;
  79.138 -import javax.lang.model.type.TypeMirror;
  79.139 -import javax.lang.model.util.Elements;
  79.140 -import javax.tools.Diagnostic;
  79.141 -import javax.tools.JavaCompiler.CompilationTask;
  79.142 -import javax.tools.JavaFileObject;
  79.143 -import javax.tools.SimpleJavaFileObject;
  79.144 -import org.netbeans.api.annotations.common.CheckForNull;
  79.145 -import org.netbeans.api.annotations.common.NonNull;
  79.146 -import org.netbeans.api.java.classpath.ClassPath;
  79.147 -import org.netbeans.api.java.platform.JavaPlatform;
  79.148 -import org.netbeans.api.java.platform.JavaPlatformManager;
  79.149 -import org.netbeans.api.java.queries.SourceForBinaryQuery;
  79.150 -import org.netbeans.api.java.queries.SourceForBinaryQuery.Result2;
  79.151 -import org.netbeans.api.java.source.ClasspathInfo;
  79.152 -import org.netbeans.api.java.source.CompilationInfo;
  79.153 -import org.netbeans.api.java.source.CompilationInfo.CacheClearPolicy;
  79.154 -import org.netbeans.api.java.source.SourceUtils;
  79.155 -import org.netbeans.api.java.source.TreeMaker;
  79.156 -import org.netbeans.modules.java.hints.providers.spi.ClassPathBasedHintProvider;
  79.157 -import org.netbeans.modules.java.hints.providers.spi.HintDescription;
  79.158 -import org.netbeans.modules.java.hints.providers.spi.Trigger.PatternDescription;
  79.159 -import org.netbeans.modules.java.hints.spiimpl.JackpotTrees.CatchWildcard;
  79.160 -import org.netbeans.modules.java.hints.spiimpl.JackpotTrees.VariableWildcard;
  79.161 -import org.netbeans.modules.java.source.JavaSourceAccessor;
  79.162 -import org.netbeans.modules.java.source.builder.TreeFactory;
  79.163 -import org.netbeans.lib.nbjavac.services.CancelService;
  79.164 -import org.netbeans.lib.nbjavac.services.NBParserFactory.NBJavacParser;
  79.165 -import org.netbeans.lib.nbjavac.services.NBParserFactory;
  79.166 -import org.netbeans.lib.nbjavac.services.NBResolve;
  79.167 -import org.netbeans.modules.java.hints.spiimpl.JackpotTrees.AnnotationWildcard;
  79.168 -import org.netbeans.modules.java.hints.spiimpl.JackpotTrees.FakeBlock;
  79.169 -import org.netbeans.modules.java.source.parsing.FileObjects;
  79.170 -import org.netbeans.modules.java.source.pretty.ImportAnalysis2;
  79.171 -import org.netbeans.modules.java.source.transform.ImmutableTreeTranslator;
  79.172 -import org.netbeans.spi.editor.hints.Severity;
  79.173 -import org.netbeans.spi.java.classpath.support.ClassPathSupport;
  79.174 -import org.openide.filesystems.FileObject;
  79.175 -import org.openide.filesystems.FileUtil;
  79.176 -import org.openide.util.Lookup;
  79.177 -import org.openide.util.NbCollections;
  79.178 -import org.openide.util.lookup.ServiceProvider;
  79.179 -
  79.180 -/**
  79.181 - *
  79.182 - * @author Jan Lahoda
  79.183 - */
  79.184 -public class Utilities {
  79.185 -
  79.186 -    private Utilities() {}
  79.187 -    
  79.188 -    public static Set<Severity> disableErrors(FileObject file) {
  79.189 -        if (file.getAttribute(DISABLE_ERRORS) != null) {
  79.190 -            return EnumSet.allOf(Severity.class);
  79.191 -        }
  79.192 -        if (!file.canWrite() && FileUtil.getArchiveFile(file) != null) {
  79.193 -            return EnumSet.allOf(Severity.class);
  79.194 -        }
  79.195 -
  79.196 -        return EnumSet.noneOf(Severity.class);
  79.197 -    }
  79.198 -
  79.199 -    private static final String DISABLE_ERRORS = "disable-java-errors";
  79.200 -    
  79.201 -
  79.202 -    public static <E> Iterable<E> checkedIterableByFilter(final Iterable raw, final Class<E> type, final boolean strict) {
  79.203 -        return new Iterable<E>() {
  79.204 -            public Iterator<E> iterator() {
  79.205 -                return NbCollections.checkedIteratorByFilter(raw.iterator(), type, strict);
  79.206 -            }
  79.207 -        };
  79.208 -    }
  79.209 -    
  79.210 -//    public static AnnotationTree constructConstraint(WorkingCopy wc, String name, TypeMirror tm) {
  79.211 -//        TreeMaker make = wc.getTreeMaker();
  79.212 -//        ExpressionTree variable = prepareAssignment(make, "variable", make.Literal(name));
  79.213 -//        ExpressionTree type     = prepareAssignment(make, "type", make.MemberSelect((ExpressionTree) make.Type(wc.getTypes().erasure(tm)), "class"));
  79.214 -//        TypeElement constraint  = wc.getElements().getTypeElement(Annotations.CONSTRAINT.toFQN());
  79.215 -//
  79.216 -//        return make.Annotation(make.QualIdent(constraint), Arrays.asList(variable, type));
  79.217 -//    }
  79.218 -
  79.219 -    public static ExpressionTree prepareAssignment(TreeMaker make, String name, ExpressionTree value) {
  79.220 -        return make.Assignment(make.Identifier(name), value);
  79.221 -    }
  79.222 -
  79.223 -    public static ExpressionTree findValue(AnnotationTree m, String name) {
  79.224 -        for (ExpressionTree et : m.getArguments()) {
  79.225 -            if (et.getKind() == Kind.ASSIGNMENT) {
  79.226 -                AssignmentTree at = (AssignmentTree) et;
  79.227 -                String varName = ((IdentifierTree) at.getVariable()).getName().toString();
  79.228 -
  79.229 -                if (varName.equals(name)) {
  79.230 -                    return at.getExpression();
  79.231 -                }
  79.232 -            }
  79.233 -
  79.234 -            if (et instanceof LiteralTree/*XXX*/ && "value".equals(name)) {
  79.235 -                return et;
  79.236 -            }
  79.237 -        }
  79.238 -
  79.239 -        return null;
  79.240 -    }
  79.241 -
  79.242 -    public static List<AnnotationTree> findArrayValue(AnnotationTree at, String name) {
  79.243 -        ExpressionTree fixesArray = findValue(at, name);
  79.244 -        List<AnnotationTree> fixes = new LinkedList<AnnotationTree>();
  79.245 -
  79.246 -        if (fixesArray != null && fixesArray.getKind() == Kind.NEW_ARRAY) {
  79.247 -            NewArrayTree trees = (NewArrayTree) fixesArray;
  79.248 -
  79.249 -            for (ExpressionTree fix : trees.getInitializers()) {
  79.250 -                if (fix.getKind() == Kind.ANNOTATION) {
  79.251 -                    fixes.add((AnnotationTree) fix);
  79.252 -                }
  79.253 -            }
  79.254 -        }
  79.255 -
  79.256 -        if (fixesArray != null && fixesArray.getKind() == Kind.ANNOTATION) {
  79.257 -            fixes.add((AnnotationTree) fixesArray);
  79.258 -        }
  79.259 -        
  79.260 -        return fixes;
  79.261 -    }
  79.262 -
  79.263 -    public static boolean isPureMemberSelect(Tree mst, boolean allowVariables) {
  79.264 -        switch (mst.getKind()) {
  79.265 -            case IDENTIFIER: return allowVariables || ((IdentifierTree) mst).getName().charAt(0) != '$';
  79.266 -            case MEMBER_SELECT: return isPureMemberSelect(((MemberSelectTree) mst).getExpression(), allowVariables);
  79.267 -            default: return false;
  79.268 -        }
  79.269 -    }
  79.270 -
  79.271 -    public static Map<String, Collection<HintDescription>> sortOutHints(Iterable<? extends HintDescription> hints, Map<String, Collection<HintDescription>> output) {
  79.272 -        for (HintDescription d : hints) {
  79.273 -            Collection<HintDescription> h = output.get(d.getMetadata().displayName);
  79.274 -
  79.275 -            if (h == null) {
  79.276 -                output.put(d.getMetadata().displayName, h = new LinkedList<HintDescription>());
  79.277 -            }
  79.278 -
  79.279 -            h.add(d);
  79.280 -        }
  79.281 -
  79.282 -        return output;
  79.283 -    }
  79.284 -
  79.285 -    public static List<HintDescription> listAllHints(Set<ClassPath> cps) {
  79.286 -        List<HintDescription> result = new LinkedList<HintDescription>();
  79.287 -
  79.288 -        for (Collection<? extends HintDescription> hints : RulesManager.getInstance().readHints(null, cps, new AtomicBoolean()).values()) {
  79.289 -            for (HintDescription hd : hints) {
  79.290 -                if (!(hd.getTrigger() instanceof PatternDescription)) continue; //TODO: only pattern based hints are currently supported
  79.291 -                result.add(hd);
  79.292 -            }
  79.293 -        }
  79.294 -
  79.295 -        result.addAll(listClassPathHints(Collections.<ClassPath>emptySet(), cps));
  79.296 -
  79.297 -        return result;
  79.298 -    }
  79.299 -
  79.300 -    public static List<HintDescription> listClassPathHints(Set<ClassPath> sourceCPs, Set<ClassPath> binaryCPs) {
  79.301 -        List<HintDescription> result = new LinkedList<HintDescription>();
  79.302 -        Set<FileObject> roots = new HashSet<FileObject>();
  79.303 -
  79.304 -        for (ClassPath cp : binaryCPs) {
  79.305 -            for (FileObject r : cp.getRoots()) {
  79.306 -                Result2 src = SourceForBinaryQuery.findSourceRoots2(r.toURL());
  79.307 -
  79.308 -                if (src != null && src.preferSources()) {
  79.309 -                    roots.addAll(Arrays.asList(src.getRoots()));
  79.310 -                } else {
  79.311 -                    roots.add(r);
  79.312 -                }
  79.313 -            }
  79.314 -        }
  79.315 -
  79.316 -        Set<ClassPath> cps = new HashSet<ClassPath>(sourceCPs);
  79.317 -
  79.318 -        cps.add(ClassPathSupport.createClassPath(roots.toArray(new FileObject[0])));
  79.319 -
  79.320 -        ClassPath cp = ClassPathSupport.createProxyClassPath(cps.toArray(new ClassPath[0]));
  79.321 -
  79.322 -        for (ClassPathBasedHintProvider p : Lookup.getDefault().lookupAll(ClassPathBasedHintProvider.class)) {
  79.323 -            result.addAll(p.computeHints(cp));
  79.324 -        }
  79.325 -
  79.326 -        return result;
  79.327 -    }
  79.328 -    
  79.329 -    public static Tree parseAndAttribute(CompilationInfo info, String pattern, Scope scope) {
  79.330 -        return parseAndAttribute(info, pattern, scope, null);
  79.331 -    }
  79.332 -
  79.333 -    public static Tree parseAndAttribute(CompilationInfo info, String pattern, Scope scope, Collection<Diagnostic<? extends JavaFileObject>> errors) {
  79.334 -        return parseAndAttribute(info, JavaSourceAccessor.getINSTANCE().getJavacTask(info), pattern, scope, errors);
  79.335 -    }
  79.336 -
  79.337 -    public static Tree parseAndAttribute(CompilationInfo info, String pattern, Scope scope, SourcePositions[] sourcePositions, Collection<Diagnostic<? extends JavaFileObject>> errors) {
  79.338 -        return parseAndAttribute(info, JavaSourceAccessor.getINSTANCE().getJavacTask(info), pattern, scope, sourcePositions, errors);
  79.339 -    }
  79.340 -
  79.341 -    public static Tree parseAndAttribute(JavacTaskImpl jti, String pattern) {
  79.342 -        return parseAndAttribute(jti, pattern, null);
  79.343 -    }
  79.344 -
  79.345 -    public static Tree parseAndAttribute(JavacTaskImpl jti, String pattern, Collection<Diagnostic<? extends JavaFileObject>> errors) {
  79.346 -        return parseAndAttribute(null, jti, pattern, null, errors);
  79.347 -    }
  79.348 -
  79.349 -    public static Tree parseAndAttribute(JavacTaskImpl jti, String pattern, SourcePositions[] sourcePositions, Collection<Diagnostic<? extends JavaFileObject>> errors) {
  79.350 -        return parseAndAttribute(null, jti, pattern, null, sourcePositions, errors);
  79.351 -    }
  79.352 -
  79.353 -    private static Tree parseAndAttribute(CompilationInfo info, JavacTaskImpl jti, String pattern, Scope scope, Collection<Diagnostic<? extends JavaFileObject>> errors) {
  79.354 -        return parseAndAttribute(info, jti, pattern, scope, new SourcePositions[1], errors);
  79.355 -    }
  79.356 -
  79.357 -    private static Tree parseAndAttribute(CompilationInfo info, JavacTaskImpl jti, String pattern, Scope scope, SourcePositions[] sourcePositions, Collection<Diagnostic<? extends JavaFileObject>> errors) {
  79.358 -        Context c = jti.getContext();
  79.359 -        TreeFactory make = TreeFactory.instance(c);
  79.360 -        List<Diagnostic<? extends JavaFileObject>> patternTreeErrors = new LinkedList<Diagnostic<? extends JavaFileObject>>();
  79.361 -        Tree toAttribute;
  79.362 -        Tree patternTree = toAttribute = !isStatement(pattern) ? parseExpression(c, pattern, true, sourcePositions, patternTreeErrors) : null;
  79.363 -        int offset = 0;
  79.364 -        boolean expression = true;
  79.365 -        boolean classMember = false;
  79.366 -
  79.367 -        if (pattern.startsWith("case ")) {//XXX: should be a lexer token
  79.368 -            List<Diagnostic<? extends JavaFileObject>> currentPatternTreeErrors = new LinkedList<Diagnostic<? extends JavaFileObject>>();
  79.369 -            Tree switchTree = parseStatement(c, "switch ($$foo) {" + pattern + "}", sourcePositions, currentPatternTreeErrors);
  79.370 -
  79.371 -            offset = "switch ($$foo) {".length();
  79.372 -            patternTreeErrors = currentPatternTreeErrors;
  79.373 -            patternTree = toAttribute = ((SwitchTree) switchTree).getCases().get(0);
  79.374 -        }
  79.375 -
  79.376 -        if (patternTree == null || isErrorTree(patternTree)) {
  79.377 -            SourcePositions[] currentPatternTreePositions = new SourcePositions[1];
  79.378 -            List<Diagnostic<? extends JavaFileObject>> currentPatternTreeErrors = new LinkedList<Diagnostic<? extends JavaFileObject>>();
  79.379 -            Tree currentPatternTree = parseStatement(c, "{" + pattern + "}", currentPatternTreePositions, currentPatternTreeErrors);
  79.380 -
  79.381 -            assert currentPatternTree.getKind() == Kind.BLOCK : currentPatternTree.getKind();
  79.382 -
  79.383 -            List<? extends StatementTree> statements = ((BlockTree) currentPatternTree).getStatements();
  79.384 -
  79.385 -            if (statements.size() == 1) {
  79.386 -                currentPatternTree = statements.get(0);
  79.387 -            } else {
  79.388 -                com.sun.tools.javac.util.List<JCStatement> newStatements = com.sun.tools.javac.util.List.<JCStatement>nil();
  79.389 -
  79.390 -                if (!statements.isEmpty() && !Utilities.isMultistatementWildcardTree(statements.get(0)))
  79.391 -                    newStatements = newStatements.append((JCStatement) make.ExpressionStatement(make.Identifier("$$1$")));
  79.392 -                for (StatementTree st : statements) {
  79.393 -                    newStatements = newStatements.append((JCStatement) st);
  79.394 -                }
  79.395 -                if (!statements.isEmpty() && !Utilities.isMultistatementWildcardTree(statements.get(statements.size() - 1)))
  79.396 -                    newStatements = newStatements.append((JCStatement) make.ExpressionStatement(make.Identifier("$$2$")));
  79.397 -
  79.398 -                currentPatternTree = new FakeBlock(0L, newStatements);
  79.399 -            }
  79.400 -
  79.401 -            if (!currentPatternTreeErrors.isEmpty() || containsError(currentPatternTree)) {
  79.402 -                //maybe a class member?
  79.403 -                SourcePositions[] classPatternTreePositions = new SourcePositions[1];
  79.404 -                List<Diagnostic<? extends JavaFileObject>> classPatternTreeErrors = new LinkedList<Diagnostic<? extends JavaFileObject>>();
  79.405 -                Tree classPatternTree = parseExpression(c, "new Object() {" + pattern + "}", false, classPatternTreePositions, classPatternTreeErrors);
  79.406 -
  79.407 -                if (!containsError(classPatternTree)) {
  79.408 -                    sourcePositions[0] = classPatternTreePositions[0];
  79.409 -                    offset = "new Object() {".length();
  79.410 -                    patternTreeErrors = classPatternTreeErrors;
  79.411 -                    patternTree = toAttribute = classPatternTree;
  79.412 -                    classMember = true;
  79.413 -                } else {
  79.414 -                    offset = 1;
  79.415 -                    sourcePositions[0] = currentPatternTreePositions[0];
  79.416 -                    VariableTree var;
  79.417 -                    Names names = Names.instance(jti.getContext());
  79.418 -                    if (currentPatternTree.getKind() == Kind.VARIABLE && (var = ((VariableTree) currentPatternTree)).getType().getKind() == Kind.ERRONEOUS && var.getName() == names.error && var.getInitializer() == null && var.getModifiers().getAnnotations().size() == 1 && !containsError(var.getModifiers().getAnnotations().get(0))) {
  79.419 -                        patternTreeErrors = currentPatternTreeErrors; //TODO: the errors are incorrect
  79.420 -                        toAttribute = currentPatternTree;
  79.421 -                        patternTree = var.getModifiers().getAnnotations().get(0);
  79.422 -                    } else {
  79.423 -                        patternTreeErrors = currentPatternTreeErrors;
  79.424 -                        patternTree = toAttribute = currentPatternTree;
  79.425 -                    }
  79.426 -                }
  79.427 -            } else {
  79.428 -                sourcePositions[0] = currentPatternTreePositions[0];
  79.429 -                offset = 1;
  79.430 -                patternTreeErrors = currentPatternTreeErrors;
  79.431 -                patternTree = toAttribute = currentPatternTree;
  79.432 -            }
  79.433 -
  79.434 -            expression = false;
  79.435 -        }
  79.436 -
  79.437 -        if (scope != null) {
  79.438 -            TypeMirror type = attributeTree(jti, toAttribute, scope, patternTreeErrors);
  79.439 -
  79.440 -            if (isError(type) && expression) {
  79.441 -                //maybe type?
  79.442 -                if (Utilities.isPureMemberSelect(patternTree, false)) {
  79.443 -                    SourcePositions[] varPositions = new SourcePositions[1];
  79.444 -                    List<Diagnostic<? extends JavaFileObject>> varErrors = new LinkedList<Diagnostic<? extends JavaFileObject>>();
  79.445 -                    Tree var = parseExpression(c, pattern + ".Class.class;", false, varPositions, varErrors);
  79.446 -
  79.447 -                    attributeTree(jti, var, scope, varErrors);
  79.448 -
  79.449 -                    ExpressionTree typeTree = ((MemberSelectTree) ((MemberSelectTree) var).getExpression()).getExpression();
  79.450 -                    final Symtab symtab = Symtab.instance(c);
  79.451 -                    final Elements el = jti.getElements();
  79.452 -                    final Trees trees = JavacTrees.instance(c);
  79.453 -                    CompilationUnitTree cut = ((JavacScope) scope).getEnv().toplevel;
  79.454 -                    final boolean[] found = new boolean[1];
  79.455 -
  79.456 -                    new TreePathScanner<Void, Void>() {
  79.457 -                        @Override public Void visitMemberSelect(MemberSelectTree node, Void p) {
  79.458 -                            Element currentElement = trees.getElement(getCurrentPath());
  79.459 -
  79.460 -                            if (!isError(currentElement)) {
  79.461 -                                if (currentElement.getKind() == ElementKind.PACKAGE && el.getPackageElement(node.toString()) == null) {
  79.462 -                                    ((JCFieldAccess) node).sym = symtab.errSymbol;
  79.463 -                                    ((JCFieldAccess) node).type = symtab.errType;
  79.464 -                                } else {
  79.465 -                                    found[0] = true;
  79.466 -                                    return null;
  79.467 -                                }
  79.468 -                            }
  79.469 -
  79.470 -                            return super.visitMemberSelect(node, p);
  79.471 -                        }
  79.472 -                        @Override public Void visitIdentifier(IdentifierTree node, Void p) {
  79.473 -                            Element currentElement = trees.getElement(getCurrentPath());
  79.474 -
  79.475 -                            if (!isError(currentElement)) {
  79.476 -                                if (currentElement.getKind() == ElementKind.PACKAGE && el.getPackageElement(node.toString()) == null) {
  79.477 -                                    ((JCIdent) node).sym = symtab.errSymbol;
  79.478 -                                    ((JCIdent) node).type = symtab.errType;
  79.479 -                                } else {
  79.480 -                                    found[0] = true;
  79.481 -                                    return null;
  79.482 -                                }
  79.483 -                            }
  79.484 -                            return super.visitIdentifier(node, p);
  79.485 -                        }
  79.486 -
  79.487 -                    }.scan(new TreePath(new TreePath(cut), typeTree), null);
  79.488 -
  79.489 -                    if (found[0]) {
  79.490 -                        sourcePositions[0] = varPositions[0];
  79.491 -                        offset = 0;
  79.492 -                        patternTreeErrors = varErrors;
  79.493 -                        patternTree = typeTree;
  79.494 -                    }
  79.495 -                }
  79.496 -            }
  79.497 -        }
  79.498 -
  79.499 -        if (classMember) {
  79.500 -            List<? extends Tree> members = ((NewClassTree) patternTree).getClassBody().getMembers();
  79.501 -            
  79.502 -            int syntheticOffset = !members.isEmpty() && members.get(0).getKind() == Kind.METHOD && (((JCMethodDecl) members.get(0)).mods.flags & Flags.GENERATEDCONSTR) != 0 ? 1 : 0;
  79.503 -
  79.504 -            if (members.size() > 1 + syntheticOffset) {
  79.505 -                ModifiersTree mt = make.Modifiers(EnumSet.noneOf(Modifier.class));
  79.506 -                List<Tree> newMembers = new LinkedList<Tree>();
  79.507 -
  79.508 -                newMembers.add(make.ExpressionStatement(make.Identifier("$$1$")));
  79.509 -                newMembers.addAll(members.subList(syntheticOffset, members.size()));
  79.510 -
  79.511 -                patternTree = make.Class(mt, "$", Collections.<TypeParameterTree>emptyList(), null, Collections.<Tree>emptyList(), newMembers);
  79.512 -            } else {
  79.513 -                patternTree = members.get(0 + syntheticOffset);
  79.514 -            }
  79.515 -        }
  79.516 -
  79.517 -        if (errors != null) {
  79.518 -            for (Diagnostic<? extends JavaFileObject> d : patternTreeErrors) {
  79.519 -                errors.add(new OffsetDiagnostic<JavaFileObject>(d, -offset));
  79.520 -            }
  79.521 -        }
  79.522 -
  79.523 -        sourcePositions[0] = new OffsetSourcePositions(sourcePositions[0], -offset);
  79.524 -        
  79.525 -        return patternTree;
  79.526 -    }
  79.527 -
  79.528 -    static boolean isError(Element el) {
  79.529 -        return (el == null || (el.getKind() == ElementKind.CLASS) && isError(((TypeElement) el).asType()));
  79.530 -    }
  79.531 -
  79.532 -    private static boolean isError(TypeMirror type) {
  79.533 -        return type == null || type.getKind() == TypeKind.ERROR;
  79.534 -    }
  79.535 -
  79.536 -    private static boolean isStatement(String pattern) {
  79.537 -        return pattern.trim().endsWith(";");
  79.538 -    }
  79.539 -
  79.540 -    private static boolean isErrorTree(Tree t) {
  79.541 -        return t.getKind() == Kind.ERRONEOUS || (t.getKind() == Kind.IDENTIFIER && ((IdentifierTree) t).getName().contentEquals("<error>")); //TODO: <error>...
  79.542 -    }
  79.543 -    
  79.544 -    private static boolean containsError(Tree t) {
  79.545 -        return new TreeScanner<Boolean, Void>() {
  79.546 -            @Override
  79.547 -            public Boolean scan(Tree node, Void p) {
  79.548 -                if (node != null && isErrorTree(node)) {
  79.549 -                    return true;
  79.550 -                }
  79.551 -                return super.scan(node, p) ==Boolean.TRUE;
  79.552 -            }
  79.553 -            @Override
  79.554 -            public Boolean reduce(Boolean r1, Boolean r2) {
  79.555 -                return r1 == Boolean.TRUE || r2 == Boolean.TRUE;
  79.556 -            }
  79.557 -        }.scan(t, null);
  79.558 -    }
  79.559 -
  79.560 -    private static JCStatement parseStatement(Context context, CharSequence stmt, SourcePositions[] pos, final List<Diagnostic<? extends JavaFileObject>> errors) {
  79.561 -        if (stmt == null || (pos != null && pos.length != 1))
  79.562 -            throw new IllegalArgumentException();
  79.563 -        JavaCompiler compiler = JavaCompiler.instance(context);
  79.564 -        JavaFileObject prev = compiler.log.useSource(new DummyJFO());
  79.565 -        Log.DiagnosticHandler discardHandler = new Log.DiscardDiagnosticHandler(compiler.log) {
  79.566 -            @Override
  79.567 -            public void report(JCDiagnostic diag) {
  79.568 -                errors.add(diag);
  79.569 -            }            
  79.570 -        };
  79.571 -        try {
  79.572 -            CharBuffer buf = CharBuffer.wrap((stmt+"\u0000").toCharArray(), 0, stmt.length());
  79.573 -            ParserFactory factory = ParserFactory.instance(context);
  79.574 -            ScannerFactory scannerFactory = ScannerFactory.instance(context);
  79.575 -            Names names = Names.instance(context);
  79.576 -            Parser parser = new JackpotJavacParser(context, (NBParserFactory) factory, scannerFactory.newScanner(buf, false), false, false, CancelService.instance(context), names);
  79.577 -            if (parser instanceof JavacParser) {
  79.578 -                if (pos != null)
  79.579 -                    pos[0] = new ParserSourcePositions((JavacParser)parser);
  79.580 -                return parser.parseStatement();
  79.581 -            }
  79.582 -            return null;
  79.583 -        } finally {
  79.584 -            compiler.log.useSource(prev);
  79.585 -            compiler.log.popDiagnosticHandler(discardHandler);
  79.586 -        }
  79.587 -    }
  79.588 -
  79.589 -    private static JCExpression parseExpression(Context context, CharSequence expr, boolean onlyFullInput, SourcePositions[] pos, final List<Diagnostic<? extends JavaFileObject>> errors) {
  79.590 -        if (expr == null || (pos != null && pos.length != 1))
  79.591 -            throw new IllegalArgumentException();
  79.592 -        JavaCompiler compiler = JavaCompiler.instance(context);
  79.593 -        JavaFileObject prev = compiler.log.useSource(new DummyJFO());
  79.594 -        Log.DiagnosticHandler discardHandler = new Log.DiscardDiagnosticHandler(compiler.log) {
  79.595 -            @Override
  79.596 -            public void report(JCDiagnostic diag) {
  79.597 -                errors.add(diag);
  79.598 -            }            
  79.599 -        };
  79.600 -        try {
  79.601 -            CharBuffer buf = CharBuffer.wrap((expr+"\u0000").toCharArray(), 0, expr.length());
  79.602 -            ParserFactory factory = ParserFactory.instance(context);
  79.603 -            ScannerFactory scannerFactory = ScannerFactory.instance(context);
  79.604 -            Names names = Names.instance(context);
  79.605 -            Scanner scanner = scannerFactory.newScanner(buf, false);
  79.606 -            Parser parser = new JackpotJavacParser(context, (NBParserFactory) factory, scanner, false, false, CancelService.instance(context), names);
  79.607 -            if (parser instanceof JavacParser) {
  79.608 -                if (pos != null)
  79.609 -                    pos[0] = new ParserSourcePositions((JavacParser)parser);
  79.610 -                JCExpression result = parser.parseExpression();
  79.611 -
  79.612 -                if (!onlyFullInput || scanner.token().kind == TokenKind.EOF) {
  79.613 -                    return result;
  79.614 -                }
  79.615 -            }
  79.616 -            return null;
  79.617 -        } finally {
  79.618 -            compiler.log.useSource(prev);
  79.619 -            compiler.log.popDiagnosticHandler(discardHandler);
  79.620 -        }
  79.621 -    }
  79.622 -
  79.623 -    private static TypeMirror attributeTree(JavacTaskImpl jti, Tree tree, Scope scope, final List<Diagnostic<? extends JavaFileObject>> errors) {
  79.624 -        Log log = Log.instance(jti.getContext());
  79.625 -        JavaFileObject prev = log.useSource(new DummyJFO());
  79.626 -        Log.DiagnosticHandler discardHandler = new Log.DiscardDiagnosticHandler(log) {
  79.627 -            @Override
  79.628 -            public void report(JCDiagnostic diag) {
  79.629 -                errors.add(diag);
  79.630 -            }            
  79.631 -        };
  79.632 -        NBResolve resolve = NBResolve.instance(jti.getContext());
  79.633 -        resolve.disableAccessibilityChecks();
  79.634 -        try {
  79.635 -            Attr attr = Attr.instance(jti.getContext());
  79.636 -            Env<AttrContext> env = ((JavacScope) scope).getEnv();
  79.637 -            if (tree instanceof JCExpression)
  79.638 -                return attr.attribExpr((JCTree) tree,env, Type.noType);
  79.639 -            return attr.attribStat((JCTree) tree,env);
  79.640 -        } finally {
  79.641 -            log.useSource(prev);
  79.642 -            log.popDiagnosticHandler(discardHandler);
  79.643 -            resolve.restoreAccessbilityChecks();
  79.644 -        }
  79.645 -    }
  79.646 -
  79.647 -    public static @CheckForNull CharSequence getWildcardTreeName(@NonNull Tree t) {
  79.648 -        if (t.getKind() == Kind.EXPRESSION_STATEMENT && ((ExpressionStatementTree) t).getExpression().getKind() == Kind.IDENTIFIER) {
  79.649 -            IdentifierTree identTree = (IdentifierTree) ((ExpressionStatementTree) t).getExpression();
  79.650 -            
  79.651 -            return identTree.getName().toString();
  79.652 -        }
  79.653 -
  79.654 -        if (t.getKind() == Kind.IDENTIFIER) {
  79.655 -            IdentifierTree identTree = (IdentifierTree) t;
  79.656 -            String name = identTree.getName().toString();
  79.657 -
  79.658 -            if (name.startsWith("$")) {
  79.659 -                return name;
  79.660 -            }
  79.661 -        }
  79.662 -        
  79.663 -        if (t.getKind() == Kind.TYPE_PARAMETER) {
  79.664 -            String name = ((TypeParameterTree) t).getName().toString();
  79.665 -
  79.666 -            if (name.startsWith("$")) {
  79.667 -                return name;
  79.668 -            }
  79.669 -        }
  79.670 -
  79.671 -        return null;
  79.672 -    }
  79.673 -
  79.674 -    public static boolean isMultistatementWildcard(@NonNull CharSequence name) {
  79.675 -        return name.charAt(name.length() - 1) == '$';
  79.676 -    }
  79.677 -
  79.678 -    public static boolean isMultistatementWildcardTree(Tree tree) {
  79.679 -        CharSequence name = Utilities.getWildcardTreeName(tree);
  79.680 -
  79.681 -        return name != null && Utilities.isMultistatementWildcard(name);
  79.682 -    }
  79.683 -
  79.684 -    private static long inc;
  79.685 -
  79.686 -    public static Scope constructScope(CompilationInfo info, Map<String, TypeMirror> constraints) {
  79.687 -        return constructScope(info, constraints, Collections.<String>emptyList());
  79.688 -    }
  79.689 -
  79.690 -    public static Scope constructScope(CompilationInfo info, Map<String, TypeMirror> constraints, Iterable<? extends String> auxiliaryImports) {
  79.691 -        ScopeDescription desc = new ScopeDescription(constraints, auxiliaryImports);
  79.692 -        Scope result = (Scope) info.getCachedValue(desc);
  79.693 -
  79.694 -        if (result != null) return result;
  79.695 -        
  79.696 -        StringBuilder clazz = new StringBuilder();
  79.697 -
  79.698 -        clazz.append("package $;");
  79.699 -
  79.700 -        for (String i : auxiliaryImports) {
  79.701 -            clazz.append(i);
  79.702 -        }
  79.703 -
  79.704 -        long count = inc++;
  79.705 -
  79.706 -        clazz.append("public class $" + count + "{");
  79.707 -
  79.708 -        for (Entry<String, TypeMirror> e : constraints.entrySet()) {
  79.709 -            if (e.getValue() != null) {
  79.710 -                clazz.append("private ");
  79.711 -                clazz.append(e.getValue().toString()); //XXX
  79.712 -                clazz.append(" ");
  79.713 -                clazz.append(e.getKey());
  79.714 -                clazz.append(";\n");
  79.715 -            }
  79.716 -        }
  79.717 -
  79.718 -        clazz.append("private void test() {\n");
  79.719 -        clazz.append("}\n");
  79.720 -        clazz.append("}\n");
  79.721 -
  79.722 -        JavacTaskImpl jti = JavaSourceAccessor.getINSTANCE().getJavacTask(info);
  79.723 -        Context context = jti.getContext();
  79.724 -        JavaCompiler compiler = JavaCompiler.instance(context);
  79.725 -        Log log = Log.instance(context);
  79.726 -        NBResolve resolve = NBResolve.instance(context);
  79.727 -        Log.DiagnosticHandler discardHandler = new Log.DiscardDiagnosticHandler(compiler.log);
  79.728 -
  79.729 -        JavaFileObject jfo = FileObjects.memoryFileObject("$", "$", new File("/tmp/$" + count + ".java").toURI(), System.currentTimeMillis(), clazz.toString());
  79.730 -
  79.731 -        boolean oldSkipAPs = compiler.skipAnnotationProcessing;
  79.732 -
  79.733 -        try {
  79.734 -            compiler.skipAnnotationProcessing = true;
  79.735 -            resolve.disableAccessibilityChecks();
  79.736 -            
  79.737 -            JCCompilationUnit cut = compiler.parse(jfo);
  79.738 -
  79.739 -            compiler.enterTrees(com.sun.tools.javac.util.List.of(cut));
  79.740 -
  79.741 -            Todo todo = compiler.todo;
  79.742 -            ListBuffer<Env<AttrContext>> defer = new ListBuffer<>();
  79.743 -            
  79.744 -            while (todo.peek() != null) {
  79.745 -                Env<AttrContext> env = todo.remove();
  79.746 -
  79.747 -                if (env.toplevel == cut)
  79.748 -                    compiler.attribute(env);
  79.749 -                else
  79.750 -                    defer = defer.append(env);
  79.751 -            }
  79.752 -
  79.753 -            todo.addAll(defer);
  79.754 -
  79.755 -            Scope res = new ScannerImpl().scan(cut, info);
  79.756 -
  79.757 -            info.putCachedValue(desc, res, CacheClearPolicy.ON_SIGNATURE_CHANGE);
  79.758 -
  79.759 -            return res;
  79.760 -        } finally {
  79.761 -            resolve.restoreAccessbilityChecks();
  79.762 -            log.popDiagnosticHandler(discardHandler);
  79.763 -            compiler.skipAnnotationProcessing = oldSkipAPs;
  79.764 -        }
  79.765 -    }
  79.766 -
  79.767 -    private static final class ScannerImpl extends TreePathScanner<Scope, CompilationInfo> {
  79.768 -
  79.769 -        @Override
  79.770 -        public Scope visitBlock(BlockTree node, CompilationInfo p) {
  79.771 -            return p.getTrees().getScope(getCurrentPath());
  79.772 -        }
  79.773 -
  79.774 -        @Override
  79.775 -        public Scope visitMethod(MethodTree node, CompilationInfo p) {
  79.776 -            if (node.getReturnType() == null) {
  79.777 -                return null;
  79.778 -            }
  79.779 -            return super.visitMethod(node, p);
  79.780 -        }
  79.781 -
  79.782 -        @Override
  79.783 -        public Scope reduce(Scope r1, Scope r2) {
  79.784 -            return r1 != null ? r1 : r2;
  79.785 -        }
  79.786 -
  79.787 -    }
  79.788 -
  79.789 -    private static final class ScopeDescription {
  79.790 -        private final Map<String, TypeMirror> constraints;
  79.791 -        private final Iterable<? extends String> auxiliaryImports;
  79.792 -
  79.793 -        public ScopeDescription(Map<String, TypeMirror> constraints, Iterable<? extends String> auxiliaryImports) {
  79.794 -            this.constraints = constraints;
  79.795 -            this.auxiliaryImports = auxiliaryImports;
  79.796 -        }
  79.797 -
  79.798 -        @Override
  79.799 -        public boolean equals(Object obj) {
  79.800 -            if (obj == null) {
  79.801 -                return false;
  79.802 -            }
  79.803 -            if (getClass() != obj.getClass()) {
  79.804 -                return false;
  79.805 -            }
  79.806 -            final ScopeDescription other = (ScopeDescription) obj;
  79.807 -            if (this.constraints != other.constraints && (this.constraints == null || !this.constraints.equals(other.constraints))) {
  79.808 -                return false;
  79.809 -            }
  79.810 -            if (this.auxiliaryImports != other.auxiliaryImports && (this.auxiliaryImports == null || !this.auxiliaryImports.equals(other.auxiliaryImports))) {
  79.811 -                return false;
  79.812 -            }
  79.813 -            return true;
  79.814 -        }
  79.815 -
  79.816 -        @Override
  79.817 -        public int hashCode() {
  79.818 -            int hash = 7;
  79.819 -            hash = 47 * hash + (this.constraints != null ? this.constraints.hashCode() : 0);
  79.820 -            hash = 47 * hash + (this.auxiliaryImports != null ? this.auxiliaryImports.hashCode() : 0);
  79.821 -            return hash;
  79.822 -        }
  79.823 -
  79.824 -    }
  79.825 -
  79.826 -//    private static Scope constructScope2(CompilationInfo info, Map<String, TypeMirror> constraints) {
  79.827 -//        JavacScope s = (JavacScope) info.getTrees().getScope(new TreePath(info.getCompilationUnit()));
  79.828 -//        Env<AttrContext> env = s.getEnv();
  79.829 -//
  79.830 -//        env = env.dup(env.tree);
  79.831 -//
  79.832 -//        env.info.
  79.833 -//    }
  79.834 -
  79.835 -    public static String toHumanReadableTime(double d) {
  79.836 -        StringBuilder result = new StringBuilder();
  79.837 -        long inSeconds = (long) (d / 1000);
  79.838 -        int seconds = (int) (inSeconds % 60);
  79.839 -        long inMinutes = inSeconds / 60;
  79.840 -        int minutes = (int) (inMinutes % 60);
  79.841 -        long inHours = inMinutes / 60;
  79.842 -
  79.843 -        if (inHours > 0) {
  79.844 -            result.append(inHours);
  79.845 -            result.append("h");
  79.846 -        }
  79.847 -
  79.848 -        if (minutes > 0) {
  79.849 -            result.append(minutes);
  79.850 -            result.append("m");
  79.851 -        }
  79.852 -        
  79.853 -        result.append(seconds);
  79.854 -        result.append("s");
  79.855 -
  79.856 -        return result.toString();
  79.857 -    }
  79.858 -
  79.859 -    public static ClasspathInfo createUniversalCPInfo() {
  79.860 -        return Lookup.getDefault().lookup(SPI.class).createUniversalCPInfo();
  79.861 -    }
  79.862 -
  79.863 -    @SuppressWarnings("deprecation")
  79.864 -    public static void waitScanFinished() throws InterruptedException {
  79.865 -        SourceUtils.waitScanFinished();
  79.866 -    }
  79.867 -
  79.868 -    public static Set<? extends String> findSuppressedWarnings(CompilationInfo info, TreePath path) {
  79.869 -        //TODO: cache?
  79.870 -        Set<String> keys = new HashSet<String>();
  79.871 -
  79.872 -        while (path != null) {
  79.873 -            Tree leaf = path.getLeaf();
  79.874 -
  79.875 -            switch (leaf.getKind()) {
  79.876 -                case METHOD:
  79.877 -                    handleSuppressWarnings(info, path, ((MethodTree) leaf).getModifiers(), keys);
  79.878 -                    break;
  79.879 -                case CLASS:
  79.880 -                    handleSuppressWarnings(info, path, ((ClassTree) leaf).getModifiers(), keys);
  79.881 -                    break;
  79.882 -                case VARIABLE:
  79.883 -                    handleSuppressWarnings(info, path, ((VariableTree) leaf).getModifiers(), keys);
  79.884 -                    break;
  79.885 -            }
  79.886 -
  79.887 -            path = path.getParentPath();
  79.888 -        }
  79.889 -
  79.890 -        return Collections.unmodifiableSet(keys);
  79.891 -    }
  79.892 -
  79.893 -    private static void handleSuppressWarnings(CompilationInfo info, TreePath path, ModifiersTree modifiers, final Set<String> keys) {
  79.894 -        Element el = info.getTrees().getElement(path);
  79.895 -
  79.896 -        if (el == null) {
  79.897 -            return ;
  79.898 -        }
  79.899 -
  79.900 -        for (AnnotationMirror am : el.getAnnotationMirrors()) {
  79.901 -            Name fqn = ((TypeElement) am.getAnnotationType().asElement()).getQualifiedName();
  79.902 -            
  79.903 -            if (!fqn.contentEquals("java.lang.SuppressWarnings")) {
  79.904 -                continue;
  79.905 -            }
  79.906 -
  79.907 -            for (Entry<? extends ExecutableElement, ? extends AnnotationValue> e : am.getElementValues().entrySet()) {
  79.908 -                if (!e.getKey().getSimpleName().contentEquals("value"))
  79.909 -                    continue;
  79.910 -
  79.911 -                e.getValue().accept(new AnnotationValueVisitor<Void, Void>() {
  79.912 -                    public Void visit(AnnotationValue av, Void p) {
  79.913 -                        av.accept(this, p);
  79.914 -                        return null;
  79.915 -                    }
  79.916 -                    public Void visit(AnnotationValue av) {
  79.917 -                        av.accept(this, null);
  79.918 -                        return null;
  79.919 -                    }
  79.920 -                    public Void visitBoolean(boolean b, Void p) {
  79.921 -                        return null;
  79.922 -                    }
  79.923 -                    public Void visitByte(byte b, Void p) {
  79.924 -                        return null;
  79.925 -                    }
  79.926 -                    public Void visitChar(char c, Void p) {
  79.927 -                        return null;
  79.928 -                    }
  79.929 -                    public Void visitDouble(double d, Void p) {
  79.930 -                        return null;
  79.931 -                    }
  79.932 -                    public Void visitFloat(float f, Void p) {
  79.933 -                        return null;
  79.934 -                    }
  79.935 -                    public Void visitInt(int i, Void p) {
  79.936 -                        return null;
  79.937 -                    }
  79.938 -                    public Void visitLong(long i, Void p) {
  79.939 -                        return null;
  79.940 -                    }
  79.941 -                    public Void visitShort(short s, Void p) {
  79.942 -                        return null;
  79.943 -                    }
  79.944 -                    public Void visitString(String s, Void p) {
  79.945 -                        keys.add(s);
  79.946 -                        return null;
  79.947 -                    }
  79.948 -                    public Void visitType(TypeMirror t, Void p) {
  79.949 -                        return null;
  79.950 -                    }
  79.951 -                    public Void visitEnumConstant(VariableElement c, Void p) {
  79.952 -                        return null;
  79.953 -                    }
  79.954 -                    public Void visitAnnotation(AnnotationMirror a, Void p) {
  79.955 -                        return null;
  79.956 -                    }
  79.957 -                    public Void visitArray(List<? extends AnnotationValue> vals, Void p) {
  79.958 -                        for (AnnotationValue av : vals) {
  79.959 -                            av.accept(this, p);
  79.960 -                        }
  79.961 -                        return null;
  79.962 -                    }
  79.963 -                    public Void visitUnknown(AnnotationValue av, Void p) {
  79.964 -                        return null;
  79.965 -                    }
  79.966 -                }, null);
  79.967 -            }
  79.968 -        }
  79.969 -    }
  79.970 -
  79.971 -    public static Tree generalizePattern(CompilationInfo info, TreePath original) {
  79.972 -        return generalizePattern(JavaSourceAccessor.getINSTANCE().getJavacTask(info), original);
  79.973 -    }
  79.974 -
  79.975 -    public static Tree generalizePattern(CompilationTask task, TreePath original) {
  79.976 -        JavacTaskImpl jti = (JavacTaskImpl) task;
  79.977 -        com.sun.tools.javac.util.Context c = jti.getContext();
  79.978 -        TreeFactory make = TreeFactory.instance(c);
  79.979 -        Trees javacTrees = Trees.instance(task);
  79.980 -        GeneralizePattern gp = new GeneralizePattern(javacTrees, make);
  79.981 -
  79.982 -        gp.scan(original, null);
  79.983 -
  79.984 -        GeneralizePatternITT itt = new GeneralizePatternITT(gp.tree2Variable);
  79.985 -
  79.986 -        itt.attach(c, new NoImports(c), null);
  79.987 -
  79.988 -        return itt.translate(original.getLeaf());
  79.989 -    }
  79.990 -
  79.991 -    public static Tree generalizePattern(CompilationInfo info, TreePath original, int firstStatement, int lastStatement) {
  79.992 -        JavacTaskImpl jti = JavaSourceAccessor.getINSTANCE().getJavacTask(info);
  79.993 -        com.sun.tools.javac.util.Context c = jti.getContext();
  79.994 -        TreeFactory make = TreeFactory.instance(c);
  79.995 -        Tree translated = Utilities.generalizePattern(jti, original);
  79.996 -
  79.997 -        assert translated.getKind() == Kind.BLOCK;
  79.998 -
  79.999 -        List<StatementTree> newStatements = new LinkedList<StatementTree>();
 79.1000 -        BlockTree block = (BlockTree) translated;
 79.1001 -
 79.1002 -        if (firstStatement != lastStatement) {
 79.1003 -            newStatements.add(make.ExpressionStatement(make.Identifier("$s0$")));
 79.1004 -            newStatements.addAll(block.getStatements().subList(firstStatement, lastStatement + 1));
 79.1005 -            newStatements.add(make.ExpressionStatement(make.Identifier("$s1$")));
 79.1006 -
 79.1007 -            translated = make.Block(newStatements, block.isStatic());
 79.1008 -        } else {
 79.1009 -            translated = block.getStatements().get(firstStatement);
 79.1010 -        }
 79.1011 -
 79.1012 -        return translated;
 79.1013 -    }
 79.1014 -
 79.1015 -    public interface SPI {
 79.1016 -        public ClasspathInfo createUniversalCPInfo();
 79.1017 -    }
 79.1018 -
 79.1019 -    @ServiceProvider(service=SPI.class)
 79.1020 -    public static final class NbSPIImpl implements SPI {
 79.1021 -
 79.1022 -        public ClasspathInfo createUniversalCPInfo() {
 79.1023 -            JavaPlatform select = JavaPlatform.getDefault();
 79.1024 -
 79.1025 -            if (select.getSpecification().getVersion() != null) {
 79.1026 -                for (JavaPlatform p : JavaPlatformManager.getDefault().getInstalledPlatforms()) {
 79.1027 -                    if (!"j2se".equals(p.getSpecification().getName()) || p.getSpecification().getVersion() == null) continue;
 79.1028 -                    if (p.getSpecification().getVersion().compareTo(select.getSpecification().getVersion()) > 0) {
 79.1029 -                        select = p;
 79.1030 -                    }
 79.1031 -                }
 79.1032 -            }
 79.1033 -
 79.1034 -            return ClasspathInfo.create(select.getBootstrapLibraries(), ClassPath.EMPTY, ClassPath.EMPTY);
 79.1035 -        }
 79.1036 -
 79.1037 -    }
 79.1038 -    
 79.1039 -    private static final class GeneralizePattern extends TreePathScanner<Void, Void> {
 79.1040 -
 79.1041 -        public final Map<Tree, Tree> tree2Variable = new HashMap<Tree, Tree>();
 79.1042 -        private final Map<Element, String> element2Variable = new HashMap<Element, String>();
 79.1043 -        private final Trees javacTrees;
 79.1044 -        private final TreeFactory make;
 79.1045 -
 79.1046 -        private int currentVariableIndex = 0;
 79.1047 -
 79.1048 -        public GeneralizePattern(Trees javacTrees, TreeFactory make) {
 79.1049 -            this.javacTrees = javacTrees;
 79.1050 -            this.make = make;
 79.1051 -        }
 79.1052 -
 79.1053 -        private @NonNull String getVariable(@NonNull Element el) {
 79.1054 -            String var = element2Variable.get(el);
 79.1055 -
 79.1056 -            if (var == null) {
 79.1057 -                element2Variable.put(el, var = "$" + currentVariableIndex++);
 79.1058 -            }
 79.1059 -
 79.1060 -            return var;
 79.1061 -        }
 79.1062 -
 79.1063 -        private boolean shouldBeGeneralized(@NonNull Element el) {
 79.1064 -            if (el.getModifiers().contains(Modifier.PRIVATE)) {
 79.1065 -                return true;
 79.1066 -            }
 79.1067 -
 79.1068 -            switch (el.getKind()) {
 79.1069 -                case LOCAL_VARIABLE:
 79.1070 -                case EXCEPTION_PARAMETER:
 79.1071 -                case PARAMETER:
 79.1072 -                    return true;
 79.1073 -            }
 79.1074 -
 79.1075 -            return false;
 79.1076 -        }
 79.1077 -
 79.1078 -        @Override
 79.1079 -        public Void visitIdentifier(IdentifierTree node, Void p) {
 79.1080 -            Element e = javacTrees.getElement(getCurrentPath());
 79.1081 -
 79.1082 -            if (e != null && shouldBeGeneralized(e)) {
 79.1083 -                tree2Variable.put(node, make.Identifier(getVariable(e)));
 79.1084 -            }
 79.1085 -
 79.1086 -            return super.visitIdentifier(node, p);
 79.1087 -        }
 79.1088 -
 79.1089 -        @Override
 79.1090 -        public Void visitVariable(VariableTree node, Void p) {
 79.1091 -            Element e = javacTrees.getElement(getCurrentPath());
 79.1092 -
 79.1093 -            if (e != null && shouldBeGeneralized(e)) {
 79.1094 -                VariableTree nue = make.Variable(node.getModifiers(), getVariable(e), node.getType(), node.getInitializer());
 79.1095 -
 79.1096 -                tree2Variable.put(node, nue);
 79.1097 -            }
 79.1098 -
 79.1099 -            return super.visitVariable(node, p);
 79.1100 -        }
 79.1101 -
 79.1102 -        @Override
 79.1103 -        public Void visitNewClass(NewClassTree node, Void p) {
 79.1104 -            //XXX:
 79.1105 -            if (node.getEnclosingExpression() != null) {
 79.1106 -                tree2Variable.put(node, make.Identifier("$" + currentVariableIndex++));
 79.1107 -                return null;
 79.1108 -            }
 79.1109 -
 79.1110 -            NewClassTree nue = make.NewClass(node.getEnclosingExpression(), Collections.<ExpressionTree>singletonList(make.Identifier("$" + currentVariableIndex++ + "$")), make.Identifier("$" + currentVariableIndex++), Collections.<ExpressionTree>singletonList(make.Identifier("$" + currentVariableIndex++ + "$")), null);
 79.1111 -
 79.1112 -            tree2Variable.put(node, nue);
 79.1113 -
 79.1114 -            return null;
 79.1115 -        }
 79.1116 -
 79.1117 -    }
 79.1118 -
 79.1119 -    private static final class GeneralizePatternITT extends ImmutableTreeTranslator {
 79.1120 -
 79.1121 -        private final Map<Tree, Tree> tree2Variable;
 79.1122 -
 79.1123 -        public GeneralizePatternITT(Map<Tree, Tree> tree2Variable) {
 79.1124 -            super(null);
 79.1125 -            this.tree2Variable = tree2Variable;
 79.1126 -        }
 79.1127 -
 79.1128 -        @Override
 79.1129 -        public Tree translate(Tree tree) {
 79.1130 -            Tree var = tree2Variable.remove(tree);
 79.1131 -
 79.1132 -            if (var != null) {
 79.1133 -                return super.translate(var);
 79.1134 -            }
 79.1135 -
 79.1136 -            return super.translate(tree);
 79.1137 -        }
 79.1138 -
 79.1139 -    }
 79.1140 -
 79.1141 -    private static final class NoImports extends ImportAnalysis2 {
 79.1142 -
 79.1143 -        public NoImports(Context env) {
 79.1144 -            super(env);
 79.1145 -        }
 79.1146 -
 79.1147 -        @Override
 79.1148 -        public void classEntered(ClassTree clazz) {}
 79.1149 -
 79.1150 -        @Override
 79.1151 -        public void enterVisibleThroughClasses(ClassTree clazz) {}
 79.1152 -
 79.1153 -        @Override
 79.1154 -        public void classLeft() {}
 79.1155 -
 79.1156 -        @Override
 79.1157 -        public ExpressionTree resolveImport(MemberSelectTree orig, Element element) {
 79.1158 -            return orig;
 79.1159 -        }
 79.1160 -
 79.1161 -        @Override
 79.1162 -        public void setCompilationUnit(CompilationUnitTree cut) {}
 79.1163 -
 79.1164 -        @Override
 79.1165 -        public void setImports(List<? extends ImportTree> importsToAdd) {}
 79.1166 -
 79.1167 -        @Override
 79.1168 -        public Set<? extends Element> getImports() {
 79.1169 -            return Collections.emptySet();
 79.1170 -        }
 79.1171 -
 79.1172 -        @Override
 79.1173 -        public void setPackage(ExpressionTree packageNameTree) {}
 79.1174 -
 79.1175 -    }
 79.1176 -
 79.1177 -    public static long patternValue(Tree pattern) {
 79.1178 -        class VisitorImpl extends TreeScanner<Void, Void> {
 79.1179 -            private int value;
 79.1180 -            @Override
 79.1181 -            public Void scan(Tree node, Void p) {
 79.1182 -                if (node != null) value++;
 79.1183 -                return super.scan(node, p);
 79.1184 -            }
 79.1185 -            @Override
 79.1186 -            public Void visitIdentifier(IdentifierTree node, Void p) {
 79.1187 -                if (node.getName().toString().startsWith("$")) value--;
 79.1188 -                
 79.1189 -                return super.visitIdentifier(node, p);
 79.1190 -            }
 79.1191 -            @Override
 79.1192 -            public Void visitNewClass(NewClassTree node, Void p) {
 79.1193 -                return null;
 79.1194 -            }
 79.1195 -        }
 79.1196 -
 79.1197 -        VisitorImpl vi = new VisitorImpl();
 79.1198 -
 79.1199 -        vi.scan(pattern, null);
 79.1200 -
 79.1201 -        return vi.value;
 79.1202 -    }
 79.1203 -
 79.1204 -    public static boolean containsMultistatementTrees(List<? extends Tree> statements) {
 79.1205 -        for (Tree t : statements) {
 79.1206 -            if (Utilities.isMultistatementWildcardTree(t)) {
 79.1207 -                return true;
 79.1208 -            }
 79.1209 -        }
 79.1210 -
 79.1211 -        return false;
 79.1212 -    }
 79.1213 -
 79.1214 -    public static boolean isJavadocSupported(CompilationInfo info) {
 79.1215 -        Context c = JavaSourceAccessor.getINSTANCE().getJavacTask(info).getContext();
 79.1216 -
 79.1217 -        try {
 79.1218 -        return c.get(Log.logKey) instanceof Messager;
 79.1219 -        } catch (NoClassDefFoundError e) {
 79.1220 -            return false;
 79.1221 -        }
 79.1222 -    }
 79.1223 -
 79.1224 -    private static class JackpotJavacParser extends NBJavacParser {
 79.1225 -
 79.1226 -        private final Context ctx;
 79.1227 -        private final com.sun.tools.javac.util.Name dollar;
 79.1228 -        public JackpotJavacParser(Context ctx, NBParserFactory fac,
 79.1229 -                         Lexer S,
 79.1230 -                         boolean keepDocComments,
 79.1231 -                         boolean keepLineMap,
 79.1232 -                         CancelService cancelService,
 79.1233 -                         Names names) {
 79.1234 -            super(fac, S, keepDocComments, keepLineMap, true, cancelService);
 79.1235 -            this.ctx = ctx;
 79.1236 -            this.dollar = names.fromString("$");
 79.1237 -        }
 79.1238 -
 79.1239 -        @Override
 79.1240 -        protected JCModifiers modifiersOpt(JCModifiers partial) {
 79.1241 -            if (token.kind == TokenKind.IDENTIFIER) {
 79.1242 -                String ident = token.name().toString();
 79.1243 -
 79.1244 -                if (Utilities.isMultistatementWildcard(ident)) {
 79.1245 -                    com.sun.tools.javac.util.Name name = token.name();
 79.1246 -
 79.1247 -                    nextToken();
 79.1248 -                    
 79.1249 -                    JCModifiers result = super.modifiersOpt(partial);
 79.1250 -                    
 79.1251 -                    result.annotations = result.annotations.prepend(new AnnotationWildcard(name, F.Ident(name)));
 79.1252 -
 79.1253 -                    return result;
 79.1254 -                }
 79.1255 -            }
 79.1256 -
 79.1257 -            return super.modifiersOpt(partial);
 79.1258 -        }
 79.1259 -
 79.1260 -        @Override
 79.1261 -        public JCVariableDecl formalParameter(boolean lambdaParam) {
 79.1262 -            if (token.kind == TokenKind.IDENTIFIER) {
 79.1263 -                if (token.name().startsWith(dollar)) {
 79.1264 -                    com.sun.tools.javac.util.Name name = token.name();
 79.1265 -
 79.1266 -                    Token peeked = S.token(1);
 79.1267 -
 79.1268 -                    if (peeked.kind == TokenKind.COMMA || peeked.kind == TokenKind.RPAREN) {
 79.1269 -                        nextToken();
 79.1270 -                        return new VariableWildcard(ctx, name, F.Ident(name));
 79.1271 -                    }
 79.1272 -                }
 79.1273 -            }
 79.1274 -
 79.1275 -            return super.formalParameter(lambdaParam);
 79.1276 -        }
 79.1277 -
 79.1278 -        @Override
 79.1279 -        protected JCVariableDecl implicitParameter() {
 79.1280 -            if (token.kind == TokenKind.IDENTIFIER) {
 79.1281 -                if (token.name().startsWith(dollar)) {
 79.1282 -                    com.sun.tools.javac.util.Name name = token.name();
 79.1283 -
 79.1284 -                    Token peeked = S.token(1);
 79.1285 -
 79.1286 -                    if (peeked.kind == TokenKind.COMMA || peeked.kind == TokenKind.RPAREN) {
 79.1287 -                        nextToken();
 79.1288 -                        return new VariableWildcard(ctx, name, F.Ident(name));
 79.1289 -                    }
 79.1290 -                }
 79.1291 -            }
 79.1292 -
 79.1293 -            return super.implicitParameter();
 79.1294 -        }
 79.1295 -        
 79.1296 -        @Override
 79.1297 -        protected JCCatch catchClause() {
 79.1298 -            if (token.kind == TokenKind.CATCH) {
 79.1299 -                Token peeked = S.token(1);
 79.1300 -                
 79.1301 -                if (   peeked.kind == TokenKind.IDENTIFIER
 79.1302 -                    && Utilities.isMultistatementWildcard(peeked.name().toString())) {
 79.1303 -                    accept(TokenKind.CATCH);
 79.1304 -                    
 79.1305 -                    com.sun.tools.javac.util.Name name = token.name();
 79.1306 -
 79.1307 -                    accept(TokenKind.IDENTIFIER);
 79.1308 -
 79.1309 -                    return new CatchWildcard(ctx, name, F.Ident(name));
 79.1310 -                } else {
 79.1311 -                    nextToken();
 79.1312 -                }
 79.1313 -            }
 79.1314 -            return super.catchClause();
 79.1315 -        }
 79.1316 -
 79.1317 -        @Override
 79.1318 -        public com.sun.tools.javac.util.List<JCTree> classOrInterfaceBodyDeclaration(com.sun.tools.javac.util.Name className, boolean isInterface) {
 79.1319 -            if (token.kind == TokenKind.IDENTIFIER) {
 79.1320 -                if (token.name().startsWith(dollar)) {
 79.1321 -                    com.sun.tools.javac.util.Name name = token.name();
 79.1322 -
 79.1323 -                    Token peeked = S.token(1);
 79.1324 -
 79.1325 -                    if (peeked.kind == TokenKind.SEMI) {
 79.1326 -                        nextToken();
 79.1327 -                        nextToken();
 79.1328 -                        
 79.1329 -                        return com.sun.tools.javac.util.List.<JCTree>of(F.Ident(name));
 79.1330 -                    }
 79.1331 -                }
 79.1332 -            }
 79.1333 -            return super.classOrInterfaceBodyDeclaration(className, isInterface);
 79.1334 -        }
 79.1335 -        
 79.1336 -        @Override
 79.1337 -        protected JCExpression checkExprStat(JCExpression t) {
 79.1338 -            if (t.getTag() == JCTree.Tag.IDENT) {
 79.1339 -                if (((IdentifierTree) t).getName().toString().startsWith("$")) {
 79.1340 -                    return t;
 79.1341 -                }
 79.1342 -            }
 79.1343 -            return super.checkExprStat(t);
 79.1344 -        }
 79.1345 -
 79.1346 -        @Override
 79.1347 -        protected JCCase switchBlockStatementGroup() {
 79.1348 -            if (token.kind == TokenKind.CASE) {
 79.1349 -                Token peeked = S.token(1);
 79.1350 -
 79.1351 -                if (peeked.kind == TokenKind.IDENTIFIER) {
 79.1352 -                    String ident = peeked.name().toString();
 79.1353 -
 79.1354 -                    if (ident.startsWith("$") && ident.endsWith("$")) {
 79.1355 -                        nextToken();
 79.1356 -                        
 79.1357 -                        int pos = token.pos;
 79.1358 -                        com.sun.tools.javac.util.Name name = token.name();
 79.1359 -
 79.1360 -                        nextToken();
 79.1361 -
 79.1362 -                        if (token.kind == TokenKind.SEMI) {
 79.1363 -                            nextToken();
 79.1364 -                        }
 79.1365 -
 79.1366 -                        return new JackpotTrees.CaseWildcard(ctx, name, F.at(pos).Ident(name));
 79.1367 -                    }
 79.1368 -                }
 79.1369 -            }
 79.1370 -
 79.1371 -            return super.switchBlockStatementGroup();
 79.1372 -        }
 79.1373 -
 79.1374 -
 79.1375 -        @Override
 79.1376 -        protected JCTree resource() {
 79.1377 -            if (token.kind == TokenKind.IDENTIFIER && token.name().startsWith(dollar)) {
 79.1378 -                Token peeked = S.token(1);
 79.1379 -
 79.1380 -                if (peeked.kind == TokenKind.SEMI || peeked.kind == TokenKind.RPAREN) {
 79.1381 -                    int pos = token.pos;
 79.1382 -                    com.sun.tools.javac.util.Name name = token.name();
 79.1383 -
 79.1384 -                    nextToken();
 79.1385 -
 79.1386 -                    return F.at(pos).Ident(name);
 79.1387 -                }
 79.1388 -            }
 79.1389 -            return super.resource();
 79.1390 -        }
 79.1391 -
 79.1392 -    }
 79.1393 -
 79.1394 -    private static final class DummyJFO extends SimpleJavaFileObject {
 79.1395 -        private DummyJFO() {
 79.1396 -            super(URI.create("dummy.java"), JavaFileObject.Kind.SOURCE);
 79.1397 -        }
 79.1398 -        @Override
 79.1399 -        public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
 79.1400 -            return "";
 79.1401 -        }
 79.1402 -    };
 79.1403 -
 79.1404 -    /**
 79.1405 -     * Only for members (i.e. generated constructor):
 79.1406 -     */
 79.1407 -    public static List<? extends Tree> filterHidden(TreePath basePath, Iterable<? extends Tree> members) {
 79.1408 -        List<Tree> result = new LinkedList<Tree>();
 79.1409 -
 79.1410 -        for (Tree t : members) {
 79.1411 -            if (!isSynthetic(basePath != null ? basePath.getCompilationUnit() : null, t)) {
 79.1412 -                result.add(t);
 79.1413 -            }
 79.1414 -        }
 79.1415 -
 79.1416 -        return result;
 79.1417 -    }
 79.1418 -
 79.1419 -    private static boolean isSynthetic(CompilationUnitTree cut, Tree leaf) throws NullPointerException {
 79.1420 -        JCTree tree = (JCTree) leaf;
 79.1421 -
 79.1422 -        if (tree.pos == (-1))
 79.1423 -            return true;
 79.1424 -
 79.1425 -        if (leaf.getKind() == Kind.METHOD) {
 79.1426 -            //check for synthetic constructor:
 79.1427 -            return (((JCMethodDecl)leaf).mods.flags & Flags.GENERATEDCONSTR) != 0L;
 79.1428 -        }
 79.1429 -
 79.1430 -        //check for synthetic superconstructor call:
 79.1431 -        if (cut != null && leaf.getKind() == Kind.EXPRESSION_STATEMENT) {
 79.1432 -            ExpressionStatementTree est = (ExpressionStatementTree) leaf;
 79.1433 -
 79.1434 -            if (est.getExpression().getKind() == Kind.METHOD_INVOCATION) {
 79.1435 -                MethodInvocationTree mit = (MethodInvocationTree) est.getExpression();
 79.1436 -
 79.1437 -                if (mit.getMethodSelect().getKind() == Kind.IDENTIFIER) {
 79.1438 -                    IdentifierTree it = (IdentifierTree) mit.getMethodSelect();
 79.1439 -
 79.1440 -                    if ("super".equals(it.getName().toString())) {
 79.1441 -                        return ((JCCompilationUnit) cut).endPositions.getEndPos(tree) == (-1);
 79.1442 -                    }
 79.1443 -                }
 79.1444 -            }
 79.1445 -        }
 79.1446 -
 79.1447 -        return false;
 79.1448 -    }
 79.1449 -
 79.1450 -    public static boolean isFakeBlock(Tree t) {
 79.1451 -        return t instanceof FakeBlock;
 79.1452 -    }
 79.1453 -
 79.1454 -    public static boolean isFakeClass(Tree t) {
 79.1455 -        if (!(t instanceof ClassTree)) {
 79.1456 -            return false;
 79.1457 -        }
 79.1458 -
 79.1459 -        ClassTree ct = (ClassTree) t;
 79.1460 -
 79.1461 -        if (ct.getMembers().isEmpty()) {
 79.1462 -            return false;
 79.1463 -        }
 79.1464 -
 79.1465 -        CharSequence wildcardTreeName = Utilities.getWildcardTreeName(ct.getMembers().get(0));
 79.1466 -
 79.1467 -        if (wildcardTreeName == null) {
 79.1468 -            return false;
 79.1469 -        }
 79.1470 -
 79.1471 -        return wildcardTreeName.toString().startsWith("$$");
 79.1472 -    }
 79.1473 -
 79.1474 -    private static final class OffsetSourcePositions implements SourcePositions {
 79.1475 -
 79.1476 -        private final SourcePositions delegate;
 79.1477 -        private final long offset;
 79.1478 -
 79.1479 -        public OffsetSourcePositions(SourcePositions delegate, long offset) {
 79.1480 -            this.delegate = delegate;
 79.1481 -            this.offset = offset;
 79.1482 -        }
 79.1483 -
 79.1484 -        public long getStartPosition(CompilationUnitTree cut, Tree tree) {
 79.1485 -            return delegate.getStartPosition(cut, tree) + offset;
 79.1486 -        }
 79.1487 -
 79.1488 -        public long getEndPosition(CompilationUnitTree cut, Tree tree) {
 79.1489 -            return delegate.getEndPosition(cut, tree) + offset;
 79.1490 -        }
 79.1491 -
 79.1492 -    }
 79.1493 -
 79.1494 -    private static final class OffsetDiagnostic<S> implements Diagnostic<S> {
 79.1495 -        private final Diagnostic<? extends S> delegate;
 79.1496 -        private final long offset;
 79.1497 -
 79.1498 -        public OffsetDiagnostic(Diagnostic<? extends S> delegate, long offset) {
 79.1499 -            this.delegate = delegate;
 79.1500 -            this.offset = offset;
 79.1501 -        }
 79.1502 -
 79.1503 -        public Diagnostic.Kind getKind() {
 79.1504 -            return delegate.getKind();
 79.1505 -        }
 79.1506 -
 79.1507 -        public S getSource() {
 79.1508 -            return delegate.getSource();
 79.1509 -        }
 79.1510 -
 79.1511 -        public long getPosition() {
 79.1512 -            return delegate.getPosition() + offset;
 79.1513 -        }
 79.1514 -
 79.1515 -        public long getStartPosition() {
 79.1516 -            return delegate.getStartPosition() + offset;
 79.1517 -        }
 79.1518 -
 79.1519 -        public long getEndPosition() {
 79.1520 -            return delegate.getEndPosition() + offset;
 79.1521 -        }
 79.1522 -
 79.1523 -        public long getLineNumber() {
 79.1524 -            throw new UnsupportedOperationException("Not supported yet.");
 79.1525 -        }
 79.1526 -
 79.1527 -        public long getColumnNumber() {
 79.1528 -            throw new UnsupportedOperationException("Not supported yet.");
 79.1529 -        }
 79.1530 -
 79.1531 -        public String getCode() {
 79.1532 -            return delegate.getCode();
 79.1533 -        }
 79.1534 -
 79.1535 -        public String getMessage(Locale locale) {
 79.1536 -            return delegate.getMessage(locale);
 79.1537 -        }
 79.1538 -
 79.1539 -    }
 79.1540 -
 79.1541 -    private static class ParserSourcePositions implements SourcePositions {
 79.1542 -
 79.1543 -        private JavacParser parser;
 79.1544 -
 79.1545 -        private ParserSourcePositions(JavacParser parser) {
 79.1546 -            this.parser = parser;
 79.1547 -        }
 79.1548 -
 79.1549 -        public long getStartPosition(CompilationUnitTree file, Tree tree) {
 79.1550 -            return parser.getStartPos((JCTree)tree);
 79.1551 -        }
 79.1552 -
 79.1553 -        public long getEndPosition(CompilationUnitTree file, Tree tree) {
 79.1554 -            return parser.getEndPos((JCTree)tree);
 79.1555 -        }
 79.1556 -    }
 79.1557 -}
    80.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/batch/BatchSearch.java	Sun Oct 16 08:01:27 2016 +0200
    80.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    80.3 @@ -1,714 +0,0 @@
    80.4 -/*
    80.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    80.6 - *
    80.7 - * Copyright 2009-2011 Oracle and/or its affiliates. All rights reserved.
    80.8 - *
    80.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   80.10 - * Other names may be trademarks of their respective owners.
   80.11 - *
   80.12 - * The contents of this file are subject to the terms of either the GNU
   80.13 - * General Public License Version 2 only ("GPL") or the Common
   80.14 - * Development and Distribution License("CDDL") (collectively, the
   80.15 - * "License"). You may not use this file except in compliance with the
   80.16 - * License. You can obtain a copy of the License at
   80.17 - * http://www.netbeans.org/cddl-gplv2.html
   80.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   80.19 - * specific language governing permissions and limitations under the
   80.20 - * License.  When distributing the software, include this License Header
   80.21 - * Notice in each file and include the License file at
   80.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   80.23 - * particular file as subject to the "Classpath" exception as provided
   80.24 - * by Oracle in the GPL Version 2 section of the License file that
   80.25 - * accompanied this code. If applicable, add the following below the
   80.26 - * License Header, with the fields enclosed by brackets [] replaced by
   80.27 - * your own identifying information:
   80.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   80.29 - *
   80.30 - * If you wish your version of this file to be governed by only the CDDL
   80.31 - * or only the GPL Version 2, indicate your decision by adding
   80.32 - * "[Contributor] elects to include this software in this distribution
   80.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   80.34 - * single choice of license, a recipient has the option to distribute
   80.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   80.36 - * to extend the choice of license to its licensees as provided above.
   80.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   80.38 - * Version 2 license, then the option applies only if the new code is
   80.39 - * made subject to such option by the copyright holder.
   80.40 - *
   80.41 - * Contributor(s):
   80.42 - *
   80.43 - * Portions Copyrighted 2009-2011 Sun Microsystems, Inc.
   80.44 - */
   80.45 -package org.netbeans.modules.java.hints.spiimpl.batch;
   80.46 -
   80.47 -import org.netbeans.spi.java.hints.HintContext.MessageKind;
   80.48 -import org.netbeans.modules.java.hints.providers.spi.HintDescription;
   80.49 -import com.sun.source.tree.Tree;
   80.50 -import com.sun.source.util.TreePath;
   80.51 -import java.io.IOException;
   80.52 -import java.io.OutputStreamWriter;
   80.53 -import java.io.Writer;
   80.54 -import java.nio.ByteBuffer;
   80.55 -import java.util.ArrayList;
   80.56 -import java.util.Collection;
   80.57 -import java.util.Collections;
   80.58 -import java.util.HashMap;
   80.59 -import java.util.HashSet;
   80.60 -import java.util.LinkedList;
   80.61 -import java.util.List;
   80.62 -import java.util.Map;
   80.63 -import java.util.Map.Entry;
   80.64 -import java.util.Set;
   80.65 -import java.util.concurrent.Callable;
   80.66 -import java.util.concurrent.atomic.AtomicBoolean;
   80.67 -import java.util.concurrent.atomic.AtomicInteger;
   80.68 -import java.util.concurrent.atomic.AtomicReference;
   80.69 -import java.util.logging.Level;
   80.70 -import java.util.logging.Logger;
   80.71 -import org.netbeans.api.annotations.common.NonNull;
   80.72 -import org.netbeans.api.annotations.common.NullAllowed;
   80.73 -import org.netbeans.api.fileinfo.NonRecursiveFolder;
   80.74 -import org.netbeans.api.java.classpath.ClassPath;
   80.75 -import org.netbeans.api.java.classpath.GlobalPathRegistry;
   80.76 -import org.netbeans.api.java.source.ClasspathInfo;
   80.77 -import org.netbeans.api.java.source.ClasspathInfo.PathKind;
   80.78 -import org.netbeans.api.java.source.CompilationController;
   80.79 -import org.netbeans.api.java.source.CompilationInfo;
   80.80 -import org.netbeans.api.java.source.JavaSource;
   80.81 -import org.netbeans.api.java.source.JavaSource.Phase;
   80.82 -import org.netbeans.api.java.source.Task;
   80.83 -import org.netbeans.api.queries.FileEncodingQuery;
   80.84 -import org.netbeans.modules.java.hints.spiimpl.MessageImpl;
   80.85 -import org.netbeans.modules.java.hints.spiimpl.Utilities;
   80.86 -import org.netbeans.modules.java.hints.spiimpl.hints.HintsInvoker;
   80.87 -import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch;
   80.88 -import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch.BulkPattern;
   80.89 -import org.netbeans.modules.java.hints.providers.spi.HintDescription.AdditionalQueryConstraints;
   80.90 -import org.netbeans.modules.java.hints.providers.spi.Trigger.PatternDescription;
   80.91 -import org.netbeans.spi.editor.hints.ErrorDescription;
   80.92 -import org.netbeans.api.java.source.matching.Matcher;
   80.93 -import org.netbeans.api.java.source.matching.Pattern;
   80.94 -import org.netbeans.modules.java.hints.providers.spi.Trigger.DecisionTrigger;
   80.95 -import org.netbeans.modules.java.hints.spiimpl.SPIAccessor;
   80.96 -import org.netbeans.modules.java.hints.spiimpl.hints.GlobalProcessingContext;
   80.97 -import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings;
   80.98 -import org.netbeans.spi.java.hints.Decision;
   80.99 -import org.netbeans.spi.java.hints.HintContext;
  80.100 -import org.openide.filesystems.FileObject;
  80.101 -import org.openide.filesystems.FileUtil;
  80.102 -import org.openide.util.Exceptions;
  80.103 -
  80.104 -/**
  80.105 - *
  80.106 - * @author lahvac
  80.107 - */
  80.108 -public class BatchSearch {
  80.109 -
  80.110 -    private static final Logger LOG = Logger.getLogger(BatchSearch.class.getName());
  80.111 -
  80.112 -    public static BatchResult findOccurrences(Iterable<? extends HintDescription> patterns, Scope scope) {
  80.113 -        return findOccurrences(patterns, scope, new ProgressHandleWrapper(null), HintsSettings.getGlobalSettings());
  80.114 -    }
  80.115 -
  80.116 -    public static BatchResult findOccurrences(final Iterable<? extends HintDescription> patterns, final Scope scope, final ProgressHandleWrapper progress, @NullAllowed HintsSettings settingsProvider) {
  80.117 -        return findOccurrencesLocal(patterns, scope.getIndexMapper(patterns), scope.getTodo(), progress, settingsProvider);
  80.118 -    }
  80.119 -
  80.120 -    private static BatchResult findOccurrencesLocal(final Iterable<? extends HintDescription> patterns, final MapIndices indexMapper, final Collection<? extends Folder> todo, final ProgressHandleWrapper progress, final @NullAllowed HintsSettings settingsProvider) {
  80.121 -        final BatchResult[] result = new BatchResult[1];
  80.122 -
  80.123 -        try {
  80.124 -            JavaSource.create(Utilities.createUniversalCPInfo()).runUserActionTask(new Task<CompilationController>() {
  80.125 -                public void run(CompilationController parameter) throws Exception {
  80.126 -                    result[0] = findOccurrencesLocalImpl(parameter, patterns, indexMapper, todo, progress, settingsProvider);
  80.127 -                }
  80.128 -            }, true);
  80.129 -        } catch (IOException ex) {
  80.130 -            throw new IllegalStateException(ex);
  80.131 -        }
  80.132 -
  80.133 -        return result[0];
  80.134 -    }
  80.135 -    
  80.136 -    private static BatchResult findOccurrencesLocalImpl(final CompilationInfo info, final Iterable<? extends HintDescription> patterns, MapIndices indexMapper, Collection<? extends Folder> todo, ProgressHandleWrapper progress, HintsSettings settingsProvider) {
  80.137 -        boolean hasKindPatterns = false;
  80.138 -
  80.139 -        for (HintDescription pattern : patterns) {
  80.140 -            if (!(pattern.getTrigger() instanceof PatternDescription)) {
  80.141 -                hasKindPatterns = true;
  80.142 -                break;
  80.143 -            }
  80.144 -        }
  80.145 -
  80.146 -        final Callable<BulkPattern> bulkPattern = hasKindPatterns ? null : new Callable<BulkPattern>() {
  80.147 -            private final AtomicReference<BulkPattern> pattern = new AtomicReference<BulkPattern>();
  80.148 -            public BulkPattern call() {
  80.149 -                if (pattern.get() == null) {
  80.150 -                    pattern.set(preparePattern(patterns, info));
  80.151 -                }
  80.152 -
  80.153 -                return pattern.get();
  80.154 -            }
  80.155 -        };
  80.156 -        final Map<IndexEnquirer, Collection<? extends Resource>> result = new HashMap<IndexEnquirer, Collection<? extends Resource>>();
  80.157 -        final Collection<MessageImpl> problems = new LinkedList<MessageImpl>();
  80.158 -        ProgressHandleWrapper innerForAll = progress.startNextPartWithEmbedding(ProgressHandleWrapper.prepareParts(2 * todo.size()));
  80.159 -        
  80.160 -        for (final Folder src : todo) {
  80.161 -            LOG.log(Level.FINE, "Processing: {0}", FileUtil.getFileDisplayName(src.getFileObject()));
  80.162 -            
  80.163 -            IndexEnquirer indexEnquirer;// = indexMapper.findIndex(src.getFileObject(), innerForAll, src.isRecursive());
  80.164 -
  80.165 -//            if (indexEnquirer == null) {
  80.166 -                indexEnquirer = new FileSystemBasedIndexEnquirer(src.getFileObject(), src.isRecursive());
  80.167 -//            }
  80.168 -
  80.169 -            Collection<? extends Resource> occurrences = indexEnquirer.findResources(patterns, innerForAll, bulkPattern, problems, settingsProvider);
  80.170 -
  80.171 -            if (!occurrences.isEmpty()) {
  80.172 -                result.put(indexEnquirer, occurrences);
  80.173 -            }
  80.174 -
  80.175 -            innerForAll.tick();
  80.176 -        }
  80.177 -
  80.178 -        return new BatchResult(result, patterns, problems);
  80.179 -    }
  80.180 -
  80.181 -    private static BulkPattern preparePattern(final Iterable<? extends HintDescription> patterns, CompilationInfo info) {
  80.182 -        Collection<String> code = new LinkedList<String>();
  80.183 -        Collection<Tree> trees = new LinkedList<Tree>();
  80.184 -        Collection<AdditionalQueryConstraints> additionalConstraints = new LinkedList<AdditionalQueryConstraints>();
  80.185 -
  80.186 -        for (HintDescription pattern : patterns) {
  80.187 -            String textPattern = ((PatternDescription) pattern.getTrigger()).getPattern();
  80.188 -
  80.189 -            code.add(textPattern);
  80.190 -            trees.add(Utilities.parseAndAttribute(info, textPattern, null));
  80.191 -            additionalConstraints.add(pattern.getAdditionalConstraints());
  80.192 -        }
  80.193 -
  80.194 -        return BulkSearch.getDefault().create(code, trees, additionalConstraints, new AtomicBoolean());
  80.195 -    }
  80.196 -
  80.197 -    public static void getVerifiedSpans(BatchResult candidates, @NonNull ProgressHandleWrapper progress, final VerifiedSpansCallBack callback, final Collection<? super MessageImpl> problems, AtomicBoolean cancel) {
  80.198 -        getVerifiedSpans(candidates, progress, callback, false, problems, cancel);
  80.199 -    }
  80.200 -
  80.201 -    public static void getVerifiedSpans(BatchResult candidates, @NonNull ProgressHandleWrapper progress, final VerifiedSpansCallBack callback, boolean doNotRegisterClassPath, final Collection<? super MessageImpl> problems, AtomicBoolean cancel) {
  80.202 -        int[] parts = new int[candidates.projectId2Resources.size()];
  80.203 -        int   index = 0;
  80.204 -
  80.205 -        for (Entry<? extends IndexEnquirer, ? extends Collection<? extends Resource>> e : candidates.projectId2Resources.entrySet()) {
  80.206 -            parts[index++] = e.getValue().size();
  80.207 -        }
  80.208 -
  80.209 -        ProgressHandleWrapper inner = progress.startNextPartWithEmbedding(parts);
  80.210 -
  80.211 -        for (Entry<? extends IndexEnquirer, ? extends Collection<? extends Resource>> e : candidates.projectId2Resources.entrySet()) {
  80.212 -            if (cancel.get()) 
  80.213 -                return;
  80.214 -            inner.startNextPart(e.getValue().size());
  80.215 -
  80.216 -            e.getKey().validateResource(e.getValue(), inner, callback, doNotRegisterClassPath, problems, cancel);
  80.217 -        }
  80.218 -    }
  80.219 -
  80.220 -    private static void getLocalVerifiedSpans(Collection<? extends Resource> resources, @NonNull final ProgressHandleWrapper progress, final VerifiedSpansCallBack callback, boolean doNotRegisterClassPath, final Collection<? super MessageImpl> problems, final AtomicBoolean cancel) {
  80.221 -        Collection<FileObject> files = new LinkedList<FileObject>();
  80.222 -        final Map<FileObject, Resource> file2Resource = new HashMap<FileObject, Resource>();
  80.223 -
  80.224 -        for (Resource r : resources) {
  80.225 -            FileObject file = r.getResolvedFile();
  80.226 -
  80.227 -            if (file != null) {
  80.228 -                files.add(file);
  80.229 -                file2Resource.put(file, r);
  80.230 -            } else {
  80.231 -                callback.cannotVerifySpan(r);
  80.232 -                progress.tick();
  80.233 -            }
  80.234 -        }
  80.235 -
  80.236 -        Map<ClasspathInfo, Collection<FileObject>> cp2Files = BatchUtilities.sortFiles(files);
  80.237 -        ClassPath[] toRegister = null;
  80.238 -
  80.239 -        if (!doNotRegisterClassPath) {
  80.240 -            Set<ClassPath> toRegisterSet = new HashSet<ClassPath>();
  80.241 -
  80.242 -            for (ClasspathInfo cpInfo : cp2Files.keySet()) {
  80.243 -                toRegisterSet.add(cpInfo.getClassPath(PathKind.SOURCE));
  80.244 -            }
  80.245 -
  80.246 -            toRegister = !toRegisterSet.isEmpty() ? toRegisterSet.toArray(new ClassPath[0]) : null;
  80.247 -
  80.248 -            if (toRegister != null) {
  80.249 -                GlobalPathRegistry.getDefault().register(ClassPath.SOURCE, toRegister);
  80.250 -                try {
  80.251 -                    Utilities.waitScanFinished();
  80.252 -                } catch (InterruptedException ex) {
  80.253 -                    Exceptions.printStackTrace(ex);
  80.254 -                }
  80.255 -            }
  80.256 -        }
  80.257 -
  80.258 -        callback.groupStarted();
  80.259 -
  80.260 -        try {
  80.261 -            final GlobalProcessingContext gpc = new GlobalProcessingContext();
  80.262 -            for (Entry<ClasspathInfo, Collection<FileObject>> e : cp2Files.entrySet()) {
  80.263 -                try {
  80.264 -                    List<FileObject> toProcess = new ArrayList<FileObject>(e.getValue());
  80.265 -                    final AtomicInteger currentPointer = new AtomicInteger();
  80.266 -
  80.267 -//                    for (FileObject f : toProcess) {
  80.268 -                    while (currentPointer.get() < toProcess.size()) {
  80.269 -                        if (cancel.get())
  80.270 -                            return;
  80.271 -                        final AtomicBoolean stop = new AtomicBoolean();
  80.272 -//                        JavaSource js = JavaSource.create(e.getKey(), f);
  80.273 -                        JavaSource js = JavaSource.create(e.getKey(), toProcess.subList(currentPointer.get(), toProcess.size()));
  80.274 -
  80.275 -                        js.runUserActionTask(new Task<CompilationController>() {
  80.276 -                            public void run(CompilationController parameter) throws Exception {
  80.277 -                                if (stop.get()) return;
  80.278 -                                if (cancel.get()) return;
  80.279 -
  80.280 -                                boolean cont = true;
  80.281 -
  80.282 -                                try {
  80.283 -                                    if (parameter.toPhase(Phase.RESOLVED).compareTo(Phase.RESOLVED) < 0)
  80.284 -                                        return ;
  80.285 -
  80.286 -                                    progress.setMessage("processing: " + FileUtil.getFileDisplayName(parameter.getFileObject()));
  80.287 -                                    Resource r = file2Resource.get(parameter.getFileObject());
  80.288 -
  80.289 -                                    HintsSettings settings = r.settings;
  80.290 -                                    Iterable<? extends HintDescription> enabledHints;
  80.291 -                                    
  80.292 -                                    if (settings == null) {
  80.293 -                                        settings = HintsSettings.getSettingsFor(parameter.getFileObject());
  80.294 -                                        List<HintDescription> hintsCopy = new ArrayList<>();
  80.295 -                                        for (HintDescription hd : r.hints) {
  80.296 -                                            if (settings.isEnabled(hd.getMetadata())) {
  80.297 -                                                hintsCopy.add(hd);
  80.298 -                                            }
  80.299 -                                        }
  80.300 -                                        enabledHints = hintsCopy;
  80.301 -                                    } else {
  80.302 -                                        enabledHints = r.hints;
  80.303 -                                    }
  80.304 -                                    
  80.305 -                                    List<ErrorDescription> hints = new HintsInvoker(settings, gpc, new AtomicBoolean()).computeHints(parameter, r.hints, problems);
  80.306 -
  80.307 -                                    assert hints != null;
  80.308 -                                    
  80.309 -                                    cont = callback.spansVerified(parameter, r, hints);
  80.310 -                                } catch (ThreadDeath td) {
  80.311 -                                    throw td;
  80.312 -                                } catch (Throwable t) {
  80.313 -                                    LOG.log(Level.INFO, "Exception while performing batch processing in " + FileUtil.getFileDisplayName(parameter.getFileObject()), t);
  80.314 -                                    problems.add(new MessageImpl(MessageKind.WARNING, "An exception occurred while processing file: " + FileUtil.getFileDisplayName(parameter.getFileObject()) + " (" + t.getLocalizedMessage() + ")."));
  80.315 -                                }
  80.316 -                                
  80.317 -                                if (cont) {
  80.318 -                                    progress.tick();
  80.319 -                                    currentPointer.incrementAndGet();
  80.320 -                                } else {
  80.321 -                                    stop.set(true);
  80.322 -                                }
  80.323 -                            }
  80.324 -                        }, true);
  80.325 -                    }
  80.326 -                } catch (IOException ex) {
  80.327 -                    Exceptions.printStackTrace(ex);
  80.328 -                }
  80.329 -            }
  80.330 -            
  80.331 -            final Map<FileObject, List<Decision>> file2Decision = new HashMap<FileObject, List<Decision>>();
  80.332 -            for (List<Decision<?, ?>> decisions : gpc.decisions.values()) {
  80.333 -                for (Decision<?, ?> d : decisions) {
  80.334 -                    if (d.makeDecision()) {
  80.335 -                        List<Decision> fileDecisions = file2Decision.get(d.root.getFileObject());
  80.336 -                        
  80.337 -                        if (fileDecisions == null) {
  80.338 -                            file2Decision.put(d.root.getFileObject(), fileDecisions = new ArrayList<Decision>());
  80.339 -                        }
  80.340 -                        
  80.341 -                        fileDecisions.add(d);
  80.342 -                    }
  80.343 -                }
  80.344 -            }
  80.345 -
  80.346 -            Map<ClasspathInfo, Collection<FileObject>> cp2FilesAfterDecision = BatchUtilities.sortFiles(file2Decision.keySet());
  80.347 -            
  80.348 -            for (Entry<ClasspathInfo, Collection<FileObject>> e : cp2FilesAfterDecision.entrySet()) {
  80.349 -                JavaSource js = JavaSource.create(e.getKey(), e.getValue());
  80.350 -                
  80.351 -                try {
  80.352 -                    js.runUserActionTask(new Task<CompilationController>() {
  80.353 -                        @Override public void run(CompilationController parameter) throws Exception {
  80.354 -                            if (parameter.toPhase(Phase.RESOLVED).compareTo(Phase.RESOLVED) < 0)
  80.355 -                                return ;
  80.356 -                            
  80.357 -                            Resource r = file2Resource.get(parameter.getFileObject());
  80.358 -
  80.359 -                            HintsSettings settings = r.settings;
  80.360 -
  80.361 -                            if (settings == null) {
  80.362 -                                settings = HintsSettings.getSettingsFor(parameter.getFileObject());
  80.363 -                            }
  80.364 -
  80.365 -                            for (Decision<?, ?> d : file2Decision.get(parameter.getFileObject())) {
  80.366 -                            for (HintDescription hd : r.hints) {
  80.367 -                                if (!(hd.getTrigger() instanceof DecisionTrigger)) continue;
  80.368 -                                if (r.settings == null && !settings.isEnabled(hd.getMetadata())) continue;
  80.369 -                                DecisionTrigger dt = (DecisionTrigger) hd.getTrigger();
  80.370 -                                if (dt.getDecisionClass() != d.getClass()) continue;
  80.371 -                                TreePath tp = d.root.resolve(parameter);
  80.372 -                                HintContext ctx = SPIAccessor.getINSTANCE().createHintContext(parameter, settings, hd.getMetadata(), new GlobalProcessingContext(), tp, Collections.<String, TreePath>emptyMap(), Collections.<String, Collection<? extends TreePath>>emptyMap(), Collections.<String, String>emptyMap());
  80.373 -                                ctx.decision = d;
  80.374 -                                Collection<? extends ErrorDescription> errors = hd.getWorker().createErrors(ctx);
  80.375 -                                
  80.376 -                                if (errors != null) {
  80.377 -                                    callback.spansVerified(parameter, file2Resource.get(parameter.getFileObject()), errors);
  80.378 -                                }
  80.379 -                            }
  80.380 -                            }
  80.381 -                        }
  80.382 -                    }, true);
  80.383 -                } catch (IOException ex) {
  80.384 -                    Exceptions.printStackTrace(ex);
  80.385 -                }
  80.386 -            }
  80.387 -        } finally {
  80.388 -            callback.groupFinished();
  80.389 -            
  80.390 -            if (toRegister != null) {
  80.391 -                GlobalPathRegistry.getDefault().unregister(ClassPath.SOURCE, toRegister);
  80.392 -            }
  80.393 -            progress.finish();
  80.394 -        }
  80.395 -    }
  80.396 -
  80.397 -    public interface VerifiedSpansCallBack {
  80.398 -        public void groupStarted();
  80.399 -        public boolean spansVerified(CompilationController wc, Resource r, Collection<? extends ErrorDescription> hints) throws Exception;
  80.400 -        public void groupFinished();
  80.401 -        public void cannotVerifySpan(Resource r);
  80.402 -    }
  80.403 -
  80.404 -    
  80.405 -    public static class Folder {
  80.406 -
  80.407 -        private FileObject file;
  80.408 -        private NonRecursiveFolder folder;
  80.409 -        
  80.410 -        public Folder(FileObject file) {
  80.411 -            this.file = file;
  80.412 -        }
  80.413 -        
  80.414 -        public Folder(NonRecursiveFolder folder) {
  80.415 -            this.folder = folder;
  80.416 -        }
  80.417 -        
  80.418 -        public FileObject getFileObject() {
  80.419 -            if (file!=null) {
  80.420 -                return file;
  80.421 -            }
  80.422 -            return folder.getFolder();
  80.423 -            
  80.424 -        }
  80.425 -        
  80.426 -        private boolean isRecursive() {
  80.427 -            if (file!=null) {
  80.428 -                return file.isFolder();
  80.429 -            }
  80.430 -            return false;
  80.431 -        }
  80.432 -
  80.433 -        public static Folder[] convert(FileObject... files) {
  80.434 -            Folder[] result = new Folder[files.length];
  80.435 -            for (int i=0;i<files.length;i++) {
  80.436 -                result[i] = new Folder(files[i]);
  80.437 -            }
  80.438 -            return result;
  80.439 -        }
  80.440 -
  80.441 -        public static Folder[] convert(Collection list) {
  80.442 -            Folder[] result = new Folder[list.size()];
  80.443 -            int i=0;
  80.444 -            for (Object item:list) {
  80.445 -                if (item instanceof FileObject)
  80.446 -                    result[i] = new Folder((FileObject) item);
  80.447 -                else 
  80.448 -                    result[i] = new Folder((NonRecursiveFolder) item);
  80.449 -                i++;
  80.450 -            }
  80.451 -            return result;
  80.452 -        }
  80.453 -
  80.454 -        @Override
  80.455 -        public String toString() {
  80.456 -            return !isRecursive()?"Non":"" + "Recursive file " + getFileObject().getPath();
  80.457 -        }
  80.458 -        
  80.459 -        
  80.460 -    }
  80.461 -    
  80.462 -    public abstract static class Scope {
  80.463 -
  80.464 -        public abstract String getDisplayName();
  80.465 -        public abstract Collection<? extends Folder> getTodo();
  80.466 -        public abstract MapIndices getIndexMapper(Iterable<? extends HintDescription> hints);
  80.467 -        
  80.468 -    }
  80.469 -    
  80.470 -    public static final class BatchResult {
  80.471 -        
  80.472 -        private final Map<? extends IndexEnquirer, ? extends Collection<? extends Resource>> projectId2Resources;
  80.473 -        private final Iterable<? extends HintDescription> patterns;
  80.474 -        public final Collection<? extends MessageImpl> problems;
  80.475 -        
  80.476 -        public BatchResult(Map<? extends IndexEnquirer, ? extends Collection<? extends Resource>> projectId2Resources, Iterable<? extends HintDescription> patterns, Collection<? extends MessageImpl> problems) {
  80.477 -            this.projectId2Resources = projectId2Resources;
  80.478 -            this.patterns = patterns;
  80.479 -            this.problems = problems;
  80.480 -        }
  80.481 -
  80.482 -        public Collection<? extends Collection<? extends Resource>> getResources() {
  80.483 -            return projectId2Resources.values();
  80.484 -        }
  80.485 -
  80.486 -        public Map<FileObject, Collection<? extends Resource>> getResourcesWithRoots() {
  80.487 -            Map<FileObject, Collection<? extends Resource>> result = new HashMap<FileObject, Collection<? extends Resource>>();
  80.488 -
  80.489 -            for (Entry<? extends IndexEnquirer, ? extends Collection<? extends Resource>> e : projectId2Resources.entrySet()) {
  80.490 -                result.put(e.getKey().src, e.getValue());
  80.491 -            }
  80.492 -
  80.493 -            return result;
  80.494 -        }
  80.495 -
  80.496 -        public Iterable<? extends HintDescription> getPatterns() {
  80.497 -            return patterns;
  80.498 -        }
  80.499 -    }
  80.500 -
  80.501 -    public static final class Resource {
  80.502 -        private final IndexEnquirer indexEnquirer;
  80.503 -        private final String relativePath;
  80.504 -        final Iterable<? extends HintDescription> hints;
  80.505 -        private final BulkPattern pattern;
  80.506 -        final HintsSettings settings;
  80.507 -
  80.508 -        public Resource(IndexEnquirer indexEnquirer, String relativePath, Iterable<? extends HintDescription> hints, BulkPattern pattern, HintsSettings settings) {
  80.509 -            this.indexEnquirer = indexEnquirer;
  80.510 -            this.relativePath = relativePath;
  80.511 -            this.hints = hints;
  80.512 -            this.pattern = pattern;
  80.513 -            this.settings = settings;
  80.514 -        }
  80.515 -
  80.516 -        public String getRelativePath() {
  80.517 -            return relativePath;
  80.518 -        }
  80.519 -        
  80.520 -        public Iterable<int[]> getCandidateSpans() {
  80.521 -            FileObject file = getResolvedFile();
  80.522 -            JavaSource js;
  80.523 -
  80.524 -            if (file != null) {
  80.525 -                js = JavaSource.forFileObject(file);
  80.526 -            } else {
  80.527 -                CharSequence text = getSourceCode();
  80.528 -
  80.529 -                if (text == null) {
  80.530 -                    return null;
  80.531 -                }
  80.532 -
  80.533 -                Writer out = null;
  80.534 -
  80.535 -                try {
  80.536 -                    file = FileUtil.createData(FileUtil.createMemoryFileSystem().getRoot(), relativePath);
  80.537 -                    out = new OutputStreamWriter(file.getOutputStream());
  80.538 -
  80.539 -                    out.write(text.toString());
  80.540 -                } catch (IOException ex) {
  80.541 -                    Exceptions.printStackTrace(ex);
  80.542 -                    return null;
  80.543 -                } finally {
  80.544 -                    if (out != null) {
  80.545 -                        try {
  80.546 -                            out.close();
  80.547 -                        } catch (IOException ex) {
  80.548 -                            Exceptions.printStackTrace(ex);
  80.549 -                        }
  80.550 -                    }
  80.551 -                }
  80.552 -
  80.553 -                js = JavaSource.create(Utilities.createUniversalCPInfo(), file);
  80.554 -            }
  80.555 -
  80.556 -            final List<int[]> span = new LinkedList<int[]>();
  80.557 -
  80.558 -            try {
  80.559 -                js.runUserActionTask(new Task<CompilationController>() {
  80.560 -                    public void run(CompilationController cc) throws Exception {
  80.561 -                        cc.toPhase(Phase.PARSED);
  80.562 -
  80.563 -                        span.addAll(doComputeSpans(cc));
  80.564 -                    }
  80.565 -                }, true);
  80.566 -            } catch (IOException ex) {
  80.567 -                Exceptions.printStackTrace(ex);
  80.568 -            }
  80.569 -
  80.570 -            return span;
  80.571 -        }
  80.572 -
  80.573 -        private Collection<int[]> doComputeSpans(CompilationInfo ci) {
  80.574 -            Collection<int[]> result = new LinkedList<int[]>();
  80.575 -            Map<String, Collection<TreePath>> found = BulkSearch.getDefault().match(ci, new AtomicBoolean(), new TreePath(ci.getCompilationUnit()), pattern);
  80.576 -            
  80.577 -            for (Entry<String, Collection<TreePath>> e : found.entrySet()) {
  80.578 -                Tree treePattern = Utilities.parseAndAttribute(ci, e.getKey(), null);
  80.579 -                
  80.580 -                for (TreePath tp : e.getValue()) {
  80.581 -                    //XXX: this pass will not be performed on the web!!!
  80.582 -                    if (   BulkSearch.getDefault().requiresLightweightVerification()
  80.583 -                        && !Matcher.create(ci).setCancel(new AtomicBoolean()).setSearchRoot(tp).setTreeTopSearch().setUntypedMatching().match(Pattern.createSimplePattern(new TreePath(new TreePath(ci.getCompilationUnit()), treePattern))).iterator().hasNext()) {
  80.584 -                        continue;
  80.585 -                    }
  80.586 -                    int[] span = new int[] {
  80.587 -                        (int) ci.getTrees().getSourcePositions().getStartPosition(ci.getCompilationUnit(), tp.getLeaf()),
  80.588 -                        (int) ci.getTrees().getSourcePositions().getEndPosition(ci.getCompilationUnit(), tp.getLeaf())
  80.589 -                    };
  80.590 -
  80.591 -                    result.add(span);
  80.592 -                }
  80.593 -            }
  80.594 -
  80.595 -            return result;
  80.596 -        }
  80.597 -        
  80.598 -        public FileObject getResolvedFile() {
  80.599 -            return indexEnquirer.src.getFileObject(relativePath);
  80.600 -        }
  80.601 -
  80.602 -        public String getDisplayName() {
  80.603 -            FileObject file = getResolvedFile();
  80.604 -
  80.605 -            if (file != null) {
  80.606 -                return FileUtil.getFileDisplayName(file);
  80.607 -            } else {
  80.608 -                return relativePath; //TODO:+container
  80.609 -            }
  80.610 -        }
  80.611 -        
  80.612 -        public CharSequence getSourceCode() {
  80.613 -            try {
  80.614 -                FileObject file = getResolvedFile();
  80.615 -                ByteBuffer bb = ByteBuffer.wrap(file.asBytes());
  80.616 -
  80.617 -                return FileEncodingQuery.getEncoding(file).decode(bb);
  80.618 -            } catch (IOException ex) {
  80.619 -                Exceptions.printStackTrace(ex);
  80.620 -                return null;
  80.621 -            }
  80.622 -        }
  80.623 -
  80.624 -        public FileObject getRoot() {
  80.625 -            return indexEnquirer.src;
  80.626 -        }
  80.627 -    }
  80.628 -
  80.629 -    public static interface MapIndices {
  80.630 -        public IndexEnquirer findIndex(FileObject root, ProgressHandleWrapper progress, boolean recursive);
  80.631 -    }
  80.632 -
  80.633 -    public static abstract class IndexEnquirer {
  80.634 -        final FileObject src;
  80.635 -        public IndexEnquirer(FileObject src) {
  80.636 -            this.src = src;
  80.637 -        }
  80.638 -        public abstract Collection<? extends Resource> findResources(Iterable<? extends HintDescription> hints, ProgressHandleWrapper progress, @NullAllowed Callable<BulkPattern> bulkPattern, Collection<? super MessageImpl> problems, HintsSettings settingsProvider);
  80.639 -        public abstract void validateResource(Collection<? extends Resource> resources, ProgressHandleWrapper progress, VerifiedSpansCallBack callback, boolean doNotRegisterClassPath, Collection<? super MessageImpl> problems, AtomicBoolean cancel);
  80.640 -//        public int[] getEstimatedSpan(Resource r);
  80.641 -    }
  80.642 -
  80.643 -    public static abstract class LocalIndexEnquirer extends IndexEnquirer {
  80.644 -        public LocalIndexEnquirer(FileObject src) {
  80.645 -            super(src);
  80.646 -        }
  80.647 -        public void validateResource(Collection<? extends Resource> resources, ProgressHandleWrapper progress, VerifiedSpansCallBack callback, boolean doNotRegisterClassPath, Collection<? super MessageImpl> problems, AtomicBoolean cancel) {
  80.648 -            getLocalVerifiedSpans(resources, progress, callback, doNotRegisterClassPath, problems, cancel);
  80.649 -        }
  80.650 -    }
  80.651 -
  80.652 -    public static final class FileSystemBasedIndexEnquirer extends LocalIndexEnquirer {
  80.653 -        private boolean recursive;
  80.654 -        public FileSystemBasedIndexEnquirer(FileObject src, boolean recursive) {
  80.655 -            super(src);
  80.656 -            this.recursive = recursive;
  80.657 -        }
  80.658 -        public Collection<? extends Resource> findResources(final Iterable<? extends HintDescription> hints, ProgressHandleWrapper progress, final @NullAllowed Callable<BulkPattern> bulkPattern, final Collection<? super MessageImpl> problems, final HintsSettings settingsProvider) {
  80.659 -            Collection<FileObject> files = new LinkedList<FileObject>();
  80.660 -
  80.661 -            final ProgressHandleWrapper innerProgress = progress.startNextPartWithEmbedding(30, 70);
  80.662 -
  80.663 -            BatchUtilities.recursive(src, src, files, innerProgress, 0, null, null, recursive);
  80.664 -
  80.665 -            LOG.log(Level.FINE, "files: {0}", files);
  80.666 -
  80.667 -            innerProgress.startNextPart(files.size());
  80.668 -
  80.669 -            final Collection<Resource> result = new ArrayList<Resource>();
  80.670 -
  80.671 -            if (!files.isEmpty()) {
  80.672 -                try {
  80.673 -                    if (bulkPattern != null) {
  80.674 -                        long start = System.currentTimeMillis();
  80.675 -
  80.676 -                        JavaSource.create(Utilities.createUniversalCPInfo(), files).runUserActionTask(new Task<CompilationController>() {
  80.677 -                            public void run(CompilationController cc) throws Exception {
  80.678 -                                if (cc.toPhase(Phase.PARSED).compareTo(Phase.PARSED) <0) {
  80.679 -                                    return ;
  80.680 -                                }
  80.681 -
  80.682 -                                try {
  80.683 -                                    boolean matches = BulkSearch.getDefault().matches(cc, new AtomicBoolean(), new TreePath(cc.getCompilationUnit()), bulkPattern.call());
  80.684 -
  80.685 -                                    if (matches) {
  80.686 -                                        result.add(new Resource(FileSystemBasedIndexEnquirer.this, FileUtil.getRelativePath(src, cc.getFileObject()), hints, bulkPattern.call(), settingsProvider));
  80.687 -                                    }
  80.688 -                                } catch (ThreadDeath td) {
  80.689 -                                    throw td;
  80.690 -                                } catch (Throwable t) {
  80.691 -                                    LOG.log(Level.INFO, "Exception while performing batch search in " + FileUtil.getFileDisplayName(cc.getFileObject()), t);
  80.692 -                                    problems.add(new MessageImpl(MessageKind.WARNING, "An exception occurred while testing file: " + FileUtil.getFileDisplayName(cc.getFileObject()) + " (" + t.getLocalizedMessage() + ")."));
  80.693 -                                }
  80.694 -
  80.695 -                                innerProgress.tick();
  80.696 -                            }
  80.697 -                        }, true);
  80.698 -
  80.699 -                        long end = System.currentTimeMillis();
  80.700 -
  80.701 -                        LOG.log(Level.FINE, "took: {0}, per file: {1}", new Object[]{end - start, (end - start) / files.size()});
  80.702 -                    } else {
  80.703 -                        for (FileObject file : files) {
  80.704 -                            result.add(new Resource(this, FileUtil.getRelativePath(src, file), hints, null, settingsProvider));
  80.705 -                        }
  80.706 -                    }
  80.707 -                } catch (IOException ex) {
  80.708 -                    Exceptions.printStackTrace(ex);
  80.709 -                }
  80.710 -            }
  80.711 -
  80.712 -            return result;
  80.713 -        }
  80.714 -
  80.715 -    }
  80.716 -
  80.717 -}
    81.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/batch/BatchUtilities.java	Sun Oct 16 08:01:27 2016 +0200
    81.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    81.3 @@ -1,586 +0,0 @@
    81.4 -/*
    81.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    81.6 - *
    81.7 - * Copyright 2009-2011 Oracle and/or its affiliates. All rights reserved.
    81.8 - *
    81.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   81.10 - * Other names may be trademarks of their respective owners.
   81.11 - *
   81.12 - * The contents of this file are subject to the terms of either the GNU
   81.13 - * General Public License Version 2 only ("GPL") or the Common
   81.14 - * Development and Distribution License("CDDL") (collectively, the
   81.15 - * "License"). You may not use this file except in compliance with the
   81.16 - * License. You can obtain a copy of the License at
   81.17 - * http://www.netbeans.org/cddl-gplv2.html
   81.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   81.19 - * specific language governing permissions and limitations under the
   81.20 - * License.  When distributing the software, include this License Header
   81.21 - * Notice in each file and include the License file at
   81.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   81.23 - * particular file as subject to the "Classpath" exception as provided
   81.24 - * by Oracle in the GPL Version 2 section of the License file that
   81.25 - * accompanied this code. If applicable, add the following below the
   81.26 - * License Header, with the fields enclosed by brackets [] replaced by
   81.27 - * your own identifying information:
   81.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   81.29 - *
   81.30 - * If you wish your version of this file to be governed by only the CDDL
   81.31 - * or only the GPL Version 2, indicate your decision by adding
   81.32 - * "[Contributor] elects to include this software in this distribution
   81.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   81.34 - * single choice of license, a recipient has the option to distribute
   81.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   81.36 - * to extend the choice of license to its licensees as provided above.
   81.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   81.38 - * Version 2 license, then the option applies only if the new code is
   81.39 - * made subject to such option by the copyright holder.
   81.40 - *
   81.41 - * Contributor(s):
   81.42 - *
   81.43 - * Portions Copyrighted 2009-2011 Sun Microsystems, Inc.
   81.44 - */
   81.45 -package org.netbeans.modules.java.hints.spiimpl.batch;
   81.46 -
   81.47 -import com.sun.tools.javac.api.JavacTaskImpl;
   81.48 -import com.sun.tools.javac.util.Log;
   81.49 -import java.io.IOException;
   81.50 -import java.lang.reflect.Constructor;
   81.51 -import java.lang.reflect.Method;
   81.52 -import java.nio.ByteBuffer;
   81.53 -import java.nio.charset.Charset;
   81.54 -import java.util.ArrayList;
   81.55 -import java.util.Collection;
   81.56 -import java.util.Collections;
   81.57 -import java.util.HashMap;
   81.58 -import java.util.HashSet;
   81.59 -import java.util.IdentityHashMap;
   81.60 -import java.util.Iterator;
   81.61 -import java.util.LinkedHashMap;
   81.62 -import java.util.LinkedHashSet;
   81.63 -import java.util.LinkedList;
   81.64 -import java.util.List;
   81.65 -import java.util.Map;
   81.66 -import java.util.Map.Entry;
   81.67 -import java.util.Properties;
   81.68 -import java.util.Set;
   81.69 -import java.util.concurrent.atomic.AtomicBoolean;
   81.70 -import java.util.logging.Level;
   81.71 -import java.util.logging.Logger;
   81.72 -import javax.swing.text.BadLocationException;
   81.73 -import javax.swing.text.Document;
   81.74 -import org.netbeans.api.annotations.common.CheckForNull;
   81.75 -import org.netbeans.api.annotations.common.NonNull;
   81.76 -import org.netbeans.api.java.classpath.ClassPath;
   81.77 -import org.netbeans.api.java.classpath.ClassPath.PathConversionMode;
   81.78 -import org.netbeans.api.java.platform.JavaPlatformManager;
   81.79 -import org.netbeans.api.java.source.ClasspathInfo;
   81.80 -import org.netbeans.api.java.source.CompilationController;
   81.81 -import org.netbeans.api.java.source.CompilationInfo;
   81.82 -import org.netbeans.api.java.source.JavaSource;
   81.83 -import org.netbeans.api.java.source.JavaSource.Phase;
   81.84 -import org.netbeans.api.java.source.ModificationResult;
   81.85 -import org.netbeans.api.java.source.ModificationResult.Difference;
   81.86 -import org.netbeans.api.java.source.Task;
   81.87 -import org.netbeans.api.java.source.WorkingCopy;
   81.88 -import org.netbeans.api.project.FileOwnerQuery;
   81.89 -import org.netbeans.api.project.Project;
   81.90 -import org.netbeans.api.project.ProjectUtils;
   81.91 -import org.netbeans.api.project.SourceGroup;
   81.92 -import org.netbeans.api.project.Sources;
   81.93 -import org.netbeans.api.queries.FileEncodingQuery;
   81.94 -import org.netbeans.api.queries.VisibilityQuery;
   81.95 -//import org.netbeans.modules.java.editor.semantic.SemanticHighlighter;
   81.96 -import org.netbeans.modules.java.hints.spiimpl.JavaFixImpl;
   81.97 -import org.netbeans.modules.java.hints.spiimpl.JavaFixImpl.Accessor;
   81.98 -import org.netbeans.modules.java.hints.spiimpl.MessageImpl;
   81.99 -import org.netbeans.modules.java.hints.spiimpl.SyntheticFix;
  81.100 -import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.BatchResult;
  81.101 -import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.Resource;
  81.102 -import org.netbeans.modules.java.hints.spiimpl.ipi.upgrade.ProjectDependencyUpgrader;
  81.103 -import org.netbeans.modules.java.source.JavaSourceAccessor;
  81.104 -import org.netbeans.modules.java.source.parsing.CompilationInfoImpl;
  81.105 -import org.netbeans.modules.java.source.save.DiffUtilities;
  81.106 -import org.netbeans.modules.java.source.save.ElementOverlay;
  81.107 -import org.netbeans.modules.parsing.api.Source;
  81.108 -import org.netbeans.modules.refactoring.spi.RefactoringElementImplementation;
  81.109 -import org.netbeans.spi.editor.hints.ErrorDescription;
  81.110 -import org.netbeans.spi.editor.hints.Fix;
  81.111 -import org.netbeans.spi.java.hints.HintContext.MessageKind;
  81.112 -import org.netbeans.spi.java.hints.JavaFix;
  81.113 -import org.openide.cookies.EditorCookie;
  81.114 -import org.openide.filesystems.FileObject;
  81.115 -import org.openide.filesystems.FileUtil;
  81.116 -import org.openide.loaders.DataObject;
  81.117 -import org.openide.loaders.DataObjectNotFoundException;
  81.118 -import org.openide.util.Exceptions;
  81.119 -import org.openide.util.Lookup;
  81.120 -
  81.121 -/**
  81.122 - *
  81.123 - * @author Jan Lahoda
  81.124 - */
  81.125 -public class BatchUtilities {
  81.126 -
  81.127 -    private static final Logger LOG = Logger.getLogger(BatchUtilities.class.getName());
  81.128 -    
  81.129 -    public static Collection<ModificationResult> applyFixes(BatchResult candidates, @NonNull final ProgressHandleWrapper progress, AtomicBoolean cancel, final Collection<? super MessageImpl> problems) {
  81.130 -        return applyFixes(candidates, progress, cancel, new ArrayList<RefactoringElementImplementation>(), problems);
  81.131 -    }
  81.132 -    
  81.133 -    public static Collection<ModificationResult> applyFixes(BatchResult candidates, @NonNull final ProgressHandleWrapper progress, AtomicBoolean cancel, final Collection<? super RefactoringElementImplementation> fileChanges, final Collection<? super MessageImpl> problems) {
  81.134 -        return applyFixes(candidates, progress, cancel, fileChanges, null, problems);
  81.135 -    }
  81.136 -    
  81.137 -    public static Collection<ModificationResult> applyFixes(BatchResult candidates, @NonNull final ProgressHandleWrapper progress, AtomicBoolean cancel, final Collection<? super RefactoringElementImplementation> fileChanges, final Map<JavaFix, ModificationResult> changesPerFix, final Collection<? super MessageImpl> problems) {
  81.138 -        return applyFixes(candidates, progress, cancel, fileChanges, changesPerFix, false, problems);
  81.139 -    }
  81.140 -    
  81.141 -    public static Collection<ModificationResult> applyFixes(BatchResult candidates, @NonNull final ProgressHandleWrapper progress, AtomicBoolean cancel, final Collection<? super RefactoringElementImplementation> fileChanges, final Map<JavaFix, ModificationResult> changesPerFix, boolean doNotRegisterClassPath, final Collection<? super MessageImpl> problems) {
  81.142 -        final Map<Project, Set<String>> processedDependencyChanges = new IdentityHashMap<Project, Set<String>>();
  81.143 -        final Map<FileObject, List<ModificationResult.Difference>> result = new LinkedHashMap<FileObject, List<ModificationResult.Difference>>();
  81.144 -        final Map<FileObject, byte[]> resourceContentChanges = new HashMap<FileObject, byte[]>();
  81.145 -
  81.146 -        BatchSearch.VerifiedSpansCallBack callback = new BatchSearch.VerifiedSpansCallBack() {
  81.147 -            private ElementOverlay overlay;
  81.148 -            public void groupStarted() {
  81.149 -                overlay = ElementOverlay.getOrCreateOverlay();
  81.150 -            }
  81.151 -            public boolean spansVerified(CompilationController wc, Resource r, Collection<? extends ErrorDescription> hints) throws Exception {
  81.152 -                if (hints.isEmpty()) return true;
  81.153 -                
  81.154 -                Constructor<WorkingCopy> wcConstr = WorkingCopy.class.getDeclaredConstructor(CompilationInfoImpl.class, ElementOverlay.class);
  81.155 -                wcConstr.setAccessible(true);
  81.156 -
  81.157 -//                final WorkingCopy copy = new WorkingCopy(JavaSourceAccessor.getINSTANCE().getCompilationInfoImpl(parameter), overlay);
  81.158 -                WorkingCopy copy = wcConstr.newInstance(JavaSourceAccessor.getINSTANCE().getCompilationInfoImpl(wc), overlay);
  81.159 -                Method setJavaSource = CompilationInfo.class.getDeclaredMethod("setJavaSource", JavaSource.class);
  81.160 -                setJavaSource.setAccessible(true);
  81.161 -
  81.162 -//                copy.setJavaSource(JavaSource.this);
  81.163 -                setJavaSource.invoke(copy, wc.getJavaSource());
  81.164 -
  81.165 -                copy.toPhase(Phase.RESOLVED);
  81.166 -                progress.tick();
  81.167 -                
  81.168 -                if (applyFixes(copy, processedDependencyChanges, hints, resourceContentChanges, fileChanges, changesPerFix, problems)) {
  81.169 -                    return false;
  81.170 -                }
  81.171 -
  81.172 -                final JavacTaskImpl jt = JavaSourceAccessor.getINSTANCE().getJavacTask(copy);
  81.173 -                Log.instance(jt.getContext()).nerrors = 0;
  81.174 -                Method getChanges = WorkingCopy.class.getDeclaredMethod("getChanges", Map.class);
  81.175 -                getChanges.setAccessible(true);
  81.176 -
  81.177 -                result.put(copy.getFileObject(), (List<ModificationResult.Difference>) getChanges.invoke(copy, new HashMap<Object, int[]>()));
  81.178 -
  81.179 -                if (LOG.isLoggable(Level.FINE)) {
  81.180 -                    LOG.log(Level.FINE, "fixes applied to: {0}", FileUtil.getFileDisplayName(wc.getFileObject()));
  81.181 -                }
  81.182 -
  81.183 -                return true;
  81.184 -            }
  81.185 -
  81.186 -            public void groupFinished() {
  81.187 -                overlay = null;
  81.188 -            }
  81.189 -
  81.190 -            public void cannotVerifySpan(Resource r) {
  81.191 -                problems.add(new MessageImpl(MessageKind.WARNING, "Cannot parse: " + r.getRelativePath()));
  81.192 -            }
  81.193 -        };
  81.194 -
  81.195 -        BatchSearch.getVerifiedSpans(candidates, progress, callback, doNotRegisterClassPath, problems, cancel);
  81.196 -        
  81.197 -        addResourceContentChanges(resourceContentChanges, result);
  81.198 -
  81.199 -        return Collections.singletonList(JavaSourceAccessor.getINSTANCE().createModificationResult(result, Collections.<Object, int[]>emptyMap()));
  81.200 -    }
  81.201 -
  81.202 -    public static void addResourceContentChanges(final Map<FileObject, byte[]> resourceContentChanges, final Map<FileObject, List<Difference>> result) {
  81.203 -        for (Entry<FileObject, byte[]> e : resourceContentChanges.entrySet()) {
  81.204 -            try {
  81.205 -                Charset encoding = FileEncodingQuery.getEncoding(e.getKey());
  81.206 -                final Document originalDocument = getDocument(e.getKey());
  81.207 -                final String[] origContent = new String[1];
  81.208 -                final Source[] s = new Source[1];
  81.209 -                if (originalDocument != null) {
  81.210 -                    originalDocument.render(new Runnable() {
  81.211 -                        @Override public void run() {
  81.212 -                            try {
  81.213 -                                origContent[0] = originalDocument.getText(0, originalDocument.getLength());
  81.214 -                                s[0] = Source.create(originalDocument);
  81.215 -                            } catch (BadLocationException ex) {
  81.216 -                                Exceptions.printStackTrace(ex);
  81.217 -                            }
  81.218 -                        }
  81.219 -                    });
  81.220 -                }
  81.221 -                
  81.222 -                if (origContent[0] == null) {
  81.223 -                    byte[] origBytes = e.getKey().asBytes();
  81.224 -                    origContent[0] = encoding.newDecoder().decode(ByteBuffer.wrap(origBytes)).toString();
  81.225 -                }
  81.226 -                String newContent  = encoding.newDecoder().decode(ByteBuffer.wrap(e.getValue())).toString();
  81.227 -
  81.228 -                result.put(e.getKey(), DiffUtilities.diff2ModificationResultDifference(e.getKey(), null, Collections.<Integer, String>emptyMap(), origContent[0], newContent, s[0]));
  81.229 -            } catch (BadLocationException ex) {
  81.230 -                Exceptions.printStackTrace(ex);
  81.231 -            } catch (IOException ex) {
  81.232 -                Exceptions.printStackTrace(ex);
  81.233 -            }
  81.234 -        }
  81.235 -    }
  81.236 -    
  81.237 -    public static @CheckForNull Document getDocument(@NonNull FileObject file) {
  81.238 -        try {
  81.239 -            DataObject od = DataObject.find(file);
  81.240 -            EditorCookie ec = od.getLookup().lookup(EditorCookie.class);
  81.241 -
  81.242 -            if (ec == null) return null;
  81.243 -
  81.244 -            return ec.getDocument();
  81.245 -        } catch (DataObjectNotFoundException ex) {
  81.246 -            LOG.log(Level.FINE, null, ex);
  81.247 -            return null;
  81.248 -        }
  81.249 -    }
  81.250 -
  81.251 -    private static String positionToString(ErrorDescription ed) {
  81.252 -        try {
  81.253 -            return ed.getFile().getNameExt() + ":" + ed.getRange().getBegin().getLine();
  81.254 -        } catch (IOException ex) {
  81.255 -            LOG.log(Level.FINE, null, ex);
  81.256 -            return ed.getFile().getNameExt();
  81.257 -        }
  81.258 -    }
  81.259 -
  81.260 -//    public static void removeUnusedImports(Collection<? extends FileObject> files) throws IOException {
  81.261 -//        Map<ClasspathInfo, Collection<FileObject>> sortedFastFiles = sortFiles(files);
  81.262 -//
  81.263 -//        for (Entry<ClasspathInfo, Collection<FileObject>> e : sortedFastFiles.entrySet()) {
  81.264 -//            JavaSource.create(e.getKey(), e.getValue()).runModificationTask(new RemoveUnusedImports()).commit();
  81.265 -//        }
  81.266 -//    }
  81.267 -//
  81.268 -//    private static final class RemoveUnusedImports implements Task<WorkingCopy> {
  81.269 -//        public void run(WorkingCopy wc) throws IOException {
  81.270 -//            Document doc = wc.getSnapshot().getSource().getDocument(true);
  81.271 -//            
  81.272 -//            if (wc.toPhase(Phase.RESOLVED).compareTo(Phase.RESOLVED) < 0) {
  81.273 -//                return;
  81.274 -//            }
  81.275 -//
  81.276 -//            //compute imports to remove:
  81.277 -//            List<TreePathHandle> unusedImports = SemanticHighlighter.computeUnusedImports(wc);
  81.278 -//            CompilationUnitTree cut = wc.getCompilationUnit();
  81.279 -//            // make the changes to the source
  81.280 -//            for (TreePathHandle handle : unusedImports) {
  81.281 -//                TreePath path = handle.resolve(wc);
  81.282 -//                assert path != null;
  81.283 -//                cut = wc.getTreeMaker().removeCompUnitImport(cut,
  81.284 -//                        (ImportTree) path.getLeaf());
  81.285 -//            }
  81.286 -//
  81.287 -//            if (!unusedImports.isEmpty()) {
  81.288 -//                wc.rewrite(wc.getCompilationUnit(), cut);
  81.289 -//            }
  81.290 -//        }
  81.291 -//    }
  81.292 -
  81.293 -    public static boolean applyFixes(WorkingCopy copy, Map<Project, Set<String>> processedDependencyChanges, Collection<? extends ErrorDescription> hints, Map<FileObject, byte[]> resourceContentChanges, Collection<? super RefactoringElementImplementation> fileChanges, Collection<? super MessageImpl> problems) throws IllegalStateException, Exception {
  81.294 -        return applyFixes(copy, processedDependencyChanges, hints, resourceContentChanges, fileChanges, null, problems);
  81.295 -    }
  81.296 -    
  81.297 -    public static boolean applyFixes(WorkingCopy copy, Map<Project, Set<String>> processedDependencyChanges, Collection<? extends ErrorDescription> hints, Map<FileObject, byte[]> resourceContentChanges, Collection<? super RefactoringElementImplementation> fileChanges, Map<JavaFix, ModificationResult> changesPerFix, Collection<? super MessageImpl> problems) throws IllegalStateException, Exception {
  81.298 -        Set<JavaFix> fixes = new LinkedHashSet<JavaFix>();
  81.299 -        for (ErrorDescription ed : hints) {
  81.300 -            if (!ed.getFixes().isComputed()) {
  81.301 -                throw new IllegalStateException();//TODO: should be problem
  81.302 -            }
  81.303 -
  81.304 -            Fix toApply = null;
  81.305 -
  81.306 -            for (Fix f : ed.getFixes().getFixes()) {
  81.307 -                if (f instanceof SyntheticFix) continue;
  81.308 -                if (toApply == null) toApply = f;
  81.309 -                else problems.add(new MessageImpl(MessageKind.WARNING, "More than one fix for: " + ed.getDescription() + " at " + positionToString(ed) + ", only the first one will be used."));
  81.310 -            }
  81.311 -
  81.312 -            if (toApply == null) {
  81.313 -                //TODO: currently giving a warning so that the hints can be augmented with "Options.QUERY", but that should be removed
  81.314 -                //if a non-query hint cannot produce any fix, it is likely Ok - if not, the hint should produce a warning itself
  81.315 -                boolean doWarning = false;
  81.316 -                assert doWarning = true;
  81.317 -                if (doWarning) {
  81.318 -                    problems.add(new MessageImpl(MessageKind.WARNING, "No fix for: " + ed.getDescription() + " at " + positionToString(ed) + "."));
  81.319 -                }
  81.320 -                continue;
  81.321 -            }
  81.322 -
  81.323 -            if (!(toApply instanceof JavaFixImpl)) {
  81.324 -                throw new IllegalStateException(toApply.getClass().getName());//XXX: hints need to provide JavaFixes
  81.325 -            }
  81.326 -
  81.327 -
  81.328 -            fixes.add(((JavaFixImpl) toApply).jf);
  81.329 -        }
  81.330 -        if (fixDependencies(copy.getFileObject(), fixes, processedDependencyChanges)) {
  81.331 -            return true;
  81.332 -        }
  81.333 -        for (JavaFix f : fixes) {
  81.334 -//                    if (cancel.get()) return ;
  81.335 -
  81.336 -            JavaFixImpl.Accessor.INSTANCE.process(f, copy, false, resourceContentChanges, fileChanges);
  81.337 -            
  81.338 -            if (changesPerFix != null) {
  81.339 -                ElementOverlay overlay = ElementOverlay.getOrCreateOverlay(); //XXX: will use the incorrect overlay?
  81.340 -                Constructor<WorkingCopy> wcConstr = WorkingCopy.class.getDeclaredConstructor(CompilationInfoImpl.class, ElementOverlay.class);
  81.341 -                wcConstr.setAccessible(true);
  81.342 -
  81.343 -//                final WorkingCopy copy = new WorkingCopy(JavaSourceAccessor.getINSTANCE().getCompilationInfoImpl(parameter), overlay);
  81.344 -                WorkingCopy perFixCopy = wcConstr.newInstance(JavaSourceAccessor.getINSTANCE().getCompilationInfoImpl(copy), overlay);
  81.345 -                Method setJavaSource = CompilationInfo.class.getDeclaredMethod("setJavaSource", JavaSource.class);
  81.346 -                setJavaSource.setAccessible(true);
  81.347 -
  81.348 -//                copy.setJavaSource(JavaSource.this);
  81.349 -                setJavaSource.invoke(perFixCopy, copy.getJavaSource());
  81.350 -
  81.351 -                perFixCopy.toPhase(Phase.RESOLVED);
  81.352 -                
  81.353 -                final Map<FileObject, byte[]> perFixResourceContentChanges = new HashMap<FileObject, byte[]>();
  81.354 -        
  81.355 -                JavaFixImpl.Accessor.INSTANCE.process(f, perFixCopy, false, perFixResourceContentChanges, new ArrayList<RefactoringElementImplementation>());
  81.356 -                
  81.357 -                final JavacTaskImpl jt = JavaSourceAccessor.getINSTANCE().getJavacTask(perFixCopy);
  81.358 -                Log.instance(jt.getContext()).nerrors = 0;
  81.359 -                Method getChanges = WorkingCopy.class.getDeclaredMethod("getChanges", Map.class);
  81.360 -                getChanges.setAccessible(true);
  81.361 -                
  81.362 -                Map<FileObject, List<Difference>> changes = new HashMap<FileObject, List<Difference>>();
  81.363 -                
  81.364 -                changes.put(perFixCopy.getFileObject(), (List<ModificationResult.Difference>) getChanges.invoke(perFixCopy, new HashMap<Object, int[]>()));
  81.365 -                
  81.366 -                addResourceContentChanges(resourceContentChanges, changes);
  81.367 -                
  81.368 -                for (Iterator<Entry<FileObject, List<Difference>>> it = changes.entrySet().iterator(); it.hasNext();) {
  81.369 -                    if (it.next().getValue().isEmpty()) it.remove();
  81.370 -                }
  81.371 -
  81.372 -                if (!changes.isEmpty()) {
  81.373 -                    ModificationResult perFixResult = JavaSourceAccessor.getINSTANCE().createModificationResult(changes, Collections.<Object, int[]>emptyMap());
  81.374 -
  81.375 -                    changesPerFix.put(f, perFixResult);
  81.376 -                }
  81.377 -            }
  81.378 -        }
  81.379 -        return false;
  81.380 -    }
  81.381 -    
  81.382 -    public static Collection<ModificationResult> applyFixes(final Map<FileObject, Collection<JavaFix>> toRun) {
  81.383 -        final Map<FileObject, List<ModificationResult.Difference>> result = new LinkedHashMap<FileObject, List<ModificationResult.Difference>>();
  81.384 -        final Map<FileObject, byte[]> resourceContentChanges = new HashMap<FileObject, byte[]>();
  81.385 -        Map<ClasspathInfo, Collection<FileObject>> cp2Files = BatchUtilities.sortFiles(toRun.keySet());
  81.386 -
  81.387 -        for (Entry<ClasspathInfo, Collection<FileObject>> e : cp2Files.entrySet()) {
  81.388 -            try {
  81.389 -                ModificationResult mr = JavaSource.create(e.getKey(), e.getValue()).runModificationTask(new Task<WorkingCopy>() {
  81.390 -                    @Override
  81.391 -                    public void run(WorkingCopy parameter) throws Exception {
  81.392 -                        if (parameter.toPhase(Phase.RESOLVED).compareTo(Phase.RESOLVED) < 0) return ;
  81.393 -
  81.394 -                        for (JavaFix jf : toRun.get(parameter.getFileObject())) {
  81.395 -                            JavaFixImpl.Accessor.INSTANCE.process(jf, parameter, false, resourceContentChanges, new ArrayList<RefactoringElementImplementation>());
  81.396 -                        }
  81.397 -                    }
  81.398 -                });
  81.399 -                
  81.400 -                result.putAll(JavaSourceAccessor.getINSTANCE().getDiffsFromModificationResult(mr));
  81.401 -            } catch (IOException ex) {
  81.402 -                Exceptions.printStackTrace(ex);
  81.403 -            }
  81.404 -        }
  81.405 -        
  81.406 -        addResourceContentChanges(resourceContentChanges, result);
  81.407 -        
  81.408 -        return Collections.singletonList(JavaSourceAccessor.getINSTANCE().createModificationResult(result, Collections.<Object, int[]>emptyMap()));
  81.409 -    }
  81.410 -
  81.411 -    public static Collection<FileObject> getSourceGroups(Iterable<? extends Project> prjs) {
  81.412 -        List<FileObject> result = new LinkedList<FileObject>();
  81.413 -        
  81.414 -        for (Project p : prjs) {
  81.415 -            Sources s = ProjectUtils.getSources(p);
  81.416 -
  81.417 -            for (SourceGroup sg : s.getSourceGroups("java")) {
  81.418 -                result.add(sg.getRootFolder());
  81.419 -            }
  81.420 -        }
  81.421 -
  81.422 -        return result;
  81.423 -    }
  81.424 -
  81.425 -    public static Map<ClasspathInfo, Collection<FileObject>> sortFiles(Collection<? extends FileObject> from) {
  81.426 -        Map<CPCategorizer, Collection<FileObject>> m = new HashMap<CPCategorizer, Collection<FileObject>>();
  81.427 -
  81.428 -        for (FileObject f : from) {
  81.429 -            CPCategorizer cpCategorizer = new CPCategorizer(f);
  81.430 -
  81.431 -            Collection<FileObject> files = m.get(cpCategorizer);
  81.432 -
  81.433 -            if (files == null) {
  81.434 -                m.put(cpCategorizer, files = new LinkedList<FileObject>());
  81.435 -            }
  81.436 -
  81.437 -            files.add(f);
  81.438 -        }
  81.439 -        
  81.440 -        Map<ClasspathInfo, Collection<FileObject>> result = new IdentityHashMap<ClasspathInfo, Collection<FileObject>>();
  81.441 -
  81.442 -        for (Entry<CPCategorizer, Collection<FileObject>> e : m.entrySet()) {
  81.443 -            result.put(ClasspathInfo.create(e.getKey().boot, e.getKey().compile, e.getKey().source), e.getValue());
  81.444 -        }
  81.445 -        
  81.446 -        return result;
  81.447 -    }
  81.448 -    
  81.449 -    private static final ClassPath getClassPath(FileObject forFO, String id) {
  81.450 -        ClassPath result = ClassPath.getClassPath(forFO, id);
  81.451 -        
  81.452 -        if (result == null) {
  81.453 -            if (ClassPath.BOOT.equals(id)) {
  81.454 -                result = JavaPlatformManager.getDefault().getDefaultPlatform().getBootstrapLibraries();
  81.455 -            } else {
  81.456 -                result = ClassPath.EMPTY;
  81.457 -            }
  81.458 -        }
  81.459 -        
  81.460 -        return result;
  81.461 -    }
  81.462 -    
  81.463 -    private static final class CPCategorizer {
  81.464 -        private final String cps;
  81.465 -        private final ClassPath boot;
  81.466 -        private final ClassPath compile;
  81.467 -        private final ClassPath source;
  81.468 -        private final FileObject sourceRoot;
  81.469 -
  81.470 -        public CPCategorizer(FileObject file) {
  81.471 -            this.boot = getClassPath(file, ClassPath.BOOT);
  81.472 -            this.compile = getClassPath(file, ClassPath.COMPILE);
  81.473 -            this.source = getClassPath(file, ClassPath.SOURCE);
  81.474 -            this.sourceRoot = source != null ? source.findOwnerRoot(file) : null;
  81.475 -            
  81.476 -            StringBuilder cps = new StringBuilder();
  81.477 -            
  81.478 -            if (boot != null) cps.append(boot.toString(PathConversionMode.PRINT));
  81.479 -            if (compile != null) cps.append(compile.toString(PathConversionMode.PRINT));
  81.480 -            if (source != null) cps.append(source.toString(PathConversionMode.PRINT));
  81.481 -            
  81.482 -            this.cps = cps.toString();
  81.483 -        }
  81.484 -
  81.485 -        @Override
  81.486 -        public int hashCode() {
  81.487 -            int hash = 5;
  81.488 -            hash = 53 * hash + this.cps.hashCode();
  81.489 -            hash = 53 * hash + (this.sourceRoot != null ? this.sourceRoot.hashCode() : 0);
  81.490 -            return hash;
  81.491 -        }
  81.492 -
  81.493 -        @Override
  81.494 -        public boolean equals(Object obj) {
  81.495 -            if (obj == null) {
  81.496 -                return false;
  81.497 -            }
  81.498 -            if (getClass() != obj.getClass()) {
  81.499 -                return false;
  81.500 -            }
  81.501 -            final CPCategorizer other = (CPCategorizer) obj;
  81.502 -            if (!this.cps.equals(other.cps)) {
  81.503 -                return false;
  81.504 -            }
  81.505 -            if (this.sourceRoot != other.sourceRoot && (this.sourceRoot == null || !this.sourceRoot.equals(other.sourceRoot))) {
  81.506 -                return false;
  81.507 -            }
  81.508 -            return true;
  81.509 -        }
  81.510 -        
  81.511 -    }
  81.512 -
  81.513 -    public static final String ENSURE_DEPENDENCY = "ensure-dependency";
  81.514 -
  81.515 -    public static boolean fixDependencies(FileObject file, Iterable<? extends JavaFix> toProcess, Map<Project, Set<String>> alreadyProcessed) {
  81.516 -        boolean modified = false;
  81.517 -//        for (FileObject file : toProcess.keySet()) {
  81.518 -            for (JavaFix fix : toProcess) {
  81.519 -                String updateTo = Accessor.INSTANCE.getOptions(fix).get(ENSURE_DEPENDENCY);
  81.520 -
  81.521 -                if (updateTo != null) {
  81.522 -                    Project p = FileOwnerQuery.getOwner(file);
  81.523 -
  81.524 -                    if (p != null) {
  81.525 -                        Set<String> seen = alreadyProcessed.get(p);
  81.526 -
  81.527 -                        if (seen == null) {
  81.528 -                            alreadyProcessed.put(p, seen = new HashSet<String>());
  81.529 -                        }
  81.530 -
  81.531 -                        if (seen.add(updateTo)) {
  81.532 -                            for (ProjectDependencyUpgrader up : Lookup.getDefault().lookupAll(ProjectDependencyUpgrader.class)) {
  81.533 -                                if (up.ensureDependency(p, updateTo, false)) { //XXX: should check whether the given project was actually modified
  81.534 -                                    modified = true;
  81.535 -                                    break;
  81.536 -                                }
  81.537 -                            }
  81.538 -                            //TODO: fail if cannot update the dependency?
  81.539 -                        }
  81.540 -                    }
  81.541 -                }
  81.542 -            }
  81.543 -
  81.544 -            return modified;
  81.545 -//        }
  81.546 -    }
  81.547 -
  81.548 -    public static void recursive(FileObject root, FileObject file, Collection<FileObject> collected, ProgressHandleWrapper progress, int depth, Properties timeStamps, Set<String> removedFiles, boolean recursive) {
  81.549 -        if (!VisibilityQuery.getDefault().isVisible(file)) return;
  81.550 -
  81.551 -        if (file.isData()) {
  81.552 -            if (timeStamps != null) {
  81.553 -                String relativePath = FileUtil.getRelativePath(root, file);
  81.554 -                String lastModified = Long.toHexString(file.lastModified().getTime());
  81.555 -
  81.556 -                removedFiles.remove(relativePath);
  81.557 -
  81.558 -                if (lastModified.equals(timeStamps.getProperty(relativePath))) {
  81.559 -                    return;
  81.560 -                }
  81.561 -
  81.562 -                timeStamps.setProperty(relativePath, lastModified);
  81.563 -            }
  81.564 -
  81.565 -            if (/*???:*/"java".equals(file.getExt()) || "text/x-java".equals(FileUtil.getMIMEType(file, "text/x-java"))) {
  81.566 -                collected.add(file);
  81.567 -            }
  81.568 -        } else {
  81.569 -            FileObject[] children = file.getChildren();
  81.570 -
  81.571 -            if (children.length == 0) return;
  81.572 -
  81.573 -            ProgressHandleWrapper inner = depth < 2 ? progress.startNextPartWithEmbedding(ProgressHandleWrapper.prepareParts(children.length)) : null;
  81.574 -
  81.575 -            if (inner == null && progress != null) {
  81.576 -                progress.startNextPart(children.length);
  81.577 -            } else {
  81.578 -                progress = null;
  81.579 -            }
  81.580 -
  81.581 -            for (FileObject c : children) {
  81.582 -                if (recursive || c.isData())
  81.583 -                    recursive(root, c, collected, inner, depth + 1, timeStamps, removedFiles, recursive);
  81.584 -
  81.585 -                if (progress != null) progress.tick();
  81.586 -            }
  81.587 -        }
  81.588 -    }    
  81.589 -}
    82.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/batch/ProgressHandleWrapper.java	Sun Oct 16 08:01:27 2016 +0200
    82.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    82.3 @@ -1,293 +0,0 @@
    82.4 -/*
    82.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    82.6 - *
    82.7 - * Copyright 2009-2011 Oracle and/or its affiliates. All rights reserved.
    82.8 - *
    82.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   82.10 - * Other names may be trademarks of their respective owners.
   82.11 - *
   82.12 - * The contents of this file are subject to the terms of either the GNU
   82.13 - * General Public License Version 2 only ("GPL") or the Common
   82.14 - * Development and Distribution License("CDDL") (collectively, the
   82.15 - * "License"). You may not use this file except in compliance with the
   82.16 - * License. You can obtain a copy of the License at
   82.17 - * http://www.netbeans.org/cddl-gplv2.html
   82.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   82.19 - * specific language governing permissions and limitations under the
   82.20 - * License.  When distributing the software, include this License Header
   82.21 - * Notice in each file and include the License file at
   82.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   82.23 - * particular file as subject to the "Classpath" exception as provided
   82.24 - * by Oracle in the GPL Version 2 section of the License file that
   82.25 - * accompanied this code. If applicable, add the following below the
   82.26 - * License Header, with the fields enclosed by brackets [] replaced by
   82.27 - * your own identifying information:
   82.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   82.29 - *
   82.30 - * If you wish your version of this file to be governed by only the CDDL
   82.31 - * or only the GPL Version 2, indicate your decision by adding
   82.32 - * "[Contributor] elects to include this software in this distribution
   82.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   82.34 - * single choice of license, a recipient has the option to distribute
   82.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   82.36 - * to extend the choice of license to its licensees as provided above.
   82.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   82.38 - * Version 2 license, then the option applies only if the new code is
   82.39 - * made subject to such option by the copyright holder.
   82.40 - *
   82.41 - * Contributor(s):
   82.42 - *
   82.43 - * Portions Copyrighted 2009-2011 Sun Microsystems, Inc.
   82.44 - */
   82.45 -package org.netbeans.modules.java.hints.spiimpl.batch;
   82.46 -
   82.47 -import java.util.Arrays;
   82.48 -import java.util.logging.Level;
   82.49 -import java.util.logging.Logger;
   82.50 -import org.netbeans.api.progress.ProgressHandle;
   82.51 -import org.netbeans.modules.analysis.spi.Analyzer.Context;
   82.52 -import org.netbeans.modules.java.hints.spiimpl.Utilities;
   82.53 -
   82.54 -public final class ProgressHandleWrapper {
   82.55 -
   82.56 -    private static final int TOTAL = 1000;
   82.57 -    private final ProgressHandleAbstraction handle;
   82.58 -    private final int[] parts;
   82.59 -    private int currentPart = -1;
   82.60 -    private int currentPartTotalWork;
   82.61 -    private int currentPartWorkDone;
   82.62 -    private long currentPartStartTime;
   82.63 -    private int currentOffset;
   82.64 -    private final long[] spentTime;
   82.65 -    private boolean debug;
   82.66 -
   82.67 -    public ProgressHandleWrapper(int... parts) {
   82.68 -        this((ProgressHandleAbstraction) null, parts);
   82.69 -    }
   82.70 -
   82.71 -    public ProgressHandleWrapper(ProgressHandle handle, int... parts) {
   82.72 -        this(new ProgressHandleBasedProgressHandleAbstraction(handle), parts);
   82.73 -    }
   82.74 -
   82.75 -    public ProgressHandleWrapper(Context handle, int... parts) {
   82.76 -        this(new AnalysisContextBasedProgressHandleAbstraction(handle), parts);
   82.77 -    }
   82.78 -
   82.79 -    public ProgressHandleWrapper(ProgressHandleAbstraction handle, int... parts) {
   82.80 -        this.handle = handle;
   82.81 -        if (handle == null) {
   82.82 -            this.parts = null;
   82.83 -            this.spentTime = null;
   82.84 -        } else {
   82.85 -            int total = 0;
   82.86 -            for (int i : parts) {
   82.87 -                total += i;
   82.88 -            }
   82.89 -            this.parts = new int[parts.length];
   82.90 -            for (int cntr = 0; cntr < parts.length; cntr++) {
   82.91 -                this.parts[cntr] = (TOTAL * parts[cntr]) / total;
   82.92 -            }
   82.93 -            this.spentTime = new long[parts.length];
   82.94 -        }
   82.95 -    }
   82.96 -
   82.97 -    public void setDebug(boolean debug) {
   82.98 -        this.debug = debug;
   82.99 -    }
  82.100 -
  82.101 -    public void startNextPart(int totalWork) {
  82.102 -        if (handle == null) {
  82.103 -            return;
  82.104 -        }
  82.105 -        if (currentPart == (-1)) {
  82.106 -            handle.start(TOTAL);
  82.107 -        } else {
  82.108 -            currentOffset += parts[currentPart];
  82.109 -            spentTime[currentPart] = System.currentTimeMillis() - currentPartStartTime;
  82.110 -        }
  82.111 -        currentPart++;
  82.112 -        currentPartTotalWork = totalWork;
  82.113 -        currentPartWorkDone = 0;
  82.114 -        currentPartStartTime = System.currentTimeMillis();
  82.115 -        currentPartWorkDoneUpdated();
  82.116 -    }
  82.117 -
  82.118 -    public ProgressHandleWrapper startNextPartWithEmbedding(int... embeddedParts) {
  82.119 -//        startNextPart(TOTAL);
  82.120 -        return new ProgressHandleWrapper(new ProgressHandleWrapperBasedProgressHandleAbstraction(this), embeddedParts);
  82.121 -    }
  82.122 -
  82.123 -    public void tick() {
  82.124 -        if (handle == null) {
  82.125 -            return;
  82.126 -        }
  82.127 -        currentPartWorkDone++;
  82.128 -        currentPartWorkDoneUpdated();
  82.129 -    }
  82.130 -
  82.131 -    private void setCurrentPartWorkDone(int done) {
  82.132 -        if (handle == null) {
  82.133 -            return;
  82.134 -        }
  82.135 -        currentPartWorkDone = done;
  82.136 -        currentPartWorkDoneUpdated();
  82.137 -    }
  82.138 -
  82.139 -    private void currentPartWorkDoneUpdated() {
  82.140 -        if (currentPartTotalWork > 0) {
  82.141 -            int parentProgress = currentOffset + (parts[currentPart] * currentPartWorkDone) / currentPartTotalWork;
  82.142 -            if (debug) {
  82.143 -                System.err.println("currentOffset=" + currentOffset);
  82.144 -                System.err.println("currentPart=" + currentPart);
  82.145 -                System.err.println("parts[currentPart]= " +parts[currentPart]);
  82.146 -                System.err.println("currentPartWorkDone=" + currentPartWorkDone);
  82.147 -                System.err.println("currentPartTotalWork= " +currentPartTotalWork);
  82.148 -                System.err.println("parentProgress=" + parentProgress);
  82.149 -            }
  82.150 -            handle.progress(parentProgress);
  82.151 -        } else {
  82.152 -            handle.progress(currentOffset + parts[currentPart]);
  82.153 -        }
  82.154 -        setAutomatedMessage();
  82.155 -    }
  82.156 -
  82.157 -    public void setMessage(String message) {
  82.158 -        if (handle == null) {
  82.159 -            return;
  82.160 -        }
  82.161 -        handle.progress(message);
  82.162 -    }
  82.163 -
  82.164 -    private void setAutomatedMessage() {
  82.165 -        if (handle == null || currentPart == (-1)) {
  82.166 -            return;
  82.167 -        }
  82.168 -        long spentTime = System.currentTimeMillis() - currentPartStartTime;
  82.169 -        double timePerUnit = ((double) spentTime) / currentPartWorkDone;
  82.170 -        String timeString;
  82.171 -        if (spentTime > 0) {
  82.172 -            double totalTime = currentPartTotalWork * timePerUnit;
  82.173 -            timeString = Utilities.toHumanReadableTime(spentTime) + "/" + Utilities.toHumanReadableTime(totalTime);
  82.174 -        } else {
  82.175 -            timeString = "No estimate";
  82.176 -        }
  82.177 -        handle.progress("Part " + (currentPart + 1) + "/" + parts.length + ", " + currentPartWorkDone + "/" + currentPartTotalWork + ", " + timeString);
  82.178 -    }
  82.179 -
  82.180 -    public void finish() {
  82.181 -        if (handle == null) {
  82.182 -            return ;
  82.183 -        }
  82.184 -
  82.185 -        handle.finish();
  82.186 -
  82.187 -        if (currentPart < 0) return ;
  82.188 -        
  82.189 -        spentTime[currentPart] = System.currentTimeMillis() - currentPartStartTime;
  82.190 -
  82.191 -        double total = 0.0;
  82.192 -
  82.193 -        for (long t : spentTime) {
  82.194 -            total += t;
  82.195 -        }
  82.196 -
  82.197 -        double[] actualSplit = new double[spentTime.length];
  82.198 -        int i = 0;
  82.199 -
  82.200 -        for (long t : spentTime) {
  82.201 -            actualSplit[i++] = TOTAL * (t / total);
  82.202 -        }
  82.203 -
  82.204 -        Logger.getLogger(ProgressHandleWrapper.class.getName()).log(Level.FINE, "Progress handle with split: {0}, actual times: {1}, actual split: {2}", new Object[] {Arrays.toString(parts), Arrays.toString(spentTime), Arrays.toString(actualSplit)});
  82.205 -    }
  82.206 -
  82.207 -    public static int[] prepareParts(int count) {
  82.208 -        int[] result = new int[count];
  82.209 -
  82.210 -        for (int cntr = 0; cntr < count; cntr++) {
  82.211 -            result[cntr] = 1;
  82.212 -        }
  82.213 -
  82.214 -        return result;
  82.215 -    }
  82.216 -
  82.217 -    public static interface ProgressHandleAbstraction {
  82.218 -
  82.219 -        public void start(int totalWork);
  82.220 -
  82.221 -        public void progress(int currentWorkDone);
  82.222 -
  82.223 -        public void progress(String message);
  82.224 -
  82.225 -        public void finish();
  82.226 -
  82.227 -    }
  82.228 -
  82.229 -    private static final class ProgressHandleBasedProgressHandleAbstraction implements ProgressHandleAbstraction {
  82.230 -        private final ProgressHandle delegate;
  82.231 -        public ProgressHandleBasedProgressHandleAbstraction(ProgressHandle delegate) {
  82.232 -            this.delegate = delegate;
  82.233 -        }
  82.234 -
  82.235 -        public void start(int totalWork) {
  82.236 -            delegate.start(totalWork);
  82.237 -        }
  82.238 -
  82.239 -        public void progress(int currentWorkDone) {
  82.240 -            delegate.progress(currentWorkDone);
  82.241 -        }
  82.242 -
  82.243 -        public void progress(String message) {
  82.244 -            delegate.progress(message);
  82.245 -        }
  82.246 -
  82.247 -        public void finish() {
  82.248 -            delegate.finish();
  82.249 -        }
  82.250 -    }
  82.251 -
  82.252 -    private static final class AnalysisContextBasedProgressHandleAbstraction implements ProgressHandleAbstraction {
  82.253 -        private final Context delegate;
  82.254 -        AnalysisContextBasedProgressHandleAbstraction(Context delegate) {
  82.255 -            this.delegate = delegate;
  82.256 -        }
  82.257 -
  82.258 -        public void start(int totalWork) {
  82.259 -            delegate.start(totalWork);
  82.260 -        }
  82.261 -
  82.262 -        public void progress(int currentWorkDone) {
  82.263 -            delegate.progress(currentWorkDone);
  82.264 -        }
  82.265 -
  82.266 -        public void progress(String message) {
  82.267 -            delegate.progress(message);
  82.268 -        }
  82.269 -
  82.270 -        public void finish() {
  82.271 -            delegate.finish();
  82.272 -        }
  82.273 -    }
  82.274 -
  82.275 -    private static final class ProgressHandleWrapperBasedProgressHandleAbstraction implements ProgressHandleAbstraction {
  82.276 -        private final ProgressHandleWrapper delegate;
  82.277 -        public ProgressHandleWrapperBasedProgressHandleAbstraction(ProgressHandleWrapper delegate) {
  82.278 -            this.delegate = delegate;
  82.279 -        }
  82.280 -
  82.281 -        public void start(int totalWork) {
  82.282 -            delegate.startNextPart(totalWork);
  82.283 -        }
  82.284 -
  82.285 -        public void progress(int currentWorkDone) {
  82.286 -            delegate.setCurrentPartWorkDone(currentWorkDone);
  82.287 -        }
  82.288 -
  82.289 -        public void progress(String message) {
  82.290 -            delegate.setMessage(message);
  82.291 -        }
  82.292 -
  82.293 -        public void finish() {}
  82.294 -    }
  82.295 -
  82.296 -}
    83.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/batch/Scopes.java	Sun Oct 16 08:01:27 2016 +0200
    83.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    83.3 @@ -1,141 +0,0 @@
    83.4 -/*
    83.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    83.6 - *
    83.7 - * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
    83.8 - *
    83.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   83.10 - * Other names may be trademarks of their respective owners.
   83.11 - *
   83.12 - * The contents of this file are subject to the terms of either the GNU
   83.13 - * General Public License Version 2 only ("GPL") or the Common
   83.14 - * Development and Distribution License("CDDL") (collectively, the
   83.15 - * "License"). You may not use this file except in compliance with the
   83.16 - * License. You can obtain a copy of the License at
   83.17 - * http://www.netbeans.org/cddl-gplv2.html
   83.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   83.19 - * specific language governing permissions and limitations under the
   83.20 - * License.  When distributing the software, include this License Header
   83.21 - * Notice in each file and include the License file at
   83.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   83.23 - * particular file as subject to the "Classpath" exception as provided
   83.24 - * by Oracle in the GPL Version 2 section of the License file that
   83.25 - * accompanied this code. If applicable, add the following below the
   83.26 - * License Header, with the fields enclosed by brackets [] replaced by
   83.27 - * your own identifying information:
   83.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   83.29 - *
   83.30 - * If you wish your version of this file to be governed by only the CDDL
   83.31 - * or only the GPL Version 2, indicate your decision by adding
   83.32 - * "[Contributor] elects to include this software in this distribution
   83.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   83.34 - * single choice of license, a recipient has the option to distribute
   83.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   83.36 - * to extend the choice of license to its licensees as provided above.
   83.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   83.38 - * Version 2 license, then the option applies only if the new code is
   83.39 - * made subject to such option by the copyright holder.
   83.40 - *
   83.41 - * Contributor(s):
   83.42 - *
   83.43 - * Portions Copyrighted 2011 Sun Microsystems, Inc.
   83.44 - */
   83.45 -package org.netbeans.modules.java.hints.spiimpl.batch;
   83.46 -
   83.47 -import java.util.Arrays;
   83.48 -import java.util.Collection;
   83.49 -import java.util.HashSet;
   83.50 -import java.util.Set;
   83.51 -import org.netbeans.api.java.classpath.ClassPath;
   83.52 -import org.netbeans.api.java.classpath.GlobalPathRegistry;
   83.53 -import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.Folder;
   83.54 -import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.IndexEnquirer;
   83.55 -import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.MapIndices;
   83.56 -import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.Scope;
   83.57 -import org.netbeans.modules.java.hints.providers.spi.HintDescription;
   83.58 -import org.openide.filesystems.FileObject;
   83.59 -import org.openide.util.Lookup;
   83.60 -
   83.61 -/**
   83.62 - *
   83.63 - * @author lahvac
   83.64 - */
   83.65 -public class Scopes {
   83.66 -
   83.67 -    public static Scope allOpenedProjectsScope() {
   83.68 -        return new AllOpenedProjectsScope();
   83.69 -    }
   83.70 -
   83.71 -    private static final class AllOpenedProjectsScope extends Scope {
   83.72 -
   83.73 -        @Override
   83.74 -        public String getDisplayName() {
   83.75 -            return "All Opened Projects";
   83.76 -        }
   83.77 -
   83.78 -        @Override
   83.79 -        public Collection<? extends Folder> getTodo() {
   83.80 -            Set<Folder> todo = new HashSet<Folder>();
   83.81 -
   83.82 -            for (ClassPath source : GlobalPathRegistry.getDefault().getPaths(ClassPath.SOURCE)) {
   83.83 -                todo.addAll(Arrays.asList(Folder.convert(source.getRoots())));
   83.84 -            }
   83.85 -
   83.86 -            return todo;
   83.87 -        }
   83.88 -
   83.89 -        @Override
   83.90 -        public MapIndices getIndexMapper(Iterable<? extends HintDescription> hints) {
   83.91 -            return getDefaultIndicesMapper();
   83.92 -        }
   83.93 -    }
   83.94 -
   83.95 -    public static Scope specifiedFoldersScope(Folder... roots) {
   83.96 -        return new SpecificFoldersScope(roots);
   83.97 -    }
   83.98 -    
   83.99 -    private static final class SpecificFoldersScope extends Scope {
  83.100 -
  83.101 -        private final Collection<? extends Folder> roots;
  83.102 -
  83.103 -        public SpecificFoldersScope(Folder... roots) {
  83.104 -            this.roots = Arrays.asList(roots);
  83.105 -        }
  83.106 -
  83.107 -        @Override
  83.108 -        public String getDisplayName() {
  83.109 -            return "Specified Root";
  83.110 -        }
  83.111 -
  83.112 -        @Override
  83.113 -        public Collection<? extends Folder> getTodo() {
  83.114 -            return roots;
  83.115 -        }
  83.116 -
  83.117 -        @Override
  83.118 -        public MapIndices getIndexMapper(Iterable<? extends HintDescription> hints) {
  83.119 -            return getDefaultIndicesMapper();
  83.120 -        }
  83.121 -    }
  83.122 -
  83.123 -    public static MapIndices getDefaultIndicesMapper() {
  83.124 -        return new MapIndices() {
  83.125 -            @Override
  83.126 -            public IndexEnquirer findIndex(FileObject root, ProgressHandleWrapper progress, boolean recursive) {
  83.127 -                IndexEnquirer e = findIndexEnquirer(root, progress, recursive);
  83.128 -
  83.129 -                if (e != null) return e;
  83.130 -                else return new BatchSearch.FileSystemBasedIndexEnquirer(root, recursive);
  83.131 -            }
  83.132 -        };
  83.133 -    }
  83.134 -    
  83.135 -    public static IndexEnquirer findIndexEnquirer(FileObject root, ProgressHandleWrapper progress, boolean recursive) {
  83.136 -        for (MapIndices mi : Lookup.getDefault().lookupAll(MapIndices.class)) {
  83.137 -            IndexEnquirer r = mi.findIndex(root, progress, recursive);
  83.138 -
  83.139 -            if (r != null) return r;
  83.140 -        }
  83.141 -
  83.142 -        return null;
  83.143 -    }
  83.144 -}
    84.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/hints/GlobalProcessingContext.java	Sun Oct 16 08:01:27 2016 +0200
    84.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    84.3 @@ -1,56 +0,0 @@
    84.4 -/*
    84.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    84.6 - *
    84.7 - * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
    84.8 - *
    84.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   84.10 - * Other names may be trademarks of their respective owners.
   84.11 - *
   84.12 - * The contents of this file are subject to the terms of either the GNU
   84.13 - * General Public License Version 2 only ("GPL") or the Common
   84.14 - * Development and Distribution License("CDDL") (collectively, the
   84.15 - * "License"). You may not use this file except in compliance with the
   84.16 - * License. You can obtain a copy of the License at
   84.17 - * http://www.netbeans.org/cddl-gplv2.html
   84.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   84.19 - * specific language governing permissions and limitations under the
   84.20 - * License.  When distributing the software, include this License Header
   84.21 - * Notice in each file and include the License file at
   84.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   84.23 - * particular file as subject to the "Classpath" exception as provided
   84.24 - * by Oracle in the GPL Version 2 section of the License file that
   84.25 - * accompanied this code. If applicable, add the following below the
   84.26 - * License Header, with the fields enclosed by brackets [] replaced by
   84.27 - * your own identifying information:
   84.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   84.29 - *
   84.30 - * If you wish your version of this file to be governed by only the CDDL
   84.31 - * or only the GPL Version 2, indicate your decision by adding
   84.32 - * "[Contributor] elects to include this software in this distribution
   84.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   84.34 - * single choice of license, a recipient has the option to distribute
   84.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   84.36 - * to extend the choice of license to its licensees as provided above.
   84.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   84.38 - * Version 2 license, then the option applies only if the new code is
   84.39 - * made subject to such option by the copyright holder.
   84.40 - *
   84.41 - * Contributor(s):
   84.42 - *
   84.43 - * Portions Copyrighted 2013 Sun Microsystems, Inc.
   84.44 - */
   84.45 -package org.netbeans.modules.java.hints.spiimpl.hints;
   84.46 -
   84.47 -import java.util.HashMap;
   84.48 -import java.util.List;
   84.49 -import java.util.Map;
   84.50 -import org.netbeans.api.java.source.TreePathHandle;
   84.51 -import org.netbeans.spi.java.hints.Decision;
   84.52 -
   84.53 -/**
   84.54 - *
   84.55 - * @author lahvac
   84.56 - */
   84.57 -public class GlobalProcessingContext {
   84.58 -    public final Map<TreePathHandle, List<Decision<?, ?>>> decisions = new HashMap<TreePathHandle, List<Decision<?, ?>>>();
   84.59 -}
    85.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/hints/HintsInvoker.java	Sun Oct 16 08:01:27 2016 +0200
    85.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    85.3 @@ -1,863 +0,0 @@
    85.4 -/*
    85.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    85.6 - *
    85.7 - * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
    85.8 - *
    85.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   85.10 - * Other names may be trademarks of their respective owners.
   85.11 - *
   85.12 - * The contents of this file are subject to the terms of either the GNU
   85.13 - * General Public License Version 2 only ("GPL") or the Common
   85.14 - * Development and Distribution License("CDDL") (collectively, the
   85.15 - * "License"). You may not use this file except in compliance with the
   85.16 - * License. You can obtain a copy of the License at
   85.17 - * http://www.netbeans.org/cddl-gplv2.html
   85.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   85.19 - * specific language governing permissions and limitations under the
   85.20 - * License.  When distributing the software, include this License Header
   85.21 - * Notice in each file and include the License file at
   85.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   85.23 - * particular file as subject to the "Classpath" exception as provided
   85.24 - * by Oracle in the GPL Version 2 section of the License file that
   85.25 - * accompanied this code. If applicable, add the following below the
   85.26 - * License Header, with the fields enclosed by brackets [] replaced by
   85.27 - * your own identifying information:
   85.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   85.29 - *
   85.30 - * If you wish your version of this file to be governed by only the CDDL
   85.31 - * or only the GPL Version 2, indicate your decision by adding
   85.32 - * "[Contributor] elects to include this software in this distribution
   85.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   85.34 - * single choice of license, a recipient has the option to distribute
   85.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   85.36 - * to extend the choice of license to its licensees as provided above.
   85.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   85.38 - * Version 2 license, then the option applies only if the new code is
   85.39 - * made subject to such option by the copyright holder.
   85.40 - *
   85.41 - * Contributor(s):
   85.42 - *
   85.43 - * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
   85.44 - */
   85.45 -
   85.46 -package org.netbeans.modules.java.hints.spiimpl.hints;
   85.47 -
   85.48 -import com.sun.source.tree.Tree;
   85.49 -import java.util.Stack;
   85.50 -import java.util.concurrent.atomic.AtomicBoolean;
   85.51 -import javax.lang.model.element.AnnotationMirror;
   85.52 -import javax.lang.model.element.AnnotationValue;
   85.53 -import javax.lang.model.element.Element;
   85.54 -import javax.lang.model.element.ExecutableElement;
   85.55 -import javax.lang.model.element.TypeElement;
   85.56 -import javax.swing.text.Document;
   85.57 -import org.netbeans.api.java.source.support.CancellableTreePathScanner;
   85.58 -import org.netbeans.editor.GuardedDocument;
   85.59 -import org.netbeans.editor.MarkBlock;
   85.60 -import org.netbeans.editor.MarkBlockChain;
   85.61 -import org.openide.filesystems.FileObject;
   85.62 -
   85.63 -import com.sun.source.tree.Tree.Kind;
   85.64 -import com.sun.source.util.TreePath;
   85.65 -import com.sun.source.util.Trees;
   85.66 -import java.io.IOException;
   85.67 -import java.util.ArrayList;
   85.68 -import java.util.Arrays;
   85.69 -import java.util.Collection;
   85.70 -import java.util.Collections;
   85.71 -import java.util.Comparator;
   85.72 -import java.util.EnumMap;
   85.73 -import java.util.HashMap;
   85.74 -import java.util.HashSet;
   85.75 -import java.util.Iterator;
   85.76 -import java.util.LinkedList;
   85.77 -import java.util.List;
   85.78 -import java.util.Map;
   85.79 -import java.util.Map.Entry;
   85.80 -import java.util.Set;
   85.81 -import java.util.prefs.Preferences;
   85.82 -import javax.annotation.processing.ProcessingEnvironment;
   85.83 -import javax.lang.model.type.TypeKind;
   85.84 -import javax.lang.model.type.TypeMirror;
   85.85 -import org.netbeans.api.annotations.common.CheckForNull;
   85.86 -import org.netbeans.api.java.source.CompilationInfo;
   85.87 -import org.netbeans.modules.java.hints.spiimpl.Hacks;
   85.88 -import org.netbeans.spi.java.hints.HintContext;
   85.89 -import org.netbeans.modules.java.hints.providers.spi.HintDescription;
   85.90 -import org.netbeans.modules.java.hints.providers.spi.HintMetadata;
   85.91 -import org.netbeans.modules.java.hints.providers.spi.Trigger;
   85.92 -import org.netbeans.modules.java.hints.providers.spi.Trigger.Kinds;
   85.93 -import org.netbeans.modules.java.hints.providers.spi.Trigger.PatternDescription;
   85.94 -import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings;
   85.95 -import org.netbeans.modules.java.hints.spiimpl.MessageImpl;
   85.96 -import org.netbeans.modules.java.hints.spiimpl.RulesManager;
   85.97 -import org.netbeans.modules.java.hints.spiimpl.SPIAccessor;
   85.98 -import org.netbeans.modules.java.hints.spiimpl.Utilities;
   85.99 -import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch;
  85.100 -import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch.BulkPattern;
  85.101 -import org.netbeans.modules.java.hints.spiimpl.pm.PatternCompiler;
  85.102 -import org.netbeans.spi.editor.hints.ErrorDescription;
  85.103 -import org.netbeans.spi.editor.hints.Severity;
  85.104 -import org.netbeans.spi.java.hints.Hint;
  85.105 -import org.netbeans.api.java.source.matching.Matcher;
  85.106 -import org.netbeans.api.java.source.matching.Occurrence;
  85.107 -import org.netbeans.api.java.source.matching.Pattern;
  85.108 -import org.netbeans.modules.java.hints.providers.spi.Trigger.DecisionTrigger;
  85.109 -import org.openide.util.Exceptions;
  85.110 -
  85.111 -/**
  85.112 - *
  85.113 - * @author lahvac
  85.114 - */
  85.115 -public class HintsInvoker {
  85.116 -
  85.117 -    private final Map<String, Long> timeLog = new HashMap<String, Long>();
  85.118 -
  85.119 -    private final HintsSettings settings;
  85.120 -    private final int caret;
  85.121 -    private final int from;
  85.122 -    private final int to;
  85.123 -    private final GlobalProcessingContext globalContext;
  85.124 -    private final AtomicBoolean cancel;
  85.125 -
  85.126 -    public HintsInvoker(HintsSettings settings, AtomicBoolean cancel) {
  85.127 -        this(settings, null, cancel);
  85.128 -    }
  85.129 -
  85.130 -    public HintsInvoker(HintsSettings settings, GlobalProcessingContext globalContext, AtomicBoolean cancel) {
  85.131 -        this(settings, -1, -1, -1, globalContext, cancel);
  85.132 -    }
  85.133 -
  85.134 -    public HintsInvoker(HintsSettings settings, int caret, AtomicBoolean cancel) {
  85.135 -        this(settings, caret, -1, -1, null, cancel);
  85.136 -    }
  85.137 -
  85.138 -    public HintsInvoker(HintsSettings settings, int from, int to, AtomicBoolean cancel) {
  85.139 -        this(settings, -1, from, to, null, cancel);
  85.140 -    }
  85.141 -
  85.142 -    private HintsInvoker(HintsSettings settings, int caret, int from, int to, GlobalProcessingContext globalContext, AtomicBoolean cancel) {
  85.143 -        this.settings = settings;
  85.144 -        this.caret = caret;
  85.145 -        this.from = from;
  85.146 -        this.to = to;
  85.147 -        this.globalContext = globalContext;
  85.148 -        this.cancel = cancel;
  85.149 -    }
  85.150 -
  85.151 -    @CheckForNull
  85.152 -    public List<ErrorDescription> computeHints(CompilationInfo info) {
  85.153 -        return computeHints(info, new TreePath(info.getCompilationUnit()));
  85.154 -    }
  85.155 -
  85.156 -    private List<ErrorDescription> computeHints(CompilationInfo info, TreePath startAt) {
  85.157 -        List<HintDescription> descs = new LinkedList<HintDescription>();
  85.158 -        Map<HintMetadata, ? extends Collection<? extends HintDescription>> allHints = RulesManager.getInstance().readHints(info, null, cancel);
  85.159 -
  85.160 -        for (Entry<HintMetadata, ? extends Collection<? extends HintDescription>> e : allHints.entrySet()) {
  85.161 -            HintMetadata m = e.getKey();
  85.162 -
  85.163 -            if (!settings.isEnabled(m)) {
  85.164 -                continue;
  85.165 -            }
  85.166 -
  85.167 -            if (caret != -1) {
  85.168 -                if (m.kind == Hint.Kind.ACTION) {
  85.169 -                    descs.addAll(e.getValue());
  85.170 -                } else {
  85.171 -                    if (settings.getSeverity(m) == Severity.HINT) {
  85.172 -                        descs.addAll(e.getValue());
  85.173 -                    }
  85.174 -                }
  85.175 -            } else {
  85.176 -                if (m.kind == Hint.Kind.INSPECTION) {
  85.177 -                    if (settings.getSeverity(m) != Severity.HINT) {
  85.178 -                        descs.addAll(e.getValue());
  85.179 -                    }
  85.180 -                }
  85.181 -            }
  85.182 -        }
  85.183 -
  85.184 -        List<ErrorDescription> errors = join(computeHints(info, startAt, descs, new LinkedList<MessageImpl>()));
  85.185 -
  85.186 -        dumpTimeSpentInHints();
  85.187 -        
  85.188 -        return errors;
  85.189 -    }
  85.190 -
  85.191 -    @CheckForNull
  85.192 -    public List<ErrorDescription> computeHints(CompilationInfo info,
  85.193 -                                               Iterable<? extends HintDescription> hints) {
  85.194 -        return computeHints(info, hints, new LinkedList<MessageImpl>());
  85.195 -    }
  85.196 -
  85.197 -    @CheckForNull
  85.198 -    public List<ErrorDescription> computeHints(CompilationInfo info,
  85.199 -                                               Iterable<? extends HintDescription> hints,
  85.200 -                                               Collection<? super MessageImpl> problems) {
  85.201 -        return join(computeHints(info, new TreePath(info.getCompilationUnit()), hints, problems));
  85.202 -    }
  85.203 -
  85.204 -    private static final Iterable<? extends Class<? extends Trigger>> TRIGGER_KINDS = Arrays.asList(Kinds.class, PatternDescription.class, DecisionTrigger.class);
  85.205 -    
  85.206 -    @CheckForNull
  85.207 -    public Map<HintDescription, List<ErrorDescription>> computeHints(CompilationInfo info,
  85.208 -                                        TreePath startAt,
  85.209 -                                        Iterable<? extends HintDescription> hints,
  85.210 -                                        Collection<? super MessageImpl> problems) {
  85.211 -        return computeHints(info, startAt, true, hints, problems);
  85.212 -    }
  85.213 -    
  85.214 -    @CheckForNull
  85.215 -    public Map<HintDescription, List<ErrorDescription>> computeHints(CompilationInfo info,
  85.216 -                                        TreePath startAt,
  85.217 -                                        boolean recursive,
  85.218 -                                        Iterable<? extends HintDescription> hints,
  85.219 -                                        Collection<? super MessageImpl> problems) {
  85.220 -        Map<Class, List<HintDescription>> triggerKind2Hints = new HashMap<Class, List<HintDescription>>();
  85.221 -
  85.222 -        for (Class<? extends Trigger> c : TRIGGER_KINDS) {
  85.223 -            triggerKind2Hints.put(c, new ArrayList<HintDescription>());
  85.224 -        }
  85.225 -
  85.226 -        for (HintDescription hd : hints) {
  85.227 -            List<HintDescription> sorted = triggerKind2Hints.get(hd.getTrigger().getClass());
  85.228 -
  85.229 -            sorted.add(hd);
  85.230 -        }
  85.231 -
  85.232 -        if (caret != -1) {
  85.233 -            TreePath tp = info.getTreeUtilities().pathFor(caret);
  85.234 -            return computeSuggestions(info, tp, true, triggerKind2Hints, problems);
  85.235 -        } else {
  85.236 -            if (from != (-1) && to != (-1)) {
  85.237 -                return computeHintsInSpan(info, triggerKind2Hints, problems);
  85.238 -            } else if (!recursive) {
  85.239 -                return computeSuggestions(info, startAt, false, triggerKind2Hints, problems);
  85.240 -            } else {
  85.241 -                return computeHintsImpl(info, startAt, triggerKind2Hints, problems);
  85.242 -            }
  85.243 -        }
  85.244 -    }
  85.245 -
  85.246 -    private Map<HintDescription, List<ErrorDescription>> computeHintsImpl(CompilationInfo info,
  85.247 -                                        TreePath startAt,
  85.248 -                                        Map<Class, List<HintDescription>> triggerKind2Hints,
  85.249 -                                        Collection<? super MessageImpl> problems) {
  85.250 -        Map<HintDescription, List<ErrorDescription>> errors = new HashMap<HintDescription, List<ErrorDescription>>();
  85.251 -        List<HintDescription> kindBasedHints = triggerKind2Hints.get(Kinds.class);
  85.252 -
  85.253 -        timeLog.put("[C] Kind Based Hints", (long) kindBasedHints.size());
  85.254 -
  85.255 -        if (!kindBasedHints.isEmpty()) {
  85.256 -            long kindStart = System.currentTimeMillis();
  85.257 -
  85.258 -            new ScannerImpl(info, cancel, sortByKinds(kindBasedHints), problems).scan(startAt, errors);
  85.259 -
  85.260 -            long kindEnd = System.currentTimeMillis();
  85.261 -
  85.262 -            timeLog.put("Kind Based Hints", kindEnd - kindStart);
  85.263 -        }
  85.264 -
  85.265 -        if (cancel.get()) return null;
  85.266 -        
  85.267 -        List<HintDescription> patternBasedHints = triggerKind2Hints.get(PatternDescription.class);
  85.268 -
  85.269 -        timeLog.put("[C] Pattern Based Hints", (long) patternBasedHints.size());
  85.270 -
  85.271 -        long patternStart = System.currentTimeMillis();
  85.272 -
  85.273 -        Map<PatternDescription, List<HintDescription>> patternHints = sortByPatterns(patternBasedHints);
  85.274 -        Map<String, List<PatternDescription>> patternTests = computePatternTests(patternHints);
  85.275 -
  85.276 -        long bulkPatternStart = System.currentTimeMillis();
  85.277 -
  85.278 -        BulkPattern bulkPattern = BulkSearch.getDefault().create(info, cancel, patternTests.keySet());
  85.279 -
  85.280 -        if (bulkPattern == null || cancel.get()) return null;
  85.281 -        
  85.282 -        long bulkPatternEnd = System.currentTimeMillis();
  85.283 -
  85.284 -        timeLog.put("Bulk Pattern preparation", bulkPatternEnd - bulkPatternStart);
  85.285 -
  85.286 -        long bulkStart = System.currentTimeMillis();
  85.287 -
  85.288 -        Map<String, Collection<TreePath>> occurringPatterns = BulkSearch.getDefault().match(info, cancel, startAt, bulkPattern, timeLog);
  85.289 -        
  85.290 -        if (occurringPatterns == null || cancel.get()) return null;
  85.291 -
  85.292 -        long bulkEnd = System.currentTimeMillis();
  85.293 -
  85.294 -        timeLog.put("Bulk Search", bulkEnd - bulkStart);
  85.295 -        
  85.296 -        Map<HintDescription, List<ErrorDescription>> computedHints = doComputeHints(info, occurringPatterns, patternTests, patternHints, problems);
  85.297 -
  85.298 -        if (computedHints == null || cancel.get()) return null;
  85.299 -        
  85.300 -        mergeAll(errors, computedHints);
  85.301 -
  85.302 -        long patternEnd = System.currentTimeMillis();
  85.303 -
  85.304 -        timeLog.put("Pattern Based Hints", patternEnd - patternStart);
  85.305 -
  85.306 -        return errors;
  85.307 -    }
  85.308 -
  85.309 -    private Map<HintDescription, List<ErrorDescription>> computeHintsInSpan(CompilationInfo info,
  85.310 -                                        Map<Class, List<HintDescription>> triggerKind2Hints,
  85.311 -                                        Collection<? super MessageImpl> problems) {
  85.312 -
  85.313 -        TreePath path = info.getTreeUtilities().pathFor((from + to) / 2);
  85.314 -
  85.315 -        while (path.getLeaf().getKind() != Kind.COMPILATION_UNIT) {
  85.316 -            int start = (int) info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), path.getLeaf());
  85.317 -            int end = (int) info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), path.getLeaf());
  85.318 -
  85.319 -            if (start <= from && end >= to) {
  85.320 -                break;
  85.321 -            }
  85.322 -
  85.323 -            path = path.getParentPath();
  85.324 -        }
  85.325 -
  85.326 -        Map<HintDescription, List<ErrorDescription>> errors = new HashMap<HintDescription, List<ErrorDescription>>();
  85.327 -        List<HintDescription> kindBasedHints = triggerKind2Hints.get(Kinds.class);
  85.328 -
  85.329 -        if (!kindBasedHints.isEmpty()) {
  85.330 -            long kindStart = System.currentTimeMillis();
  85.331 -
  85.332 -            new ScannerImpl(info, cancel, sortByKinds(kindBasedHints), problems).scan(path, errors);
  85.333 -
  85.334 -            long kindEnd = System.currentTimeMillis();
  85.335 -
  85.336 -            timeLog.put("Kind Based Hints", kindEnd - kindStart);
  85.337 -        }
  85.338 -
  85.339 -        List<HintDescription> patternBasedHints = triggerKind2Hints.get(PatternDescription.class);
  85.340 -
  85.341 -        if (!patternBasedHints.isEmpty()) {
  85.342 -            long patternStart = System.currentTimeMillis();
  85.343 -
  85.344 -            Map<PatternDescription, List<HintDescription>> patternHints = sortByPatterns(patternBasedHints);
  85.345 -            Map<String, List<PatternDescription>> patternTests = computePatternTests(patternHints);
  85.346 -
  85.347 -            long bulkStart = System.currentTimeMillis();
  85.348 -
  85.349 -            BulkPattern bulkPattern = BulkSearch.getDefault().create(info, cancel, patternTests.keySet());
  85.350 -            
  85.351 -            if (bulkPattern == null || cancel.get()) return null;
  85.352 -            
  85.353 -            Map<String, Collection<TreePath>> occurringPatterns = BulkSearch.getDefault().match(info, cancel, path, bulkPattern, timeLog);
  85.354 -
  85.355 -            long bulkEnd = System.currentTimeMillis();
  85.356 -
  85.357 -            timeLog.put("Bulk Search", bulkEnd - bulkStart);
  85.358 -            
  85.359 -            Map<HintDescription, List<ErrorDescription>> computedHints = doComputeHints(info, occurringPatterns, patternTests, patternHints, problems);
  85.360 -
  85.361 -            if (computedHints == null || cancel.get()) return null;
  85.362 -            
  85.363 -            mergeAll(errors, computedHints);
  85.364 -
  85.365 -            long patternEnd = System.currentTimeMillis();
  85.366 -
  85.367 -            timeLog.put("Pattern Based Hints", patternEnd - patternStart);
  85.368 -        }
  85.369 -
  85.370 -        if (path != null) {
  85.371 -            Map<HintDescription, List<ErrorDescription>> suggestions = computeSuggestions(info, path, true, triggerKind2Hints, problems);
  85.372 -            
  85.373 -            if (suggestions == null || cancel.get()) return null;
  85.374 -            
  85.375 -            mergeAll(errors, suggestions);
  85.376 -        }
  85.377 -
  85.378 -        return errors;
  85.379 -    }
  85.380 -
  85.381 -    private Map<HintDescription, List<ErrorDescription>> computeSuggestions(CompilationInfo info,
  85.382 -                                        TreePath workOn,
  85.383 -                                        boolean up,
  85.384 -                                        Map<Class, List<HintDescription>> triggerKind2Hints,
  85.385 -                                        Collection<? super MessageImpl> problems) {
  85.386 -        Map<HintDescription, List<ErrorDescription>> errors = new HashMap<HintDescription, List<ErrorDescription>>();
  85.387 -        List<HintDescription> kindBasedHints = triggerKind2Hints.get(Kinds.class);
  85.388 -
  85.389 -        if (!kindBasedHints.isEmpty()) {
  85.390 -            long kindStart = System.currentTimeMillis();
  85.391 -            
  85.392 -            Map<Kind, List<HintDescription>> hints = sortByKinds(kindBasedHints);
  85.393 -            TreePath proc = workOn;
  85.394 -
  85.395 -            while (proc != null) {
  85.396 -                new ScannerImpl(info, cancel, hints, problems).scanDoNotGoDeeper(proc, errors);
  85.397 -                if (!up) break;
  85.398 -                proc = proc.getParentPath();
  85.399 -            }
  85.400 -
  85.401 -            long kindEnd = System.currentTimeMillis();
  85.402 -
  85.403 -            timeLog.put("Kind Based Suggestions", kindEnd - kindStart);
  85.404 -        }
  85.405 -        
  85.406 -        if (cancel.get()) return null;
  85.407 -
  85.408 -        List<HintDescription> patternBasedHints = triggerKind2Hints.get(PatternDescription.class);
  85.409 -
  85.410 -        if (!patternBasedHints.isEmpty()) {
  85.411 -            long patternStart = System.currentTimeMillis();
  85.412 -
  85.413 -            Map<PatternDescription, List<HintDescription>> patternHints = sortByPatterns(patternBasedHints);
  85.414 -            Map<String, List<PatternDescription>> patternTests = computePatternTests(patternHints);
  85.415 -
  85.416 -            //pretend that all the patterns occur on all treepaths from the current path
  85.417 -            //up (probably faster than using BulkSearch over whole file)
  85.418 -            //TODO: what about machint trees under the current path?
  85.419 -            Set<TreePath> paths = new HashSet<TreePath>();
  85.420 -
  85.421 -            TreePath tp = workOn;
  85.422 -
  85.423 -            while (tp != null) {
  85.424 -                paths.add(tp);
  85.425 -                if (!up) break;
  85.426 -                tp = tp.getParentPath();
  85.427 -            }
  85.428 -
  85.429 -            Map<String, Collection<TreePath>> occurringPatterns = new HashMap<String, Collection<TreePath>>();
  85.430 -
  85.431 -            for (String p : patternTests.keySet()) {
  85.432 -                occurringPatterns.put(p, paths);
  85.433 -            }
  85.434 -
  85.435 -//            long bulkStart = System.currentTimeMillis();
  85.436 -//
  85.437 -//            BulkPattern bulkPattern = BulkSearch.getDefault().create(info, patternTests.keySet());
  85.438 -//            Map<String, Collection<TreePath>> occurringPatterns = BulkSearch.getDefault().match(info, new TreePath(info.getCompilationUnit()), bulkPattern, timeLog);
  85.439 -//
  85.440 -//            long bulkEnd = System.currentTimeMillis();
  85.441 -//
  85.442 -//            Set<Tree> acceptedLeafs = new HashSet<Tree>();
  85.443 -//
  85.444 -//            TreePath tp = workOn;
  85.445 -//
  85.446 -//            while (tp != null) {
  85.447 -//                acceptedLeafs.add(tp.getLeaf());
  85.448 -//                tp = tp.getParentPath();
  85.449 -//            }
  85.450 -//
  85.451 -//            for (Entry<String, Collection<TreePath>> e : occurringPatterns.entrySet()) {
  85.452 -//                for (Iterator<TreePath> it = e.getValue().iterator(); it.hasNext(); ) {
  85.453 -//                    if (!acceptedLeafs.contains(it.next().getLeaf())) {
  85.454 -//                        it.remove();
  85.455 -//                    }
  85.456 -//                }
  85.457 -//            }
  85.458 -//
  85.459 -//            timeLog.put("Bulk Search", bulkEnd - bulkStart);
  85.460 -
  85.461 -            Map<HintDescription, List<ErrorDescription>> computed = doComputeHints(info, occurringPatterns, patternTests, patternHints, problems);
  85.462 -            
  85.463 -            if (computed == null || cancel.get()) return null;
  85.464 -            
  85.465 -            mergeAll(errors, computed);
  85.466 -
  85.467 -            long patternEnd = System.currentTimeMillis();
  85.468 -
  85.469 -            timeLog.put("Pattern Based Hints", patternEnd - patternStart);
  85.470 -        }
  85.471 -
  85.472 -        return errors;
  85.473 -    }
  85.474 -
  85.475 -    public Map<HintDescription, List<ErrorDescription>> doComputeHints(CompilationInfo info, Map<String, Collection<TreePath>> occurringPatterns, Map<String, List<PatternDescription>> patterns, Map<PatternDescription, List<HintDescription>> patternHints) throws IllegalStateException {
  85.476 -        return doComputeHints(info, occurringPatterns, patterns, patternHints, new LinkedList<MessageImpl>());
  85.477 -    }
  85.478 -
  85.479 -    private static Map<Kind, List<HintDescription>> sortByKinds(List<HintDescription> kindBasedHints) {
  85.480 -        Map<Kind, List<HintDescription>> result = new EnumMap<Kind, List<HintDescription>>(Kind.class);
  85.481 -
  85.482 -        for (HintDescription hd : kindBasedHints) {
  85.483 -            for (Kind k : ((Kinds) hd.getTrigger()).getKinds()) {
  85.484 -                List<HintDescription> hints = result.get(k);
  85.485 -
  85.486 -                if (hints == null) {
  85.487 -                    result.put(k, hints = new ArrayList<HintDescription>());
  85.488 -                }
  85.489 -
  85.490 -                hints.add(hd);
  85.491 -            }
  85.492 -        }
  85.493 -
  85.494 -        return result;
  85.495 -    }
  85.496 -
  85.497 -    private static Map<PatternDescription, List<HintDescription>> sortByPatterns(List<HintDescription> kindBasedHints) {
  85.498 -        Map<PatternDescription, List<HintDescription>> result = new HashMap<PatternDescription, List<HintDescription>>();
  85.499 -
  85.500 -        for (HintDescription hd : kindBasedHints) {
  85.501 -            List<HintDescription> hints = result.get((PatternDescription) hd.getTrigger());
  85.502 -
  85.503 -            if (hints == null) {
  85.504 -                result.put((PatternDescription) hd.getTrigger(), hints = new ArrayList<HintDescription>());
  85.505 -            }
  85.506 -
  85.507 -            hints.add(hd);
  85.508 -        }
  85.509 -
  85.510 -        return result;
  85.511 -    }
  85.512 -
  85.513 -    public static Map<String, List<PatternDescription>> computePatternTests(Map<PatternDescription, List<HintDescription>> patternHints) {
  85.514 -        Map<String, List<PatternDescription>> patternTests = new HashMap<String, List<PatternDescription>>();
  85.515 -        for (Entry<PatternDescription, List<HintDescription>> e : patternHints.entrySet()) {
  85.516 -            String p = e.getKey().getPattern();
  85.517 -            List<PatternDescription> descs = patternTests.get(p);
  85.518 -            if (descs == null) {
  85.519 -                patternTests.put(p, descs = new LinkedList<PatternDescription>());
  85.520 -            }
  85.521 -            descs.add(e.getKey());
  85.522 -        }
  85.523 -        return patternTests;
  85.524 -    }
  85.525 -
  85.526 -    private Map<HintDescription, List<ErrorDescription>> doComputeHints(CompilationInfo info, Map<String, Collection<TreePath>> occurringPatterns, Map<String, List<PatternDescription>> patterns, Map<PatternDescription, List<HintDescription>> patternHints, Collection<? super MessageImpl> problems) throws IllegalStateException {
  85.527 -        Map<HintDescription, List<ErrorDescription>> errors = new HashMap<HintDescription, List<ErrorDescription>>();
  85.528 -
  85.529 -        for (Entry<String, Collection<TreePath>> occ : occurringPatterns.entrySet()) {
  85.530 -            PATTERN_LOOP: for (PatternDescription d : patterns.get(occ.getKey())) {
  85.531 -                if (cancel.get()) return null;
  85.532 -                
  85.533 -                Map<String, TypeMirror> constraints = new HashMap<String, TypeMirror>();
  85.534 -
  85.535 -                for (Entry<String, String> e : d.getConstraints().entrySet()) {
  85.536 -                    TypeMirror designedType = Hacks.parseFQNType(info, e.getValue());
  85.537 -
  85.538 -                    if (designedType == null || designedType.getKind() == TypeKind.ERROR) {
  85.539 -                        //will not bind to anything anyway (#190449), skip pattern:
  85.540 -                        continue PATTERN_LOOP;
  85.541 -                    }
  85.542 -
  85.543 -                    constraints.put(e.getKey(), designedType);
  85.544 -                }
  85.545 -
  85.546 -                Pattern pattern = PatternCompiler.compile(info, occ.getKey(), constraints, d.getImports());
  85.547 -
  85.548 -                for (TreePath candidate : occ.getValue()) {
  85.549 -                    if (cancel.get()) return null;
  85.550 -                
  85.551 -                    Iterator<? extends Occurrence> verified = Matcher.create(info).setCancel(cancel).setSearchRoot(candidate).setTreeTopSearch().match(pattern).iterator();
  85.552 -
  85.553 -                    if (!verified.hasNext()) {
  85.554 -                        continue;
  85.555 -                    }
  85.556 -
  85.557 -                    Set<String> suppressedWarnings = new HashSet<String>(Utilities.findSuppressedWarnings(info, candidate));
  85.558 -                    Occurrence verifiedVariables = verified.next();
  85.559 -
  85.560 -                    for (HintDescription hd : patternHints.get(d)) {
  85.561 -                        HintMetadata hm = hd.getMetadata();
  85.562 -                        HintContext c = SPIAccessor.getINSTANCE().createHintContext(info, settings, hm, globalContext != null ? globalContext : new GlobalProcessingContext(), candidate, verifiedVariables.getVariables(), verifiedVariables.getMultiVariables(), verifiedVariables.getVariables2Names(), constraints, problems, globalContext != null, cancel, caret);
  85.563 -
  85.564 -                        if (!Collections.disjoint(suppressedWarnings, hm.suppressWarnings))
  85.565 -                            continue;
  85.566 -
  85.567 -                        Collection<? extends ErrorDescription> workerErrors = runHint(hd, c);
  85.568 -
  85.569 -                        if (workerErrors != null) {
  85.570 -                            merge(errors, hd, workerErrors);
  85.571 -                        }
  85.572 -                    }
  85.573 -                }
  85.574 -            }
  85.575 -        }
  85.576 -
  85.577 -        return errors;
  85.578 -    }
  85.579 -
  85.580 -//    public static void computeHints(URI file, ProcessingEnvironment env, CompilationUnitTree cut, RulesManager m) {
  85.581 -//        Map<Kind, HintDescription> hints = m.getKindBasedHints();
  85.582 -//
  85.583 -//        if (hints.isEmpty()) {
  85.584 -//            return ;
  85.585 -//        }
  85.586 -//
  85.587 -//        List<ErrorDescription> errors = new  LinkedList<ErrorDescription>();
  85.588 -//
  85.589 -//        File af = new File(file.getPath());
  85.590 -//        FileObject f = FileUtil.toFileObject(af);
  85.591 -//
  85.592 -//        new ScannerImpl(f, env, hints).scan(cut, errors);
  85.593 -//
  85.594 -//        for (ErrorDescription ed : errors) {
  85.595 -//            Diagnostic.Kind k;
  85.596 -//
  85.597 -//            switch (ed.getSeverity()) {
  85.598 -//                case ERROR:
  85.599 -//                    k = Diagnostic.Kind.ERROR;
  85.600 -//                    break;
  85.601 -//                default:
  85.602 -//                    k = Diagnostic.Kind.WARNING;
  85.603 -//                    break;
  85.604 -//            }
  85.605 -//
  85.606 -//            env.getMessager().printMessage(k, ed.getDescription());
  85.607 -//        }
  85.608 -//    }
  85.609 -
  85.610 -    public Map<String, Long> getTimeLog() {
  85.611 -        return timeLog;
  85.612 -    }
  85.613 -
  85.614 -    private final class ScannerImpl extends CancellableTreePathScanner<Void, Map<HintDescription, List<ErrorDescription>>> {
  85.615 -
  85.616 -        private final Stack<Set<String>> suppresWarnings = new Stack<Set<String>>();
  85.617 -        private final CompilationInfo info;
  85.618 -        private final FileObject file;
  85.619 -        private final ProcessingEnvironment env;
  85.620 -        private final Map<Kind, List<HintDescription>> hints;
  85.621 -        private final Collection<? super MessageImpl> problems;
  85.622 -        
  85.623 -        public ScannerImpl(CompilationInfo info, AtomicBoolean cancel, Map<Kind, List<HintDescription>> hints, Collection<? super MessageImpl> problems) {
  85.624 -            super(cancel);
  85.625 -            this.info = info;
  85.626 -            this.file = null;
  85.627 -            this.env  = null;
  85.628 -            this.hints = hints;
  85.629 -            this.problems = problems;
  85.630 -        }
  85.631 -
  85.632 -        public ScannerImpl(FileObject file, ProcessingEnvironment env, Map<Kind, List<HintDescription>> hints, Collection<? super MessageImpl> problems) {
  85.633 -            super(new AtomicBoolean());
  85.634 -            this.info = null;
  85.635 -            this.file = file;
  85.636 -            this.env = env;
  85.637 -            this.hints = hints;
  85.638 -            this.problems = problems;
  85.639 -        }
  85.640 -
  85.641 -        private void runAndAdd(TreePath path, List<HintDescription> rules, Map<HintDescription, List<ErrorDescription>> d) {
  85.642 -            if (rules != null && !isInGuarded(info, path)) {
  85.643 -                OUTER: for (HintDescription hd : rules) {
  85.644 -                    if (isCanceled()) {
  85.645 -                        return ;
  85.646 -                    }
  85.647 -
  85.648 -                    HintMetadata hm = hd.getMetadata();
  85.649 -
  85.650 -                    for (String wname : hm.suppressWarnings) {
  85.651 -                        if( !suppresWarnings.empty() && suppresWarnings.peek().contains(wname)) {
  85.652 -                            continue OUTER;
  85.653 -                        }
  85.654 -                    }
  85.655 -
  85.656 -                    HintContext c = SPIAccessor.getINSTANCE().createHintContext(info, settings, hm, globalContext != null ? globalContext : new GlobalProcessingContext(), path, Collections.<String, TreePath>emptyMap(), Collections.<String, Collection<? extends TreePath>>emptyMap(), Collections.<String, String>emptyMap(), Collections.<String, TypeMirror>emptyMap(), new ArrayList<MessageImpl>(), globalContext != null, cancel, caret);
  85.657 -                    Collection<? extends ErrorDescription> errors = runHint(hd, c);
  85.658 -
  85.659 -                    if (errors != null) {
  85.660 -                        merge(d, hd, errors);
  85.661 -                    }
  85.662 -                }
  85.663 -            }
  85.664 -        }
  85.665 -
  85.666 -        @Override
  85.667 -        public Void scan(Tree tree, Map<HintDescription, List<ErrorDescription>> p) {
  85.668 -            if (tree == null)
  85.669 -                return null;
  85.670 -
  85.671 -            TreePath tp = new TreePath(getCurrentPath(), tree);
  85.672 -            Kind k = tree.getKind();
  85.673 -
  85.674 -            boolean b = pushSuppressWarrnings(tp);
  85.675 -            try {
  85.676 -                runAndAdd(tp, hints.get(k), p);
  85.677 -
  85.678 -                if (isCanceled()) {
  85.679 -                    return null;
  85.680 -                }
  85.681 -
  85.682 -                return super.scan(tree, p);
  85.683 -            } finally {
  85.684 -                if (b) {
  85.685 -                    suppresWarnings.pop();
  85.686 -                }
  85.687 -            }
  85.688 -        }
  85.689 -
  85.690 -        @Override
  85.691 -        public Void scan(TreePath path, Map<HintDescription, List<ErrorDescription>> p) {
  85.692 -            Kind k = path.getLeaf().getKind();
  85.693 -            boolean b = pushSuppressWarrnings(path);
  85.694 -            try {
  85.695 -                runAndAdd(path, hints.get(k), p);
  85.696 -
  85.697 -                if (isCanceled()) {
  85.698 -                    return null;
  85.699 -                }
  85.700 -
  85.701 -                return super.scan(path, p);
  85.702 -            } finally {
  85.703 -                if (b) {
  85.704 -                    suppresWarnings.pop();
  85.705 -                }
  85.706 -            }
  85.707 -        }
  85.708 -
  85.709 -        public void scanDoNotGoDeeper(TreePath path, Map<HintDescription, List<ErrorDescription>> p) {
  85.710 -            Kind k = path.getLeaf().getKind();
  85.711 -            runAndAdd(path, hints.get(k), p);
  85.712 -        }
  85.713 -
  85.714 -        private boolean pushSuppressWarrnings(TreePath path) {
  85.715 -            switch(path.getLeaf().getKind()) {
  85.716 -                case ANNOTATION_TYPE:
  85.717 -                case CLASS:
  85.718 -                case ENUM:
  85.719 -                case INTERFACE:
  85.720 -                case METHOD:
  85.721 -                case VARIABLE:
  85.722 -                    Set<String> current = suppresWarnings.size() == 0 ? null : suppresWarnings.peek();
  85.723 -                    Set<String> nju = current == null ? new HashSet<String>() : new HashSet<String>(current);
  85.724 -
  85.725 -                    Element e = getTrees().getElement(path);
  85.726 -
  85.727 -                    if ( e != null) {
  85.728 -                        for (AnnotationMirror am : e.getAnnotationMirrors()) {
  85.729 -                            String name = ((TypeElement)am.getAnnotationType().asElement()).getQualifiedName().toString();
  85.730 -                            if ( "java.lang.SuppressWarnings".equals(name) ) { // NOI18N
  85.731 -                                Map<? extends ExecutableElement, ? extends AnnotationValue> elementValues = am.getElementValues();
  85.732 -                                for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : elementValues.entrySet()) {
  85.733 -                                    if( "value".equals(entry.getKey().getSimpleName().toString()) ) { // NOI18N
  85.734 -                                        Object value = entry.getValue().getValue();
  85.735 -                                        if ( value instanceof List) {
  85.736 -                                            for (Object av : (List)value) {
  85.737 -                                                if( av instanceof AnnotationValue ) {
  85.738 -                                                    Object wname = ((AnnotationValue)av).getValue();
  85.739 -                                                    if ( wname instanceof String ) {
  85.740 -                                                        nju.add((String)wname);
  85.741 -                                                    }
  85.742 -                                                }
  85.743 -                                            }
  85.744 -                                        }
  85.745 -                                    }
  85.746 -                                }
  85.747 -                            }
  85.748 -                        }
  85.749 -                    }
  85.750 -
  85.751 -                    suppresWarnings.push(nju);
  85.752 -                    return true;
  85.753 -            }
  85.754 -            return false;
  85.755 -        }
  85.756 -
  85.757 -        private Trees getTrees() {
  85.758 -            return info != null ? info.getTrees() : Trees.instance(env);
  85.759 -        }
  85.760 -    }
  85.761 -
  85.762 -    static boolean isInGuarded(CompilationInfo info, TreePath tree) {
  85.763 -        if (info == null) {
  85.764 -            return false;
  85.765 -        }
  85.766 -
  85.767 -        try {
  85.768 -            Document doc = info.getDocument();
  85.769 -
  85.770 -            if (doc instanceof GuardedDocument) {
  85.771 -                int start = (int) info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), tree.getLeaf());
  85.772 -                int end = (int) info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), tree.getLeaf());
  85.773 -                GuardedDocument gdoc = (GuardedDocument) doc;
  85.774 -                MarkBlockChain guardedBlockChain = gdoc.getGuardedBlockChain();
  85.775 -                if (guardedBlockChain.compareBlock(start, end) == MarkBlock.INNER) {
  85.776 -                    return true;
  85.777 -                }
  85.778 -            }
  85.779 -        } catch (IOException ex) {
  85.780 -            Exceptions.printStackTrace(ex);
  85.781 -        }
  85.782 -
  85.783 -        return false;
  85.784 -    }
  85.785 -
  85.786 -    private Collection<? extends ErrorDescription> runHint(HintDescription hd, HintContext ctx) {
  85.787 -        long start = System.nanoTime();
  85.788 -
  85.789 -        try {
  85.790 -            return hd.getWorker().createErrors(ctx);
  85.791 -        } finally {
  85.792 -            long end = System.nanoTime();
  85.793 -            reportSpentTime(hd.getMetadata().id, end - start);
  85.794 -        }
  85.795 -    }
  85.796 -
  85.797 -    public static <K, V> Map<K, List<V>> merge(Map<K, List<V>> to, K key, Collection<? extends V> value) {
  85.798 -        List<V> toColl = to.get(key);
  85.799 -
  85.800 -        if (toColl == null) {
  85.801 -            to.put(key, toColl = new LinkedList<V>());
  85.802 -        }
  85.803 -
  85.804 -        toColl.addAll(value);
  85.805 -
  85.806 -        return to;
  85.807 -    }
  85.808 -
  85.809 -    public static <K, V> Map<K, List<V>> mergeAll(Map<K, List<V>> to, Map<? extends K, ? extends Collection<? extends V>> what) {
  85.810 -        for (Entry<? extends K, ? extends Collection<? extends V>> e : what.entrySet()) {
  85.811 -            List<V> toColl = to.get(e.getKey());
  85.812 -
  85.813 -            if (toColl == null) {
  85.814 -                to.put(e.getKey(), toColl = new LinkedList<V>());
  85.815 -            }
  85.816 -
  85.817 -            toColl.addAll(e.getValue());
  85.818 -        }
  85.819 -
  85.820 -        return to;
  85.821 -    }
  85.822 -
  85.823 -    public static List<ErrorDescription> join(Map<?, ? extends List<? extends ErrorDescription>> errors) {
  85.824 -        if (errors == null) return null;
  85.825 -        
  85.826 -        List<ErrorDescription> result = new LinkedList<ErrorDescription>();
  85.827 -
  85.828 -        for (Entry<?, ? extends Collection<? extends ErrorDescription>> e : errors.entrySet()) {
  85.829 -            result.addAll(e.getValue());
  85.830 -        }
  85.831 -
  85.832 -        return result;
  85.833 -    }
  85.834 -
  85.835 -    private static final boolean logTimeSpentInHints = Boolean.getBoolean("java.HintsInvoker.time.in.hints");
  85.836 -    private final Map<String, Long> hint2SpentTime = new HashMap<String, Long>();
  85.837 -
  85.838 -    private void reportSpentTime(String id, long nanoTime) {
  85.839 -        if (!logTimeSpentInHints) return;
  85.840 -        
  85.841 -        Long prev = hint2SpentTime.get(id);
  85.842 -
  85.843 -        if (prev == null) {
  85.844 -            prev = (long) 0;
  85.845 -        }
  85.846 -
  85.847 -        hint2SpentTime.put(id, prev + nanoTime);
  85.848 -    }
  85.849 -
  85.850 -    private void dumpTimeSpentInHints() {
  85.851 -        if (!logTimeSpentInHints) return;
  85.852 -
  85.853 -        List<Entry<String, Long>> l = new ArrayList<Entry<String, Long>>(hint2SpentTime.entrySet());
  85.854 -
  85.855 -        Collections.sort(l, new Comparator<Entry<String, Long>>() {
  85.856 -            @Override
  85.857 -            public int compare(Entry<String, Long> o1, Entry<String, Long> o2) {
  85.858 -                return (int) Math.signum(o1.getValue() - o2.getValue());
  85.859 -            }
  85.860 -        });
  85.861 -
  85.862 -        for (Entry<String, Long> e : l) {
  85.863 -            System.err.println(e.getKey() + "=" + String.format("%3.2f", e.getValue() / 1000000.0));
  85.864 -        }
  85.865 -    }
  85.866 -}
    86.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/hints/HintsTask.java	Sun Oct 16 08:01:27 2016 +0200
    86.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    86.3 @@ -1,254 +0,0 @@
    86.4 -/*
    86.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    86.6 - *
    86.7 - * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
    86.8 - *
    86.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   86.10 - * Other names may be trademarks of their respective owners.
   86.11 - *
   86.12 - * The contents of this file are subject to the terms of either the GNU
   86.13 - * General Public License Version 2 only ("GPL") or the Common
   86.14 - * Development and Distribution License("CDDL") (collectively, the
   86.15 - * "License"). You may not use this file except in compliance with the
   86.16 - * License. You can obtain a copy of the License at
   86.17 - * http://www.netbeans.org/cddl-gplv2.html
   86.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   86.19 - * specific language governing permissions and limitations under the
   86.20 - * License.  When distributing the software, include this License Header
   86.21 - * Notice in each file and include the License file at
   86.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   86.23 - * particular file as subject to the "Classpath" exception as provided
   86.24 - * by Oracle in the GPL Version 2 section of the License file that
   86.25 - * accompanied this code. If applicable, add the following below the
   86.26 - * License Header, with the fields enclosed by brackets [] replaced by
   86.27 - * your own identifying information:
   86.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   86.29 - *
   86.30 - * If you wish your version of this file to be governed by only the CDDL
   86.31 - * or only the GPL Version 2, indicate your decision by adding
   86.32 - * "[Contributor] elects to include this software in this distribution
   86.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   86.34 - * single choice of license, a recipient has the option to distribute
   86.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   86.36 - * to extend the choice of license to its licensees as provided above.
   86.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   86.38 - * Version 2 license, then the option applies only if the new code is
   86.39 - * made subject to such option by the copyright holder.
   86.40 - *
   86.41 - * Contributor(s):
   86.42 - *
   86.43 - * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
   86.44 - */
   86.45 -
   86.46 -package org.netbeans.modules.java.hints.spiimpl.hints;
   86.47 -
   86.48 -import java.util.List;
   86.49 -import java.util.Map.Entry;
   86.50 -import java.util.concurrent.atomic.AtomicBoolean;
   86.51 -import java.util.logging.Level;
   86.52 -import java.util.logging.Logger;
   86.53 -import javax.swing.event.ChangeEvent;
   86.54 -import javax.swing.event.ChangeListener;
   86.55 -import javax.swing.text.BadLocationException;
   86.56 -import javax.swing.text.Document;
   86.57 -import org.netbeans.api.editor.mimelookup.MimeLookup;
   86.58 -import org.netbeans.api.editor.mimelookup.MimeRegistration;
   86.59 -import org.netbeans.api.java.source.CancellableTask;
   86.60 -import org.netbeans.api.java.source.CompilationInfo;
   86.61 -import org.netbeans.api.java.source.JavaSource.Phase;
   86.62 -import org.netbeans.api.java.source.JavaSource.Priority;
   86.63 -import org.netbeans.api.java.source.JavaSourceTaskFactory;
   86.64 -import org.netbeans.api.java.source.support.CaretAwareJavaSourceTaskFactory;
   86.65 -import org.netbeans.api.java.source.support.EditorAwareJavaSourceTaskFactory;
   86.66 -import org.netbeans.editor.BaseDocument;
   86.67 -import org.netbeans.editor.Utilities;
   86.68 -import org.netbeans.lib.editor.util.swing.DocumentUtilities;
   86.69 -import org.netbeans.modules.java.hints.providers.spi.PositionRefresherHelper;
   86.70 -import org.netbeans.modules.java.hints.providers.spi.PositionRefresherHelper.DocumentVersion;
   86.71 -import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings;
   86.72 -import org.netbeans.modules.parsing.spi.TaskIndexingMode;
   86.73 -import org.netbeans.spi.editor.hints.Context;
   86.74 -import org.netbeans.spi.editor.hints.ErrorDescription;
   86.75 -import org.netbeans.spi.editor.hints.HintsController;
   86.76 -import org.netbeans.spi.editor.hints.Severity;
   86.77 -import org.netbeans.spi.editor.hints.settings.FileHintPreferences;
   86.78 -import org.openide.filesystems.FileObject;
   86.79 -import org.openide.util.WeakListeners;
   86.80 -import org.openide.util.lookup.ServiceProvider;
   86.81 -
   86.82 -/**
   86.83 - *
   86.84 - * @author lahvac
   86.85 - */
   86.86 -public class HintsTask implements CancellableTask<CompilationInfo> {
   86.87 -
   86.88 -    public static final String KEY_HINTS = HintsInvoker.class.getName() + "-hints";
   86.89 -    public static final String KEY_SUGGESTIONS = HintsInvoker.class.getName() + "-suggestions";
   86.90 -
   86.91 -    private static final Logger TIMER = Logger.getLogger("TIMER");
   86.92 -    private static final Logger TIMER_EDITOR = Logger.getLogger("TIMER.editor");
   86.93 -    private static final Logger TIMER_CARET = Logger.getLogger("TIMER.caret");
   86.94 -
   86.95 -    private final AtomicBoolean cancel = new AtomicBoolean();
   86.96 -
   86.97 -    private final boolean caretAware;
   86.98 -
   86.99 -    public HintsTask(boolean caretAware) {
  86.100 -        this.caretAware = caretAware;
  86.101 -    }
  86.102 -    
  86.103 -    public void run(CompilationInfo info) {
  86.104 -        cancel.set(false);
  86.105 -
  86.106 -        if (org.netbeans.modules.java.hints.spiimpl.Utilities.disableErrors(info.getFileObject()).contains(Severity.VERIFIER)) {
  86.107 -            return;
  86.108 -        }
  86.109 -
  86.110 -        Document doc = info.getSnapshot().getSource().getDocument(false);
  86.111 -        long version = doc != null ? DocumentUtilities.getDocumentVersion(doc) : 0;
  86.112 -        long startTime = System.currentTimeMillis();
  86.113 -
  86.114 -        int caret = CaretAwareJavaSourceTaskFactory.getLastPosition(info.getFileObject());
  86.115 -        HintsSettings settings = HintsSettings.getSettingsFor(info.getFileObject());
  86.116 -        HintsInvoker inv = caretAware ? new HintsInvoker(settings, caret, cancel) : new HintsInvoker(settings, cancel);
  86.117 -        List<ErrorDescription> result = inv.computeHints(info);
  86.118 -
  86.119 -        if (result == null || cancel.get()) {
  86.120 -            return;
  86.121 -        }
  86.122 -
  86.123 -        HintsController.setErrors(info.getFileObject(), caretAware ? KEY_SUGGESTIONS : KEY_HINTS, result);
  86.124 -
  86.125 -        if (caretAware) {
  86.126 -            SuggestionsPositionRefresherHelper.setVersion(doc, caret);
  86.127 -        } else {
  86.128 -            HintPositionRefresherHelper.setVersion(doc);
  86.129 -        }
  86.130 -
  86.131 -        long endTime = System.currentTimeMillis();
  86.132 -        
  86.133 -        TIMER.log(Level.FINE, "Jackpot 3.0 Hints Task" + (caretAware ? " - Caret Aware" : ""), new Object[] {info.getFileObject(), endTime - startTime});
  86.134 -
  86.135 -        Logger l = caretAware ? TIMER_CARET : TIMER_EDITOR;
  86.136 -
  86.137 -        for (Entry<String, Long> e : inv.getTimeLog().entrySet()) {
  86.138 -            l.log(Level.FINE, e.getKey(), new Object[] {info.getFileObject(), e.getValue()});
  86.139 -        }
  86.140 -    }
  86.141 -
  86.142 -    public void cancel() {
  86.143 -        cancel.set(true);
  86.144 -    }
  86.145 -
  86.146 -
  86.147 -    @ServiceProvider(service=JavaSourceTaskFactory.class)
  86.148 -    public static final class FactoryImpl extends EditorAwareJavaSourceTaskFactory implements ChangeListener {
  86.149 -
  86.150 -        public FactoryImpl() {
  86.151 -            super(Phase.RESOLVED, Priority.LOW, TaskIndexingMode.ALLOWED_DURING_SCAN);
  86.152 -            FileHintPreferences.addChangeListener(WeakListeners.change(this, HintsSettings.class));
  86.153 -        }
  86.154 -
  86.155 -        @Override
  86.156 -        protected CancellableTask<CompilationInfo> createTask(FileObject file) {
  86.157 -            return new HintsTask(false);
  86.158 -        }
  86.159 -
  86.160 -	@Override
  86.161 -	public void stateChanged(ChangeEvent e) {
  86.162 -	    for (FileObject file : getFileObjects()) {
  86.163 -		reschedule(file);
  86.164 -	    }
  86.165 -	}
  86.166 -        
  86.167 -    }
  86.168 -
  86.169 -    @ServiceProvider(service=JavaSourceTaskFactory.class)
  86.170 -    public static final class CaretFactoryImpl extends CaretAwareJavaSourceTaskFactory implements ChangeListener {
  86.171 -
  86.172 -        public CaretFactoryImpl() {
  86.173 -            super(Phase.RESOLVED, Priority.LOW);
  86.174 -            FileHintPreferences.addChangeListener(WeakListeners.change(this, HintsSettings.class));
  86.175 -        }
  86.176 -
  86.177 -        @Override
  86.178 -        protected CancellableTask<CompilationInfo> createTask(FileObject file) {
  86.179 -            return new HintsTask(true);
  86.180 -        }
  86.181 -
  86.182 -	@Override
  86.183 -	public void stateChanged(ChangeEvent e) {
  86.184 -	    for (FileObject file : getFileObjects()) {
  86.185 -		reschedule(file);
  86.186 -	    }
  86.187 -	}
  86.188 -
  86.189 -    }
  86.190 -
  86.191 -    @MimeRegistration(mimeType="text/x-java", service=PositionRefresherHelper.class)
  86.192 -    public static final class HintPositionRefresherHelper extends PositionRefresherHelper<DocumentVersion> {
  86.193 -
  86.194 -        public HintPositionRefresherHelper() {
  86.195 -            super(KEY_HINTS);
  86.196 -        }
  86.197 -
  86.198 -        @Override
  86.199 -        protected boolean isUpToDate(Context context, Document doc, DocumentVersion oldVersion) {
  86.200 -            return true;
  86.201 -        }
  86.202 -
  86.203 -        @Override
  86.204 -        public List<ErrorDescription> getErrorDescriptionsAt(CompilationInfo info, Context context, Document doc) throws BadLocationException {
  86.205 -            int rowStart = Utilities.getRowStart((BaseDocument) doc, context.getPosition());
  86.206 -            int rowEnd = Utilities.getRowEnd((BaseDocument) doc, context.getPosition());
  86.207 -
  86.208 -            return new HintsInvoker(HintsSettings.getSettingsFor(info.getFileObject()), rowStart, rowEnd, context.getCancel()).computeHints(info);
  86.209 -        }
  86.210 -
  86.211 -        private static void setVersion(Document doc) {
  86.212 -            for (PositionRefresherHelper h : MimeLookup.getLookup("text/x-java").lookupAll(PositionRefresherHelper.class)) {
  86.213 -                if (h instanceof HintPositionRefresherHelper) {
  86.214 -                    ((HintPositionRefresherHelper) h).setVersion(doc, new DocumentVersion(doc));
  86.215 -                }
  86.216 -            }
  86.217 -        }
  86.218 -
  86.219 -    }
  86.220 -
  86.221 -    @MimeRegistration(mimeType="text/x-java", service=PositionRefresherHelper.class)
  86.222 -    public static final class SuggestionsPositionRefresherHelper extends PositionRefresherHelper<SuggestionsDocumentVersion> {
  86.223 -
  86.224 -        public SuggestionsPositionRefresherHelper() {
  86.225 -            super(KEY_SUGGESTIONS);
  86.226 -        }
  86.227 -
  86.228 -        @Override
  86.229 -        protected boolean isUpToDate(Context context, Document doc, SuggestionsDocumentVersion oldVersion) {
  86.230 -            return oldVersion.suggestionsCaret == context.getPosition();
  86.231 -        }
  86.232 -
  86.233 -        @Override
  86.234 -        public List<ErrorDescription> getErrorDescriptionsAt(CompilationInfo info, Context context, Document doc) throws BadLocationException {
  86.235 -            return new HintsInvoker(HintsSettings.getSettingsFor(info.getFileObject()), context.getPosition(), context.getCancel()).computeHints(info);
  86.236 -        }
  86.237 -
  86.238 -        private static void setVersion(Document doc, int caret) {
  86.239 -            for (PositionRefresherHelper h : MimeLookup.getLookup("text/x-java").lookupAll(PositionRefresherHelper.class)) {
  86.240 -                if (h instanceof SuggestionsPositionRefresherHelper) {
  86.241 -                    ((SuggestionsPositionRefresherHelper) h).setVersion(doc, new SuggestionsDocumentVersion(doc, caret));
  86.242 -                }
  86.243 -            }
  86.244 -        }
  86.245 -    }
  86.246 -
  86.247 -    private static class SuggestionsDocumentVersion extends DocumentVersion {
  86.248 -
  86.249 -        private final int suggestionsCaret;
  86.250 -        
  86.251 -        public SuggestionsDocumentVersion(Document doc, int suggestionsCaret) {
  86.252 -            super(doc);
  86.253 -            this.suggestionsCaret = suggestionsCaret;
  86.254 -        }
  86.255 -    }
  86.256 -
  86.257 -}
    87.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/ipi/upgrade/ProjectDependencyUpgrader.java	Sun Oct 16 08:01:27 2016 +0200
    87.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    87.3 @@ -1,64 +0,0 @@
    87.4 -/*
    87.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    87.6 - *
    87.7 - * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
    87.8 - *
    87.9 - * The contents of this file are subject to the terms of either the GNU
   87.10 - * General Public License Version 2 only ("GPL") or the Common
   87.11 - * Development and Distribution License("CDDL") (collectively, the
   87.12 - * "License"). You may not use this file except in compliance with the
   87.13 - * License. You can obtain a copy of the License at
   87.14 - * http://www.netbeans.org/cddl-gplv2.html
   87.15 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   87.16 - * specific language governing permissions and limitations under the
   87.17 - * License.  When distributing the software, include this License Header
   87.18 - * Notice in each file and include the License file at
   87.19 - * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
   87.20 - * particular file as subject to the "Classpath" exception as provided
   87.21 - * by Sun in the GPL Version 2 section of the License file that
   87.22 - * accompanied this code. If applicable, add the following below the
   87.23 - * License Header, with the fields enclosed by brackets [] replaced by
   87.24 - * your own identifying information:
   87.25 - * "Portions Copyrighted [year] [name of copyright owner]"
   87.26 - *
   87.27 - * If you wish your version of this file to be governed by only the CDDL
   87.28 - * or only the GPL Version 2, indicate your decision by adding
   87.29 - * "[Contributor] elects to include this software in this distribution
   87.30 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   87.31 - * single choice of license, a recipient has the option to distribute
   87.32 - * your version of this file under either the CDDL, the GPL Version 2 or
   87.33 - * to extend the choice of license to its licensees as provided above.
   87.34 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   87.35 - * Version 2 license, then the option applies only if the new code is
   87.36 - * made subject to such option by the copyright holder.
   87.37 - *
   87.38 - * Contributor(s):
   87.39 - *
   87.40 - * Portions Copyrighted 2010 Sun Microsystems, Inc.
   87.41 - */
   87.42 -package org.netbeans.modules.java.hints.spiimpl.ipi.upgrade;
   87.43 -
   87.44 -import org.netbeans.api.project.Project;
   87.45 -import org.openide.DialogDisplayer;
   87.46 -import org.openide.NotifyDescriptor;
   87.47 -import org.openide.filesystems.FileObject;
   87.48 -import org.openide.modules.SpecificationVersion;
   87.49 -
   87.50 -/**
   87.51 - *
   87.52 - * @author lahvac
   87.53 - */
   87.54 -public abstract class ProjectDependencyUpgrader {
   87.55 -
   87.56 -    public abstract boolean ensureDependency(Project p, FileObject dep, SpecificationVersion spec, boolean canShowUI);
   87.57 -    public abstract boolean ensureDependency(Project p, String specification, boolean b);
   87.58 -
   87.59 -    protected final boolean showDependencyUpgradeDialog(Project p, String dep, SpecificationVersion currentDependency, SpecificationVersion spec, boolean newDepenency, boolean canShowUI) {
   87.60 -        if (!canShowUI) return true;
   87.61 -        
   87.62 -        NotifyDescriptor nd = new NotifyDescriptor.Confirmation("New version: " + spec, "Update spec version.", NotifyDescriptor.YES_NO_OPTION);
   87.63 -
   87.64 -        return DialogDisplayer.getDefault().notify(nd) == NotifyDescriptor.YES_OPTION;
   87.65 -    }
   87.66 -
   87.67 -}
    88.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/options/HintsSettings.java	Sun Oct 16 08:01:27 2016 +0200
    88.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    88.3 @@ -1,149 +0,0 @@
    88.4 -/*
    88.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    88.6 - *
    88.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
    88.8 - *
    88.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   88.10 - * Other names may be trademarks of their respective owners.
   88.11 - *
   88.12 - * The contents of this file are subject to the terms of either the GNU
   88.13 - * General Public License Version 2 only ("GPL") or the Common
   88.14 - * Development and Distribution License("CDDL") (collectively, the
   88.15 - * "License"). You may not use this file except in compliance with the
   88.16 - * License. You can obtain a copy of the License at
   88.17 - * http://www.netbeans.org/cddl-gplv2.html
   88.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   88.19 - * specific language governing permissions and limitations under the
   88.20 - * License.  When distributing the software, include this License Header
   88.21 - * Notice in each file and include the License file at
   88.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   88.23 - * particular file as subject to the "Classpath" exception as provided
   88.24 - * by Oracle in the GPL Version 2 section of the License file that
   88.25 - * accompanied this code. If applicable, add the following below the
   88.26 - * License Header, with the fields enclosed by brackets [] replaced by
   88.27 - * your own identifying information:
   88.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   88.29 - *
   88.30 - * Contributor(s):
   88.31 - *
   88.32 - * The Original Software is NetBeans. The Initial Developer of the Original
   88.33 - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2010 Sun
   88.34 - * Microsystems, Inc. All Rights Reserved.
   88.35 - *
   88.36 - * If you wish your version of this file to be governed by only the CDDL
   88.37 - * or only the GPL Version 2, indicate your decision by adding
   88.38 - * "[Contributor] elects to include this software in this distribution
   88.39 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   88.40 - * single choice of license, a recipient has the option to distribute
   88.41 - * your version of this file under either the CDDL, the GPL Version 2 or
   88.42 - * to extend the choice of license to its licensees as provided above.
   88.43 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   88.44 - * Version 2 license, then the option applies only if the new code is
   88.45 - * made subject to such option by the copyright holder.
   88.46 - */
   88.47 -package org.netbeans.modules.java.hints.spiimpl.options;
   88.48 -
   88.49 -import java.util.prefs.Preferences;
   88.50 -import org.netbeans.api.editor.mimelookup.MimeRegistration;
   88.51 -import org.netbeans.modules.java.hints.providers.spi.HintMetadata;
   88.52 -import org.netbeans.spi.editor.hints.Severity;
   88.53 -import org.netbeans.spi.editor.hints.settings.FileHintPreferences;
   88.54 -import org.netbeans.spi.editor.hints.settings.FileHintPreferences.GlobalHintPreferencesProvider;
   88.55 -import org.openide.filesystems.FileObject;
   88.56 -import org.openide.util.NbPreferences;
   88.57 -
   88.58 -/**
   88.59 - *
   88.60 - * @author Petr Hrebejk
   88.61 - * @author Jan Lahoda
   88.62 - */
   88.63 -public abstract class HintsSettings {
   88.64 -
   88.65 -    private static final String ENABLED_KEY = "enabled";         // NOI18N
   88.66 -    private static final String OLD_SEVERITY_KEY = "severity";       // NOI18N
   88.67 -    private static final String NEW_SEVERITY_KEY = "hintSeverity";       // NOI18N
   88.68 -//    protected static final String IN_TASK_LIST_KEY = "inTaskList"; // NOI18N
   88.69 -
   88.70 -    public abstract boolean isEnabled(HintMetadata hint);
   88.71 -    public abstract void setEnabled(HintMetadata hint, boolean value);
   88.72 -    public abstract Preferences getHintPreferences(HintMetadata hint);
   88.73 -    public abstract Severity getSeverity(HintMetadata hint);
   88.74 -    public abstract void setSeverity(HintMetadata hint, Severity severity);
   88.75 -//    public abstract Iterable<? extends HintDescription> getEnabledHints();
   88.76 -    
   88.77 -    private static final class PreferencesBasedHintsSettings extends HintsSettings {
   88.78 -
   88.79 -        private final Preferences preferences;
   88.80 -        private final boolean useDefaultEnabled;
   88.81 -        private final Severity overrideSeverity;
   88.82 -
   88.83 -        public PreferencesBasedHintsSettings(Preferences preferences, boolean useDefaultEnabled, Severity overrideSeverity) {
   88.84 -            this.preferences = preferences;
   88.85 -            this.useDefaultEnabled = useDefaultEnabled;
   88.86 -            this.overrideSeverity = overrideSeverity;
   88.87 -        }
   88.88 -
   88.89 -        @Override
   88.90 -        public boolean isEnabled(HintMetadata hint) {
   88.91 -            return getHintPreferences(hint).getBoolean(ENABLED_KEY, useDefaultEnabled && hint.enabled);
   88.92 -        }
   88.93 -
   88.94 -        @Override
   88.95 -        public void setEnabled(HintMetadata hint, boolean value) {
   88.96 -            getHintPreferences(hint).putBoolean(ENABLED_KEY, value);
   88.97 -        }
   88.98 -
   88.99 -        @Override
  88.100 -        public Preferences getHintPreferences(HintMetadata hint) {
  88.101 -            return preferences.node(hint.id);
  88.102 -        }
  88.103 -
  88.104 -        @Override
  88.105 -        public Severity getSeverity(HintMetadata hint) {
  88.106 -            Preferences prefs = getHintPreferences(hint);
  88.107 -            String s = prefs.get(NEW_SEVERITY_KEY, null);
  88.108 -            if (s != null) return Severity.valueOf(s);
  88.109 -
  88.110 -            s = prefs.get(OLD_SEVERITY_KEY, null);
  88.111 -
  88.112 -            if (s == null) return overrideSeverity != null ? overrideSeverity : hint != null ? hint.severity : null;
  88.113 -
  88.114 -            if ("ERROR".equals(s)) return Severity.ERROR;
  88.115 -            else if ("WARNING".equals(s)) return Severity.VERIFIER;
  88.116 -            else if ("CURRENT_LINE_WARNING".equals(s)) return Severity.HINT;
  88.117 -
  88.118 -            return overrideSeverity != null ? overrideSeverity : hint != null ? hint.severity : null;
  88.119 -        }
  88.120 -        
  88.121 -        @Override
  88.122 -        public void setSeverity(HintMetadata hint, Severity severity) {
  88.123 -            getHintPreferences(hint).put(NEW_SEVERITY_KEY, severity.name());
  88.124 -        }
  88.125 -    }
  88.126 -    
  88.127 -    public static HintsSettings createPreferencesBasedHintsSettings(Preferences preferences, boolean useDefaultEnabled, Severity overrideSeverity) {
  88.128 -        return new PreferencesBasedHintsSettings(preferences, useDefaultEnabled, overrideSeverity);
  88.129 -    }
  88.130 -    
  88.131 -    public static HintsSettings getSettingsFor(FileObject file) {
  88.132 -        return createPreferencesBasedHintsSettings(FileHintPreferences.getFilePreferences(file, "text/x-java"), true, null);
  88.133 -    }
  88.134 -    
  88.135 -    public static HintsSettings getGlobalSettings() {
  88.136 -        return GLOBAL_SETTINGS;
  88.137 -    }
  88.138 -    
  88.139 -    private static final String DEFAULT_PROFILE = "default"; // NOI18N
  88.140 -    private static final String PREFERENCES_LOCATION = "org/netbeans/modules/java/hints";
  88.141 -    private static final HintsSettings GLOBAL_SETTINGS = createPreferencesBasedHintsSettings(NbPreferences.root().node(PREFERENCES_LOCATION).node(DEFAULT_PROFILE), true, null);
  88.142 -    
  88.143 -    @MimeRegistration(mimeType="text/x-java", service=GlobalHintPreferencesProvider.class)
  88.144 -    public static class GlobalSettingsProvider implements GlobalHintPreferencesProvider {
  88.145 -
  88.146 -        @Override
  88.147 -        public Preferences getGlobalPreferences() {
  88.148 -            return NbPreferences.root().node(PREFERENCES_LOCATION).node(DEFAULT_PROFILE);
  88.149 -        }
  88.150 -        
  88.151 -    }
  88.152 -}
    89.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/pm/BulkSearch.java	Sun Oct 16 08:01:27 2016 +0200
    89.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    89.3 @@ -1,190 +0,0 @@
    89.4 -/*
    89.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    89.6 - *
    89.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
    89.8 - *
    89.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   89.10 - * Other names may be trademarks of their respective owners.
   89.11 - *
   89.12 - * The contents of this file are subject to the terms of either the GNU
   89.13 - * General Public License Version 2 only ("GPL") or the Common
   89.14 - * Development and Distribution License("CDDL") (collectively, the
   89.15 - * "License"). You may not use this file except in compliance with the
   89.16 - * License. You can obtain a copy of the License at
   89.17 - * http://www.netbeans.org/cddl-gplv2.html
   89.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   89.19 - * specific language governing permissions and limitations under the
   89.20 - * License.  When distributing the software, include this License Header
   89.21 - * Notice in each file and include the License file at
   89.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   89.23 - * particular file as subject to the "Classpath" exception as provided
   89.24 - * by Oracle in the GPL Version 2 section of the License file that
   89.25 - * accompanied this code. If applicable, add the following below the
   89.26 - * License Header, with the fields enclosed by brackets [] replaced by
   89.27 - * your own identifying information:
   89.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   89.29 - *
   89.30 - * If you wish your version of this file to be governed by only the CDDL
   89.31 - * or only the GPL Version 2, indicate your decision by adding
   89.32 - * "[Contributor] elects to include this software in this distribution
   89.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   89.34 - * single choice of license, a recipient has the option to distribute
   89.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   89.36 - * to extend the choice of license to its licensees as provided above.
   89.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   89.38 - * Version 2 license, then the option applies only if the new code is
   89.39 - * made subject to such option by the copyright holder.
   89.40 - *
   89.41 - * Contributor(s):
   89.42 - *
   89.43 - * Portions Copyrighted 2009 Sun Microsystems, Inc.
   89.44 - */
   89.45 -
   89.46 -package org.netbeans.modules.java.hints.spiimpl.pm;
   89.47 -
   89.48 -import com.sun.source.tree.Tree;
   89.49 -import com.sun.source.util.TreePath;
   89.50 -import java.io.InputStream;
   89.51 -import java.io.OutputStream;
   89.52 -import java.util.Arrays;
   89.53 -import java.util.Collection;
   89.54 -import java.util.LinkedList;
   89.55 -import java.util.List;
   89.56 -import java.util.Map;
   89.57 -import java.util.Set;
   89.58 -import java.util.concurrent.atomic.AtomicBoolean;
   89.59 -import org.netbeans.api.annotations.common.CheckForNull;
   89.60 -import org.netbeans.api.java.source.CompilationInfo;
   89.61 -import org.netbeans.modules.java.hints.spiimpl.Utilities;
   89.62 -import org.netbeans.modules.java.hints.providers.spi.HintDescription.AdditionalQueryConstraints;
   89.63 -
   89.64 -/**
   89.65 - *
   89.66 - * @author lahvac
   89.67 - */
   89.68 -public abstract class BulkSearch {
   89.69 -
   89.70 -    private static final BulkSearch INSTANCE = new NFABasedBulkSearch();
   89.71 -//    private static final BulkSearch INSTANCE = new REBasedBulkSearch();
   89.72 -
   89.73 -    public static BulkSearch getDefault() {
   89.74 -        return INSTANCE;
   89.75 -    }
   89.76 -    
   89.77 -    private final boolean requiresLightweightVerification;
   89.78 -    
   89.79 -    protected BulkSearch(boolean requiresLightweightVerification) {
   89.80 -        this.requiresLightweightVerification = requiresLightweightVerification;
   89.81 -    }
   89.82 -    
   89.83 -    public final Map<String, Collection<TreePath>> match(CompilationInfo info, AtomicBoolean cancel, TreePath toSearch, BulkPattern pattern) {
   89.84 -        return match(info, cancel, toSearch, pattern, null);
   89.85 -    }
   89.86 -
   89.87 -    public final boolean requiresLightweightVerification() {
   89.88 -        return requiresLightweightVerification;
   89.89 -    }
   89.90 -
   89.91 -    @CheckForNull
   89.92 -    public abstract Map<String, Collection<TreePath>> match(CompilationInfo info, AtomicBoolean cancel, TreePath toSearch, BulkPattern pattern, Map<String, Long> timeLog);
   89.93 -
   89.94 -    public abstract boolean matches(InputStream encoded, AtomicBoolean cancel, BulkPattern pattern);
   89.95 -    
   89.96 -    @CheckForNull
   89.97 -    public abstract Map<String, Integer> matchesWithFrequencies(InputStream encoded, BulkPattern pattern, AtomicBoolean cancel);
   89.98 -    
   89.99 -    public abstract boolean matches(CompilationInfo info, AtomicBoolean cancel, TreePath toSearch, BulkPattern pattern);
  89.100 -
  89.101 -    public abstract void encode(Tree tree, EncodingContext ctx, AtomicBoolean cancel);
  89.102 -    
  89.103 -    @CheckForNull
  89.104 -    public final BulkPattern create(CompilationInfo info, AtomicBoolean cancel, String... code) {
  89.105 -        return create(info, cancel, Arrays.asList(code));
  89.106 -    }
  89.107 -
  89.108 -    @CheckForNull
  89.109 -    public final BulkPattern create(CompilationInfo info, AtomicBoolean cancel, Collection<? extends String> code) {
  89.110 -        List<Tree> patterns = new LinkedList<Tree>();
  89.111 -        List<AdditionalQueryConstraints> additionalConstraints = new LinkedList<AdditionalQueryConstraints>();
  89.112 -
  89.113 -        for (String c : code) {
  89.114 -            patterns.add(Utilities.parseAndAttribute(info, c, null));
  89.115 -            additionalConstraints.add(AdditionalQueryConstraints.empty());
  89.116 -        }
  89.117 -
  89.118 -        return create(code, patterns, additionalConstraints, cancel);
  89.119 -    }
  89.120 -    
  89.121 -    @CheckForNull
  89.122 -    public abstract BulkPattern create(Collection<? extends String> code, Collection<? extends Tree> patterns, Collection<? extends AdditionalQueryConstraints> additionalConstraints, AtomicBoolean cancel);
  89.123 -
  89.124 -    public static abstract class BulkPattern {
  89.125 -
  89.126 -        private final List<? extends String> patterns;
  89.127 -        private final List<? extends Set<? extends String>> identifiers;
  89.128 -        private final List<List<List<String>>> requiredContent;
  89.129 -        private final List<AdditionalQueryConstraints> additionalConstraints;
  89.130 -
  89.131 -        public BulkPattern(List<? extends String> patterns, List<? extends Set<? extends String>> identifiers, List<List<List<String>>> requiredContent, List<AdditionalQueryConstraints> additionalConstraints) {
  89.132 -            this.patterns = patterns;
  89.133 -            this.identifiers = identifiers;//TODO: immutable, maybe clone
  89.134 -            this.requiredContent = requiredContent;
  89.135 -            this.additionalConstraints = additionalConstraints;
  89.136 -        }
  89.137 -
  89.138 -        public List<? extends String> getPatterns() {
  89.139 -            return patterns;
  89.140 -        }
  89.141 -
  89.142 -        public List<? extends Set<? extends String>> getIdentifiers() {
  89.143 -            return identifiers;
  89.144 -        }
  89.145 -
  89.146 -        public List<List<List<String>>> getRequiredContent() {
  89.147 -            return requiredContent;
  89.148 -        }
  89.149 -
  89.150 -        public List<AdditionalQueryConstraints> getAdditionalConstraints() {
  89.151 -            return additionalConstraints;
  89.152 -        }
  89.153 -
  89.154 -    }
  89.155 -
  89.156 -    public static final class EncodingContext {
  89.157 -
  89.158 -        private final OutputStream out;
  89.159 -        private final boolean forDuplicates;
  89.160 -        private Set<? extends String> identifiers;
  89.161 -        private List<String> content;
  89.162 -
  89.163 -        public EncodingContext(OutputStream out, boolean forDuplicates) {
  89.164 -            this.out = out;
  89.165 -            this.forDuplicates = forDuplicates;
  89.166 -        }
  89.167 -
  89.168 -        public Set<? extends String> getIdentifiers() {
  89.169 -            return identifiers;
  89.170 -        }
  89.171 -
  89.172 -        public OutputStream getOut() {
  89.173 -            return out;
  89.174 -        }
  89.175 -
  89.176 -        public boolean isForDuplicates() {
  89.177 -            return forDuplicates;
  89.178 -        }
  89.179 -
  89.180 -        public void setIdentifiers(Set<? extends String> identifiers) {
  89.181 -            this.identifiers = identifiers;
  89.182 -        }
  89.183 -
  89.184 -        public void setContent(List<String> content) {
  89.185 -            this.content = content;
  89.186 -        }
  89.187 -
  89.188 -        public List<String> getContent() {
  89.189 -            return content;
  89.190 -        }
  89.191 -
  89.192 -    }
  89.193 -}
    90.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/pm/CopyFinderBasedBulkSearch.java	Sun Oct 16 08:01:27 2016 +0200
    90.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    90.3 @@ -1,141 +0,0 @@
    90.4 -/*
    90.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    90.6 - *
    90.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
    90.8 - *
    90.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   90.10 - * Other names may be trademarks of their respective owners.
   90.11 - *
   90.12 - * The contents of this file are subject to the terms of either the GNU
   90.13 - * General Public License Version 2 only ("GPL") or the Common
   90.14 - * Development and Distribution License("CDDL") (collectively, the
   90.15 - * "License"). You may not use this file except in compliance with the
   90.16 - * License. You can obtain a copy of the License at
   90.17 - * http://www.netbeans.org/cddl-gplv2.html
   90.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   90.19 - * specific language governing permissions and limitations under the
   90.20 - * License.  When distributing the software, include this License Header
   90.21 - * Notice in each file and include the License file at
   90.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   90.23 - * particular file as subject to the "Classpath" exception as provided
   90.24 - * by Oracle in the GPL Version 2 section of the License file that
   90.25 - * accompanied this code. If applicable, add the following below the
   90.26 - * License Header, with the fields enclosed by brackets [] replaced by
   90.27 - * your own identifying information:
   90.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   90.29 - *
   90.30 - * If you wish your version of this file to be governed by only the CDDL
   90.31 - * or only the GPL Version 2, indicate your decision by adding
   90.32 - * "[Contributor] elects to include this software in this distribution
   90.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   90.34 - * single choice of license, a recipient has the option to distribute
   90.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   90.36 - * to extend the choice of license to its licensees as provided above.
   90.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   90.38 - * Version 2 license, then the option applies only if the new code is
   90.39 - * made subject to such option by the copyright holder.
   90.40 - *
   90.41 - * Contributor(s):
   90.42 - *
   90.43 - * Portions Copyrighted 2009 Sun Microsystems, Inc.
   90.44 - */
   90.45 -
   90.46 -package org.netbeans.modules.java.hints.spiimpl.pm;
   90.47 -
   90.48 -import com.sun.source.tree.Tree;
   90.49 -import com.sun.source.util.TreePath;
   90.50 -import java.io.InputStream;
   90.51 -import java.util.Collection;
   90.52 -import java.util.Collections;
   90.53 -import java.util.HashMap;
   90.54 -import java.util.Iterator;
   90.55 -import java.util.LinkedList;
   90.56 -import java.util.Map;
   90.57 -import java.util.Map.Entry;
   90.58 -import java.util.concurrent.atomic.AtomicBoolean;
   90.59 -import javax.lang.model.type.TypeMirror;
   90.60 -import org.netbeans.api.java.source.CompilationInfo;
   90.61 -import org.netbeans.modules.java.hints.providers.spi.HintDescription.AdditionalQueryConstraints;
   90.62 -import org.netbeans.api.java.source.matching.Matcher;
   90.63 -import org.netbeans.api.java.source.matching.Occurrence;
   90.64 -import org.netbeans.api.java.source.matching.Pattern;
   90.65 -import org.openide.util.Parameters;
   90.66 -
   90.67 -/**
   90.68 - *
   90.69 - * @author lahvac
   90.70 - */
   90.71 -public class CopyFinderBasedBulkSearch extends BulkSearch {
   90.72 -
   90.73 -    public CopyFinderBasedBulkSearch() {
   90.74 -        super(false);
   90.75 -    }
   90.76 -
   90.77 -    @Override
   90.78 -    public Map<String, Collection<TreePath>> match(CompilationInfo info, AtomicBoolean cancel, TreePath toSearch, BulkPattern pattern, Map<String, Long> timeLog) {
   90.79 -        Parameters.notNull("info", info);
   90.80 -        Map<String, Collection<TreePath>> result = new HashMap<String, Collection<TreePath>>();
   90.81 -        TreePath topLevel = new TreePath(info.getCompilationUnit());
   90.82 -        
   90.83 -        for (Entry<Tree, String> e : ((BulkPatternImpl) pattern).pattern2Code.entrySet()) {
   90.84 -            for (Occurrence od : Matcher.create(info).setCancel(new AtomicBoolean()).setUntypedMatching().setCancel(cancel).match(Pattern.createPatternWithFreeVariables(new TreePath(topLevel, e.getKey()), Collections.<String, TypeMirror>emptyMap()))) {
   90.85 -                Collection<TreePath> c = result.get(e.getValue());
   90.86 -
   90.87 -                if (c == null) {
   90.88 -                    result.put(e.getValue(), c = new LinkedList<TreePath>());
   90.89 -                }
   90.90 -
   90.91 -                c.add(od.getOccurrenceRoot());
   90.92 -            }
   90.93 -        }
   90.94 -
   90.95 -        return result;
   90.96 -    }
   90.97 -
   90.98 -    @Override
   90.99 -    public boolean matches(CompilationInfo info, AtomicBoolean cancel, TreePath toSearch, BulkPattern pattern) {
  90.100 -        //XXX: performance
  90.101 -        return !match(info, cancel, toSearch, pattern).isEmpty();
  90.102 -    }
  90.103 -
  90.104 -    @Override
  90.105 -    public BulkPattern create(Collection<? extends String> code, Collection<? extends Tree> patterns, Collection<? extends AdditionalQueryConstraints> additionalConstraints, AtomicBoolean cancel) {
  90.106 -        Map<Tree, String> pattern2Code = new HashMap<Tree, String>();
  90.107 -
  90.108 -        Iterator<? extends String> itCode = code.iterator();
  90.109 -        Iterator<? extends Tree>   itPatt = patterns.iterator();
  90.110 -
  90.111 -        while (itCode.hasNext() && itPatt.hasNext()) {
  90.112 -            pattern2Code.put(itPatt.next(), itCode.next());
  90.113 -        }
  90.114 -
  90.115 -        return new BulkPatternImpl(additionalConstraints, pattern2Code);
  90.116 -    }
  90.117 -
  90.118 -    @Override
  90.119 -    public boolean matches(InputStream encoded, AtomicBoolean cancel, BulkPattern pattern) {
  90.120 -        throw new UnsupportedOperationException("Not supported yet.");
  90.121 -    }
  90.122 -
  90.123 -    @Override
  90.124 -    public void encode(Tree tree, EncodingContext ctx, AtomicBoolean cancel) {
  90.125 -        throw new UnsupportedOperationException("Not supported yet.");
  90.126 -    }
  90.127 -
  90.128 -    @Override
  90.129 -    public Map<String, Integer> matchesWithFrequencies(InputStream encoded, BulkPattern pattern, AtomicBoolean cancel) {
  90.130 -        throw new UnsupportedOperationException("Not supported yet.");
  90.131 -    }
  90.132 -
  90.133 -    private static final class BulkPatternImpl extends BulkPattern {
  90.134 -
  90.135 -        private final Map<Tree, String> pattern2Code;
  90.136 -        
  90.137 -        public BulkPatternImpl(Collection<? extends AdditionalQueryConstraints> additionalConstraints, Map<Tree, String> pattern2Code) {
  90.138 -            super(new LinkedList<String>(pattern2Code.values()), null, null, new LinkedList<AdditionalQueryConstraints>(additionalConstraints));
  90.139 -            this.pattern2Code = pattern2Code;
  90.140 -        }
  90.141 -
  90.142 -    }
  90.143 -
  90.144 -}
    91.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/pm/NFA.java	Sun Oct 16 08:01:27 2016 +0200
    91.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    91.3 @@ -1,216 +0,0 @@
    91.4 -/*
    91.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    91.6 - *
    91.7 - * Copyright 2009-2010 Oracle and/or its affiliates. All rights reserved.
    91.8 - *
    91.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   91.10 - * Other names may be trademarks of their respective owners.
   91.11 - *
   91.12 - * The contents of this file are subject to the terms of either the GNU
   91.13 - * General Public License Version 2 only ("GPL") or the Common
   91.14 - * Development and Distribution License("CDDL") (collectively, the
   91.15 - * "License"). You may not use this file except in compliance with the
   91.16 - * License. You can obtain a copy of the License at
   91.17 - * http://www.netbeans.org/cddl-gplv2.html
   91.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   91.19 - * specific language governing permissions and limitations under the
   91.20 - * License.  When distributing the software, include this License Header
   91.21 - * Notice in each file and include the License file at
   91.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   91.23 - * particular file as subject to the "Classpath" exception as provided
   91.24 - * by Oracle in the GPL Version 2 section of the License file that
   91.25 - * accompanied this code. If applicable, add the following below the
   91.26 - * License Header, with the fields enclosed by brackets [] replaced by
   91.27 - * your own identifying information:
   91.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   91.29 - *
   91.30 - * If you wish your version of this file to be governed by only the CDDL
   91.31 - * or only the GPL Version 2, indicate your decision by adding
   91.32 - * "[Contributor] elects to include this software in this distribution
   91.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   91.34 - * single choice of license, a recipient has the option to distribute
   91.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   91.36 - * to extend the choice of license to its licensees as provided above.
   91.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   91.38 - * Version 2 license, then the option applies only if the new code is
   91.39 - * made subject to such option by the copyright holder.
   91.40 - *
   91.41 - * Contributor(s):
   91.42 - *
   91.43 - * Portions Copyrighted 2009 Sun Microsystems, Inc.
   91.44 - */
   91.45 -
   91.46 -package org.netbeans.modules.java.hints.spiimpl.pm;
   91.47 -
   91.48 -import java.util.BitSet;
   91.49 -import java.util.HashSet;
   91.50 -import java.util.Map;
   91.51 -import java.util.Set;
   91.52 -
   91.53 -/**
   91.54 - *
   91.55 - * @author lahvac
   91.56 - */
   91.57 -public class NFA<I, R> {
   91.58 -
   91.59 -    /*XXX: private*/ final int stateCount;
   91.60 -    private final int startingState;
   91.61 -    private final Set<I> inputs;
   91.62 -    private final Map<Key<I>, State> transitionTable;
   91.63 -    private final Map<Integer, R> finalStates;
   91.64 -
   91.65 -    private final State startingStateObject;
   91.66 -
   91.67 -    private NFA(int startingState, int stateCount, Set<I> inputs, Map<Key<I>, State> transitionTable, Map<Integer, R> finalStates) {
   91.68 -        this.startingState = startingState;
   91.69 -        this.stateCount = stateCount;
   91.70 -        this.inputs = inputs;
   91.71 -        this.transitionTable = transitionTable;
   91.72 -        this.finalStates = finalStates;
   91.73 -
   91.74 -        startingStateObject = State.create().mutableOr(startingState);
   91.75 -    }
   91.76 -
   91.77 -    public State getStartingState() {
   91.78 -        return startingStateObject;
   91.79 -    }
   91.80 -
   91.81 -    public State transition(final State active, final I input) {
   91.82 -        State result = null;
   91.83 -
   91.84 -//        for (int i : active) {
   91.85 -        for (int i = active.nextSetBit(0); i >= 0; i = active.nextSetBit(i+1)) {
   91.86 -             State target = transitionTable.get(Key.create(i, input));
   91.87 -
   91.88 -             if (target != null) {
   91.89 -                 if (result == null) {
   91.90 -                     result = State.create();
   91.91 -                 }
   91.92 -                 
   91.93 -                 result.mutableOr(target);
   91.94 -             }
   91.95 -        }
   91.96 -
   91.97 -        State r;
   91.98 -
   91.99 -        //XXX:
  91.100 -        if (result == null) {
  91.101 -            r = startingStateObject;
  91.102 -        } else {
  91.103 -            r = result.mutableOr(startingState);//???
  91.104 -        }
  91.105 -
  91.106 -        return r;
  91.107 -    }
  91.108 -
  91.109 -    public Set<R> getResults(State bs) {
  91.110 -        Set<R> result = new HashSet<R>();
  91.111 -
  91.112 -        for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) {
  91.113 -            if (finalStates.get(i) != null) {
  91.114 -                result.add(finalStates.get(i));
  91.115 -            }
  91.116 -        }
  91.117 -
  91.118 -        return result;
  91.119 -    }
  91.120 -
  91.121 -    public static <I, R> NFA<I, R> create(int startingState, int stateCount, Set<I> inputs, Map<Key<I>, State> transitionTable, Map<Integer, R> finalStates) {
  91.122 -        return new NFA<I, R>(startingState, stateCount, inputs, transitionTable, finalStates);
  91.123 -    }
  91.124 -
  91.125 -    public State join(State s1, State s2) {
  91.126 -        State bs = State.create();
  91.127 -
  91.128 -        bs.mutableOr(s1);
  91.129 -        bs.mutableOr(s2);
  91.130 -
  91.131 -        return bs;
  91.132 -    }
  91.133 -
  91.134 -    public static final class Key<I> {
  91.135 -        private final int state;
  91.136 -        private final I   input;
  91.137 -
  91.138 -        private Key(int state, I input) {
  91.139 -            this.state = state;
  91.140 -            this.input = input;
  91.141 -        }
  91.142 -
  91.143 -        public static <I> Key<I> create(int state, I input) {
  91.144 -            return new Key<I>(state, input);
  91.145 -        }
  91.146 -
  91.147 -        @Override
  91.148 -        public boolean equals(Object obj) {
  91.149 -            if (obj == null) {
  91.150 -                return false;
  91.151 -            }
  91.152 -            if (getClass() != obj.getClass()) {
  91.153 -                return false;
  91.154 -            }
  91.155 -            final Key<?> other = (Key<?>) obj;
  91.156 -            if (this.state != other.state) {
  91.157 -                return false;
  91.158 -            }
  91.159 -            if (this.input != other.input && (this.input == null || !this.input.equals(other.input))) {
  91.160 -                return false;
  91.161 -            }
  91.162 -            return true;
  91.163 -        }
  91.164 -
  91.165 -        @Override
  91.166 -        public int hashCode() {
  91.167 -            int hash = 3;
  91.168 -            hash = 83 * hash + this.state;
  91.169 -            hash = 83 * hash + (this.input != null ? this.input.hashCode() : 0);
  91.170 -            return hash;
  91.171 -        }
  91.172 -
  91.173 -        @Override
  91.174 -        public String toString() {
  91.175 -            return "[" + state + ", " + input + "]";
  91.176 -        }
  91.177 -
  91.178 -    }
  91.179 -
  91.180 -//    public static final class State extends HashSet<Integer> {
  91.181 -//        private State() {
  91.182 -//        }
  91.183 -//
  91.184 -//        public static State create() {
  91.185 -//            return new State();
  91.186 -//        }
  91.187 -//
  91.188 -//        public State mutableOr(int state) {
  91.189 -//            add(state);
  91.190 -//            return this;
  91.191 -//        }
  91.192 -//
  91.193 -//        public State mutableOr(State or) {
  91.194 -//            addAll(or);
  91.195 -//            return this;
  91.196 -//        }
  91.197 -//
  91.198 -//    }
  91.199 -
  91.200 -    public static final class State extends BitSet {
  91.201 -        private State() {}
  91.202 -
  91.203 -        public static State create() {
  91.204 -            return new State();
  91.205 -        }
  91.206 -
  91.207 -        public State mutableOr(int state) {
  91.208 -            set(state);
  91.209 -            return this;
  91.210 -        }
  91.211 -
  91.212 -        public State mutableOr(State or) {
  91.213 -            or(or);
  91.214 -            return this;
  91.215 -        }
  91.216 -
  91.217 -    }
  91.218 -
  91.219 -}
    92.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/pm/NFABasedBulkSearch.java	Sun Oct 16 08:01:27 2016 +0200
    92.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    92.3 @@ -1,826 +0,0 @@
    92.4 -/*
    92.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    92.6 - *
    92.7 - * Copyright 2009-2010 Oracle and/or its affiliates. All rights reserved.
    92.8 - *
    92.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   92.10 - * Other names may be trademarks of their respective owners.
   92.11 - *
   92.12 - * The contents of this file are subject to the terms of either the GNU
   92.13 - * General Public License Version 2 only ("GPL") or the Common
   92.14 - * Development and Distribution License("CDDL") (collectively, the
   92.15 - * "License"). You may not use this file except in compliance with the
   92.16 - * License. You can obtain a copy of the License at
   92.17 - * http://www.netbeans.org/cddl-gplv2.html
   92.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   92.19 - * specific language governing permissions and limitations under the
   92.20 - * License.  When distributing the software, include this License Header
   92.21 - * Notice in each file and include the License file at
   92.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   92.23 - * particular file as subject to the "Classpath" exception as provided
   92.24 - * by Oracle in the GPL Version 2 section of the License file that
   92.25 - * accompanied this code. If applicable, add the following below the
   92.26 - * License Header, with the fields enclosed by brackets [] replaced by
   92.27 - * your own identifying information:
   92.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   92.29 - *
   92.30 - * If you wish your version of this file to be governed by only the CDDL
   92.31 - * or only the GPL Version 2, indicate your decision by adding
   92.32 - * "[Contributor] elects to include this software in this distribution
   92.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   92.34 - * single choice of license, a recipient has the option to distribute
   92.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   92.36 - * to extend the choice of license to its licensees as provided above.
   92.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   92.38 - * Version 2 license, then the option applies only if the new code is
   92.39 - * made subject to such option by the copyright holder.
   92.40 - *
   92.41 - * Contributor(s):
   92.42 - *
   92.43 - * Portions Copyrighted 2009-2010 Sun Microsystems, Inc.
   92.44 - */
   92.45 -
   92.46 -package org.netbeans.modules.java.hints.spiimpl.pm;
   92.47 -
   92.48 -import com.sun.source.tree.AnnotationTree;
   92.49 -import com.sun.source.tree.BlockTree;
   92.50 -import com.sun.source.tree.ClassTree;
   92.51 -import com.sun.source.tree.IdentifierTree;
   92.52 -import com.sun.source.tree.LiteralTree;
   92.53 -import com.sun.source.tree.MemberSelectTree;
   92.54 -import com.sun.source.tree.MethodTree;
   92.55 -import com.sun.source.tree.ModifiersTree;
   92.56 -import com.sun.source.tree.StatementTree;
   92.57 -import com.sun.source.tree.Tree;
   92.58 -import com.sun.source.tree.Tree.Kind;
   92.59 -import com.sun.source.tree.VariableTree;
   92.60 -import com.sun.source.util.TreePath;
   92.61 -import com.sun.source.util.TreeScanner;
   92.62 -import java.io.ByteArrayOutputStream;
   92.63 -import java.io.IOException;
   92.64 -import java.io.InputStream;
   92.65 -import java.io.UnsupportedEncodingException;
   92.66 -import java.util.ArrayList;
   92.67 -import java.util.Collection;
   92.68 -import java.util.Collections;
   92.69 -import java.util.EnumMap;
   92.70 -import java.util.EnumSet;
   92.71 -import java.util.HashMap;
   92.72 -import java.util.HashSet;
   92.73 -import java.util.Iterator;
   92.74 -import java.util.LinkedHashMap;
   92.75 -import java.util.LinkedList;
   92.76 -import java.util.List;
   92.77 -import java.util.Map;
   92.78 -import java.util.Map.Entry;
   92.79 -import java.util.Set;
   92.80 -import java.util.Stack;
   92.81 -import java.util.concurrent.atomic.AtomicBoolean;
   92.82 -import javax.lang.model.element.Name;
   92.83 -import org.netbeans.api.java.source.CompilationInfo;
   92.84 -import org.netbeans.api.java.source.support.CancellableTreeScanner;
   92.85 -import org.netbeans.modules.java.hints.spiimpl.Utilities;
   92.86 -import org.netbeans.modules.java.hints.providers.spi.HintDescription.AdditionalQueryConstraints;
   92.87 -import org.openide.util.Exceptions;
   92.88 -
   92.89 -/**
   92.90 - *
   92.91 - * @author lahvac
   92.92 - */
   92.93 -public class NFABasedBulkSearch extends BulkSearch {
   92.94 -
   92.95 -    public NFABasedBulkSearch() {
   92.96 -        super(false);
   92.97 -    }
   92.98 -
   92.99 -    @Override
  92.100 -    public Map<String, Collection<TreePath>> match(CompilationInfo info, final AtomicBoolean cancel, TreePath tree, BulkPattern patternIn, Map<String, Long> timeLog) {
  92.101 -        BulkPatternImpl pattern = (BulkPatternImpl) patternIn;
  92.102 -        
  92.103 -        final Map<Res, Collection<TreePath>> occurringPatterns = new HashMap<Res, Collection<TreePath>>();
  92.104 -        final NFA<Input, Res> nfa = pattern.toNFA();
  92.105 -        final Set<String> identifiers = new HashSet<String>();
  92.106 -
  92.107 -        new CollectIdentifiers<Void, TreePath>(identifiers, cancel) {
  92.108 -            private NFA.State active = nfa.getStartingState();
  92.109 -            @Override
  92.110 -            public Void scan(Tree node, TreePath p) {
  92.111 -                if (node == null) {
  92.112 -                    return null;
  92.113 -                }
  92.114 -
  92.115 -                TreePath currentPath = new TreePath(p, node);
  92.116 -                boolean[] goDeeper = new boolean[1];
  92.117 -                final NFA.State newActiveAfterVariable = nfa.transition(active, new Input(Kind.IDENTIFIER, "$", false));
  92.118 -                Input normalizedInput = normalizeInput(node, goDeeper, null);
  92.119 -                boolean ignoreKind = normalizedInput.kind == Kind.IDENTIFIER || normalizedInput.kind == Kind.MEMBER_SELECT;
  92.120 -
  92.121 -                NFA.State newActiveBefore = nfa.transition(active, normalizedInput);
  92.122 -
  92.123 -                if (normalizedInput.name != null && !ignoreKind) {
  92.124 -                    newActiveBefore = nfa.join(newActiveBefore, nfa.transition(active, new Input(normalizedInput.kind, "$", false)));
  92.125 -                }
  92.126 -
  92.127 -                active = newActiveBefore;
  92.128 -
  92.129 -                if (goDeeper[0]) {
  92.130 -                    super.scan(node, currentPath);
  92.131 -                } else {
  92.132 -                    new CollectIdentifiers<Void, Void>(identifiers, cancel).scan(node, null);
  92.133 -                }
  92.134 -                
  92.135 -                if (cancel.get()) return null;
  92.136 -
  92.137 -                NFA.State newActiveAfter = nfa.transition(active, UP);
  92.138 -
  92.139 -                active = nfa.join(newActiveAfter, nfa.transition(newActiveAfterVariable, UP));
  92.140 -
  92.141 -                for (Res r : nfa.getResults(active)) {
  92.142 -                    addOccurrence(r, currentPath);
  92.143 -                }
  92.144 -
  92.145 -                return null;
  92.146 -            }
  92.147 -
  92.148 -            @Override
  92.149 -            public Void scan(Iterable<? extends Tree> nodes, TreePath p) {
  92.150 -                active = nfa.transition(active, new Input(Kind.IDENTIFIER, "(", false));
  92.151 -                try {
  92.152 -                    return super.scan(nodes, p);
  92.153 -                } finally {
  92.154 -                    active = nfa.transition(active, UP);
  92.155 -                }
  92.156 -            }
  92.157 -            
  92.158 -            private void addOccurrence(Res r, TreePath currentPath) {
  92.159 -                Collection<TreePath> occurrences = occurringPatterns.get(r);
  92.160 -                if (occurrences == null) {
  92.161 -                    occurringPatterns.put(r, occurrences = new LinkedList<TreePath>());
  92.162 -                }
  92.163 -                occurrences.add(currentPath);
  92.164 -            }
  92.165 -        }.scan(tree, tree.getParentPath());
  92.166 -
  92.167 -        if (cancel.get()) return null;
  92.168 -        
  92.169 -        Map<String, Collection<TreePath>> result = new HashMap<String, Collection<TreePath>>();
  92.170 -
  92.171 -        for (Entry<Res, Collection<TreePath>> e : occurringPatterns.entrySet()) {
  92.172 -            if (cancel.get()) return null;
  92.173 -            if (!identifiers.containsAll(pattern.getIdentifiers().get(e.getKey().patternIndex))) {
  92.174 -                continue;
  92.175 -            }
  92.176 -
  92.177 -            result.put(e.getKey().pattern, e.getValue());
  92.178 -        }
  92.179 -
  92.180 -        return result;
  92.181 -    }
  92.182 -
  92.183 -    @Override
  92.184 -    public BulkPattern create(Collection<? extends String> code, Collection<? extends Tree> patterns, Collection<? extends AdditionalQueryConstraints> additionalConstraints, final AtomicBoolean cancel) {
  92.185 -        int startState = 0;
  92.186 -        final int[] nextState = new int[] {1};
  92.187 -        final Map<NFA.Key<Input>, NFA.State> transitionTable = new LinkedHashMap<NFA.Key<Input>, NFA.State>();
  92.188 -        Map<Integer, Res> finalStates = new HashMap<Integer, Res>();
  92.189 -        List<Set<? extends String>> identifiers = new LinkedList<Set<? extends String>>();
  92.190 -        List<List<List<String>>> requiredContent = new ArrayList<List<List<String>>>();
  92.191 -        Iterator<? extends String> codeIt = code.iterator();
  92.192 -        int patternIndex = 0;
  92.193 -
  92.194 -        for (final Tree pattern : patterns) {
  92.195 -            final int[] currentState = new int[] {startState};
  92.196 -            final Set<String> patternIdentifiers = new HashSet<String>();
  92.197 -            final List<List<String>> content = new ArrayList<List<String>>();
  92.198 -
  92.199 -            identifiers.add(patternIdentifiers);
  92.200 -            requiredContent.add(content);
  92.201 -
  92.202 -            class Scanner extends CollectIdentifiers<Void, Void> {
  92.203 -                public Scanner() {
  92.204 -                    super(patternIdentifiers, cancel);
  92.205 -                }
  92.206 -                private boolean auxPath;
  92.207 -                private List<String> currentContent;
  92.208 -                {
  92.209 -                    content.add(currentContent = new ArrayList<String>());
  92.210 -                }
  92.211 -                @Override
  92.212 -                public Void scan(Tree t, Void v) {
  92.213 -                    if (t == null) {
  92.214 -                        return null;
  92.215 -                    }
  92.216 -
  92.217 -                    if (Utilities.isMultistatementWildcardTree(t) || multiModifiers(t)) {
  92.218 -                        int target = nextState[0]++;
  92.219 -
  92.220 -                        setBit(transitionTable, NFA.Key.create(currentState[0], new Input(Kind.IDENTIFIER, "$", false)), target);
  92.221 -                        setBit(transitionTable, NFA.Key.create(target, UP), currentState[0]);
  92.222 -
  92.223 -                        content.add(currentContent = new ArrayList<String>());
  92.224 -                        
  92.225 -                        return null;
  92.226 -                    }
  92.227 -
  92.228 -                    if (t.getKind() == Kind.BLOCK) {
  92.229 -                        StatementTree singletonStatement = null;
  92.230 -                        BlockTree bt = (BlockTree) t;
  92.231 -
  92.232 -                        if (!bt.isStatic()) {
  92.233 -                            switch (bt.getStatements().size()) {
  92.234 -                                case 1:
  92.235 -                                    singletonStatement = bt.getStatements().get(0);
  92.236 -                                    break;
  92.237 -                                case 2:
  92.238 -                                    if (Utilities.isMultistatementWildcardTree(bt.getStatements().get(0))) {
  92.239 -                                        singletonStatement = bt.getStatements().get(1);
  92.240 -                                    } else {
  92.241 -                                        if (Utilities.isMultistatementWildcardTree(bt.getStatements().get(1))) {
  92.242 -                                            singletonStatement = bt.getStatements().get(0);
  92.243 -                                        }
  92.244 -                                    }
  92.245 -                                    break;
  92.246 -                                case 3:
  92.247 -                                    if (Utilities.isMultistatementWildcardTree(bt.getStatements().get(0)) && Utilities.isMultistatementWildcardTree(bt.getStatements().get(2))) {
  92.248 -                                        singletonStatement = bt.getStatements().get(1);
  92.249 -                                    }
  92.250 -                                    break;
  92.251 -                            }
  92.252 -                        }
  92.253 -
  92.254 -                        if (singletonStatement != null) {
  92.255 -                            int backup = currentState[0];
  92.256 -
  92.257 -                            boolean oldAuxPath = auxPath;
  92.258 -
  92.259 -                            auxPath = true;
  92.260 -
  92.261 -                            scan(singletonStatement, null);
  92.262 -
  92.263 -                            auxPath = oldAuxPath;
  92.264 -
  92.265 -                            int target = currentState[0];
  92.266 -
  92.267 -                            setBit(transitionTable, NFA.Key.create(backup, new Input(Kind.BLOCK, null, false)), currentState[0] = nextState[0]++);
  92.268 -                            setBit(transitionTable, NFA.Key.create(currentState[0], new Input(Kind.IDENTIFIER, "(", false)), currentState[0] = nextState[0]++);
  92.269 -
  92.270 -                            for (StatementTree st : bt.getStatements()) {
  92.271 -                                scan(st, null);
  92.272 -                            }
  92.273 -
  92.274 -                            setBit(transitionTable, NFA.Key.create(currentState[0], UP), currentState[0] = nextState[0]++);
  92.275 -                            setBit(transitionTable, NFA.Key.create(currentState[0], UP), target);
  92.276 -                            currentState[0] = target;
  92.277 -
  92.278 -                            return null;
  92.279 -                        }
  92.280 -                    }
  92.281 -                    
  92.282 -                    boolean[] goDeeper = new boolean[1];
  92.283 -                    Input[] bypass = new Input[1];
  92.284 -                    Input i = normalizeInput(t, goDeeper, bypass);
  92.285 -
  92.286 -                    if (!TO_IGNORE.contains(i.kind) && !auxPath) {
  92.287 -                        currentContent.add(kind2EncodedString.get(i.kind));
  92.288 -                    }
  92.289 -
  92.290 -                    if (i.name != null && !auxPath) {
  92.291 -                        if (!"$".equals(i.name)) {
  92.292 -                            if (isIdentifierAcceptable(i.name)) {
  92.293 -                                currentContent.add(i.name);
  92.294 -                            }
  92.295 -                            if (Utilities.isPureMemberSelect(t, false)) {
  92.296 -                                content.add(currentContent = new ArrayList<String>());
  92.297 -                            }
  92.298 -                        } else {
  92.299 -                            content.add(currentContent = new ArrayList<String>());
  92.300 -                        }
  92.301 -                    }
  92.302 -
  92.303 -                    int backup = currentState[0];
  92.304 -
  92.305 -                    handleTree(i, goDeeper, t, bypass);
  92.306 -
  92.307 -                    boolean oldAuxPath = auxPath;
  92.308 -
  92.309 -                    auxPath = true;
  92.310 -
  92.311 -                    if (StatementTree.class.isAssignableFrom(t.getKind().asInterface()) && t != pattern) {
  92.312 -                        int target = currentState[0];
  92.313 -
  92.314 -                        setBit(transitionTable, NFA.Key.create(backup, new Input(Kind.BLOCK, null, false)), currentState[0] = nextState[0]++);
  92.315 -                        setBit(transitionTable, NFA.Key.create(currentState[0], new Input(Kind.IDENTIFIER, "(", false)), currentState[0] = nextState[0]++);
  92.316 -                        handleTree(i, goDeeper, t, bypass);
  92.317 -                        setBit(transitionTable, NFA.Key.create(currentState[0], UP), currentState[0] = nextState[0]++);
  92.318 -                        setBit(transitionTable, NFA.Key.create(currentState[0], UP), target);
  92.319 -                        currentState[0] = target;
  92.320 -                    }
  92.321 -
  92.322 -                    auxPath = oldAuxPath;
  92.323 -
  92.324 -                    return null;
  92.325 -                }
  92.326 -
  92.327 -                @Override
  92.328 -                public Void scan(Iterable<? extends Tree> nodes, Void p) {
  92.329 -                    setBit(transitionTable, NFA.Key.create(currentState[0], new Input(Kind.IDENTIFIER, "(", false)), currentState[0] = nextState[0]++);
  92.330 -                    try {
  92.331 -                        return super.scan(nodes, p);
  92.332 -                    } finally {
  92.333 -                        setBit(transitionTable, NFA.Key.create(currentState[0], UP), currentState[0] = nextState[0]++);
  92.334 -                    }
  92.335 -                }
  92.336 -
  92.337 -                private void handleTree(Input i, boolean[] goDeeper, Tree t, Input[] bypass) {
  92.338 -                    int backup = currentState[0];
  92.339 -                    int target = nextState[0]++;
  92.340 -
  92.341 -                    setBit(transitionTable, NFA.Key.create(backup, i), currentState[0] = nextState[0]++);
  92.342 -
  92.343 -                    if (goDeeper[0]) {
  92.344 -                        super.scan(t, null);
  92.345 -                    } else {
  92.346 -                        new CollectIdentifiers<Void, Void>(patternIdentifiers, cancel).scan(t, null);
  92.347 -                        int aux = nextState[0]++;
  92.348 -                        setBit(transitionTable, NFA.Key.create(backup, new Input(Kind.MEMBER_SELECT, i.name, false)), aux);
  92.349 -                        setBit(transitionTable, NFA.Key.create(aux, new Input(Kind.IDENTIFIER, "$", false)), aux = nextState[0]++);
  92.350 -                        setBit(transitionTable, NFA.Key.create(aux, UP), aux = nextState[0]++);
  92.351 -                        setBit(transitionTable, NFA.Key.create(aux, UP), target);
  92.352 -                    }
  92.353 -
  92.354 -                    setBit(transitionTable, NFA.Key.create(currentState[0], UP), target);
  92.355 -                    
  92.356 -                    if (bypass[0] != null) {
  92.357 -                        int intermediate = nextState[0]++;
  92.358 -                        
  92.359 -                        setBit(transitionTable, NFA.Key.create(backup, bypass[0]), intermediate);
  92.360 -                        setBit(transitionTable, NFA.Key.create(intermediate, UP), target);
  92.361 -                    }
  92.362 -                    
  92.363 -                    currentState[0] = target;
  92.364 -                }
  92.365 -            }
  92.366 -
  92.367 -            Scanner s = new Scanner();
  92.368 -
  92.369 -            s.scan(pattern, null);
  92.370 -
  92.371 -            finalStates.put(currentState[0], new Res(codeIt.next(), patternIndex++));
  92.372 -        }
  92.373 -
  92.374 -        if (cancel.get()) return null;
  92.375 -        
  92.376 -        NFA<Input, Res> nfa = NFA.<Input, Res>create(startState, nextState[0], null, transitionTable, finalStates);
  92.377 -
  92.378 -        return new BulkPatternImpl(new LinkedList<String>(code), identifiers, requiredContent, new LinkedList<AdditionalQueryConstraints>(additionalConstraints), nfa);
  92.379 -    }
  92.380 -
  92.381 -    private static void setBit(Map<NFA.Key<Input>, NFA.State> transitionTable, NFA.Key<Input> input, int state) {
  92.382 -        NFA.State target = transitionTable.get(input);
  92.383 -
  92.384 -        if (target == null) {
  92.385 -            transitionTable.put(input, target = NFA.State.create());
  92.386 -        }
  92.387 -
  92.388 -        target.mutableOr(state);
  92.389 -    }
  92.390 -
  92.391 -    private static Input normalizeInput(Tree t, boolean[] goDeeper, Input[] bypass) {
  92.392 -        if (t.getKind() == Kind.IDENTIFIER && ((IdentifierTree) t).getName().toString().startsWith("$")) {
  92.393 -            goDeeper[0] = false;
  92.394 -            return new Input(Kind.IDENTIFIER, "$", false);
  92.395 -        }
  92.396 -
  92.397 -        if (Utilities.getWildcardTreeName(t) != null) {
  92.398 -            goDeeper[0] = false;
  92.399 -            return new Input(Kind.IDENTIFIER, "$", false);
  92.400 -        }
  92.401 -        
  92.402 -        if (t.getKind() == Kind.IDENTIFIER) {
  92.403 -            goDeeper[0] = false;
  92.404 -            String name = ((IdentifierTree) t).getName().toString();
  92.405 -            return new Input(Kind.IDENTIFIER, name, false);
  92.406 -        }
  92.407 -
  92.408 -        if (t.getKind() == Kind.MEMBER_SELECT) {
  92.409 -            String name = ((MemberSelectTree) t).getIdentifier().toString();
  92.410 -            if (name.startsWith("$")) {
  92.411 -                goDeeper[0] = false;//???
  92.412 -                return new Input(Kind.IDENTIFIER, "$", false);
  92.413 -            }
  92.414 -            if (bypass != null && Utilities.isPureMemberSelect(t, true)) {
  92.415 -                bypass[0] = new Input(Kind.IDENTIFIER, name, false);
  92.416 -            }
  92.417 -            goDeeper[0] = true;
  92.418 -            return new Input(Kind.MEMBER_SELECT, name, false);
  92.419 -        }
  92.420 -
  92.421 -        goDeeper[0] = true;
  92.422 -
  92.423 -        String name;
  92.424 -
  92.425 -        switch (t.getKind()) {
  92.426 -            case CLASS: name = ((ClassTree)t).getSimpleName().toString(); break;
  92.427 -            case VARIABLE: name = ((VariableTree)t).getName().toString(); break;
  92.428 -            case METHOD: name = ((MethodTree)t).getName().toString(); break;
  92.429 -            case BOOLEAN_LITERAL: name = ((LiteralTree) t).getValue().toString(); break;
  92.430 -            default: name = null;
  92.431 -        }
  92.432 -
  92.433 -        if (name != null) {
  92.434 -            if (!name.isEmpty() && name.charAt(0) == '$') {
  92.435 -                name = "$";
  92.436 -            }
  92.437 -        }
  92.438 -        return new Input(t.getKind(), name, false);
  92.439 -    }
  92.440 -    
  92.441 -    private boolean multiModifiers(Tree t) {
  92.442 -        if (t.getKind() != Kind.MODIFIERS) return false;
  92.443 -        
  92.444 -        List<AnnotationTree> annotations = new ArrayList<AnnotationTree>(((ModifiersTree) t).getAnnotations());
  92.445 -
  92.446 -        return !annotations.isEmpty() && annotations.get(0).getAnnotationType().getKind() == Kind.IDENTIFIER;
  92.447 -    }
  92.448 -
  92.449 -    @Override
  92.450 -    public boolean matches(CompilationInfo info, AtomicBoolean cancel, TreePath tree, BulkPattern pattern) {
  92.451 -        //XXX: performance
  92.452 -        return !match(info, cancel, tree, pattern).isEmpty();
  92.453 -    }
  92.454 -
  92.455 -    private static final Set<Kind> TO_IGNORE = EnumSet.of(Kind.BLOCK, Kind.IDENTIFIER, Kind.MEMBER_SELECT);
  92.456 -
  92.457 -    @Override
  92.458 -    public void encode(Tree tree, final EncodingContext ctx, AtomicBoolean cancel) {
  92.459 -        final Set<String> identifiers = new HashSet<String>();
  92.460 -        final List<String> content = new ArrayList<String>();
  92.461 -        if (!ctx.isForDuplicates()) {
  92.462 -            new CollectIdentifiers<Void, Void>(identifiers, cancel).scan(tree, null);
  92.463 -            try {
  92.464 -                int size = identifiers.size();
  92.465 -                ctx.getOut().write((size >> 24) & 0xFF);
  92.466 -                ctx.getOut().write((size >> 16) & 0xFF);
  92.467 -                ctx.getOut().write((size >>  8) & 0xFF);
  92.468 -                ctx.getOut().write((size >>  0) & 0xFF);
  92.469 -                for (String ident : identifiers) {
  92.470 -                    ctx.getOut().write(ident.getBytes("UTF-8"));//XXX: might probably contain ';'
  92.471 -                    ctx.getOut().write(';');
  92.472 -                }
  92.473 -            } catch (IOException ex) {
  92.474 -                throw new IllegalStateException(ex);
  92.475 -            }
  92.476 -        }
  92.477 -        if (cancel.get());
  92.478 -        new CollectIdentifiers<Void, Void>(new HashSet<String>(), cancel) {
  92.479 -            private boolean encode = true;
  92.480 -            @Override
  92.481 -            public Void scan(Tree t, Void v) {
  92.482 -                if (t == null) return null;
  92.483 -
  92.484 -                if (t instanceof StatementTree && Utilities.isMultistatementWildcardTree((StatementTree) t)) {
  92.485 -                    return null;
  92.486 -                }
  92.487 -
  92.488 -                boolean[] goDeeper = new boolean[1];
  92.489 -
  92.490 -                Input i = normalizeInput(t, goDeeper, null);
  92.491 -                try {
  92.492 -                    ctx.getOut().write('(');
  92.493 -                    ctx.getOut().write(kind2Encoded.get(i.kind));
  92.494 -                    if (!TO_IGNORE.contains(i.kind)) {
  92.495 -                        content.add(kind2EncodedString.get(i.kind));
  92.496 -                    }
  92.497 -                    if (i.name != null) {
  92.498 -                        if (encode) {
  92.499 -                            ctx.getOut().write('$');
  92.500 -                            ctx.getOut().write(i.name.getBytes("UTF-8"));
  92.501 -                            ctx.getOut().write(';');
  92.502 -                        }
  92.503 -                        if (isIdentifierAcceptable(i.name)) content.add(i.name);
  92.504 -                    }
  92.505 -
  92.506 -                    boolean oldEncode = encode;
  92.507 -
  92.508 -                    encode &= goDeeper[0];
  92.509 -                    super.scan(t, v);
  92.510 -                    encode = oldEncode;
  92.511 -
  92.512 -                    ctx.getOut().write(')');
  92.513 -                } catch (IOException ex) {
  92.514 -                    //XXX
  92.515 -                    Exceptions.printStackTrace(ex);
  92.516 -                }
  92.517 -
  92.518 -                return null;
  92.519 -            }
  92.520 -            @Override
  92.521 -            public Void scan(Iterable<? extends Tree> nodes, Void p) {
  92.522 -                try {
  92.523 -                    ctx.getOut().write('(');
  92.524 -                    ctx.getOut().write(kind2Encoded.get(Kind.IDENTIFIER));
  92.525 -                    ctx.getOut().write('$');
  92.526 -                    ctx.getOut().write('(');
  92.527 -                    ctx.getOut().write(';');
  92.528 -                    super.scan(nodes, p);
  92.529 -                    ctx.getOut().write(')');
  92.530 -                } catch (IOException ex) {
  92.531 -                    //XXX
  92.532 -                    Exceptions.printStackTrace(ex);
  92.533 -                }
  92.534 -                return null;
  92.535 -            }
  92.536 -        }.scan(tree, null);
  92.537 -
  92.538 -        ctx.setIdentifiers(identifiers);
  92.539 -        ctx.setContent(content);
  92.540 -        if (cancel.get());
  92.541 -    }
  92.542 -
  92.543 -    @Override
  92.544 -    public boolean matches(InputStream encoded, AtomicBoolean cancel, BulkPattern patternIn) {
  92.545 -        try {
  92.546 -            return !matchesImpl(encoded, cancel, patternIn, false).isEmpty();
  92.547 -        } catch (IOException ex) {
  92.548 -            Exceptions.printStackTrace(ex);
  92.549 -            return false;
  92.550 -        }
  92.551 -    }
  92.552 -
  92.553 -    @Override
  92.554 -    public Map<String, Integer> matchesWithFrequencies(InputStream encoded, BulkPattern patternIn, AtomicBoolean cancel) {
  92.555 -        try {
  92.556 -            return matchesImpl(encoded, cancel, patternIn, true);
  92.557 -        } catch (IOException ex) {
  92.558 -            Exceptions.printStackTrace(ex);
  92.559 -            return Collections.emptyMap();
  92.560 -        }
  92.561 -    }
  92.562 -
  92.563 -    public Map<String, Integer> matchesImpl(InputStream encoded, AtomicBoolean cancel, BulkPattern patternIn, boolean withFrequencies) throws IOException {
  92.564 -        BulkPatternImpl pattern = (BulkPatternImpl) patternIn;
  92.565 -        final NFA<Input, Res> nfa = pattern.toNFA();
  92.566 -        Stack<NFA.State> skips = new Stack<NFA.State>();
  92.567 -        NFA.State active = nfa.getStartingState();
  92.568 -        int identSize = 0;
  92.569 -
  92.570 -        identSize = encoded.read();
  92.571 -        identSize = (identSize << 8) + encoded.read();
  92.572 -        identSize = (identSize << 8) + encoded.read();
  92.573 -        identSize = (identSize << 8) + encoded.read();
  92.574 -
  92.575 -        Set<String> identifiers = new HashSet<String>(2 * identSize);
  92.576 -
  92.577 -        while (identSize-- > 0) {
  92.578 -            if (cancel.get()) return null;
  92.579 -            int read = encoded.read();
  92.580 -
  92.581 -            ByteArrayOutputStream baos = new ByteArrayOutputStream();
  92.582 -
  92.583 -            //read name:
  92.584 -            while (read != ';') {
  92.585 -                baos.write(read);
  92.586 -                read = encoded.read();
  92.587 -            }
  92.588 -
  92.589 -            identifiers.add(new String(baos.toByteArray(), "UTF-8"));
  92.590 -        }
  92.591 -
  92.592 -        Map<String, Integer> patternsAndFrequencies = new HashMap<String, Integer>();
  92.593 -        int read = encoded.read();
  92.594 -        
  92.595 -        while (read != (-1)) {
  92.596 -            if (cancel.get()) return null;
  92.597 -            if (read == '(') {
  92.598 -                read = encoded.read(); //kind
  92.599 -
  92.600 -                Kind k = encoded2Kind.get((read << 8) + encoded.read());
  92.601 -
  92.602 -                read = encoded.read();
  92.603 -
  92.604 -                String name;
  92.605 -
  92.606 -                if (read == '$') {
  92.607 -                    //XXX:
  92.608 -                    read = encoded.read();
  92.609 -
  92.610 -                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
  92.611 -
  92.612 -                    //read name:
  92.613 -                    while (read != ';') {
  92.614 -                        baos.write(read);
  92.615 -                        read = encoded.read();
  92.616 -                    }
  92.617 -
  92.618 -                    read = encoded.read();
  92.619 -                    name = new String(baos.toByteArray(), "UTF-8");
  92.620 -                } else {
  92.621 -                    name = null;
  92.622 -                }
  92.623 -                
  92.624 -                final NFA.State newActiveAfterVariable = nfa.transition(active, new Input(Kind.IDENTIFIER, "$", false));
  92.625 -                Input normalizedInput = new Input(k, name, false);
  92.626 -                boolean ignoreKind = normalizedInput.kind == Kind.IDENTIFIER || normalizedInput.kind == Kind.MEMBER_SELECT;
  92.627 -
  92.628 -                NFA.State newActive = nfa.transition(active, normalizedInput);
  92.629 -
  92.630 -                if (normalizedInput.name != null && !ignoreKind) {
  92.631 -                    newActive = nfa.join(newActive, nfa.transition(active, new Input(k, "$", false)));
  92.632 -                }
  92.633 -
  92.634 -                active = newActive;
  92.635 -
  92.636 -                skips.push(newActiveAfterVariable);
  92.637 -            } else {
  92.638 -                NFA.State newActiveAfterVariable = skips.pop();
  92.639 -                NFA.State newActive = nfa.transition(active, UP);
  92.640 -                NFA.State s2 = nfa.transition(newActiveAfterVariable, UP);
  92.641 -
  92.642 -                active = nfa.join(newActive, s2);
  92.643 -                
  92.644 -                for (Res res : nfa.getResults(active)) {
  92.645 -                    if (identifiers.containsAll(pattern.getIdentifiers().get(res.patternIndex))) {
  92.646 -                        if (!withFrequencies) {
  92.647 -                            patternsAndFrequencies.put(res.pattern, 1);
  92.648 -                            return patternsAndFrequencies;
  92.649 -                        }
  92.650 -                        
  92.651 -                        Integer freqs = patternsAndFrequencies.get(res.pattern);
  92.652 -
  92.653 -                        if (freqs == null) freqs = 0;
  92.654 -
  92.655 -                        patternsAndFrequencies.put(res.pattern, freqs + 1);
  92.656 -                    }
  92.657 -                }
  92.658 -
  92.659 -                read = encoded.read();
  92.660 -            }
  92.661 -        }
  92.662 -
  92.663 -        return patternsAndFrequencies;
  92.664 -    }
  92.665 -
  92.666 -    private static final Map<Kind, byte[]> kind2Encoded;
  92.667 -    private static final Map<Kind, String> kind2EncodedString;
  92.668 -    private static final Map<Integer, Kind> encoded2Kind;
  92.669 -
  92.670 -    static {
  92.671 -        kind2Encoded = new EnumMap<Kind, byte[]>(Kind.class);
  92.672 -        kind2EncodedString = new EnumMap<Kind, String>(Kind.class);
  92.673 -        encoded2Kind = new HashMap<Integer, Kind>();
  92.674 -
  92.675 -        for (Kind k : Kind.values()) {
  92.676 -            String enc = Integer.toHexString(k.ordinal());
  92.677 -
  92.678 -            if (enc.length() < 2) {
  92.679 -                enc = "0" + enc;
  92.680 -            }
  92.681 -
  92.682 -            try {
  92.683 -                final byte[] bytes = enc.getBytes("UTF-8");
  92.684 -
  92.685 -                assert bytes.length == 2;
  92.686 -
  92.687 -                kind2Encoded.put(k, bytes);
  92.688 -                kind2EncodedString.put(k, enc);
  92.689 -
  92.690 -                encoded2Kind.put((bytes[0] << 8) + bytes[1], k);
  92.691 -            } catch (UnsupportedEncodingException ex) {
  92.692 -                throw new IllegalStateException(ex);
  92.693 -            }
  92.694 -        }
  92.695 -    }
  92.696 -
  92.697 -    public static class BulkPatternImpl extends BulkPattern {
  92.698 -
  92.699 -        private final NFA<Input, Res> nfa;
  92.700 -
  92.701 -        private BulkPatternImpl(List<? extends String> patterns, List<? extends Set<? extends String>> identifiers, List<List<List<String>>> requiredContent, List<AdditionalQueryConstraints> additionalConstraints, NFA<Input, Res> nfa) {
  92.702 -            super(patterns, identifiers, requiredContent, additionalConstraints);
  92.703 -            this.nfa = nfa;
  92.704 -        }
  92.705 -
  92.706 -        NFA<Input, Res> toNFA() {
  92.707 -            return nfa;
  92.708 -        }
  92.709 -        
  92.710 -    }
  92.711 -
  92.712 -    private static final class Res {
  92.713 -        private final String pattern;
  92.714 -        private final int patternIndex;
  92.715 -
  92.716 -        public Res(String pattern, int patternIndex) {
  92.717 -            this.pattern = pattern;
  92.718 -            this.patternIndex = patternIndex;
  92.719 -        }
  92.720 -
  92.721 -    }
  92.722 -
  92.723 -    private static final class Input {
  92.724 -        private final Kind kind;
  92.725 -        private final String name;
  92.726 -        private final boolean end;
  92.727 -
  92.728 -        private Input(Kind kind, String name, boolean end) {
  92.729 -            this.kind = kind;
  92.730 -            this.name = name;
  92.731 -            this.end = end;
  92.732 -        }
  92.733 -
  92.734 -        @Override
  92.735 -        public boolean equals(Object obj) {
  92.736 -            if (obj == null) {
  92.737 -                return false;
  92.738 -            }
  92.739 -            if (getClass() != obj.getClass()) {
  92.740 -                return false;
  92.741 -            }
  92.742 -            final Input other = (Input) obj;
  92.743 -            if (this.kind != other.kind) {
  92.744 -                return false;
  92.745 -            }
  92.746 -            if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
  92.747 -                return false;
  92.748 -            }
  92.749 -            if (this.end != other.end) {
  92.750 -                return false;
  92.751 -            }
  92.752 -            return true;
  92.753 -        }
  92.754 -
  92.755 -        @Override
  92.756 -        public int hashCode() {
  92.757 -            int hash = 7;
  92.758 -            hash = 47 * hash + (this.kind != null ? this.kind.hashCode() : 17);
  92.759 -            hash = 47 * hash + (this.name != null ? this.name.hashCode() : 0);
  92.760 -            hash = 47 * hash + (this.end ? 1 : 0);
  92.761 -            return hash;
  92.762 -        }
  92.763 -
  92.764 -        @Override
  92.765 -        public String toString() {
  92.766 -            return kind + ", " + name + ", " + end;
  92.767 -        }
  92.768 -
  92.769 -    }
  92.770 -
  92.771 -    private static final Input UP = new Input(null, null, true);
  92.772 -
  92.773 -    private static boolean isIdentifierAcceptable(CharSequence content) {
  92.774 -        if (content.length() == 0) return false;
  92.775 -        if (content.charAt(0) == '$' || content.charAt(0) == '<') return false;
  92.776 -        String stringValue = content.toString();
  92.777 -        if (stringValue.contentEquals("java") || "lang".equals(stringValue)) return false;
  92.778 -        return true;
  92.779 -    }
  92.780 -
  92.781 -    private static class CollectIdentifiers<R, P> extends CancellableTreeScanner<R, P> {
  92.782 -
  92.783 -        private final Set<String> identifiers;
  92.784 -
  92.785 -        public CollectIdentifiers(Set<String> identifiers, AtomicBoolean cancel) {
  92.786 -            super(cancel);
  92.787 -            this.identifiers = identifiers;
  92.788 -        }
  92.789 -
  92.790 -        private void addIdentifier(Name ident) {
  92.791 -            if (!isIdentifierAcceptable(ident)) return;
  92.792 -            identifiers.add(ident.toString());
  92.793 -        }
  92.794 -
  92.795 -        @Override
  92.796 -        public R visitMemberSelect(MemberSelectTree node, P p) {
  92.797 -            addIdentifier(node.getIdentifier());
  92.798 -            return super.visitMemberSelect(node, p);
  92.799 -        }
  92.800 -
  92.801 -        @Override
  92.802 -        public R visitIdentifier(IdentifierTree node, P p) {
  92.803 -            addIdentifier(node.getName());
  92.804 -            return super.visitIdentifier(node, p);
  92.805 -        }
  92.806 -
  92.807 -        @Override
  92.808 -        public R visitClass(ClassTree node, P p) {
  92.809 -            if (node.getSimpleName().length() == 0) {
  92.810 -                return scan(Utilities.filterHidden(null, node.getMembers()), p);
  92.811 -            }
  92.812 -            addIdentifier(node.getSimpleName());
  92.813 -            return super.visitClass(node, p);
  92.814 -        }
  92.815 -
  92.816 -        @Override
  92.817 -        public R visitMethod(MethodTree node, P p) {
  92.818 -            addIdentifier(node.getName());
  92.819 -            return super.visitMethod(node, p);
  92.820 -        }
  92.821 -
  92.822 -        @Override
  92.823 -        public R visitVariable(VariableTree node, P p) {
  92.824 -            addIdentifier(node.getName());
  92.825 -            return super.visitVariable(node, p);
  92.826 -        }
  92.827 -
  92.828 -    }
  92.829 -}
    93.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/pm/PatternCompiler.java	Sun Oct 16 08:01:27 2016 +0200
    93.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    93.3 @@ -1,72 +0,0 @@
    93.4 -/*
    93.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    93.6 - *
    93.7 - * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
    93.8 - *
    93.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   93.10 - * Other names may be trademarks of their respective owners.
   93.11 - *
   93.12 - * The contents of this file are subject to the terms of either the GNU
   93.13 - * General Public License Version 2 only ("GPL") or the Common
   93.14 - * Development and Distribution License("CDDL") (collectively, the
   93.15 - * "License"). You may not use this file except in compliance with the
   93.16 - * License. You can obtain a copy of the License at
   93.17 - * http://www.netbeans.org/cddl-gplv2.html
   93.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   93.19 - * specific language governing permissions and limitations under the
   93.20 - * License.  When distributing the software, include this License Header
   93.21 - * Notice in each file and include the License file at
   93.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   93.23 - * particular file as subject to the "Classpath" exception as provided
   93.24 - * by Oracle in the GPL Version 2 section of the License file that
   93.25 - * accompanied this code. If applicable, add the following below the
   93.26 - * License Header, with the fields enclosed by brackets [] replaced by
   93.27 - * your own identifying information:
   93.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   93.29 - *
   93.30 - * If you wish your version of this file to be governed by only the CDDL
   93.31 - * or only the GPL Version 2, indicate your decision by adding
   93.32 - * "[Contributor] elects to include this software in this distribution
   93.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   93.34 - * single choice of license, a recipient has the option to distribute
   93.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   93.36 - * to extend the choice of license to its licensees as provided above.
   93.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   93.38 - * Version 2 license, then the option applies only if the new code is
   93.39 - * made subject to such option by the copyright holder.
   93.40 - *
   93.41 - * Contributor(s):
   93.42 - *
   93.43 - * Portions Copyrighted 2008-2009 Sun Microsystems, Inc.
   93.44 - */
   93.45 -
   93.46 -package org.netbeans.modules.java.hints.spiimpl.pm;
   93.47 -
   93.48 -import com.sun.source.tree.Scope;
   93.49 -import com.sun.source.tree.Tree;
   93.50 -import com.sun.source.util.TreePath;
   93.51 -import java.util.Map;
   93.52 -import javax.lang.model.type.TypeMirror;
   93.53 -import org.netbeans.api.java.source.CompilationInfo;
   93.54 -import org.netbeans.modules.java.hints.spiimpl.Utilities;
   93.55 -import org.netbeans.api.java.source.matching.Pattern;
   93.56 -
   93.57 -/**XXX: cancelability!
   93.58 - *
   93.59 - * @author Jan Lahoda
   93.60 - */
   93.61 -public class PatternCompiler {
   93.62 -
   93.63 -    public static Pattern compile(CompilationInfo info, String pattern, Map<String, TypeMirror> constraints, Iterable<? extends String> imports) {
   93.64 -        Scope scope = Utilities.constructScope(info, constraints, imports);
   93.65 -
   93.66 -        if (scope == null) {
   93.67 -            return null; //TODO: can happen?
   93.68 -        }
   93.69 -
   93.70 -        Tree patternTree = Utilities.parseAndAttribute(info, pattern, scope);
   93.71 -
   93.72 -        return Pattern.createPatternWithFreeVariables(new TreePath(new TreePath(info.getCompilationUnit()), patternTree), constraints);
   93.73 -    }
   93.74 -
   93.75 -}
    94.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/processor/Bundle.properties	Sun Oct 16 08:01:27 2016 +0200
    94.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    94.3 @@ -1,3 +0,0 @@
    94.4 -OpenIDE-Module-Name=Java Hints Annotation Processor
    94.5 -OpenIDE-Module-Display-Category=Java
    94.6 -OpenIDE-Module-Short-Description=Java Hints Annotation Processor
    95.1 --- a/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/processor/JavaHintsAnnotationProcessor.java	Sun Oct 16 08:01:27 2016 +0200
    95.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    95.3 @@ -1,635 +0,0 @@
    95.4 -/*
    95.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    95.6 - *
    95.7 - * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
    95.8 - *
    95.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   95.10 - * Other names may be trademarks of their respective owners.
   95.11 - *
   95.12 - * The contents of this file are subject to the terms of either the GNU
   95.13 - * General Public License Version 2 only ("GPL") or the Common
   95.14 - * Development and Distribution License("CDDL") (collectively, the
   95.15 - * "License"). You may not use this file except in compliance with the
   95.16 - * License. You can obtain a copy of the License at
   95.17 - * http://www.netbeans.org/cddl-gplv2.html
   95.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   95.19 - * specific language governing permissions and limitations under the
   95.20 - * License.  When distributing the software, include this License Header
   95.21 - * Notice in each file and include the License file at
   95.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   95.23 - * particular file as subject to the "Classpath" exception as provided
   95.24 - * by Oracle in the GPL Version 2 section of the License file that
   95.25 - * accompanied this code. If applicable, add the following below the
   95.26 - * License Header, with the fields enclosed by brackets [] replaced by
   95.27 - * your own identifying information:
   95.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   95.29 - *
   95.30 - * If you wish your version of this file to be governed by only the CDDL
   95.31 - * or only the GPL Version 2, indicate your decision by adding
   95.32 - * "[Contributor] elects to include this software in this distribution
   95.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   95.34 - * single choice of license, a recipient has the option to distribute
   95.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   95.36 - * to extend the choice of license to its licensees as provided above.
   95.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   95.38 - * Version 2 license, then the option applies only if the new code is
   95.39 - * made subject to such option by the copyright holder.
   95.40 - *
   95.41 - * Contributor(s):
   95.42 - *
   95.43 - * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
   95.44 - */
   95.45 -
   95.46 -package org.netbeans.modules.java.hints.spiimpl.processor;
   95.47 -
   95.48 -import java.lang.reflect.Array;
   95.49 -import java.util.Map.Entry;
   95.50 -import java.util.*;
   95.51 -import java.util.AbstractMap.SimpleEntry;
   95.52 -import java.util.logging.Logger;
   95.53 -import java.util.regex.Matcher;
   95.54 -import java.util.regex.Pattern;
   95.55 -import javax.annotation.processing.Processor;
   95.56 -import javax.annotation.processing.RoundEnvironment;
   95.57 -import javax.annotation.processing.SupportedAnnotationTypes;
   95.58 -import javax.annotation.processing.SupportedSourceVersion;
   95.59 -import javax.lang.model.SourceVersion;
   95.60 -import javax.lang.model.element.*;
   95.61 -import javax.lang.model.type.DeclaredType;
   95.62 -import javax.lang.model.type.TypeMirror;
   95.63 -import javax.lang.model.util.AbstractAnnotationValueVisitor6;
   95.64 -import javax.lang.model.util.ElementFilter;
   95.65 -import javax.lang.model.util.ElementScanner6;
   95.66 -import javax.lang.model.util.Elements;
   95.67 -import javax.lang.model.util.Types;
   95.68 -import javax.tools.Diagnostic.Kind;
   95.69 -import org.openide.filesystems.annotations.LayerBuilder;
   95.70 -import org.openide.filesystems.annotations.LayerBuilder.File;
   95.71 -import org.openide.filesystems.annotations.LayerGeneratingProcessor;
   95.72 -import org.openide.filesystems.annotations.LayerGenerationException;
   95.73 -import org.openide.util.NbCollections;
   95.74 -import org.openide.util.lookup.ServiceProvider;
   95.75 -
   95.76 -/**Inspired by https://sezpoz.dev.java.net/.
   95.77 - *
   95.78 - * @author lahvac
   95.79 - */
   95.80 -@SupportedSourceVersion(SourceVersion.RELEASE_6)
   95.81 -@SupportedAnnotationTypes("org.netbeans.spi.java.hints.*")
   95.82 -@ServiceProvider(service=Processor.class, position=100)
   95.83 -public class JavaHintsAnnotationProcessor extends LayerGeneratingProcessor {
   95.84 -    
   95.85 -    private static final Logger LOG = Logger.getLogger(JavaHintsAnnotationProcessor.class.getName());
   95.86 -    
   95.87 -    @Override
   95.88 -    protected boolean handleProcess(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) throws LayerGenerationException {
   95.89 -        if (!roundEnv.processingOver()) {
   95.90 -            generateTypeList("org.netbeans.spi.java.hints.Hint", roundEnv);
   95.91 -        }
   95.92 -
   95.93 -        return false;
   95.94 -    }
   95.95 -
   95.96 -    private static final String[] TRIGGERS = new String[] {
   95.97 -        "org.netbeans.spi.java.hints.TriggerTreeKind",
   95.98 -        "org.netbeans.spi.java.hints.TriggerPattern",
   95.99 -        "org.netbeans.spi.java.hints.TriggerPatterns",
  95.100 -    };
  95.101 -
  95.102 -    private static final String[] OPTIONS = new String[] {
  95.103 -        "org.netbeans.spi.java.hints.BooleanOption"
  95.104 -    };
  95.105 -
  95.106 -    private void generateTypeList(String annotationName, RoundEnvironment roundEnv) throws LayerGenerationException {
  95.107 -        TypeElement hint = processingEnv.getElementUtils().getTypeElement(annotationName);
  95.108 -
  95.109 -        if (hint == null) return ;
  95.110 -        
  95.111 -        for (Element annotated : roundEnv.getElementsAnnotatedWith(hint)) {
  95.112 -            if (!verifyHintAnnotationAcceptable(annotated)) continue;
  95.113 -            if (!annotated.getKind().isClass() && !annotated.getKind().isInterface()) {
  95.114 -                if (annotated.getKind() != ElementKind.METHOD) {
  95.115 -                    //the compiler should have already warned about this
  95.116 -                    continue;
  95.117 -                }
  95.118 -
  95.119 -                annotated = annotated.getEnclosingElement();
  95.120 -            } else {
  95.121 -                if (!annotated.getKind().isClass()) {
  95.122 -                    //the compiler should have already warned about this
  95.123 -                    continue;
  95.124 -                }
  95.125 -            }
  95.126 -
  95.127 -            if (!annotated.getKind().isClass()) {
  95.128 -                processingEnv.getMessager().printMessage(Kind.ERROR, "Internal error - cannot find class containing the hint", annotated);
  95.129 -                continue;
  95.130 -            }
  95.131 -
  95.132 -            TypeElement clazz = (TypeElement) annotated;
  95.133 -            String classFolder = "org-netbeans-modules-java-hints/code-hints/" + getFQN(clazz).replace('.', '-') + ".class";
  95.134 -
  95.135 -            {
  95.136 -                LayerBuilder builder = layer(clazz);
  95.137 -                File clazzFolder = builder.folder(classFolder);
  95.138 -                
  95.139 -                for (AnnotationMirror am : clazz.getAnnotationMirrors()) {
  95.140 -                    dumpAnnotation(builder, clazzFolder, clazz, am, true);
  95.141 -                }
  95.142 -                
  95.143 -                clazzFolder.write();
  95.144 -            }
  95.145 -
  95.146 -            for (ExecutableElement ee : ElementFilter.methodsIn(clazz.getEnclosedElements())) {
  95.147 -                if (!ee.getAnnotationMirrors().isEmpty()) {
  95.148 -                    LayerBuilder builder = layer(ee);
  95.149 -                    File methodFolder = builder.folder(classFolder + "/" + ee.getSimpleName() + ".method");
  95.150 -
  95.151 -                    for (AnnotationMirror am : ee.getAnnotationMirrors()) {
  95.152 -                        dumpAnnotation(builder, methodFolder, ee, am, true);
  95.153 -                    }
  95.154 -
  95.155 -                    methodFolder.write();
  95.156 -                }
  95.157 -            }
  95.158 -
  95.159 -            for (VariableElement var : ElementFilter.fieldsIn(clazz.getEnclosedElements())) {
  95.160 -                if (!var.getAnnotationMirrors().isEmpty()) {
  95.161 -                    LayerBuilder builder = layer(var);
  95.162 -                    File fieldFolder = builder.folder(classFolder + "/" + var.getSimpleName() + ".field");
  95.163 -
  95.164 -                    for (AnnotationMirror am : var.getAnnotationMirrors()) {
  95.165 -                        dumpAnnotation(builder, fieldFolder, var, am, true);
  95.166 -                    }
  95.167 -
  95.168 -                    if (var.getConstantValue() instanceof String) {
  95.169 -                        fieldFolder.stringvalue("constantValue", (String) var.getConstantValue());
  95.170 -                    }
  95.171 -
  95.172 -                    fieldFolder.write();
  95.173 -                }
  95.174 -            }
  95.175 -            
  95.176 -            new ElementScanner6<Void, Void>() {
  95.177 -                @Override public Void scan(Element e, Void p) {
  95.178 -                    AnnotationMirror hintMirror = findAnnotation(e.getAnnotationMirrors(), "org.netbeans.spi.java.hints.Hint");
  95.179 -            
  95.180 -                    if (hintMirror != null) {
  95.181 -                        String qualifiedName;
  95.182 -                        switch (e.getKind()) {
  95.183 -                            case METHOD: case CONSTRUCTOR:
  95.184 -                                qualifiedName = e.getEnclosingElement().asType().toString() + "." + e.getSimpleName().toString() + e.asType().toString();
  95.185 -                                break;
  95.186 -                            case FIELD: case ENUM_CONSTANT:
  95.187 -                                qualifiedName = e.getEnclosingElement().asType().toString() + "." + e.getSimpleName().toString();
  95.188 -                                break;
  95.189 -                            case ANNOTATION_TYPE: case CLASS:
  95.190 -                            case ENUM: case INTERFACE:
  95.191 -                            default:
  95.192 -                                qualifiedName = e.asType().toString();
  95.193 -                                break;
  95.194 -                        }
  95.195 -                        
  95.196 -                        try {
  95.197 -                            File keywordsFile = layer(e)
  95.198 -                                               .file("OptionsDialog/Keywords/".concat(qualifiedName))
  95.199 -                                               .stringvalue("location", "Editor")
  95.200 -                                               .bundlevalue("tabTitle", "org.netbeans.modules.options.editor.Bundle", "CTL_Hints_DisplayName");
  95.201 -
  95.202 -                            String displayName = getAttributeValue(hintMirror, "displayName", String.class);
  95.203 -
  95.204 -                            if (displayName != null)
  95.205 -                                keywordsFile = keywordsFile.bundlevalue("keywords-1", displayName);
  95.206 -
  95.207 -                            String description = getAttributeValue(hintMirror, "description", String.class);
  95.208 -
  95.209 -                            if (description != null)
  95.210 -                                keywordsFile = keywordsFile.bundlevalue("keywords-2", description);
  95.211 -
  95.212 -                            int i = 3;
  95.213 -
  95.214 -                            for (String sw : getAttributeValue(hintMirror, "suppressWarnings", String[].class)) {
  95.215 -                                keywordsFile = keywordsFile.stringvalue("keywords-" + i++, sw);
  95.216 -                            }
  95.217 -
  95.218 -                            keywordsFile.write();
  95.219 -                        } catch (LayerGenerationException ex) {
  95.220 -                            JavaHintsAnnotationProcessor.<RuntimeException>rethrowAsRuntime(ex);
  95.221 -                        }
  95.222 -                    }
  95.223 -
  95.224 -                    return super.scan(e, p);
  95.225 -                }
  95.226 -            }.scan(annotated, null);
  95.227 -        }
  95.228 -
  95.229 -        for (String ann : TRIGGERS) {
  95.230 -            TypeElement annRes = processingEnv.getElementUtils().getTypeElement(ann);
  95.231 -
  95.232 -            if (annRes == null) continue;
  95.233 -
  95.234 -            for (ExecutableElement method : ElementFilter.methodsIn(roundEnv.getElementsAnnotatedWith(annRes))) {
  95.235 -                verifyHintMethod(method);
  95.236 -                verifyTriggerAnnotations(method);
  95.237 -            }
  95.238 -        }
  95.239 -
  95.240 -        for (String ann : OPTIONS) {
  95.241 -            TypeElement annRes = processingEnv.getElementUtils().getTypeElement(ann);
  95.242 -
  95.243 -            if (annRes == null) continue;
  95.244 -
  95.245 -            for (VariableElement var : ElementFilter.fieldsIn(roundEnv.getElementsAnnotatedWith(annRes))) {
  95.246 -                verifyOptionField(var);
  95.247 -            }
  95.248 -        }
  95.249 -
  95.250 -    }
  95.251 -
  95.252 -    private void dumpAnnotation(LayerBuilder builder, File folder, Element errElement, AnnotationMirror annotation, boolean topLevel) {
  95.253 -        String fqn = getFQN(((TypeElement) annotation.getAnnotationType().asElement())).replace('.', '-');
  95.254 -        if (topLevel && !fqn.startsWith("org-netbeans-spi-java-hints")) return ;
  95.255 -        final File   annotationFolder = builder.folder(folder.getPath() + "/" + fqn + ".annotation");
  95.256 -
  95.257 -        for (Entry<? extends ExecutableElement, ? extends AnnotationValue> e : annotation.getElementValues().entrySet()) {
  95.258 -            final String attrName = e.getKey().getSimpleName().toString();
  95.259 -            e.getValue().accept(new DumpAnnotationValue(builder, annotationFolder, attrName, errElement, annotation, e.getValue()), null);
  95.260 -        }
  95.261 -
  95.262 -        annotationFolder.write();
  95.263 -    }
  95.264 -
  95.265 -    private String getFQN(TypeElement clazz) {
  95.266 -        return processingEnv.getElementUtils().getBinaryName(clazz).toString();
  95.267 -    }
  95.268 -
  95.269 -    static final String ERR_RETURN_TYPE = "The return type must be either org.netbeans.spi.editor.hints.ErrorDescription or java.util.List<org.netbeans.spi.editor.hints.ErrorDescription>";
  95.270 -    static final String ERR_PARAMETERS = "The method must have exactly one parameter of type org.netbeans.spi.java.hints.HintContext";
  95.271 -    static final String ERR_MUST_BE_STATIC = "The method must be static";
  95.272 -    static final String ERR_OPTION_TYPE = "The option field must be of type java.lang.String";
  95.273 -    static final String ERR_OPTION_MUST_BE_STATIC_FINAL = "The option field must be static final";
  95.274 -    static final String WARN_BUNDLE_KEY_NOT_FOUND = "Bundle key %s not found";
  95.275 -
  95.276 -    private static AnnotationMirror findAnnotation(Iterable<? extends AnnotationMirror> annotations, String annotationFQN) {
  95.277 -        for (AnnotationMirror am : annotations) {
  95.278 -            if (((TypeElement) am.getAnnotationType().asElement()).getQualifiedName().contentEquals(annotationFQN)) {
  95.279 -                return am;
  95.280 -            }
  95.281 -        }
  95.282 -
  95.283 -        return null;
  95.284 -    }
  95.285 -
  95.286 -    private <T> T getAttributeValue(AnnotationMirror annotation, String attribute, Class<T> clazz) {
  95.287 -        if (clazz.isArray()) {
  95.288 -            Iterable<?> attributes = getAttributeValueInternal(annotation, attribute, Iterable.class);
  95.289 -            
  95.290 -            Collection<Object> coll = new ArrayList<Object>();
  95.291 -            Class<?> componentType = clazz.getComponentType();
  95.292 -
  95.293 -            for (Object attr : attributes) {
  95.294 -                if (attr instanceof AnnotationValue) {
  95.295 -                    attr = ((AnnotationValue) attr).getValue();
  95.296 -                }
  95.297 -                
  95.298 -                if (componentType.isAssignableFrom(attr.getClass())) {
  95.299 -                    coll.add(componentType.cast(attr));
  95.300 -                }
  95.301 -            }
  95.302 -
  95.303 -            return clazz.cast(coll.toArray((Object[]) Array.newInstance(clazz.getComponentType(), 0)));
  95.304 -        } else {
  95.305 -            return getAttributeValueInternal(annotation, attribute, clazz);
  95.306 -        }
  95.307 -    }
  95.308 -
  95.309 -    private <T> T getAttributeValueInternal(AnnotationMirror annotation, String attribute, Class<T> clazz) {
  95.310 -        for (Entry<? extends ExecutableElement, ? extends AnnotationValue> e : processingEnv.getElementUtils().getElementValuesWithDefaults(annotation).entrySet()) {
  95.311 -            if (e.getKey().getSimpleName().contentEquals(attribute)) {
  95.312 -                Object value = e.getValue().getValue();
  95.313 -
  95.314 -                if (clazz.isAssignableFrom(value.getClass())) {
  95.315 -                    return clazz.cast(value);
  95.316 -                }
  95.317 -
  95.318 -                return null;
  95.319 -            }
  95.320 -        }
  95.321 -        
  95.322 -        return null;
  95.323 -    }
  95.324 -
  95.325 -    private AnnotationValue getAttributeValueDescription(AnnotationMirror annotation, String attribute) {
  95.326 -        for (Entry<? extends ExecutableElement, ? extends AnnotationValue> e : processingEnv.getElementUtils().getElementValuesWithDefaults(annotation).entrySet()) {
  95.327 -            if (e.getKey().getSimpleName().contentEquals(attribute)) {
  95.328 -                return e.getValue();
  95.329 -            }
  95.330 -        }
  95.331 -
  95.332 -        return null;
  95.333 -    }
  95.334 -    
  95.335 -    private boolean verifyHintAnnotationAcceptable(Element hint) {
  95.336 -        AnnotationMirror hintMirror = findAnnotation(hint.getAnnotationMirrors(), "org.netbeans.spi.java.hints.Hint");
  95.337 -
  95.338 -        if (hintMirror == null) return false;
  95.339 -
  95.340 -        String id = getAttributeValue(hintMirror, "id", String.class);
  95.341 -
  95.342 -        if (id == null || id.isEmpty()) {
  95.343 -            switch (hint.getKind()) {
  95.344 -                case CLASS:
  95.345 -                case METHOD:
  95.346 -                    break; //OK
  95.347 -                default:
  95.348 -                    //compiler should have already warned about this
  95.349 -                    return false;
  95.350 -            }
  95.351 -        }
  95.352 -
  95.353 -        TypeMirror customizerProviderType = getAttributeValue(hintMirror, "customizerProvider", TypeMirror.class);
  95.354 -
  95.355 -        if (customizerProviderType != null) {
  95.356 -            Element customizerProvider = processingEnv.getTypeUtils().asElement(customizerProviderType);
  95.357 -
  95.358 -            if (customizerProvider != null) {
  95.359 -                if (customizerProvider.getKind() != ElementKind.CLASS) {
  95.360 -                    TypeElement customizerProviderInterface = processingEnv.getElementUtils().getTypeElement("org.netbeans.spi.java.hints.CustomizerProvider");
  95.361 -
  95.362 -                    if (customizerProviderInterface != null && !customizerProviderInterface.equals(customizerProvider)) {
  95.363 -                        processingEnv.getMessager().printMessage(Kind.ERROR, "Customizer provider must be a concrete class", hint, hintMirror, getAttributeValueDescription(hintMirror, "customizerProvider"));
  95.364 -                    }
  95.365 -                } else {
  95.366 -                    TypeElement customizerProviderClazz = (TypeElement) customizerProvider;
  95.367 -
  95.368 -                    if (!customizerProviderClazz.getModifiers().contains(Modifier.PUBLIC)) {
  95.369 -                        processingEnv.getMessager().printMessage(Kind.ERROR, "Customizer provider must be public", hint, hintMirror, getAttributeValueDescription(hintMirror, "customizerProvider"));
  95.370 -                    }
  95.371 -
  95.372 -                    if (   customizerProviderClazz.getEnclosingElement().getKind() != ElementKind.PACKAGE
  95.373 -                        && !customizerProviderClazz.getModifiers().contains(Modifier.STATIC)) {
  95.374 -                        processingEnv.getMessager().printMessage(Kind.ERROR, "Customizer provider must be non-static innerclass", hint, hintMirror, getAttributeValueDescription(hintMirror, "customizerProvider"));
  95.375 -                    }
  95.376 -
  95.377 -                    boolean foundDefaultConstructor = false;
  95.378 -
  95.379 -                    for (ExecutableElement ee : ElementFilter.constructorsIn(customizerProviderClazz.getEnclosedElements())) {
  95.380 -                        if (ee.getParameters().isEmpty()) {
  95.381 -                            foundDefaultConstructor = true;
  95.382 -                            if (!ee.getModifiers().contains(Modifier.PUBLIC)) {
  95.383 -                                processingEnv.getMessager().printMessage(Kind.ERROR, "Customizer provider must provide a public default constructor", hint, hintMirror, getAttributeValueDescription(hintMirror, "customizerProvider"));
  95.384 -                            }
  95.385 -                            break;
  95.386 -                        }
  95.387 -                    }
  95.388 -
  95.389 -                    if (!foundDefaultConstructor) {
  95.390 -                        processingEnv.getMessager().printMessage(Kind.ERROR, "Customizer provider must provide a public default constructor", hint, hintMirror, getAttributeValueDescription(hintMirror, "customizerProvider"));
  95.391 -                    }
  95.392 -                }
  95.393 -            }
  95.394 -        }
  95.395 -
  95.396 -        return true;
  95.397 -    }
  95.398 -
  95.399 -    private boolean verifyHintMethod(ExecutableElement method) {
  95.400 -        StringBuilder error = new StringBuilder();
  95.401 -        Elements elements = processingEnv.getElementUtils();
  95.402 -        TypeElement errDesc = elements.getTypeElement("org.netbeans.spi.editor.hints.ErrorDescription");
  95.403 -        TypeElement jlIterable = elements.getTypeElement("java.lang.Iterable");
  95.404 -        TypeElement hintCtx = elements.getTypeElement("org.netbeans.spi.java.hints.HintContext");
  95.405 -
  95.406 -        if (errDesc == null || jlIterable == null || hintCtx == null) {
  95.407 -            return true;
  95.408 -        }
  95.409 -
  95.410 -        Types types = processingEnv.getTypeUtils();
  95.411 -        TypeMirror errDescType = errDesc.asType(); //no type params, no need to erasure
  95.412 -        TypeMirror jlIterableErrDesc = types.getDeclaredType(jlIterable, errDescType);
  95.413 -        TypeMirror ret = method.getReturnType();
  95.414 -
  95.415 -        if (!types.isSameType(ret, errDescType) && !types.isAssignable(ret, jlIterableErrDesc)) {
  95.416 -            error.append(ERR_RETURN_TYPE);
  95.417 -            error.append("\n");
  95.418 -        }
  95.419 -
  95.420 -        if (method.getParameters().size() != 1 || !types.isSameType(method.getParameters().get(0).asType(), hintCtx.asType())) {
  95.421 -            error.append(ERR_PARAMETERS);
  95.422 -            error.append("\n");
  95.423 -        }
  95.424 -
  95.425 -        if (!method.getModifiers().contains(Modifier.STATIC)) {
  95.426 -            error.append(ERR_MUST_BE_STATIC);
  95.427 -            error.append("\n");
  95.428 -        }
  95.429 -
  95.430 -        if (error.length() == 0) {
  95.431 -            return true;
  95.432 -        }
  95.433 -
  95.434 -        if (error.charAt(error.length() - 1) == '\n') {
  95.435 -            error.delete(error.length() - 1, error.length());
  95.436 -        }
  95.437 -
  95.438 -        processingEnv.getMessager().printMessage(Kind.ERROR, error.toString(), method);
  95.439 -
  95.440 -        return false;
  95.441 -    }
  95.442 -
  95.443 -    private static final Pattern VARIABLE_PATTERN = Pattern.compile("\\$[a-zA-Z0-9_]+");
  95.444 -    private boolean verifyTriggerAnnotations(ExecutableElement method) {
  95.445 -        List<AnnotationMirror> patternAnnotations = new ArrayList<AnnotationMirror>();
  95.446 -        AnnotationMirror am = findAnnotation(method.getAnnotationMirrors(), "org.netbeans.spi.java.hints.TriggerPattern");
  95.447 -
  95.448 -        if (am != null) {
  95.449 -            patternAnnotations.add(am);
  95.450 -        }
  95.451 -
  95.452 -        am = findAnnotation(method.getAnnotationMirrors(), "org.netbeans.spi.java.hints.TriggerPatterns");
  95.453 -
  95.454 -        if (am != null) {
  95.455 -            patternAnnotations.addAll(Arrays.asList(getAttributeValue(am, "value", AnnotationMirror[].class)));
  95.456 -        }
  95.457 -
  95.458 -        for (AnnotationMirror patternDescription : patternAnnotations) {
  95.459 -            String pattern = getAttributeValue(patternDescription, "value", String.class);
  95.460 -
  95.461 -            if (pattern == null) continue;
  95.462 -
  95.463 -            Set<String> variables = new HashSet<String>();
  95.464 -            Matcher m = VARIABLE_PATTERN.matcher(pattern);
  95.465 -
  95.466 -            while (m.find()) {
  95.467 -                variables.add(m.group(0));
  95.468 -            }
  95.469 -
  95.470 -            for (AnnotationMirror constraint : getAttributeValue(patternDescription, "constraints", AnnotationMirror[].class)) {
  95.471 -                String variable = getAttributeValue(constraint, "variable", String.class);
  95.472 -                String type = getAttributeValue(constraint, "type", String.class);
  95.473 -
  95.474 -                if (variable == null || type == null) continue;
  95.475 -
  95.476 -                if (!variables.contains(variable)) {
  95.477 -                    processingEnv.getMessager().printMessage(Kind.WARNING, "Variable " + variable + " not used in the pattern", method, constraint, getAttributeValueDescription(constraint, "variable"));
  95.478 -                }
  95.479 -            }
  95.480 -        }
  95.481 -
  95.482 -        return false;
  95.483 -    }
  95.484 -
  95.485 -    private boolean verifyOptionField(VariableElement field) {
  95.486 -        StringBuilder error = new StringBuilder();
  95.487 -        Elements elements = processingEnv.getElementUtils();
  95.488 -        TypeElement jlString = elements.getTypeElement("java.lang.String");
  95.489 -
  95.490 -        if (jlString == null) {
  95.491 -            return true;
  95.492 -        }
  95.493 -
  95.494 -        Types types = processingEnv.getTypeUtils();
  95.495 -        TypeMirror jlStringType = jlString.asType(); //no type params, no need to erasure
  95.496 -
  95.497 -        if (!types.isSameType(field.asType(), jlStringType)) {
  95.498 -            error.append(ERR_RETURN_TYPE);
  95.499 -            error.append("\n");
  95.500 -        }
  95.501 -
  95.502 -        if (!field.getModifiers().contains(Modifier.STATIC) || !field.getModifiers().contains(Modifier.FINAL)) {
  95.503 -            error.append(ERR_OPTION_MUST_BE_STATIC_FINAL);
  95.504 -            error.append("\n");
  95.505 -        }
  95.506 -
  95.507 -        Object key = field.getConstantValue();
  95.508 -
  95.509 -        if (key == null) {
  95.510 -            error.append("Option field not a compile-time constant");
  95.511 -            error.append("\n");
  95.512 -        }
  95.513 -
  95.514 -        if (error.length() == 0) {
  95.515 -            return true;
  95.516 -        }
  95.517 -
  95.518 -        if (error.charAt(error.length() - 1) == '\n') {
  95.519 -            error.delete(error.length() - 1, error.length());
  95.520 -        }
  95.521 -
  95.522 -        processingEnv.getMessager().printMessage(Kind.ERROR, error.toString(), field);
  95.523 -
  95.524 -        return false;
  95.525 -    }
  95.526 -
  95.527 -    private class DumpAnnotationValue extends AbstractAnnotationValueVisitor6<Void, Void> {
  95.528 -
  95.529 -        private final LayerBuilder builder;
  95.530 -        private final File annotationFolder;
  95.531 -        private final String attrName;
  95.532 -        private final Element errElement;
  95.533 -        private final AnnotationMirror errAnnotationMirror;
  95.534 -        private final AnnotationValue errAnnotationValue;
  95.535 -
  95.536 -        public DumpAnnotationValue(LayerBuilder builder, File annotationFolder, String attrName, Element errElement, AnnotationMirror errAnnotationMirror, AnnotationValue errAnnotationValue) {
  95.537 -            this.builder = builder;
  95.538 -            this.annotationFolder = annotationFolder;
  95.539 -            this.attrName = attrName;
  95.540 -            this.errElement = errElement;
  95.541 -            this.errAnnotationMirror = errAnnotationMirror;
  95.542 -            this.errAnnotationValue = errAnnotationValue;
  95.543 -        }
  95.544 -
  95.545 -        public Void visitBoolean(boolean b, Void p) {
  95.546 -            annotationFolder.boolvalue(attrName, b);
  95.547 -            return null;
  95.548 -        }
  95.549 -
  95.550 -        public Void visitByte(byte b, Void p) {
  95.551 -            annotationFolder.bytevalue(attrName, b);
  95.552 -            return null;
  95.553 -        }
  95.554 -
  95.555 -        public Void visitChar(char c, Void p) {
  95.556 -            annotationFolder.charvalue(attrName, c);
  95.557 -            return null;
  95.558 -        }
  95.559 -
  95.560 -        public Void visitDouble(double d, Void p) {
  95.561 -            annotationFolder.doublevalue(attrName, d);
  95.562 -            return null;
  95.563 -        }
  95.564 -
  95.565 -        public Void visitFloat(float f, Void p) {
  95.566 -            annotationFolder.floatvalue(attrName, f);
  95.567 -            return null;
  95.568 -        }
  95.569 -
  95.570 -        public Void visitInt(int i, Void p) {
  95.571 -            annotationFolder.intvalue(attrName, i);
  95.572 -            return null;
  95.573 -        }
  95.574 -
  95.575 -        public Void visitLong(long i, Void p) {
  95.576 -            annotationFolder.longvalue(attrName, i);
  95.577 -            return null;
  95.578 -        }
  95.579 -
  95.580 -        public Void visitShort(short s, Void p) {
  95.581 -            annotationFolder.shortvalue(attrName, s);
  95.582 -            return null;
  95.583 -        }
  95.584 -
  95.585 -        public Void visitString(String s, Void p) {
  95.586 -            if ("displayName".equals(attrName) || "description".equals(attrName) || "tooltip".equals(attrName)) {
  95.587 -                try {
  95.588 -                    annotationFolder.bundlevalue(attrName, s);
  95.589 -                } catch (LayerGenerationException ex) {
  95.590 -                   processingEnv.getMessager().printMessage(Kind.ERROR, ex.getLocalizedMessage(), errElement, errAnnotationMirror, errAnnotationValue);
  95.591 -                }
  95.592 -            } else {
  95.593 -                annotationFolder.stringvalue(attrName, s);
  95.594 -            }
  95.595 -            return null;
  95.596 -        }
  95.597 -
  95.598 -        public Void visitType(TypeMirror t, Void p) {
  95.599 -            annotationFolder.stringvalue(attrName, getFQN(((TypeElement) ((DeclaredType) t).asElement())));
  95.600 -            return null;
  95.601 -        }
  95.602 -
  95.603 -        public Void visitEnumConstant(VariableElement c, Void p) {
  95.604 -            TypeElement owner = (TypeElement) c.getEnclosingElement();
  95.605 -            annotationFolder.stringvalue(attrName, getFQN(owner) + "." + c.getSimpleName());
  95.606 -            return null;
  95.607 -        }
  95.608 -
  95.609 -        public Void visitAnnotation(AnnotationMirror a, Void p) {
  95.610 -            File f = builder.folder(annotationFolder.getPath() + "/" + attrName);
  95.611 -            
  95.612 -            dumpAnnotation(builder, f, errElement, a, false);
  95.613 -
  95.614 -            f.write();
  95.615 -            return null;
  95.616 -        }
  95.617 -
  95.618 -        public Void visitArray(List<? extends AnnotationValue> vals, Void p) {
  95.619 -            File arr = builder.folder(annotationFolder.getPath() + "/" + attrName);
  95.620 -            int c = 0;
  95.621 -
  95.622 -            for (AnnotationValue av : vals) {
  95.623 -                av.accept(new DumpAnnotationValue(builder, arr, "item" + c, errElement, errAnnotationMirror, av), null);
  95.624 -                c++;
  95.625 -            }
  95.626 -
  95.627 -            arr.write();
  95.628 -
  95.629 -            return null;
  95.630 -        }
  95.631 -    }
  95.632 -    
  95.633 -    @SuppressWarnings("unchecked")
  95.634 -    private static <T extends Throwable> void rethrowAsRuntime(Throwable t) throws T {
  95.635 -        throw (T) t;
  95.636 -    }
  95.637 -
  95.638 -}
    96.1 --- a/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/BooleanOption.java	Sun Oct 16 08:01:27 2016 +0200
    96.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    96.3 @@ -1,87 +0,0 @@
    96.4 -/*
    96.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    96.6 - *
    96.7 - * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
    96.8 - *
    96.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   96.10 - * Other names may be trademarks of their respective owners.
   96.11 - *
   96.12 - * The contents of this file are subject to the terms of either the GNU
   96.13 - * General Public License Version 2 only ("GPL") or the Common
   96.14 - * Development and Distribution License("CDDL") (collectively, the
   96.15 - * "License"). You may not use this file except in compliance with the
   96.16 - * License. You can obtain a copy of the License at
   96.17 - * http://www.netbeans.org/cddl-gplv2.html
   96.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   96.19 - * specific language governing permissions and limitations under the
   96.20 - * License.  When distributing the software, include this License Header
   96.21 - * Notice in each file and include the License file at
   96.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   96.23 - * particular file as subject to the "Classpath" exception as provided
   96.24 - * by Oracle in the GPL Version 2 section of the License file that
   96.25 - * accompanied this code. If applicable, add the following below the
   96.26 - * License Header, with the fields enclosed by brackets [] replaced by
   96.27 - * your own identifying information:
   96.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   96.29 - *
   96.30 - * If you wish your version of this file to be governed by only the CDDL
   96.31 - * or only the GPL Version 2, indicate your decision by adding
   96.32 - * "[Contributor] elects to include this software in this distribution
   96.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   96.34 - * single choice of license, a recipient has the option to distribute
   96.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   96.36 - * to extend the choice of license to its licensees as provided above.
   96.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   96.38 - * Version 2 license, then the option applies only if the new code is
   96.39 - * made subject to such option by the copyright holder.
   96.40 - *
   96.41 - * Contributor(s):
   96.42 - *
   96.43 - * Portions Copyrighted 2012 Sun Microsystems, Inc.
   96.44 - */
   96.45 -package org.netbeans.spi.java.hints;
   96.46 -
   96.47 -import java.lang.annotation.ElementType;
   96.48 -import java.lang.annotation.Retention;
   96.49 -import java.lang.annotation.RetentionPolicy;
   96.50 -import java.lang.annotation.Target;
   96.51 -import java.util.prefs.Preferences;
   96.52 -
   96.53 -/**Specify an option that affects the way the hint works.
   96.54 - *
   96.55 - * Only {@code static final String} compile-time constant can be marked with this
   96.56 - * annotation. The value of the constant will be used as the key to the hint's {@link Preferences}.
   96.57 - *
   96.58 - * For hints that consist of a class, all options that are directly enclosed in the class
   96.59 - * will be used in their source order.
   96.60 - *
   96.61 - * For hints that consist of a single method, use {@link UseOptions} to specify which options
   96.62 - * from the enclosing class should be used. The order of the options will be the order in which
   96.63 - * they appear in the source code of the enclosing class.
   96.64 - *
   96.65 - * The customizer will be generated automatically when {@link BooleanOption} is used.
   96.66 - *
   96.67 - * Two keys need to be defined in the corresponding {@code Bundle.properties}:
   96.68 - * {@code LBL_<class-fqn>.<field_name>}, which will be used as the display name of
   96.69 - * the corresponding checkbox in the customizer, and {@code TP_<class-fqn>.<field_name>}
   96.70 - * which will be used as the tooltip of the checkbox.
   96.71 - *
   96.72 - * @author lahvac
   96.73 - */
   96.74 -@Retention(RetentionPolicy.SOURCE)
   96.75 -@Target(ElementType.FIELD)
   96.76 -public @interface BooleanOption {
   96.77 -
   96.78 -    /**The options' display name. Will be used as the display name of the
   96.79 -     * checkbox in the customizer.
   96.80 -     */
   96.81 -    public String displayName();
   96.82 -    /**The tooltip of the checkbox in the customizer.
   96.83 -     */
   96.84 -    public String tooltip();
   96.85 -    
   96.86 -    /**The default value of the option.
   96.87 -     */
   96.88 -    public boolean defaultValue();
   96.89 -    
   96.90 -}
    97.1 --- a/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/Bundle.properties	Sun Oct 16 08:01:27 2016 +0200
    97.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    97.3 @@ -1,7 +0,0 @@
    97.4 -#{0}: hint/suggestion name
    97.5 -FIX_DisableHint=Disable "{0}" Hint
    97.6 -FIX_ConfigureHint=Configure "{0}" Hint
    97.7 -FIX_DisableSuggestion=Disable "{0}" Suggestion
    97.8 -FIX_ConfigureSuggestion=Configure "{0}" Suggestion
    97.9 -#{0}: Key of the warning
   97.10 -LBL_FIX_Suppress_Waning=Suppress Warning - {0}
    98.1 --- a/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/ConstraintVariableType.java	Sun Oct 16 08:01:27 2016 +0200
    98.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    98.3 @@ -1,73 +0,0 @@
    98.4 -/*
    98.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    98.6 - *
    98.7 - * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
    98.8 - *
    98.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   98.10 - * Other names may be trademarks of their respective owners.
   98.11 - *
   98.12 - * The contents of this file are subject to the terms of either the GNU
   98.13 - * General Public License Version 2 only ("GPL") or the Common
   98.14 - * Development and Distribution License("CDDL") (collectively, the
   98.15 - * "License"). You may not use this file except in compliance with the
   98.16 - * License. You can obtain a copy of the License at
   98.17 - * http://www.netbeans.org/cddl-gplv2.html
   98.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   98.19 - * specific language governing permissions and limitations under the
   98.20 - * License.  When distributing the software, include this License Header
   98.21 - * Notice in each file and include the License file at
   98.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   98.23 - * particular file as subject to the "Classpath" exception as provided
   98.24 - * by Oracle in the GPL Version 2 section of the License file that
   98.25 - * accompanied this code. If applicable, add the following below the
   98.26 - * License Header, with the fields enclosed by brackets [] replaced by
   98.27 - * your own identifying information:
   98.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   98.29 - *
   98.30 - * If you wish your version of this file to be governed by only the CDDL
   98.31 - * or only the GPL Version 2, indicate your decision by adding
   98.32 - * "[Contributor] elects to include this software in this distribution
   98.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   98.34 - * single choice of license, a recipient has the option to distribute
   98.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   98.36 - * to extend the choice of license to its licensees as provided above.
   98.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   98.38 - * Version 2 license, then the option applies only if the new code is
   98.39 - * made subject to such option by the copyright holder.
   98.40 - *
   98.41 - * Contributor(s):
   98.42 - *
   98.43 - * Portions Copyrighted 2008-2009 Sun Microsystems, Inc.
   98.44 - */
   98.45 -
   98.46 -package org.netbeans.spi.java.hints;
   98.47 -
   98.48 -import java.lang.annotation.Target;
   98.49 -
   98.50 -/**Specifies a type of a variable. During the matching process, only those
   98.51 - * sections of the source code that have the given type are considered.
   98.52 - *
   98.53 - * @author Jan Lahoda
   98.54 - */
   98.55 -@Target({})
   98.56 -public @interface ConstraintVariableType {
   98.57 -
   98.58 -    /**Variable name, must start with the dollar sign (<code>$</code>).
   98.59 -     * Variable<code>$this</code> is automatically bound to the current class.
   98.60 -     */
   98.61 -    public String variable();
   98.62 -
   98.63 -    /**The required type of the section of source code. The value must be a type
   98.64 -     * per JLS 4.1, i.e. a primitive type (JLS 4.2), or a reference type (JLS 4.3).
   98.65 -     * All elements of the type must be resolvable when written to any Java file,
   98.66 -     * they may not contain e.g. references to type variables, simple names, etc.
   98.67 -     *
   98.68 -     * The type may include any actual type arguments, including wildcard.
   98.69 -     *
   98.70 -     * While matching, the type of the tree that corresponds to the variable in
   98.71 -     * the actual occurrence candidate is accepted if it is assignable into the
   98.72 -     * variable defined by the attribute.
   98.73 -     */
   98.74 -    public String type();
   98.75 -    
   98.76 -}
    99.1 --- a/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/CustomizerProvider.java	Sun Oct 16 08:01:27 2016 +0200
    99.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    99.3 @@ -1,66 +0,0 @@
    99.4 -/*
    99.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    99.6 - *
    99.7 - * Copyright 2010-2012 Oracle and/or its affiliates. All rights reserved.
    99.8 - *
    99.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   99.10 - * Other names may be trademarks of their respective owners.
   99.11 - *
   99.12 - * The contents of this file are subject to the terms of either the GNU
   99.13 - * General Public License Version 2 only ("GPL") or the Common
   99.14 - * Development and Distribution License("CDDL") (collectively, the
   99.15 - * "License"). You may not use this file except in compliance with the
   99.16 - * License. You can obtain a copy of the License at
   99.17 - * http://www.netbeans.org/cddl-gplv2.html
   99.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   99.19 - * specific language governing permissions and limitations under the
   99.20 - * License.  When distributing the software, include this License Header
   99.21 - * Notice in each file and include the License file at
   99.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   99.23 - * particular file as subject to the "Classpath" exception as provided
   99.24 - * by Oracle in the GPL Version 2 section of the License file that
   99.25 - * accompanied this code. If applicable, add the following below the
   99.26 - * License Header, with the fields enclosed by brackets [] replaced by
   99.27 - * your own identifying information:
   99.28 - * "Portions Copyrighted [year] [name of copyright owner]"
   99.29 - *
   99.30 - * If you wish your version of this file to be governed by only the CDDL
   99.31 - * or only the GPL Version 2, indicate your decision by adding
   99.32 - * "[Contributor] elects to include this software in this distribution
   99.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
   99.34 - * single choice of license, a recipient has the option to distribute
   99.35 - * your version of this file under either the CDDL, the GPL Version 2 or
   99.36 - * to extend the choice of license to its licensees as provided above.
   99.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
   99.38 - * Version 2 license, then the option applies only if the new code is
   99.39 - * made subject to such option by the copyright holder.
   99.40 - *
   99.41 - * Contributor(s):
   99.42 - *
   99.43 - * Portions Copyrighted 2010-2012 Sun Microsystems, Inc.
   99.44 - */
   99.45 -
   99.46 -package org.netbeans.spi.java.hints;
   99.47 -
   99.48 -import java.util.prefs.Preferences;
   99.49 -import javax.swing.JComponent;
   99.50 -import org.netbeans.api.annotations.common.NonNull;
   99.51 -
   99.52 -/**A factory for hint customizer.
   99.53 - *
   99.54 - * @author lahvac
   99.55 - */
   99.56 -public interface CustomizerProvider {
   99.57 -
   99.58 -    /**Create a customizer component. The hint settings are in the given
   99.59 -     * {@link Preferences}. The customizer can write into the provided {@link Preferences}
   99.60 -     * immediately, the values will be persisted or rolled-back automatically
   99.61 -     * based on the user's gesture.
   99.62 -     *
   99.63 -     * @param prefs the hints preferences from which the data to show should be read,
   99.64 -     *              and to which the new settings should be written
   99.65 -     * @return a customizer component
   99.66 -     */
   99.67 -    public @NonNull JComponent getCustomizer(@NonNull Preferences prefs);
   99.68 -
   99.69 -}
   100.1 --- a/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/Decision.java	Sun Oct 16 08:01:27 2016 +0200
   100.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   100.3 @@ -1,106 +0,0 @@
   100.4 -/*
   100.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   100.6 - *
   100.7 - * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
   100.8 - *
   100.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  100.10 - * Other names may be trademarks of their respective owners.
  100.11 - *
  100.12 - * The contents of this file are subject to the terms of either the GNU
  100.13 - * General Public License Version 2 only ("GPL") or the Common
  100.14 - * Development and Distribution License("CDDL") (collectively, the
  100.15 - * "License"). You may not use this file except in compliance with the
  100.16 - * License. You can obtain a copy of the License at
  100.17 - * http://www.netbeans.org/cddl-gplv2.html
  100.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  100.19 - * specific language governing permissions and limitations under the
  100.20 - * License.  When distributing the software, include this License Header
  100.21 - * Notice in each file and include the License file at
  100.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  100.23 - * particular file as subject to the "Classpath" exception as provided
  100.24 - * by Oracle in the GPL Version 2 section of the License file that
  100.25 - * accompanied this code. If applicable, add the following below the
  100.26 - * License Header, with the fields enclosed by brackets [] replaced by
  100.27 - * your own identifying information:
  100.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  100.29 - *
  100.30 - * If you wish your version of this file to be governed by only the CDDL
  100.31 - * or only the GPL Version 2, indicate your decision by adding
  100.32 - * "[Contributor] elects to include this software in this distribution
  100.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  100.34 - * single choice of license, a recipient has the option to distribute
  100.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  100.36 - * to extend the choice of license to its licensees as provided above.
  100.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  100.38 - * Version 2 license, then the option applies only if the new code is
  100.39 - * made subject to such option by the copyright holder.
  100.40 - *
  100.41 - * Contributor(s):
  100.42 - *
  100.43 - * Portions Copyrighted 2013 Sun Microsystems, Inc.
  100.44 - */
  100.45 -package org.netbeans.spi.java.hints;
  100.46 -
  100.47 -import java.util.ArrayList;
  100.48 -import java.util.HashMap;
  100.49 -import java.util.List;
  100.50 -import java.util.Map;
  100.51 -import org.netbeans.api.java.source.CompilationInfo;
  100.52 -import org.netbeans.api.java.source.TreePathHandle;
  100.53 -import org.openide.filesystems.FileObject;
  100.54 -
  100.55 -/**
  100.56 - *
  100.57 - * @author lahvac
  100.58 - */
  100.59 -public abstract class Decision<V, R> {
  100.60 -    
  100.61 -    /*XXX: should not be public*/public final TreePathHandle root;
  100.62 -    private final Map<FileObject, List<V>> file2Facts = new HashMap<FileObject, List<V>>();
  100.63 -
  100.64 -    protected Decision(TreePathHandle root) {
  100.65 -        this.root = root;
  100.66 -    }
  100.67 -    
  100.68 -    protected abstract R makeDecision(Iterable<? extends V> input);
  100.69 -    
  100.70 -    private R previousResult;
  100.71 -    
  100.72 -    /*XXX: should not be public*/public boolean makeDecision() {
  100.73 -        List<V> inputs = new ArrayList<V>();
  100.74 -        
  100.75 -        for (List<V> v : file2Facts.values()) {
  100.76 -            inputs.addAll(v);
  100.77 -        }
  100.78 -        
  100.79 -        R current = makeDecision(inputs);
  100.80 -        
  100.81 -        boolean changed = !(previousResult == null ? current == null : previousResult.equals(current));
  100.82 -        
  100.83 -        previousResult = current;
  100.84 -        
  100.85 -        return changed;
  100.86 -    }
  100.87 -    
  100.88 -    public R getCurrentResult() {
  100.89 -        return previousResult;
  100.90 -    }
  100.91 -    
  100.92 -    public void recordLocalFact(/*XXX: should not require the CompilationInfo!*/CompilationInfo info, V fact) {
  100.93 -        List<V> facts = file2Facts.get(info.getFileObject());
  100.94 -        
  100.95 -        if (facts == null) {
  100.96 -            file2Facts.put(info.getFileObject(), facts = new ArrayList<V>());
  100.97 -        }
  100.98 -        
  100.99 -        facts.add(fact);
 100.100 -    }
 100.101 -    
 100.102 -    public static abstract class Factory<V, R, DecisionImpl extends Decision<V, R>> {
 100.103 -        /*XXX: should not be public*/public final Class<DecisionImpl> decisionClass;
 100.104 -        public Factory(Class<DecisionImpl> decisionClass) {
 100.105 -            this.decisionClass = decisionClass;
 100.106 -        }
 100.107 -        public abstract DecisionImpl create(TreePathHandle handle);
 100.108 -    }
 100.109 -}
   101.1 --- a/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/ErrorDescriptionFactory.java	Sun Oct 16 08:01:27 2016 +0200
   101.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   101.3 @@ -1,619 +0,0 @@
   101.4 -/*
   101.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   101.6 - *
   101.7 - * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
   101.8 - *
   101.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  101.10 - * Other names may be trademarks of their respective owners.
  101.11 - *
  101.12 - * The contents of this file are subject to the terms of either the GNU
  101.13 - * General Public License Version 2 only ("GPL") or the Common
  101.14 - * Development and Distribution License("CDDL") (collectively, the
  101.15 - * "License"). You may not use this file except in compliance with the
  101.16 - * License. You can obtain a copy of the License at
  101.17 - * http://www.netbeans.org/cddl-gplv2.html
  101.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  101.19 - * specific language governing permissions and limitations under the
  101.20 - * License.  When distributing the software, include this License Header
  101.21 - * Notice in each file and include the License file at
  101.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  101.23 - * particular file as subject to the "Classpath" exception as provided
  101.24 - * by Oracle in the GPL Version 2 section of the License file that
  101.25 - * accompanied this code. If applicable, add the following below the
  101.26 - * License Header, with the fields enclosed by brackets [] replaced by
  101.27 - * your own identifying information:
  101.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  101.29 - *
  101.30 - * If you wish your version of this file to be governed by only the CDDL
  101.31 - * or only the GPL Version 2, indicate your decision by adding
  101.32 - * "[Contributor] elects to include this software in this distribution
  101.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  101.34 - * single choice of license, a recipient has the option to distribute
  101.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  101.36 - * to extend the choice of license to its licensees as provided above.
  101.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  101.38 - * Version 2 license, then the option applies only if the new code is
  101.39 - * made subject to such option by the copyright holder.
  101.40 - *
  101.41 - * Contributor(s):
  101.42 - *
  101.43 - * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
  101.44 - */
  101.45 -
  101.46 -package org.netbeans.spi.java.hints;
  101.47 -
  101.48 -import com.sun.source.tree.BlockTree;
  101.49 -import com.sun.source.tree.ClassTree;
  101.50 -import com.sun.source.tree.LiteralTree;
  101.51 -import com.sun.source.tree.MemberSelectTree;
  101.52 -import com.sun.source.tree.MethodInvocationTree;
  101.53 -import com.sun.source.tree.MethodTree;
  101.54 -import com.sun.source.tree.ModifiersTree;
  101.55 -import com.sun.source.tree.StatementTree;
  101.56 -import com.sun.source.tree.Tree;
  101.57 -import com.sun.source.tree.Tree.Kind;
  101.58 -import com.sun.source.tree.VariableTree;
  101.59 -import com.sun.source.util.TreePath;
  101.60 -import java.io.IOException;
  101.61 -import java.util.Arrays;
  101.62 -import java.util.Collection;
  101.63 -import java.util.Collections;
  101.64 -import java.util.EnumSet;
  101.65 -import java.util.LinkedHashSet;
  101.66 -import java.util.LinkedList;
  101.67 -import java.util.List;
  101.68 -import java.util.Set;
  101.69 -import javax.lang.model.SourceVersion;
  101.70 -import javax.lang.model.element.TypeElement;
  101.71 -import javax.swing.SwingUtilities;
  101.72 -import org.netbeans.api.annotations.common.NonNull;
  101.73 -import org.netbeans.api.java.source.CompilationInfo;
  101.74 -import org.netbeans.api.java.source.GeneratorUtilities;
  101.75 -import org.netbeans.api.java.source.JavaSource;
  101.76 -import org.netbeans.api.java.source.JavaSource.Phase;
  101.77 -import org.netbeans.api.java.source.Task;
  101.78 -import org.netbeans.api.java.source.TreePathHandle;
  101.79 -import org.netbeans.api.java.source.WorkingCopy;
  101.80 -import org.netbeans.api.lexer.TokenSequence;
  101.81 -import org.netbeans.api.options.OptionsDisplayer;
  101.82 -import org.netbeans.modules.analysis.api.CodeAnalysis;
  101.83 -import org.netbeans.modules.analysis.spi.Analyzer.WarningDescription;
  101.84 -import org.netbeans.modules.java.hints.providers.spi.HintMetadata;
  101.85 -import org.netbeans.modules.java.hints.providers.spi.HintMetadata.Options;
  101.86 -import org.netbeans.modules.java.hints.spiimpl.Hacks.InspectAndTransformOpener;
  101.87 -import org.netbeans.modules.java.hints.spiimpl.SPIAccessor;
  101.88 -import org.netbeans.modules.java.hints.spiimpl.SyntheticFix;
  101.89 -import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings;
  101.90 -import org.netbeans.spi.editor.hints.ChangeInfo;
  101.91 -import org.netbeans.spi.editor.hints.EnhancedFix;
  101.92 -import org.netbeans.spi.editor.hints.ErrorDescription;
  101.93 -import org.netbeans.spi.editor.hints.Fix;
  101.94 -import org.netbeans.spi.editor.hints.LazyFixList;
  101.95 -import org.openide.filesystems.FileObject;
  101.96 -import org.openide.util.Lookup;
  101.97 -import org.openide.util.NbBundle;
  101.98 -import org.openide.util.NbBundle.Messages;
  101.99 -import org.openide.util.Parameters;
 101.100 -
 101.101 -/**
 101.102 - *
 101.103 - * @author Jan Lahoda
 101.104 - */
 101.105 -public class ErrorDescriptionFactory {
 101.106 -
 101.107 -    private ErrorDescriptionFactory() {
 101.108 -    }
 101.109 -
 101.110 -//    public static ErrorDescription forTree(HintContext context, String text, Fix... fixes) {
 101.111 -//        return forTree(context, context.getContext(), text, fixes);
 101.112 -//    }
 101.113 -
 101.114 -    public static ErrorDescription forTree(HintContext context, TreePath tree, String text, Fix... fixes) {
 101.115 -        return forTree(context, tree.getLeaf(), text, fixes);
 101.116 -    }
 101.117 -    
 101.118 -    public static ErrorDescription forTree(HintContext context, Tree tree, String text, Fix... fixes) {
 101.119 -        int start;
 101.120 -        int end;
 101.121 -
 101.122 -        if (context.getHintMetadata().kind == Hint.Kind.INSPECTION) {
 101.123 -            start = (int) context.getInfo().getTrees().getSourcePositions().getStartPosition(context.getInfo().getCompilationUnit(), tree);
 101.124 -            end = (int) context.getInfo().getTrees().getSourcePositions().getEndPosition(context.getInfo().getCompilationUnit(), tree);
 101.125 -        } else {
 101.126 -            start = end = context.getCaretLocation();
 101.127 -        }
 101.128 -
 101.129 -        if (start != (-1) && end != (-1)) {
 101.130 -            LazyFixList fixesForED = org.netbeans.spi.editor.hints.ErrorDescriptionFactory.lazyListForFixes(resolveDefaultFixes(context, fixes));
 101.131 -            return org.netbeans.spi.editor.hints.ErrorDescriptionFactory.createErrorDescription("text/x-java:" + context.getHintMetadata().id, context.getSeverity(), text, context.getHintMetadata().description, fixesForED, context.getInfo().getFileObject(), start, end);
 101.132 -        }
 101.133 -
 101.134 -        return null;
 101.135 -    }
 101.136 -    
 101.137 -    /**Create a new {@link ErrorDescription}. Severity is automatically inferred from the {@link HintContext},
 101.138 -     * and the {@link ErrorDescription} is created to be consistent with {@link ErrorDescription}s created
 101.139 -     * by the other factory methods in this class.
 101.140 -     * 
 101.141 -     * @param context from which the {@link Severity} and other properties are inferred.
 101.142 -     * @param start start of the warning
 101.143 -     * @param end end of the warning
 101.144 -     * @param text the warning text
 101.145 -     * @param fixes one or more {@link Fix}es to show shown to the user.
 101.146 -     * @return a standard {@link ErrorDescription} for use in Java source
 101.147 -     * @since 1.9
 101.148 -     */
 101.149 -    public static ErrorDescription forSpan(HintContext context, int start, int end, String text, Fix... fixes) {
 101.150 -        if (context.getHintMetadata().kind != Hint.Kind.INSPECTION) {
 101.151 -            start = end = context.getCaretLocation();
 101.152 -        }
 101.153 -
 101.154 -        if (start != (-1) && end != (-1)) {
 101.155 -            LazyFixList fixesForED = org.netbeans.spi.editor.hints.ErrorDescriptionFactory.lazyListForFixes(resolveDefaultFixes(context, fixes));
 101.156 -            return org.netbeans.spi.editor.hints.ErrorDescriptionFactory.createErrorDescription("text/x-java:" + context.getHintMetadata().id, context.getSeverity(), text, context.getHintMetadata().description, fixesForED, context.getInfo().getFileObject(), start, end);
 101.157 -        }
 101.158 -
 101.159 -        return null;
 101.160 -    }
 101.161 -    
 101.162 -    public static ErrorDescription forName(HintContext context, TreePath tree, String text, Fix... fixes) {
 101.163 -        return forName(context, tree.getLeaf(), text, fixes);
 101.164 -    }
 101.165 -
 101.166 -    public static ErrorDescription forName(HintContext context, Tree tree, String text, Fix... fixes) {
 101.167 -        int[] span;
 101.168 -        
 101.169 -        if (context.getHintMetadata().kind == Hint.Kind.INSPECTION) {
 101.170 -            span = computeNameSpan(tree, context);
 101.171 -        } else {
 101.172 -            span = new int[] {context.getCaretLocation(), context.getCaretLocation()};
 101.173 -        }
 101.174 -        
 101.175 -        if (span != null && span[0] != (-1) && span[1] != (-1)) {
 101.176 -            LazyFixList fixesForED = org.netbeans.spi.editor.hints.ErrorDescriptionFactory.lazyListForFixes(resolveDefaultFixes(context, fixes));
 101.177 -            return org.netbeans.spi.editor.hints.ErrorDescriptionFactory.createErrorDescription("text/x-java:" + context.getHintMetadata().id, context.getSeverity(), text, context.getHintMetadata().description, fixesForED, context.getInfo().getFileObject(), span[0], span[1]);
 101.178 -        }
 101.179 -
 101.180 -        return null;
 101.181 -    }
 101.182 -
 101.183 -    private static int[] computeNameSpan(Tree tree, HintContext context) {
 101.184 -        switch (tree.getKind()) {
 101.185 -            case METHOD:
 101.186 -                return context.getInfo().getTreeUtilities().findNameSpan((MethodTree) tree);
 101.187 -            case ANNOTATION_TYPE:
 101.188 -            case CLASS:
 101.189 -            case ENUM:
 101.190 -            case INTERFACE:
 101.191 -                return context.getInfo().getTreeUtilities().findNameSpan((ClassTree) tree);
 101.192 -            case VARIABLE:
 101.193 -                return context.getInfo().getTreeUtilities().findNameSpan((VariableTree) tree);
 101.194 -            case MEMBER_SELECT:
 101.195 -                //XXX:
 101.196 -                MemberSelectTree mst = (MemberSelectTree) tree;
 101.197 -                int[] span = context.getInfo().getTreeUtilities().findNameSpan(mst);
 101.198 -
 101.199 -                if (span == null) {
 101.200 -                    int end = (int) context.getInfo().getTrees().getSourcePositions().getEndPosition(context.getInfo().getCompilationUnit(), tree);
 101.201 -                    span = new int[] {end - mst.getIdentifier().length(), end};
 101.202 -                }
 101.203 -                return span;
 101.204 -            case METHOD_INVOCATION:
 101.205 -                return computeNameSpan(((MethodInvocationTree) tree).getMethodSelect(), context);
 101.206 -            case BLOCK:
 101.207 -                Collection<? extends TreePath> prefix = context.getMultiVariables().get("$$1$");
 101.208 -                
 101.209 -                if (prefix != null) {
 101.210 -                    BlockTree bt = (BlockTree) tree;
 101.211 -                    
 101.212 -                    if (bt.getStatements().size() > prefix.size()) {
 101.213 -                        return computeNameSpan(bt.getStatements().get(prefix.size()), context);
 101.214 -                    }
 101.215 -                }
 101.216 -            default:
 101.217 -                int start = (int) context.getInfo().getTrees().getSourcePositions().getStartPosition(context.getInfo().getCompilationUnit(), tree);
 101.218 -                if (    StatementTree.class.isAssignableFrom(tree.getKind().asInterface())
 101.219 -                    && tree.getKind() != Kind.EXPRESSION_STATEMENT
 101.220 -                    && tree.getKind() != Kind.BLOCK) {
 101.221 -                    TokenSequence<?> ts = context.getInfo().getTokenHierarchy().tokenSequence();
 101.222 -                    ts.move(start);
 101.223 -                    if (ts.moveNext()) {
 101.224 -                        return new int[] {ts.offset(), ts.offset() + ts.token().length()};
 101.225 -                    }
 101.226 -                }
 101.227 -                return new int[] {
 101.228 -                    start,
 101.229 -                    (int) context.getInfo().getTrees().getSourcePositions().getEndPosition(context.getInfo().getCompilationUnit(), tree),
 101.230 -                };
 101.231 -        }
 101.232 -    }
 101.233 -
 101.234 -    static List<Fix> resolveDefaultFixes(HintContext ctx, Fix... provided) {
 101.235 -        List<Fix> auxiliaryFixes = new LinkedList<Fix>();
 101.236 -        HintMetadata hm = SPIAccessor.getINSTANCE().getHintMetadata(ctx);
 101.237 -
 101.238 -        if (hm != null) {
 101.239 -            Set<String> suppressWarningsKeys = new LinkedHashSet<String>();
 101.240 -
 101.241 -            for (String key : hm.suppressWarnings) {
 101.242 -                if (key == null || key.length() == 0) {
 101.243 -                    break;
 101.244 -                }
 101.245 -
 101.246 -                suppressWarningsKeys.add(key);
 101.247 -            }
 101.248 -
 101.249 -
 101.250 -            auxiliaryFixes.add(new DisableConfigure(hm, true, SPIAccessor.getINSTANCE().getHintSettings(ctx)));
 101.251 -            auxiliaryFixes.add(new DisableConfigure(hm, false, null));
 101.252 -
 101.253 -            if (hm.kind == Hint.Kind.INSPECTION) {
 101.254 -                auxiliaryFixes.add(new InspectFix(hm, false));
 101.255 -                if (!hm.options.contains(Options.QUERY)) {
 101.256 -                    auxiliaryFixes.add(new InspectFix(hm, true));
 101.257 -                }
 101.258 -            }
 101.259 -            
 101.260 -            if (!suppressWarningsKeys.isEmpty()) {
 101.261 -                auxiliaryFixes.addAll(createSuppressWarnings(ctx.getInfo(), ctx.getPath(), suppressWarningsKeys.toArray(new String[0])));
 101.262 -            }
 101.263 -
 101.264 -            List<Fix> result = new LinkedList<Fix>();
 101.265 -
 101.266 -            for (Fix f : provided != null ? provided : new Fix[0]) {
 101.267 -                if (f == null) continue;
 101.268 -                
 101.269 -                result.add(org.netbeans.spi.editor.hints.ErrorDescriptionFactory.attachSubfixes(f, auxiliaryFixes));
 101.270 -            }
 101.271 -
 101.272 -            if (result.isEmpty()) {
 101.273 -                result.add(org.netbeans.spi.editor.hints.ErrorDescriptionFactory.attachSubfixes(new TopLevelConfigureFix(hm), auxiliaryFixes));
 101.274 -            }
 101.275 -
 101.276 -            return result;
 101.277 -        }
 101.278 -
 101.279 -        return Arrays.asList(provided);
 101.280 -    }
 101.281 -
 101.282 -    private static class DisableConfigure implements Fix, SyntheticFix {
 101.283 -        private final @NonNull HintMetadata metadata;
 101.284 -        private final boolean disable;
 101.285 -        private final HintsSettings hintsSettings;
 101.286 -
 101.287 -        DisableConfigure(@NonNull HintMetadata metadata, boolean disable, HintsSettings hintsSettings) {
 101.288 -            this.metadata = metadata;
 101.289 -            this.disable = disable;
 101.290 -            this.hintsSettings = hintsSettings;
 101.291 -        }
 101.292 -
 101.293 -        @Override
 101.294 -        public String getText() {
 101.295 -            String displayName = metadata.displayName;
 101.296 -            String key;
 101.297 -            switch (metadata.kind) {
 101.298 -                case INSPECTION:
 101.299 -                    key = disable ? "FIX_DisableHint" : "FIX_ConfigureHint";
 101.300 -                    break;
 101.301 -                case ACTION:
 101.302 -                    key = disable ? "FIX_DisableSuggestion" : "FIX_ConfigureSuggestion";
 101.303 -                    break;
 101.304 -                default:
 101.305 -                    throw new IllegalStateException();
 101.306 -            }
 101.307 -
 101.308 -            return NbBundle.getMessage(ErrorDescriptionFactory.class, key, displayName);
 101.309 -        }
 101.310 -
 101.311 -        @Override
 101.312 -        public ChangeInfo implement() throws Exception {
 101.313 -            if (disable) {
 101.314 -                hintsSettings.setEnabled(metadata, false);
 101.315 -                //XXX: re-run hints task
 101.316 -            } else {
 101.317 -                OptionsDisplayer.getDefault().open("Editor/Hints/text/x-java/" + metadata.id);
 101.318 -            }
 101.319 -
 101.320 -            return null;
 101.321 -        }
 101.322 -
 101.323 -        @Override
 101.324 -        public boolean equals(Object obj) {
 101.325 -            if (obj == null) {
 101.326 -                return false;
 101.327 -            }
 101.328 -            if (this.getClass() != obj.getClass()) {
 101.329 -                return false;
 101.330 -            }
 101.331 -            final DisableConfigure other = (DisableConfigure) obj;
 101.332 -            if (this.metadata != other.metadata && (this.metadata == null || !this.metadata.equals(other.metadata))) {
 101.333 -                return false;
 101.334 -            }
 101.335 -            if (this.disable != other.disable) {
 101.336 -                return false;
 101.337 -            }
 101.338 -            return true;
 101.339 -        }
 101.340 -
 101.341 -        @Override
 101.342 -        public int hashCode() {
 101.343 -            int hash = 7;
 101.344 -            hash = 43 * hash + (this.metadata != null ? this.metadata.hashCode() : 0);
 101.345 -            hash = 43 * hash + (this.disable ? 1 : 0);
 101.346 -            return hash;
 101.347 -        }
 101.348 -
 101.349 -
 101.350 -    }
 101.351 -
 101.352 -    private static final class TopLevelConfigureFix extends DisableConfigure implements EnhancedFix {
 101.353 -
 101.354 -        public TopLevelConfigureFix(@NonNull HintMetadata metadata) {
 101.355 -            super(metadata, false, null);
 101.356 -        }
 101.357 -
 101.358 -        @Override
 101.359 -        public CharSequence getSortText() {
 101.360 -            return "\uFFFFzz";
 101.361 -        }
 101.362 -        
 101.363 -    }
 101.364 -
 101.365 -    private static class InspectFix implements Fix, SyntheticFix {
 101.366 -        private final @NonNull HintMetadata metadata;
 101.367 -        private final boolean transform;
 101.368 -
 101.369 -        InspectFix(@NonNull HintMetadata metadata, boolean transform) {
 101.370 -            this.metadata = metadata;
 101.371 -            this.transform = transform;
 101.372 -        }
 101.373 -
 101.374 -        @Override
 101.375 -        @Messages({
 101.376 -            "DN_InspectAndTransform=Run Inspect&Transform on...",
 101.377 -            "DN_Inspect=Run Inspect on..."
 101.378 -        })
 101.379 -        public String getText() {
 101.380 -            return transform ? Bundle.DN_InspectAndTransform() : Bundle.DN_Inspect();
 101.381 -        }
 101.382 -
 101.383 -        @Override
 101.384 -        public ChangeInfo implement() throws Exception {
 101.385 -            SwingUtilities.invokeLater(new Runnable() {
 101.386 -                @Override
 101.387 -                public void run() {
 101.388 -                    if (transform) {
 101.389 -                        final InspectAndTransformOpener o = Lookup.getDefault().lookup(InspectAndTransformOpener.class);
 101.390 -
 101.391 -                        if (o != null) {
 101.392 -                            o.openIAT(metadata);
 101.393 -                        } else {
 101.394 -                            //warn
 101.395 -                        }
 101.396 -                    } else {
 101.397 -                        CodeAnalysis.open(WarningDescription.create("text/x-java:" + metadata.id, null, null, null));
 101.398 -                    }
 101.399 -                }
 101.400 -            });
 101.401 -            
 101.402 -            return null;
 101.403 -        }
 101.404 -
 101.405 -        @Override
 101.406 -        public boolean equals(Object obj) {
 101.407 -            if (obj == null) {
 101.408 -                return false;
 101.409 -            }
 101.410 -            if (this.getClass() != obj.getClass()) {
 101.411 -                return false;
 101.412 -            }
 101.413 -            final InspectFix other = (InspectFix) obj;
 101.414 -            if (this.metadata != other.metadata && (this.metadata == null || !this.metadata.equals(other.metadata))) {
 101.415 -                return false;
 101.416 -            }
 101.417 -            if (this.transform != other.transform) {
 101.418 -                return false;
 101.419 -            }
 101.420 -            return true;
 101.421 -        }
 101.422 -
 101.423 -        @Override
 101.424 -        public int hashCode() {
 101.425 -            int hash = 7;
 101.426 -            hash = 43 * hash + (this.metadata != null ? this.metadata.hashCode() : 0);
 101.427 -            hash = 43 * hash + (this.transform ? 1 : 0);
 101.428 -            return hash;
 101.429 -        }
 101.430 -
 101.431 -
 101.432 -    }
 101.433 -    
 101.434 -    /** Creates a fix, which when invoked adds @SuppresWarnings(keys) to
 101.435 -     * nearest declaration.
 101.436 -     * @param compilationInfo CompilationInfo to work on
 101.437 -     * @param treePath TreePath to a tree. The method will find nearest outer
 101.438 -     *        declaration. (type, method, field or local variable)
 101.439 -     * @param keys keys to be contained in the SuppresWarnings annotation. E.g.
 101.440 -     *        @SuppresWarnings( "key" ) or @SuppresWarnings( {"key1", "key2", ..., "keyN" } ).
 101.441 -     * @throws IllegalArgumentException if keys are null or empty or id no suitable element
 101.442 -     *         to put the annotation on is found (e.g. if TreePath to CompilationUnit is given")
 101.443 -     */
 101.444 -    static Fix createSuppressWarningsFix(CompilationInfo compilationInfo, TreePath treePath, String... keys ) {
 101.445 -        Parameters.notNull("compilationInfo", compilationInfo);
 101.446 -        Parameters.notNull("treePath", treePath);
 101.447 -        Parameters.notNull("keys", keys);
 101.448 -
 101.449 -        if (keys.length == 0) {
 101.450 -            throw new IllegalArgumentException("key must not be empty"); // NOI18N
 101.451 -        }
 101.452 -
 101.453 -        if (!isSuppressWarningsSupported(compilationInfo)) {
 101.454 -            return null;
 101.455 -        }
 101.456 -
 101.457 -        while (treePath.getLeaf().getKind() != Kind.COMPILATION_UNIT && !DECLARATION.contains(treePath.getLeaf().getKind())) {
 101.458 -            treePath = treePath.getParentPath();
 101.459 -        }
 101.460 -
 101.461 -        if (treePath.getLeaf().getKind() != Kind.COMPILATION_UNIT) {
 101.462 -            return new FixImpl(TreePathHandle.create(treePath, compilationInfo), compilationInfo.getFileObject(), keys);
 101.463 -        } else {
 101.464 -            return null;
 101.465 -        }
 101.466 -    }
 101.467 -
 101.468 -    /** Creates a fix, which when invoked adds @SuppresWarnings(keys) to
 101.469 -     * nearest declaration.
 101.470 -     * @param compilationInfo CompilationInfo to work on
 101.471 -     * @param treePath TreePath to a tree. The method will find nearest outer
 101.472 -     *        declaration. (type, method, field or local variable)
 101.473 -     * @param keys keys to be contained in the SuppresWarnings annotation. E.g.
 101.474 -     *        @SuppresWarnings( "key" ) or @SuppresWarnings( {"key1", "key2", ..., "keyN" } ).
 101.475 -     * @throws IllegalArgumentException if keys are null or empty or id no suitable element
 101.476 -     *         to put the annotation on is found (e.g. if TreePath to CompilationUnit is given")
 101.477 -     */
 101.478 -    static List<Fix> createSuppressWarnings(CompilationInfo compilationInfo, TreePath treePath, String... keys ) {
 101.479 -        Parameters.notNull("compilationInfo", compilationInfo);
 101.480 -        Parameters.notNull("treePath", treePath);
 101.481 -        Parameters.notNull("keys", keys);
 101.482 -
 101.483 -        if (keys.length == 0) {
 101.484 -            throw new IllegalArgumentException("key must not be empty"); // NOI18N
 101.485 -        }
 101.486 -
 101.487 -        Fix f = createSuppressWarningsFix(compilationInfo, treePath, keys);
 101.488 -
 101.489 -        if (f != null) {
 101.490 -            return Collections.<Fix>singletonList(f);
 101.491 -        } else {
 101.492 -            return Collections.emptyList();
 101.493 -        }
 101.494 -    }
 101.495 -
 101.496 -    private static boolean isSuppressWarningsSupported(CompilationInfo info) {
 101.497 -        //cannot suppress if there is no SuppressWarnings annotation in the platform:
 101.498 -        if (info.getElements().getTypeElement("java.lang.SuppressWarnings") == null)
 101.499 -            return false;
 101.500 -
 101.501 -        return info.getSourceVersion().compareTo(SourceVersion.RELEASE_5) >= 0;
 101.502 -    }
 101.503 -
 101.504 -    private static final Set<Kind> DECLARATION = EnumSet.of(Kind.ANNOTATION_TYPE, Kind.CLASS, Kind.ENUM, Kind.INTERFACE, Kind.METHOD, Kind.VARIABLE);
 101.505 -
 101.506 -    private static final class FixImpl implements Fix, SyntheticFix {
 101.507 -
 101.508 -        private String keys[];
 101.509 -        private TreePathHandle handle;
 101.510 -        private FileObject file;
 101.511 -
 101.512 -        public FixImpl(TreePathHandle handle, FileObject file, String... keys) {
 101.513 -            this.keys = keys;
 101.514 -            this.handle = handle;
 101.515 -            this.file = file;
 101.516 -        }
 101.517 -
 101.518 -        public String getText() {
 101.519 -            StringBuilder keyNames = new StringBuilder();
 101.520 -            for (int i = 0; i < keys.length; i++) {
 101.521 -                String string = keys[i];
 101.522 -                keyNames.append(string);
 101.523 -                if ( i < keys.length - 1) {
 101.524 -                    keyNames.append(", "); // NOI18N
 101.525 -                }
 101.526 -            }
 101.527 -
 101.528 -            return NbBundle.getMessage(ErrorDescriptionFactory.class, "LBL_FIX_Suppress_Waning",  keyNames.toString() );  // NOI18N
 101.529 -        }
 101.530 -
 101.531 -        public ChangeInfo implement() throws IOException {
 101.532 -            JavaSource js = JavaSource.forFileObject(file);
 101.533 -
 101.534 -            js.runModificationTask(new Task<WorkingCopy>() {
 101.535 -                public void run(WorkingCopy copy) throws IOException {
 101.536 -                    copy.toPhase(Phase.RESOLVED); //XXX: performance
 101.537 -                    TreePath path = handle.resolve(copy);
 101.538 -
 101.539 -                    while (path != null && path.getLeaf().getKind() != Kind.COMPILATION_UNIT && !DECLARATION.contains(path.getLeaf().getKind())) {
 101.540 -                        path = path.getParentPath();
 101.541 -                    }
 101.542 -
 101.543 -                    if (path.getLeaf().getKind() == Kind.COMPILATION_UNIT) {
 101.544 -                        return ;
 101.545 -                    }
 101.546 -
 101.547 -                    Tree top = path.getLeaf();
 101.548 -                    ModifiersTree modifiers = null;
 101.549 -
 101.550 -                    switch (top.getKind()) {
 101.551 -                        case ANNOTATION_TYPE:
 101.552 -                        case CLASS:
 101.553 -                        case ENUM:
 101.554 -                        case INTERFACE:
 101.555 -                            modifiers = ((ClassTree) top).getModifiers();
 101.556 -                            break;
 101.557 -                        case METHOD:
 101.558 -                            modifiers = ((MethodTree) top).getModifiers();
 101.559 -                            break;
 101.560 -                        case VARIABLE:
 101.561 -                            modifiers = ((VariableTree) top).getModifiers();
 101.562 -                            break;
 101.563 -                        default: assert false : "Unhandled Tree.Kind";  // NOI18N
 101.564 -                    }
 101.565 -
 101.566 -                    if (modifiers == null) {
 101.567 -                        return ;
 101.568 -                    }
 101.569 -
 101.570 -                    TypeElement el = copy.getElements().getTypeElement("java.lang.SuppressWarnings");  // NOI18N
 101.571 -
 101.572 -                    if (el == null) {
 101.573 -                        return ;
 101.574 -                    }
 101.575 -
 101.576 -                    LiteralTree[] keyLiterals = new LiteralTree[keys.length];
 101.577 -
 101.578 -                    for (int i = 0; i < keys.length; i++) {
 101.579 -                        keyLiterals[i] = copy.getTreeMaker().
 101.580 -                                Literal(keys[i]);
 101.581 -                    }
 101.582 -
 101.583 -                    ModifiersTree nueMods = GeneratorUtilities.get(copy).appendToAnnotationValue(modifiers, el, "value", keyLiterals);
 101.584 -
 101.585 -                    copy.rewrite(modifiers, nueMods);
 101.586 -                }
 101.587 -            }).commit();
 101.588 -
 101.589 -            return null;
 101.590 -        }
 101.591 -
 101.592 -        @Override
 101.593 -        public boolean equals(Object obj) {
 101.594 -            if (obj == null) {
 101.595 -                return false;
 101.596 -            }
 101.597 -            if (getClass() != obj.getClass()) {
 101.598 -                return false;
 101.599 -            }
 101.600 -            final FixImpl other = (FixImpl) obj;
 101.601 -            if (!Arrays.deepEquals(this.keys, other.keys)) {
 101.602 -                return false;
 101.603 -            }
 101.604 -            if (this.handle != other.handle && (this.handle == null || !this.handle.equals(other.handle))) {
 101.605 -                return false;
 101.606 -            }
 101.607 -            if (this.file != other.file && (this.file == null || !this.file.equals(other.file))) {
 101.608 -                return false;
 101.609 -            }
 101.610 -            return true;
 101.611 -        }
 101.612 -
 101.613 -        @Override
 101.614 -        public int hashCode() {
 101.615 -            int hash = 5;
 101.616 -            hash = 79 * hash + Arrays.deepHashCode(this.keys);
 101.617 -            hash = 79 * hash + (this.handle != null ? this.handle.hashCode() : 0);
 101.618 -            hash = 79 * hash + (this.file != null ? this.file.hashCode() : 0);
 101.619 -            return hash;
 101.620 -        }
 101.621 -    }
 101.622 -}
   102.1 --- a/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/Hint.java	Sun Oct 16 08:01:27 2016 +0200
   102.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   102.3 @@ -1,128 +0,0 @@
   102.4 -/*
   102.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   102.6 - *
   102.7 - * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
   102.8 - *
   102.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  102.10 - * Other names may be trademarks of their respective owners.
  102.11 - *
  102.12 - * The contents of this file are subject to the terms of either the GNU
  102.13 - * General Public License Version 2 only ("GPL") or the Common
  102.14 - * Development and Distribution License("CDDL") (collectively, the
  102.15 - * "License"). You may not use this file except in compliance with the
  102.16 - * License. You can obtain a copy of the License at
  102.17 - * http://www.netbeans.org/cddl-gplv2.html
  102.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  102.19 - * specific language governing permissions and limitations under the
  102.20 - * License.  When distributing the software, include this License Header
  102.21 - * Notice in each file and include the License file at
  102.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  102.23 - * particular file as subject to the "Classpath" exception as provided
  102.24 - * by Oracle in the GPL Version 2 section of the License file that
  102.25 - * accompanied this code. If applicable, add the following below the
  102.26 - * License Header, with the fields enclosed by brackets [] replaced by
  102.27 - * your own identifying information:
  102.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  102.29 - *
  102.30 - * If you wish your version of this file to be governed by only the CDDL
  102.31 - * or only the GPL Version 2, indicate your decision by adding
  102.32 - * "[Contributor] elects to include this software in this distribution
  102.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  102.34 - * single choice of license, a recipient has the option to distribute
  102.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  102.36 - * to extend the choice of license to its licensees as provided above.
  102.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  102.38 - * Version 2 license, then the option applies only if the new code is
  102.39 - * made subject to such option by the copyright holder.
  102.40 - *
  102.41 - * Contributor(s):
  102.42 - *
  102.43 - * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
  102.44 - */
  102.45 -
  102.46 -package org.netbeans.spi.java.hints;
  102.47 -
  102.48 -import java.lang.annotation.ElementType;
  102.49 -import java.lang.annotation.Retention;
  102.50 -import java.lang.annotation.RetentionPolicy;
  102.51 -import java.lang.annotation.Target;
  102.52 -import org.netbeans.spi.editor.hints.Severity;
  102.53 -
  102.54 -/** Description of a hint.
  102.55 - * When applied to a class, any enclosed method marked with a trigger
  102.56 - * will be considered to be part of this hint. When applied to a method, only this specific
  102.57 - * method will be considered to the part of the hint.
  102.58 - * Currently recognized triggers include {@link TriggerPattern} and {@link TriggerTreeKind}.
  102.59 - * @author lahvac, Petr Hrebejk
  102.60 - */
  102.61 -@Target({ElementType.TYPE, ElementType.METHOD})
  102.62 -@Retention(RetentionPolicy.SOURCE)
  102.63 -public @interface Hint {
  102.64 -    /**Manually specify the hint's id. Use only reorganizing code to keep compatibility with settings
  102.65 -     * from previous version. Id will be generated automatically is not specified.
  102.66 -     */
  102.67 -    public String id() default "";
  102.68 -    /** The hint's display name.
  102.69 -     */
  102.70 -    public String displayName();
  102.71 -    /** The hint's long description.
  102.72 -     */
  102.73 -    public String description();
  102.74 -    /**Category where the hint belongs.
  102.75 -     */
  102.76 -    public String category();
  102.77 -    /**Should the hint be enabled by default?*/
  102.78 -    public boolean enabled() default true;
  102.79 -    /**Default severity of the hint. {@link Severity#HINT} will typically be shown
  102.80 -     * only on the line with the caret.*/
  102.81 -    public Severity severity() default Severity.VERIFIER;
  102.82 -    /**Suppress warnings keys that should automatically suppress the hint.*/
  102.83 -    public String[] suppressWarnings() default {};
  102.84 -    /**A customizer that allows to customize hint's preferences.
  102.85 -     */
  102.86 -    public Class<? extends CustomizerProvider> customizerProvider() default CustomizerProvider.class;
  102.87 -    /**Whether the hint should be considered an {@link Kind#INSPECTION inspection}, i.e. it detects a code smell,
  102.88 -     * or otherwise leads to improving the code, or a {@link Kind#SUGGESTION}, which is simply
  102.89 -     * an offer to do automatically do something for the user.
  102.90 -     */
  102.91 -    public Kind hintKind() default Kind.INSPECTION;
  102.92 -    /**Specify various options for the hint*/
  102.93 -    public Options[] options() default {};
  102.94 -
  102.95 -    /**Whether the hint should be considered a {@link Kind#HINT hint}, e.g. it
  102.96 -     * detects a code smell, or otherwise leads to improving the code, or a {@link Kind#ACTION},
  102.97 -     * which is simply an offer to do automatically do something for the user.
  102.98 -     */
  102.99 -   public enum Kind {
 102.100 -       /**The hint represents a code-smell detector, or alike. It marks code that
 102.101 -        * is not correct (in some sense).
 102.102 -        */
 102.103 -       INSPECTION,
 102.104 -       
 102.105 -       /**The hint represents an offer to the user to automatically alter the code.
 102.106 -        * The transformation is not intended to improve the code, only allow the
 102.107 -        * user to do some kind of code transformation quickly.
 102.108 -        *
 102.109 -        * The only meaningful severity for suggestions if {@link Severity#CURRENT_LINE_WARNING}.
 102.110 -        */
 102.111 -       ACTION;
 102.112 -    }
 102.113 -
 102.114 -   /**Various options to altering the behavior of the hint.
 102.115 -    */
 102.116 -    public enum Options {
 102.117 -        /**The hint does not produce any automatic transformations that could be run
 102.118 -         * inside the Inspect&Refactor dialog.
 102.119 -         */
 102.120 -        QUERY,
 102.121 -        /**The hint cannot be run inside the Inspect&Refactor dialog.
 102.122 -         */
 102.123 -        NO_BATCH,
 102.124 -        /**
 102.125 -         * The hint requires heavyweight processing so it should be run explicitly only by Inspect, Refactor (or similar) 
 102.126 -         * features
 102.127 -         */
 102.128 -        HEAVY;
 102.129 -    }
 102.130 -
 102.131 -}
   103.1 --- a/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/HintContext.java	Sun Oct 16 08:01:27 2016 +0200
   103.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   103.3 @@ -1,230 +0,0 @@
   103.4 -/*
   103.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   103.6 - *
   103.7 - * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
   103.8 - *
   103.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  103.10 - * Other names may be trademarks of their respective owners.
  103.11 - *
  103.12 - * The contents of this file are subject to the terms of either the GNU
  103.13 - * General Public License Version 2 only ("GPL") or the Common
  103.14 - * Development and Distribution License("CDDL") (collectively, the
  103.15 - * "License"). You may not use this file except in compliance with the
  103.16 - * License. You can obtain a copy of the License at
  103.17 - * http://www.netbeans.org/cddl-gplv2.html
  103.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  103.19 - * specific language governing permissions and limitations under the
  103.20 - * License.  When distributing the software, include this License Header
  103.21 - * Notice in each file and include the License file at
  103.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  103.23 - * particular file as subject to the "Classpath" exception as provided
  103.24 - * by Oracle in the GPL Version 2 section of the License file that
  103.25 - * accompanied this code. If applicable, add the following below the
  103.26 - * License Header, with the fields enclosed by brackets [] replaced by
  103.27 - * your own identifying information:
  103.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  103.29 - *
  103.30 - * If you wish your version of this file to be governed by only the CDDL
  103.31 - * or only the GPL Version 2, indicate your decision by adding
  103.32 - * "[Contributor] elects to include this software in this distribution
  103.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  103.34 - * single choice of license, a recipient has the option to distribute
  103.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  103.36 - * to extend the choice of license to its licensees as provided above.
  103.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  103.38 - * Version 2 license, then the option applies only if the new code is
  103.39 - * made subject to such option by the copyright holder.
  103.40 - *
  103.41 - * Contributor(s):
  103.42 - *
  103.43 - * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
  103.44 - */
  103.45 -
  103.46 -package org.netbeans.spi.java.hints;
  103.47 -
  103.48 -import com.sun.source.util.TreePath;
  103.49 -import java.util.ArrayList;
  103.50 -import java.util.Collection;
  103.51 -import java.util.Collections;
  103.52 -import java.util.HashMap;
  103.53 -import java.util.LinkedList;
  103.54 -import java.util.List;
  103.55 -import java.util.Map;
  103.56 -import java.util.concurrent.atomic.AtomicBoolean;
  103.57 -import java.util.prefs.Preferences;
  103.58 -import javax.lang.model.type.TypeMirror;
  103.59 -import org.netbeans.api.java.source.CompilationInfo;
  103.60 -import org.netbeans.api.java.source.TreePathHandle;
  103.61 -import org.netbeans.modules.java.hints.providers.spi.HintMetadata;
  103.62 -import org.netbeans.modules.java.hints.spiimpl.MessageImpl;
  103.63 -import org.netbeans.modules.java.hints.spiimpl.SPIAccessor;
  103.64 -import org.netbeans.modules.java.hints.spiimpl.hints.GlobalProcessingContext;
  103.65 -import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings;
  103.66 -import org.netbeans.spi.editor.hints.Severity;
  103.67 -import org.netbeans.spi.java.hints.Decision.Factory;
  103.68 -import org.netbeans.spi.java.hints.Hint.Kind;
  103.69 -
  103.70 -/**
  103.71 - *
  103.72 - * @author Jan Lahoda
  103.73 - */
  103.74 -public class HintContext {
  103.75 -
  103.76 -    private final CompilationInfo info;
  103.77 -    private final HintsSettings settings;
  103.78 -    private final Preferences preferences;
  103.79 -    private final Severity severity;
  103.80 -    private final HintMetadata metadata;
  103.81 -    private final GlobalProcessingContext globalContext;
  103.82 -    private final TreePath path;
  103.83 -    private final Map<String, TreePath> variables;
  103.84 -    private final Map<String, Collection<? extends TreePath>> multiVariables;
  103.85 -    private final Map<String, String> variableNames;
  103.86 -    private final Collection<? super MessageImpl> messages;
  103.87 -    private final Map<String, TypeMirror> constraints;
  103.88 -    private final boolean bulkMode;
  103.89 -    private final AtomicBoolean cancel;
  103.90 -    private final int caret;
  103.91 -
  103.92 -    private HintContext(CompilationInfo info, HintsSettings settings, HintMetadata metadata, GlobalProcessingContext globalContext, TreePath path, Map<String, TreePath> variables, Map<String, Collection<? extends TreePath>> multiVariables, Map<String, String> variableNames, Map<String, TypeMirror> constraints, Collection<? super MessageImpl> problems, boolean bulkMode, AtomicBoolean cancel, int caret) {
  103.93 -        this.info = info;
  103.94 -        this.settings = settings;
  103.95 -        this.preferences = metadata != null ? settings.getHintPreferences(metadata) : null;
  103.96 -        this.severity = preferences != null ? settings.getSeverity(metadata) : Severity.ERROR;
  103.97 -        this.metadata = metadata;
  103.98 -        this.globalContext = globalContext;
  103.99 -        this.path = path;
 103.100 -
 103.101 -        variables = new HashMap<String, TreePath>(variables);
 103.102 -        variables.put("$_", path);
 103.103 -        
 103.104 -        this.variables = variables;
 103.105 -        this.multiVariables = multiVariables;
 103.106 -        this.variableNames = variableNames;
 103.107 -        this.messages = problems;
 103.108 -        this.constraints = constraints;
 103.109 -        this.bulkMode = bulkMode;
 103.110 -        this.cancel = cancel;
 103.111 -        this.caret = caret;
 103.112 -    }
 103.113 -
 103.114 -    public CompilationInfo getInfo() {
 103.115 -        return info;
 103.116 -    }
 103.117 -
 103.118 -    public Preferences getPreferences() {
 103.119 -        return preferences;
 103.120 -    }
 103.121 -
 103.122 -    public Severity getSeverity() {
 103.123 -        return severity;
 103.124 -    }
 103.125 -
 103.126 -    public TreePath getPath() {
 103.127 -        return path;
 103.128 -    }
 103.129 -
 103.130 -    public Map<String, TreePath> getVariables() {
 103.131 -        return variables;
 103.132 -    }
 103.133 -
 103.134 -    public Map<String, Collection<? extends TreePath>> getMultiVariables() {
 103.135 -        return multiVariables;
 103.136 -    }
 103.137 -
 103.138 -    public Map<String, String> getVariableNames() {
 103.139 -        return variableNames;
 103.140 -    }
 103.141 -
 103.142 -    HintMetadata getHintMetadata() {
 103.143 -        return metadata;
 103.144 -    }
 103.145 -
 103.146 -    //TODO: not sure it should be here:
 103.147 -    public Map<String, TypeMirror> getConstraints() {
 103.148 -        return constraints;
 103.149 -    }
 103.150 -
 103.151 -    /**
 103.152 -     * Will be used only for refactoring(s), will be ignored for hints.
 103.153 -     * 
 103.154 -     * @param kind
 103.155 -     * @param text
 103.156 -     */
 103.157 -    public void reportMessage(MessageKind kind, String text) {
 103.158 -        messages.add(new MessageImpl(kind, text));
 103.159 -    }
 103.160 -
 103.161 -    /**Returns {@code true} if the hint is being run in over many files, {@code false}
 103.162 -     * if only the file opened in the editor is being inspected.
 103.163 -     *
 103.164 -     * @return {@code true} if the hint is being run in over many files.
 103.165 -     */
 103.166 -    public boolean isBulkMode() {
 103.167 -        return bulkMode;
 103.168 -    }
 103.169 -
 103.170 -    /**Returns {@code true} if the computation has been canceled.
 103.171 -     *
 103.172 -     * @return {@code true} if the computation has been canceled.
 103.173 -     */
 103.174 -    public boolean isCanceled() {
 103.175 -        return cancel.get();
 103.176 -    }
 103.177 -
 103.178 -    /**For suggestions, returns the caret location for the editor
 103.179 -     * for which the suggestion is being computed. Returns -1 for hints.
 103.180 -     *
 103.181 -     * @return for suggestions, returns the caret location, -1 otherwise
 103.182 -     */
 103.183 -    public int getCaretLocation() {
 103.184 -        return metadata.kind == Kind.ACTION ? caret : -1;
 103.185 -    }
 103.186 -    
 103.187 -    public <V, R, D extends Decision<V, R>> D findDecision(TreePathHandle forPath, Factory<V, R, D> f) {
 103.188 -        List<Decision<?, ?>> decs = globalContext.decisions.get(forPath);
 103.189 -
 103.190 -        if (decs == null) {
 103.191 -            globalContext.decisions.put(forPath, decs = new ArrayList<Decision<?, ?>>());
 103.192 -        }
 103.193 -
 103.194 -        for (Decision<?, ?> d : decs) {
 103.195 -            if (d.getClass() == f.decisionClass) {
 103.196 -                return f.decisionClass.cast(d);
 103.197 -            }
 103.198 -        }
 103.199 -
 103.200 -        D res = f.create(forPath);
 103.201 -
 103.202 -        decs.add((Decision<?, ?>) res);
 103.203 -
 103.204 -        return res;
 103.205 -    }
 103.206 -
 103.207 -    public Decision<?, ?> decision;
 103.208 -
 103.209 -    public Decision<?, ?> getDecision() {
 103.210 -        return decision;
 103.211 -    }
 103.212 -
 103.213 -    public enum MessageKind {
 103.214 -        WARNING, ERROR;
 103.215 -    }
 103.216 -    
 103.217 -    static {
 103.218 -        SPIAccessor.setINSTANCE(new SPIAccessor() {
 103.219 -            @Override public HintContext createHintContext(CompilationInfo info, HintsSettings settings, HintMetadata metadata, GlobalProcessingContext globalContext, TreePath path, Map<String, TreePath> variables, Map<String, Collection<? extends TreePath>> multiVariables, Map<String, String> variableNames, Map<String, TypeMirror> constraints, Collection<? super MessageImpl> problems, boolean bulkMode, AtomicBoolean cancel, int caret) {
 103.220 -                return new HintContext(info, settings, metadata, globalContext, path, variables, multiVariables, variableNames, constraints, problems, bulkMode, cancel, caret);
 103.221 -            }
 103.222 -            @Override public HintContext createHintContext(CompilationInfo info, HintsSettings settings, HintMetadata metadata, GlobalProcessingContext globalContext, TreePath path, Map<String, TreePath> variables, Map<String, Collection<? extends TreePath>> multiVariables, Map<String, String> variableNames) {
 103.223 -                return new HintContext(info, settings, metadata, globalContext, path, variables, multiVariables, variableNames, Collections.<String, TypeMirror>emptyMap(), new LinkedList<MessageImpl>(), false, new AtomicBoolean(), -1);
 103.224 -            }
 103.225 -            @Override public HintMetadata getHintMetadata(HintContext ctx) {
 103.226 -                return ctx.getHintMetadata();
 103.227 -            }
 103.228 -            @Override public HintsSettings getHintSettings(HintContext ctx) {
 103.229 -                return ctx.settings;
 103.230 -            }
 103.231 -        });
 103.232 -    }
 103.233 -}
   104.1 --- a/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/HintSeverity.java	Sun Oct 16 08:01:27 2016 +0200
   104.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   104.3 @@ -1,69 +0,0 @@
   104.4 -/*
   104.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   104.6 - *
   104.7 - * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
   104.8 - *
   104.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  104.10 - * Other names may be trademarks of their respective owners.
  104.11 - *
  104.12 - * The contents of this file are subject to the terms of either the GNU
  104.13 - * General Public License Version 2 only ("GPL") or the Common
  104.14 - * Development and Distribution License("CDDL") (collectively, the
  104.15 - * "License"). You may not use this file except in compliance with the
  104.16 - * License. You can obtain a copy of the License at
  104.17 - * http://www.netbeans.org/cddl-gplv2.html
  104.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  104.19 - * specific language governing permissions and limitations under the
  104.20 - * License.  When distributing the software, include this License Header
  104.21 - * Notice in each file and include the License file at
  104.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  104.23 - * particular file as subject to the "Classpath" exception as provided
  104.24 - * by Oracle in the GPL Version 2 section of the License file that
  104.25 - * accompanied this code. If applicable, add the following below the
  104.26 - * License Header, with the fields enclosed by brackets [] replaced by
  104.27 - * your own identifying information:
  104.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  104.29 - *
  104.30 - * If you wish your version of this file to be governed by only the CDDL
  104.31 - * or only the GPL Version 2, indicate your decision by adding
  104.32 - * "[Contributor] elects to include this software in this distribution
  104.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  104.34 - * single choice of license, a recipient has the option to distribute
  104.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  104.36 - * to extend the choice of license to its licensees as provided above.
  104.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  104.38 - * Version 2 license, then the option applies only if the new code is
  104.39 - * made subject to such option by the copyright holder.
  104.40 - *
  104.41 - * Contributor(s):
  104.42 - *
  104.43 - * Portions Copyrighted 2011 Sun Microsystems, Inc.
  104.44 - */
  104.45 -package org.netbeans.spi.java.hints;
  104.46 -
  104.47 -import org.netbeans.spi.editor.hints.Severity;
  104.48 -
  104.49 -/** Severity of hint
  104.50 - *  <li><code>ERROR</code>  - will show up as error
  104.51 - *  <li><code>WARNING</code>  - will show up as warning
  104.52 - *  <li><code>CURRENT_LINE_WARNING</code>  - will only show up when the caret is placed in the erroneous element
  104.53 - * @author Petr Hrebejk
  104.54 - */
  104.55 -public enum HintSeverity {
  104.56 -    ERROR,
  104.57 -    WARNING,
  104.58 -    CURRENT_LINE_WARNING;
  104.59 -
  104.60 -    public Severity toEditorSeverity() {
  104.61 -        switch ( this ) {
  104.62 -            case ERROR:
  104.63 -                return Severity.ERROR;
  104.64 -            case WARNING:
  104.65 -                return Severity.VERIFIER;
  104.66 -            case CURRENT_LINE_WARNING:
  104.67 -                return Severity.HINT;
  104.68 -            default:
  104.69 -                return null;
  104.70 -        }
  104.71 -    }
  104.72 -}
   105.1 --- a/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/IntegerOption.java	Sun Oct 16 08:01:27 2016 +0200
   105.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   105.3 @@ -1,99 +0,0 @@
   105.4 -/*
   105.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   105.6 - *
   105.7 - * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
   105.8 - *
   105.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  105.10 - * Other names may be trademarks of their respective owners.
  105.11 - *
  105.12 - * The contents of this file are subject to the terms of either the GNU
  105.13 - * General Public License Version 2 only ("GPL") or the Common
  105.14 - * Development and Distribution License("CDDL") (collectively, the
  105.15 - * "License"). You may not use this file except in compliance with the
  105.16 - * License. You can obtain a copy of the License at
  105.17 - * http://www.netbeans.org/cddl-gplv2.html
  105.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  105.19 - * specific language governing permissions and limitations under the
  105.20 - * License.  When distributing the software, include this License Header
  105.21 - * Notice in each file and include the License file at
  105.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  105.23 - * particular file as subject to the "Classpath" exception as provided
  105.24 - * by Oracle in the GPL Version 2 section of the License file that
  105.25 - * accompanied this code. If applicable, add the following below the
  105.26 - * License Header, with the fields enclosed by brackets [] replaced by
  105.27 - * your own identifying information:
  105.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  105.29 - *
  105.30 - * If you wish your version of this file to be governed by only the CDDL
  105.31 - * or only the GPL Version 2, indicate your decision by adding
  105.32 - * "[Contributor] elects to include this software in this distribution
  105.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  105.34 - * single choice of license, a recipient has the option to distribute
  105.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  105.36 - * to extend the choice of license to its licensees as provided above.
  105.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  105.38 - * Version 2 license, then the option applies only if the new code is
  105.39 - * made subject to such option by the copyright holder.
  105.40 - *
  105.41 - * Contributor(s):
  105.42 - *
  105.43 - * Portions Copyrighted 2013 Sun Microsystems, Inc.
  105.44 - */
  105.45 -package org.netbeans.spi.java.hints;
  105.46 -
  105.47 -import java.lang.annotation.Documented;
  105.48 -import java.lang.annotation.ElementType;
  105.49 -import java.lang.annotation.Retention;
  105.50 -import java.lang.annotation.RetentionPolicy;
  105.51 -import java.lang.annotation.Target;
  105.52 -
  105.53 -/**
  105.54 - *  Declares an int-value option that affects hint processing.
  105.55 - *  If the Hint mixes integer and boolean options, the integer options
  105.56 - *  come first, boolean second in the UI.
  105.57 - * 
  105.58 - *  @author sdedic
  105.59 - */
  105.60 -@Retention(RetentionPolicy.SOURCE)
  105.61 -@Target(ElementType.FIELD)
  105.62 -@Documented
  105.63 -public @interface IntegerOption {
  105.64 -    /**
  105.65 -     * @return Display name of the option
  105.66 -     */
  105.67 -    public String displayName();
  105.68 -    
  105.69 -    /**
  105.70 -     * @return tooltip for mouse hover over the option
  105.71 -     */
  105.72 -    public String tooltip() default "";
  105.73 -    
  105.74 -    /**
  105.75 -     * @return default value for the option
  105.76 -     */
  105.77 -    public int defaultValue() default 0;
  105.78 -    
  105.79 -    /**
  105.80 -     * Minimum value for the option. If Integer.MIN_VALUE (the default),
  105.81 -     * no minimum will be enforced.
  105.82 -     * 
  105.83 -     * @return minimum value.
  105.84 -     */
  105.85 -    public int minValue() default 0;
  105.86 -    
  105.87 -    /**
  105.88 -     * Maximum value for the option. If Integer.MAX_VALUE (the default),
  105.89 -     * no maximum will be enforced. Please do choose a reasonable maximum value,
  105.90 -     * as the UI may size the input box to accommodate all digits of the maximum
  105.91 -     * permitted value, and the input box may seem unreasonably large.
  105.92 -     * 
  105.93 -     * @return maximum value
  105.94 -     */
  105.95 -    public int maxValue() default Integer.MAX_VALUE;
  105.96 -    
  105.97 -    /**
  105.98 -     * If non-zero, a spinner will be created with the specified step. If zero (the default),
  105.99 -     * a plain input will be presented. Negative values are not accepted at the moment and are reserved.
 105.100 -     */
 105.101 -    public int step() default 0;
 105.102 -}
   106.1 --- a/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/JavaFix.java	Sun Oct 16 08:01:27 2016 +0200
   106.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   106.3 @@ -1,309 +0,0 @@
   106.4 -/*
   106.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   106.6 - *
   106.7 - * Copyright 2008-2012 Oracle and/or its affiliates. All rights reserved.
   106.8 - *
   106.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  106.10 - * Other names may be trademarks of their respective owners.
  106.11 - *
  106.12 - * The contents of this file are subject to the terms of either the GNU
  106.13 - * General Public License Version 2 only ("GPL") or the Common
  106.14 - * Development and Distribution License("CDDL") (collectively, the
  106.15 - * "License"). You may not use this file except in compliance with the
  106.16 - * License. You can obtain a copy of the License at
  106.17 - * http://www.netbeans.org/cddl-gplv2.html
  106.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  106.19 - * specific language governing permissions and limitations under the
  106.20 - * License.  When distributing the software, include this License Header
  106.21 - * Notice in each file and include the License file at
  106.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  106.23 - * particular file as subject to the "Classpath" exception as provided
  106.24 - * by Oracle in the GPL Version 2 section of the License file that
  106.25 - * accompanied this code. If applicable, add the following below the
  106.26 - * License Header, with the fields enclosed by brackets [] replaced by
  106.27 - * your own identifying information:
  106.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  106.29 - *
  106.30 - * If you wish your version of this file to be governed by only the CDDL
  106.31 - * or only the GPL Version 2, indicate your decision by adding
  106.32 - * "[Contributor] elects to include this software in this distribution
  106.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  106.34 - * single choice of license, a recipient has the option to distribute
  106.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  106.36 - * to extend the choice of license to its licensees as provided above.
  106.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  106.38 - * Version 2 license, then the option applies only if the new code is
  106.39 - * made subject to such option by the copyright holder.
  106.40 - *
  106.41 - * Contributor(s):
  106.42 - *
  106.43 - * Portions Copyrighted 2008-2012 Sun Microsystems, Inc.
  106.44 - */
  106.45 -
  106.46 -package org.netbeans.spi.java.hints;
  106.47 -
  106.48 -import com.sun.source.util.TreePath;
  106.49 -import java.io.ByteArrayInputStream;
  106.50 -import java.io.ByteArrayOutputStream;
  106.51 -import java.io.IOException;
  106.52 -import java.io.InputStream;
  106.53 -import java.io.OutputStream;
  106.54 -import java.nio.ByteBuffer;
  106.55 -import java.util.Collection;
  106.56 -import java.util.Collections;
  106.57 -import java.util.HashMap;
  106.58 -import java.util.List;
  106.59 -import java.util.Map;
  106.60 -import java.util.logging.Level;
  106.61 -import java.util.logging.Logger;
  106.62 -import javax.lang.model.type.TypeMirror;
  106.63 -import javax.swing.text.BadLocationException;
  106.64 -import javax.swing.text.Document;
  106.65 -import org.netbeans.api.annotations.common.NonNull;
  106.66 -import org.netbeans.api.java.source.CompilationInfo;
  106.67 -import org.netbeans.api.java.source.TreePathHandle;
  106.68 -import org.netbeans.api.java.source.WorkingCopy;
  106.69 -import org.netbeans.api.queries.FileEncodingQuery;
  106.70 -import org.netbeans.modules.java.hints.spiimpl.JavaFixImpl;
  106.71 -import org.netbeans.modules.java.hints.spiimpl.batch.BatchUtilities;
  106.72 -import org.netbeans.modules.refactoring.spi.RefactoringElementImplementation;
  106.73 -import org.netbeans.spi.editor.hints.ChangeInfo;
  106.74 -import org.netbeans.spi.editor.hints.Fix;
  106.75 -import org.openide.filesystems.FileObject;
  106.76 -import org.openide.util.Exceptions;
  106.77 -import org.openide.util.Parameters;
  106.78 -
  106.79 -/**A base class for fixes that modify Java source code. Using this class
  106.80 - * as a base class makes creating the fix somewhat simpler, but also supports
  106.81 - * running the hint in the Inspect&Transform dialog. The fix can be converted
  106.82 - * to {@link Fix} by means of the {@link #toEditorFix() } method.
  106.83 - *
  106.84 - * @see JavaFixUtilities for various predefined fixes.
  106.85 - * @author Jan Lahoda
  106.86 - */
  106.87 -public abstract class JavaFix {
  106.88 -
  106.89 -    private final TreePathHandle handle;
  106.90 -    private final Map<String, String> options;
  106.91 -
  106.92 -    /**Create JavaFix with the given base {@link TreePath}. The base {@link TreePath}
  106.93 -     * will be passed back to the real implementation of the fix.
  106.94 -     *
  106.95 -     * @param info a {@link CompilationInfo} from which the given {@link TreePath} originates
  106.96 -     * @param tp a {@link TreePath} that will be passed back to the
  106.97 -     *           {@link #performRewrite(org.netbeans.spi.java.hints.JavaFix.TransformationContext) } method
  106.98 -     */
  106.99 -    protected JavaFix(@NonNull CompilationInfo info, @NonNull TreePath tp) {
 106.100 -        this(info, tp, Collections.<String, String>emptyMap());
 106.101 -    }
 106.102 -
 106.103 -    JavaFix(CompilationInfo info, TreePath tp, Map<String, String> options) {
 106.104 -        this.handle = TreePathHandle.create(tp, info);
 106.105 -        this.options = Collections.unmodifiableMap(new HashMap<String, String>(options));
 106.106 -    }
 106.107 -
 106.108 -    /**Create JavaFix with the given base {@link TreePathHandle}. The base {@link TreePathHandle}
 106.109 -     * will be resolved and passed back to the real implementation of the fix.
 106.110 -     *
 106.111 -     * @param handle a {@link TreePathHandle} that will be resolved and passed back to the
 106.112 -     *              {@link #performRewrite(org.netbeans.spi.java.hints.JavaFix.TransformationContext) } method
 106.113 -     */
 106.114 -    protected JavaFix(@NonNull TreePathHandle handle) {
 106.115 -        this(handle, Collections.<String, String>emptyMap());
 106.116 -    }
 106.117 -
 106.118 -    JavaFix(TreePathHandle handle, Map<String, String> options) {
 106.119 -        this.handle = handle;
 106.120 -        this.options = Collections.unmodifiableMap(new HashMap<String, String>(options));
 106.121 -    }
 106.122 -
 106.123 -    /**The display text of the fix.
 106.124 -     *
 106.125 -     * @return the display text of the fix.
 106.126 -     */
 106.127 -    protected abstract @NonNull String getText();
 106.128 -
 106.129 -    /**Do the transformations needed to implement the hint's function.
 106.130 -     *
 106.131 -     * @param ctx a context over which the fix should operate
 106.132 -     * @throws Exception if something goes wrong while performing the transformation
 106.133 -     *                   - will be logged by the infrastructure
 106.134 -     */
 106.135 -    protected abstract void performRewrite(@NonNull TransformationContext ctx) throws Exception;
 106.136 -
 106.137 -    /**Convert this {@link JavaFix} into the Editor Hints {@link Fix}.
 106.138 -     *
 106.139 -     * @return a {@link Fix}, that when invoked, will invoke {@link #performRewrite(org.netbeans.spi.java.hints.JavaFix.TransformationContext) }
 106.140 -     * method on this {@link JavaFix}.
 106.141 -     */
 106.142 -    public final Fix toEditorFix() {
 106.143 -        return new JavaFixImpl(this);
 106.144 -    }
 106.145 -
 106.146 -    static {
 106.147 -        JavaFixImpl.Accessor.INSTANCE = new JavaFixImpl.Accessor() {
 106.148 -            @Override
 106.149 -            public String getText(JavaFix jf) {
 106.150 -                return jf.getText();
 106.151 -            }
 106.152 -            @Override
 106.153 -            public ChangeInfo process(JavaFix jf, WorkingCopy wc, boolean canShowUI, Map<FileObject, byte[]> resourceContent, Collection<? super RefactoringElementImplementation> fileChanges) throws Exception {
 106.154 -                TreePath tp = jf.handle.resolve(wc);
 106.155 -
 106.156 -                if (tp == null) {
 106.157 -                    Logger.getLogger(JavaFix.class.getName()).log(Level.SEVERE, "Cannot resolve handle={0}", jf.handle);
 106.158 -                    return null;
 106.159 -                }
 106.160 -
 106.161 -                jf.performRewrite(new TransformationContext(wc, tp, canShowUI, resourceContent, fileChanges));
 106.162 -
 106.163 -                return null;
 106.164 -            }
 106.165 -            @Override
 106.166 -            public FileObject getFile(JavaFix jf) {
 106.167 -                return jf.handle.getFileObject();
 106.168 -            }
 106.169 -            @Override
 106.170 -            public Map<String, String> getOptions(JavaFix jf) {
 106.171 -                return jf.options;
 106.172 -            }
 106.173 -
 106.174 -            @Override
 106.175 -            public Fix rewriteFix(CompilationInfo info, String displayName, TreePath what, String to, Map<String, TreePath> parameters, Map<String, Collection<? extends TreePath>> parametersMulti, Map<String, String> parameterNames, Map<String, TypeMirror> constraints, Map<String, String> options, String... imports) {
 106.176 -                return JavaFixUtilities.rewriteFix(info, displayName, what, to, parameters, parametersMulti, parameterNames, constraints, options, imports);
 106.177 -            }
 106.178 -
 106.179 -            @Override
 106.180 -            public Fix createSuppressWarningsFix(CompilationInfo compilationInfo, TreePath treePath, String... keys) {
 106.181 -                return ErrorDescriptionFactory.createSuppressWarningsFix(compilationInfo, treePath, keys);
 106.182 -            }
 106.183 -
 106.184 -            @Override
 106.185 -            public List<Fix> createSuppressWarnings(CompilationInfo compilationInfo, TreePath treePath, String... keys) {
 106.186 -                return ErrorDescriptionFactory.createSuppressWarnings(compilationInfo, treePath, keys);
 106.187 -            }
 106.188 -
 106.189 -            @Override
 106.190 -            public List<Fix> resolveDefaultFixes(HintContext ctx, Fix... provided) {
 106.191 -                return ErrorDescriptionFactory.resolveDefaultFixes(ctx, provided);
 106.192 -            }
 106.193 -        };
 106.194 -    }
 106.195 -
 106.196 -    /**A context that contains a reference to a {@link WorkingCopy} through which
 106.197 -     * modifications of Java source code can be made.
 106.198 -     *
 106.199 -     */
 106.200 -    public static final class TransformationContext {
 106.201 -        private final WorkingCopy workingCopy;
 106.202 -        private final TreePath path;
 106.203 -        private final boolean canShowUI;
 106.204 -        private final Map<FileObject, byte[]> resourceContentChanges;
 106.205 -        private final Collection<? super RefactoringElementImplementation> fileChanges;
 106.206 -        TransformationContext(WorkingCopy workingCopy, TreePath path, boolean canShowUI, Map<FileObject, byte[]> resourceContentChanges, Collection<? super RefactoringElementImplementation> fileChanges) {
 106.207 -            this.workingCopy = workingCopy;
 106.208 -            this.path = path;
 106.209 -            this.canShowUI = canShowUI;
 106.210 -            this.resourceContentChanges = resourceContentChanges;
 106.211 -            this.fileChanges = fileChanges;
 106.212 -        }
 106.213 -
 106.214 -        boolean isCanShowUI() {
 106.215 -            return canShowUI;
 106.216 -        }
 106.217 -
 106.218 -        /**Returns the {@link TreePath} that was passed to a {@link JavaFix} constructor.
 106.219 -         *
 106.220 -         * @return the {@link TreePath} that was passed to a {@link JavaFix} constructor.
 106.221 -         */
 106.222 -        public @NonNull TreePath getPath() {
 106.223 -            return path;
 106.224 -        }
 106.225 -
 106.226 -        /**A {@link WorkingCopy} over which the transformation should operate.
 106.227 -         * @return {@link WorkingCopy} over which the transformation should operate.
 106.228 -         */
 106.229 -        public @NonNull WorkingCopy getWorkingCopy() {
 106.230 -            return workingCopy;
 106.231 -        }
 106.232 -
 106.233 -        /**Allows access to non-Java resources. The content of this InputStream will
 106.234 -         * include all changes done through {@link #getResourceOutput(org.openide.filesystems.FileObject) }
 106.235 -         * before calling this method.
 106.236 -         *
 106.237 -         * @param file whose content should be returned
 106.238 -         * @return the file's content
 106.239 -         * @throws IOException if something goes wrong while opening the file
 106.240 -         * @throws IllegalArgumentException if {@code file} parameter is null, or
 106.241 -         *                                  if it represents a Java file
 106.242 -         */
 106.243 -        public @NonNull InputStream getResourceContent(@NonNull FileObject file) throws IOException, IllegalArgumentException {
 106.244 -            Parameters.notNull("file", file);
 106.245 -            if ("text/x-java".equals(file.getMIMEType("text/x-java")))
 106.246 -                throw new IllegalArgumentException("Cannot access Java files");
 106.247 -
 106.248 -            byte[] newContent = resourceContentChanges != null ? resourceContentChanges.get(file) : null;
 106.249 -
 106.250 -            if (newContent == null) {
 106.251 -                final Document doc = BatchUtilities.getDocument(file);
 106.252 -
 106.253 -                if (doc != null) {
 106.254 -                    final String[] result = new String[1];
 106.255 -
 106.256 -                    doc.render(new Runnable() {
 106.257 -                        @Override public void run() {
 106.258 -                            try {
 106.259 -                                result[0] = doc.getText(0, doc.getLength());
 106.260 -                            } catch (BadLocationException ex) {
 106.261 -                                Exceptions.printStackTrace(ex);
 106.262 -                            }
 106.263 -                        }
 106.264 -                    });
 106.265 -
 106.266 -                    if (result[0] != null) {
 106.267 -                        ByteBuffer encoded = FileEncodingQuery.getEncoding(file).encode(result[0]);
 106.268 -                        byte[] encodedBytes = new byte[encoded.remaining()];
 106.269 -
 106.270 -                        encoded.get(encodedBytes);
 106.271 -
 106.272 -                        return new ByteArrayInputStream(encodedBytes);
 106.273 -                    }
 106.274 -                }
 106.275 -                
 106.276 -                return file.getInputStream();
 106.277 -            } else {
 106.278 -                return new ByteArrayInputStream(newContent);
 106.279 -            }
 106.280 -        }
 106.281 -
 106.282 -        /**Record a changed version of a file. The changes will be applied altogether with
 106.283 -         * changes to the Java file. In Inspect&Transform, changes done through this
 106.284 -         * method will be part of the preview.
 106.285 -         *
 106.286 -         * @param file whose content should be changed
 106.287 -         * @return an {@link java.io.OutputStream} into which the new content of the file should be written
 106.288 -         * @throws IOException if something goes wrong while opening the file
 106.289 -         * @throws IllegalArgumentException if {@code file} parameter is null, or
 106.290 -         *                                  if it represents a Java file
 106.291 -         */
 106.292 -        public @NonNull OutputStream getResourceOutput(@NonNull final FileObject file) throws IOException {
 106.293 -            Parameters.notNull("file", file);
 106.294 -            if ("text/x-java".equals(file.getMIMEType("text/x-java")))
 106.295 -                throw new IllegalArgumentException("Cannot access Java files");
 106.296 -            if (resourceContentChanges == null) return file.getOutputStream();
 106.297 -
 106.298 -            return new ByteArrayOutputStream() {
 106.299 -                @Override public void close() throws IOException {
 106.300 -                    super.close();
 106.301 -                    resourceContentChanges.put(file, toByteArray());
 106.302 -                }
 106.303 -            };
 106.304 -        }
 106.305 -
 106.306 -        Collection<? super RefactoringElementImplementation> getFileChanges() {
 106.307 -            return fileChanges;
 106.308 -        }
 106.309 -
 106.310 -    }
 106.311 -
 106.312 -}
   107.1 --- a/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/JavaFixUtilities.java	Sun Oct 16 08:01:27 2016 +0200
   107.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   107.3 @@ -1,1642 +0,0 @@
   107.4 -/*
   107.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   107.6 - *
   107.7 - * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
   107.8 - *
   107.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  107.10 - * Other names may be trademarks of their respective owners.
  107.11 - *
  107.12 - * The contents of this file are subject to the terms of either the GNU
  107.13 - * General Public License Version 2 only ("GPL") or the Common
  107.14 - * Development and Distribution License("CDDL") (collectively, the
  107.15 - * "License"). You may not use this file except in compliance with the
  107.16 - * License. You can obtain a copy of the License at
  107.17 - * http://www.netbeans.org/cddl-gplv2.html
  107.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  107.19 - * specific language governing permissions and limitations under the
  107.20 - * License.  When distributing the software, include this License Header
  107.21 - * Notice in each file and include the License file at
  107.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  107.23 - * particular file as subject to the "Classpath" exception as provided
  107.24 - * by Oracle in the GPL Version 2 section of the License file that
  107.25 - * accompanied this code. If applicable, add the following below the
  107.26 - * License Header, with the fields enclosed by brackets [] replaced by
  107.27 - * your own identifying information:
  107.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  107.29 - *
  107.30 - * If you wish your version of this file to be governed by only the CDDL
  107.31 - * or only the GPL Version 2, indicate your decision by adding
  107.32 - * "[Contributor] elects to include this software in this distribution
  107.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  107.34 - * single choice of license, a recipient has the option to distribute
  107.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  107.36 - * to extend the choice of license to its licensees as provided above.
  107.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  107.38 - * Version 2 license, then the option applies only if the new code is
  107.39 - * made subject to such option by the copyright holder.
  107.40 - *
  107.41 - * Contributor(s):
  107.42 - *
  107.43 - * Portions Copyrighted 2012 Sun Microsystems, Inc.
  107.44 - */
  107.45 -package org.netbeans.spi.java.hints;
  107.46 -
  107.47 -import com.sun.javadoc.Doc;
  107.48 -import com.sun.javadoc.Tag;
  107.49 -import com.sun.source.tree.AnnotationTree;
  107.50 -import com.sun.source.tree.AssignmentTree;
  107.51 -import com.sun.source.tree.BinaryTree;
  107.52 -import com.sun.source.tree.BlockTree;
  107.53 -import com.sun.source.tree.CaseTree;
  107.54 -import com.sun.source.tree.CatchTree;
  107.55 -import com.sun.source.tree.ClassTree;
  107.56 -import com.sun.source.tree.CompilationUnitTree;
  107.57 -import com.sun.source.tree.CompoundAssignmentTree;
  107.58 -import com.sun.source.tree.ExpressionStatementTree;
  107.59 -import com.sun.source.tree.ExpressionTree;
  107.60 -import com.sun.source.tree.IdentifierTree;
  107.61 -import com.sun.source.tree.IfTree;
  107.62 -import com.sun.source.tree.LambdaExpressionTree;
  107.63 -import com.sun.source.tree.LiteralTree;
  107.64 -import com.sun.source.tree.MemberSelectTree;
  107.65 -import com.sun.source.tree.MethodInvocationTree;
  107.66 -import com.sun.source.tree.MethodTree;
  107.67 -import com.sun.source.tree.ModifiersTree;
  107.68 -import com.sun.source.tree.NewArrayTree;
  107.69 -import com.sun.source.tree.NewClassTree;
  107.70 -import com.sun.source.tree.ParameterizedTypeTree;
  107.71 -import com.sun.source.tree.ParenthesizedTree;
  107.72 -import com.sun.source.tree.Scope;
  107.73 -import com.sun.source.tree.StatementTree;
  107.74 -import com.sun.source.tree.SwitchTree;
  107.75 -import com.sun.source.tree.Tree;
  107.76 -import com.sun.source.tree.Tree.Kind;
  107.77 -import com.sun.source.tree.TryTree;
  107.78 -import com.sun.source.tree.TypeParameterTree;
  107.79 -import com.sun.source.tree.UnaryTree;
  107.80 -import com.sun.source.tree.UnionTypeTree;
  107.81 -import com.sun.source.tree.VariableTree;
  107.82 -import com.sun.source.util.SourcePositions;
  107.83 -import com.sun.source.util.TreePath;
  107.84 -import com.sun.source.util.TreePathScanner;
  107.85 -import com.sun.source.util.TreeScanner;
  107.86 -import java.io.IOException;
  107.87 -import java.util.ArrayList;
  107.88 -import java.util.Arrays;
  107.89 -import java.util.Collection;
  107.90 -import java.util.Collections;
  107.91 -import java.util.EnumMap;
  107.92 -import java.util.EnumSet;
  107.93 -import java.util.HashMap;
  107.94 -import java.util.IdentityHashMap;
  107.95 -import java.util.Iterator;
  107.96 -import java.util.LinkedList;
  107.97 -import java.util.List;
  107.98 -import java.util.Map;
  107.99 -import java.util.Map.Entry;
 107.100 -import java.util.Set;
 107.101 -import java.util.concurrent.Callable;
 107.102 -import java.util.logging.Level;
 107.103 -import java.util.logging.Logger;
 107.104 -import java.util.regex.Matcher;
 107.105 -import javax.lang.model.element.Element;
 107.106 -import javax.lang.model.element.ElementKind;
 107.107 -import javax.lang.model.element.Modifier;
 107.108 -import javax.lang.model.element.TypeElement;
 107.109 -import javax.lang.model.type.TypeKind;
 107.110 -import javax.lang.model.type.TypeMirror;
 107.111 -import org.netbeans.api.java.classpath.ClassPath;
 107.112 -import org.netbeans.api.java.classpath.ClassPath.PathConversionMode;
 107.113 -import org.netbeans.api.java.queries.SourceForBinaryQuery;
 107.114 -import org.netbeans.api.java.source.ClasspathInfo;
 107.115 -import org.netbeans.api.java.source.ClasspathInfo.PathKind;
 107.116 -import org.netbeans.api.java.source.CompilationInfo;
 107.117 -import org.netbeans.api.java.source.SourceUtils;
 107.118 -import org.netbeans.api.java.source.TreeMaker;
 107.119 -import org.netbeans.api.java.source.TreePathHandle;
 107.120 -import org.netbeans.api.java.source.TypeMirrorHandle;
 107.121 -import org.netbeans.api.java.source.WorkingCopy;
 107.122 -import org.netbeans.api.java.source.matching.Occurrence;
 107.123 -import org.netbeans.api.java.source.matching.Pattern;
 107.124 -import org.netbeans.api.project.FileOwnerQuery;
 107.125 -import org.netbeans.api.project.Project;
 107.126 -import org.netbeans.modules.java.hints.spiimpl.Hacks;
 107.127 -import org.netbeans.modules.java.hints.spiimpl.Utilities;
 107.128 -import org.netbeans.modules.java.hints.spiimpl.ipi.upgrade.ProjectDependencyUpgrader;
 107.129 -import org.netbeans.modules.refactoring.spi.SimpleRefactoringElementImplementation;
 107.130 -import org.netbeans.spi.editor.hints.Fix;
 107.131 -import org.netbeans.spi.java.classpath.support.ClassPathSupport;
 107.132 -import org.netbeans.spi.java.hints.JavaFix.TransformationContext;
 107.133 -import org.openide.filesystems.FileObject;
 107.134 -import org.openide.filesystems.FileUtil;
 107.135 -import org.openide.loaders.DataFolder;
 107.136 -import org.openide.loaders.DataObject;
 107.137 -import org.openide.loaders.DataObjectNotFoundException;
 107.138 -import org.openide.modules.SpecificationVersion;
 107.139 -import org.openide.text.PositionBounds;
 107.140 -import org.openide.util.Exceptions;
 107.141 -import org.openide.util.Lookup;
 107.142 -import org.openide.util.NbBundle.Messages;
 107.143 -import org.openide.util.NbCollections;
 107.144 -
 107.145 -/**Factory methods for various predefined {@link JavaFix} implementations.
 107.146 - *
 107.147 - * @author lahvac
 107.148 - */
 107.149 -public class JavaFixUtilities {
 107.150 -
 107.151 -    /**Prepare a fix that will replace the given tree node ({@code what}) with the
 107.152 -     * given code. Any variables in the {@code to} pattern will be replaced with their
 107.153 -     * values from {@link HintContext#getVariables() }, {@link HintContext#getMultiVariables() }
 107.154 -     * and {@link HintContext#getVariableNames() }.
 107.155 -     *
 107.156 -     * @param ctx basic context for which the fix should be created
 107.157 -     * @param displayName the display name of the fix
 107.158 -     * @param what the tree node that should be replaced
 107.159 -     * @param to the new code that should replaced the {@code what} tree node
 107.160 -     * @return an editor fix that performs the required transformation
 107.161 -     */
 107.162 -    public static Fix rewriteFix(HintContext ctx, String displayName, TreePath what, final String to) {
 107.163 -        return rewriteFix(ctx.getInfo(), displayName, what, to, ctx.getVariables(), ctx.getMultiVariables(), ctx.getVariableNames(), ctx.getConstraints(), Collections.<String, String>emptyMap());
 107.164 -    }
 107.165 -
 107.166 -    static Fix rewriteFix(CompilationInfo info, String displayName, TreePath what, final String to, Map<String, TreePath> parameters, Map<String, Collection<? extends TreePath>> parametersMulti, final Map<String, String> parameterNames, Map<String, TypeMirror> constraints, Map<String, String> options, String... imports) {
 107.167 -        final Map<String, TreePathHandle> params = new HashMap<String, TreePathHandle>();
 107.168 -        final Map<String, Object> extraParamsData = new HashMap<String, Object>();
 107.169 -
 107.170 -        for (Entry<String, TreePath> e : parameters.entrySet()) {
 107.171 -            params.put(e.getKey(), TreePathHandle.create(e.getValue(), info));
 107.172 -            if (e.getValue() instanceof Callable) {
 107.173 -                try {
 107.174 -                    extraParamsData.put(e.getKey(), ((Callable) e.getValue()).call());
 107.175 -                } catch (Exception ex) {
 107.176 -                    Exceptions.printStackTrace(ex);
 107.177 -                }
 107.178 -            }
 107.179 -        }
 107.180 -
 107.181 -        final Map<String, Collection<TreePathHandle>> paramsMulti = new HashMap<String, Collection<TreePathHandle>>();
 107.182 -
 107.183 -        for (Entry<String, Collection<? extends TreePath>> e : parametersMulti.entrySet()) {
 107.184 -            Collection<TreePathHandle> tph = new LinkedList<TreePathHandle>();
 107.185 -
 107.186 -            for (TreePath tp : e.getValue()) {
 107.187 -                tph.add(TreePathHandle.create(tp, info));
 107.188 -            }
 107.189 -
 107.190 -            paramsMulti.put(e.getKey(), tph);
 107.191 -        }
 107.192 -
 107.193 -        final Map<String, TypeMirrorHandle<?>> constraintsHandles = new HashMap<String, TypeMirrorHandle<?>>();
 107.194 -
 107.195 -        for (Entry<String, TypeMirror> c : constraints.entrySet()) {
 107.196 -            constraintsHandles.put(c.getKey(), TypeMirrorHandle.create(c.getValue()));
 107.197 -        }
 107.198 -
 107.199 -        if (displayName == null) {
 107.200 -            displayName = defaultFixDisplayName(info, parameters, to);
 107.201 -        }
 107.202 -
 107.203 -        return new JavaFixRealImpl(info, what, options, displayName, to, params, extraParamsData, paramsMulti, parameterNames, constraintsHandles, Arrays.asList(imports)).toEditorFix();
 107.204 -    }
 107.205 -
 107.206 -    /**Creates a fix that removes the given code corresponding to the given tree
 107.207 -     * node from the source code.
 107.208 -     * 
 107.209 -     * @param ctx basic context for which the fix should be created
 107.210 -     * @param displayName the display name of the fix
 107.211 -     * @param what the tree node that should be removed
 107.212 -     * @return an editor fix that removes the give tree from the source code
 107.213 -     */
 107.214 -    public static Fix removeFromParent(HintContext ctx, String displayName, TreePath what) {
 107.215 -        return new RemoveFromParent(displayName, ctx.getInfo(), what).toEditorFix();
 107.216 -    }
 107.217 -
 107.218 -    private static String defaultFixDisplayName(CompilationInfo info, Map<String, TreePath> variables, String replaceTarget) {
 107.219 -        Map<String, String> stringsForVariables = new HashMap<String, String>();
 107.220 -
 107.221 -        for (Entry<String, TreePath> e : variables.entrySet()) {
 107.222 -            Tree t = e.getValue().getLeaf();
 107.223 -            SourcePositions sp = info.getTrees().getSourcePositions();
 107.224 -            int startPos = (int) sp.getStartPosition(info.getCompilationUnit(), t);
 107.225 -            int endPos = (int) sp.getEndPosition(info.getCompilationUnit(), t);
 107.226 -
 107.227 -            if (startPos >= 0 && endPos >= 0) {
 107.228 -                stringsForVariables.put(e.getKey(), info.getText().substring(startPos, endPos));
 107.229 -            } else {
 107.230 -                stringsForVariables.put(e.getKey(), "");
 107.231 -            }
 107.232 -        }
 107.233 -
 107.234 -        if (!stringsForVariables.containsKey("$this")) {
 107.235 -            //XXX: is this correct?
 107.236 -            stringsForVariables.put("$this", "this");
 107.237 -        }
 107.238 -
 107.239 -        for (Entry<String, String> e : stringsForVariables.entrySet()) {
 107.240 -            String quotedVariable = java.util.regex.Pattern.quote(e.getKey());
 107.241 -            String quotedTarget = Matcher.quoteReplacement(e.getValue());
 107.242 -            replaceTarget = replaceTarget.replaceAll(quotedVariable, quotedTarget);
 107.243 -        }
 107.244 -
 107.245 -        return "Rewrite to " + replaceTarget;
 107.246 -    }
 107.247 -
 107.248 -    private static void checkDependency(CompilationInfo copy, Element e, boolean canShowUI) {
 107.249 -        SpecificationVersion sv = computeSpecVersion(copy, e);
 107.250 -
 107.251 -        while (sv == null && e.getKind() != ElementKind.PACKAGE) {
 107.252 -            e = e.getEnclosingElement();
 107.253 -            sv = computeSpecVersion(copy, e);
 107.254 -        }
 107.255 -
 107.256 -        if (sv == null) {
 107.257 -            return ;
 107.258 -        }
 107.259 -
 107.260 -        Project currentProject = FileOwnerQuery.getOwner(copy.getFileObject());
 107.261 -
 107.262 -        if (currentProject == null) {
 107.263 -            return ;
 107.264 -        }
 107.265 -
 107.266 -        FileObject file = getFile(copy, e);
 107.267 -
 107.268 -        if (file == null) {
 107.269 -            return ;
 107.270 -        }
 107.271 -
 107.272 -        FileObject root = findRootForFile(file, copy.getClasspathInfo());
 107.273 -
 107.274 -        if (root == null) {
 107.275 -            return ;
 107.276 -        }
 107.277 -
 107.278 -        Project referedProject = FileOwnerQuery.getOwner(file);
 107.279 -
 107.280 -        if (referedProject != null && currentProject.getProjectDirectory().equals(referedProject.getProjectDirectory())) {
 107.281 -            return ;
 107.282 -        }
 107.283 -
 107.284 -        for (ProjectDependencyUpgrader pdu : Lookup.getDefault().lookupAll(ProjectDependencyUpgrader.class)) {
 107.285 -            if (pdu.ensureDependency(currentProject, root, sv, canShowUI)) {
 107.286 -                return ;
 107.287 -            }
 107.288 -        }
 107.289 -    }
 107.290 -
 107.291 -    private static java.util.regex.Pattern SPEC_VERSION = java.util.regex.Pattern.compile("[0-9]+(\\.[0-9]+)+");
 107.292 -
 107.293 -    static SpecificationVersion computeSpecVersion(CompilationInfo info, Element el) {
 107.294 -        if (!Utilities.isJavadocSupported(info)) return null;
 107.295 -
 107.296 -        Doc javaDoc = info.getElementUtilities().javaDocFor(el);
 107.297 -
 107.298 -        if (javaDoc == null) return null;
 107.299 -
 107.300 -        for (Tag since : javaDoc.tags("@since")) {
 107.301 -            String text = since.text();
 107.302 -
 107.303 -            Matcher m = SPEC_VERSION.matcher(text);
 107.304 -
 107.305 -            if (!m.find()) {
 107.306 -                continue;
 107.307 -            }
 107.308 -
 107.309 -            return new SpecificationVersion(m.group()/*ver.toString()*/);
 107.310 -        }
 107.311 -
 107.312 -        return null;
 107.313 -    }
 107.314 -
 107.315 -    @SuppressWarnings("deprecation")
 107.316 -    private static FileObject getFile(CompilationInfo copy, Element e) {
 107.317 -        return SourceUtils.getFile(e, copy.getClasspathInfo());
 107.318 -    }
 107.319 -
 107.320 -    private static FileObject findRootForFile(final FileObject file, final ClasspathInfo cpInfo) {
 107.321 -        ClassPath cp = ClassPathSupport.createProxyClassPath(
 107.322 -            new ClassPath[] {
 107.323 -                cpInfo.getClassPath(ClasspathInfo.PathKind.SOURCE),
 107.324 -                cpInfo.getClassPath(ClasspathInfo.PathKind.BOOT),
 107.325 -                cpInfo.getClassPath(ClasspathInfo.PathKind.COMPILE),
 107.326 -            });
 107.327 -
 107.328 -        FileObject root = cp.findOwnerRoot(file);
 107.329 -
 107.330 -        if (root != null) {
 107.331 -            return root;
 107.332 -        }
 107.333 -
 107.334 -        for (ClassPath.Entry e : cp.entries()) {
 107.335 -            FileObject[] sourceRoots = SourceForBinaryQuery.findSourceRoots(e.getURL()).getRoots();
 107.336 -
 107.337 -            if (sourceRoots.length == 0) continue;
 107.338 -
 107.339 -            ClassPath sourcePath = ClassPathSupport.createClassPath(sourceRoots);
 107.340 -
 107.341 -            root = sourcePath.findOwnerRoot(file);
 107.342 -
 107.343 -            if (root != null) {
 107.344 -                return root;
 107.345 -            }
 107.346 -        }
 107.347 -        return null;
 107.348 -    }
 107.349 -
 107.350 -    private static boolean isStaticElement(Element el) {
 107.351 -        if (el == null) return false;
 107.352 -
 107.353 -        if (el.asType() == null || el.asType().getKind() == TypeKind.ERROR) {
 107.354 -            return false;
 107.355 -        }
 107.356 -
 107.357 -        if (el.getModifiers().contains(Modifier.STATIC)) {
 107.358 -            //XXX:
 107.359 -            if (!el.getKind().isClass() && !el.getKind().isInterface()) {
 107.360 -                return false;
 107.361 -            }
 107.362 -
 107.363 -            return true;
 107.364 -        }
 107.365 -
 107.366 -        if (el.getKind().isClass() || el.getKind().isInterface()) {
 107.367 -            return el.getEnclosingElement().getKind() == ElementKind.PACKAGE;
 107.368 -        }
 107.369 -
 107.370 -        return false;
 107.371 -    }
 107.372 -
 107.373 -    private static class JavaFixRealImpl extends JavaFix {
 107.374 -        private final String displayName;
 107.375 -        private final Map<String, TreePathHandle> params;
 107.376 -        private final Map<String, Object> extraParamsData;
 107.377 -        private final Map<String, Collection<TreePathHandle>> paramsMulti;
 107.378 -        private final Map<String, String> parameterNames;
 107.379 -        private final Map<String, TypeMirrorHandle<?>> constraintsHandles;
 107.380 -        private final Iterable<? extends String> imports;
 107.381 -        private final String to;
 107.382 -
 107.383 -        public JavaFixRealImpl(CompilationInfo info, TreePath what, Map<String, String> options, String displayName, String to, Map<String, TreePathHandle> params, Map<String, Object> extraParamsData, Map<String, Collection<TreePathHandle>> paramsMulti, final Map<String, String> parameterNames, Map<String, TypeMirrorHandle<?>> constraintsHandles, Iterable<? extends String> imports) {
 107.384 -            super(info, what, options);
 107.385 -
 107.386 -            this.displayName = displayName;
 107.387 -            this.to = to;
 107.388 -            this.params = params;
 107.389 -            this.extraParamsData = extraParamsData;
 107.390 -            this.paramsMulti = paramsMulti;
 107.391 -            this.parameterNames = parameterNames;
 107.392 -            this.constraintsHandles = constraintsHandles;
 107.393 -            this.imports = imports;
 107.394 -        }
 107.395 -
 107.396 -        @Override
 107.397 -        protected String getText() {
 107.398 -            return displayName;
 107.399 -        }
 107.400 -
 107.401 -        @Override
 107.402 -        protected void performRewrite(TransformationContext ctx) {
 107.403 -            final WorkingCopy wc = ctx.getWorkingCopy();
 107.404 -            TreePath tp = ctx.getPath();
 107.405 -            final Map<String, TreePath> parameters = new HashMap<String, TreePath>();
 107.406 -
 107.407 -            for (Entry<String, TreePathHandle> e : params.entrySet()) {
 107.408 -                TreePath p = e.getValue().resolve(wc);
 107.409 -
 107.410 -                if (p == null) {
 107.411 -                    Logger.getLogger(JavaFix.class.getName()).log(Level.SEVERE, "Cannot resolve handle={0}", e.getValue());
 107.412 -                }
 107.413 -
 107.414 -                parameters.put(e.getKey(), p);
 107.415 -            }
 107.416 -
 107.417 -            final Map<String, Collection<TreePath>> parametersMulti = new HashMap<String, Collection<TreePath>>();
 107.418 -
 107.419 -            for (Entry<String, Collection<TreePathHandle>> e : paramsMulti.entrySet()) {
 107.420 -                Collection<TreePath> tps = new LinkedList<TreePath>();
 107.421 -
 107.422 -                for (TreePathHandle tph : e.getValue()) {
 107.423 -                    TreePath p = tph.resolve(wc);
 107.424 -
 107.425 -                    if (p == null) {
 107.426 -                        Logger.getLogger(JavaFix.class.getName()).log(Level.SEVERE, "Cannot resolve handle={0}", e.getValue());
 107.427 -                    }
 107.428 -
 107.429 -                    tps.add(p);
 107.430 -                }
 107.431 -
 107.432 -                parametersMulti.put(e.getKey(), tps);
 107.433 -            }
 107.434 -
 107.435 -            Map<String, TypeMirror> constraints = new HashMap<String, TypeMirror>();
 107.436 -
 107.437 -            for (Entry<String, TypeMirrorHandle<?>> c : constraintsHandles.entrySet()) {
 107.438 -                constraints.put(c.getKey(), c.getValue().resolve(wc));
 107.439 -            }
 107.440 -
 107.441 -            Scope scope = Utilities.constructScope(wc, constraints, imports);
 107.442 -
 107.443 -            assert scope != null;
 107.444 -
 107.445 -            Tree parsed = Utilities.parseAndAttribute(wc, to, scope);
 107.446 -            
 107.447 -            if (parsed.getKind() == Kind.EXPRESSION_STATEMENT && ExpressionTree.class.isAssignableFrom(tp.getLeaf().getKind().asInterface())) {
 107.448 -                parsed = ((ExpressionStatementTree) parsed).getExpression();
 107.449 -            }
 107.450 -            
 107.451 -            Map<Tree, Tree> rewriteFromTo = new IdentityHashMap<Tree, Tree>();
 107.452 -            Tree original;
 107.453 -
 107.454 -            if (Utilities.isFakeBlock(parsed)) {
 107.455 -                TreePath parent = tp.getParentPath();
 107.456 -                List<? extends StatementTree> statements = ((BlockTree) parsed).getStatements();
 107.457 -                
 107.458 -                if (tp.getLeaf().getKind() == Kind.BLOCK) {
 107.459 -                    BlockTree real = (BlockTree) tp.getLeaf();
 107.460 -                    rewriteFromTo.put(original = real, wc.getTreeMaker().Block(statements, real.isStatic()));
 107.461 -                } else {
 107.462 -                    statements = statements.subList(1, statements.size() - 1);
 107.463 -
 107.464 -                    if (parent.getLeaf().getKind() == Kind.BLOCK) {
 107.465 -                        List<StatementTree> newStatements = new LinkedList<StatementTree>();
 107.466 -
 107.467 -                        for (StatementTree st : ((BlockTree) parent.getLeaf()).getStatements()) {
 107.468 -                            if (st == tp.getLeaf()) {
 107.469 -                                newStatements.addAll(statements);
 107.470 -                            } else {
 107.471 -                                newStatements.add(st);
 107.472 -                            }
 107.473 -                        }
 107.474 -
 107.475 -                        rewriteFromTo.put(original = parent.getLeaf(), wc.getTreeMaker().Block(newStatements, ((BlockTree) parent.getLeaf()).isStatic()));
 107.476 -                    } else {
 107.477 -                        rewriteFromTo.put(original = tp.getLeaf(), wc.getTreeMaker().Block(statements, false));
 107.478 -                    }
 107.479 -                }
 107.480 -            } else if (Utilities.isFakeClass(parsed)) {
 107.481 -                TreePath parent = tp.getParentPath();
 107.482 -                List<? extends Tree> members = ((ClassTree) parsed).getMembers();
 107.483 -
 107.484 -                members = members.subList(1, members.size());
 107.485 -
 107.486 -                assert parent.getLeaf().getKind() == Kind.CLASS;
 107.487 -
 107.488 -                List<Tree> newMembers = new LinkedList<Tree>();
 107.489 -
 107.490 -                ClassTree ct = (ClassTree) parent.getLeaf();
 107.491 -
 107.492 -                for (Tree t : ct.getMembers()) {
 107.493 -                    if (t == tp.getLeaf()) {
 107.494 -                        newMembers.addAll(members);
 107.495 -                    } else {
 107.496 -                        newMembers.add(t);
 107.497 -                    }
 107.498 -                }
 107.499 -
 107.500 -                rewriteFromTo.put(original = parent.getLeaf(), wc.getTreeMaker().Class(ct.getModifiers(), ct.getSimpleName(), ct.getTypeParameters(), ct.getExtendsClause(), ct.getImplementsClause(), newMembers));
 107.501 -            } else if (tp.getLeaf().getKind() == Kind.BLOCK && parametersMulti.containsKey("$$1$") && parsed.getKind() != Kind.BLOCK && StatementTree.class.isAssignableFrom(parsed.getKind().asInterface())) {
 107.502 -                List<StatementTree> newStatements = new LinkedList<StatementTree>();
 107.503 -
 107.504 -                newStatements.add(wc.getTreeMaker().ExpressionStatement(wc.getTreeMaker().Identifier("$$1$")));
 107.505 -                newStatements.add((StatementTree) parsed);
 107.506 -                newStatements.add(wc.getTreeMaker().ExpressionStatement(wc.getTreeMaker().Identifier("$$2$")));
 107.507 -
 107.508 -                parsed = wc.getTreeMaker().Block(newStatements, ((BlockTree) tp.getLeaf()).isStatic());
 107.509 -
 107.510 -                rewriteFromTo.put(original = tp.getLeaf(), parsed);
 107.511 -            } else {
 107.512 -                while (   tp.getParentPath().getLeaf().getKind() == Kind.PARENTHESIZED
 107.513 -                       && tp.getLeaf().getKind() != parsed.getKind()
 107.514 -                       && tp.getParentPath() != null
 107.515 -                       && tp.getParentPath().getParentPath() != null
 107.516 -                       && !requiresParenthesis(parsed, tp.getParentPath().getLeaf(), tp.getParentPath().getParentPath().getLeaf())
 107.517 -                       && requiresParenthesis(tp.getLeaf(), tp.getParentPath().getLeaf(), tp.getParentPath().getParentPath().getLeaf()))
 107.518 -                    tp = tp.getParentPath();
 107.519 -                rewriteFromTo.put(original = tp.getLeaf(), parsed);
 107.520 -            }
 107.521 -
 107.522 -            //prevent generating QualIdents inside import clauses - might be better to solve that inside ImportAnalysis2,
 107.523 -            //but that seems not to be straightforward:
 107.524 -            boolean inImport = parsed.getKind() == Kind.IMPORT;
 107.525 -            boolean inPackage = false;
 107.526 -            TreePath w = tp;
 107.527 -
 107.528 -            while (!inImport && w != null) {
 107.529 -                inImport |= w.getLeaf().getKind() == Kind.IMPORT;
 107.530 -                inPackage |= w.getParentPath() != null && w.getParentPath().getLeaf().getKind() == Kind.COMPILATION_UNIT && ((CompilationUnitTree) w.getParentPath().getLeaf()).getPackageName() == w.getLeaf();
 107.531 -                w = w.getParentPath();
 107.532 -            }
 107.533 -
 107.534 -            final Set<Tree> originalTrees = Collections.newSetFromMap(new IdentityHashMap<Tree, Boolean>());
 107.535 -            
 107.536 -            new TreeScanner<Void, Void>() {
 107.537 -                @Override public Void scan(Tree tree, Void p) {
 107.538 -                    originalTrees.add(tree);
 107.539 -                    return super.scan(tree, p);
 107.540 -                }
 107.541 -            }.scan(original, null);
 107.542 -            
 107.543 -            new ReplaceParameters(wc, ctx.isCanShowUI(), inImport, parameters, extraParamsData, parametersMulti, parameterNames, rewriteFromTo, originalTrees).scan(new TreePath(tp.getParentPath(), rewriteFromTo.get(original)), null);
 107.544 -
 107.545 -            if (inPackage) {
 107.546 -                String newPackage = wc.getTreeUtilities().translate(wc.getCompilationUnit().getPackageName(), new IdentityHashMap<Tree, Tree>(rewriteFromTo))./*XXX: not correct*/toString();
 107.547 -
 107.548 -                ClassPath source = wc.getClasspathInfo().getClassPath(PathKind.SOURCE);
 107.549 -                FileObject ownerRoot = source.findOwnerRoot(wc.getFileObject());
 107.550 -
 107.551 -                if (ownerRoot != null) {
 107.552 -                    ctx.getFileChanges().add(new MoveFile(wc.getFileObject(), ownerRoot, newPackage.replace('.', '/')));
 107.553 -                } else {
 107.554 -                    Logger.getLogger(JavaFix.class.getName()).log(Level.WARNING, "{0} not on its source path ({1})", new Object[] {FileUtil.getFileDisplayName(wc.getFileObject()), source.toString(PathConversionMode.PRINT)});
 107.555 -                }
 107.556 -            }
 107.557 -            
 107.558 -            for (Entry<Tree, Tree> e : rewriteFromTo.entrySet()) {
 107.559 -                wc.rewrite(e.getKey(), e.getValue());
 107.560 -            }
 107.561 -        }
 107.562 -    }
 107.563 -
 107.564 -    private static final Set<Kind> NUMBER_LITERAL_KINDS = EnumSet.of(Kind.FLOAT_LITERAL, Kind.DOUBLE_LITERAL, Kind.INT_LITERAL, Kind.LONG_LITERAL);
 107.565 -
 107.566 -    private static class ReplaceParameters extends TreePathScanner<Number, Void> {
 107.567 -
 107.568 -        private final CompilationInfo info;
 107.569 -        private final TreeMaker make;
 107.570 -        private final boolean canShowUI;
 107.571 -        private final boolean inImport;
 107.572 -        private final Map<String, TreePath> parameters;
 107.573 -        private final Map<String, Object> extraParamsData;
 107.574 -        private final Map<String, Collection<TreePath>> parametersMulti;
 107.575 -        private final Map<String, String> parameterNames;
 107.576 -        private final Map<Tree, Tree> rewriteFromTo;
 107.577 -        private final Set<Tree> originalTrees;
 107.578 -
 107.579 -        public ReplaceParameters(WorkingCopy wc, boolean canShowUI, boolean inImport, Map<String, TreePath> parameters, Map<String, Object> extraParamsData, Map<String, Collection<TreePath>> parametersMulti, Map<String, String> parameterNames, Map<Tree, Tree> rewriteFromTo, Set<Tree> originalTrees) {
 107.580 -            this.parameters = parameters;
 107.581 -            this.info = wc;
 107.582 -            this.make = wc.getTreeMaker();
 107.583 -            this.canShowUI = canShowUI;
 107.584 -            this.inImport = inImport;
 107.585 -            this.extraParamsData = extraParamsData;
 107.586 -            this.parametersMulti = parametersMulti;
 107.587 -            this.parameterNames = parameterNames;
 107.588 -            this.rewriteFromTo = rewriteFromTo;
 107.589 -            this.originalTrees = originalTrees;
 107.590 -        }
 107.591 -
 107.592 -        @Override
 107.593 -        public Number visitIdentifier(IdentifierTree node, Void p) {
 107.594 -            String name = node.getName().toString();
 107.595 -            Tree newNode = handleIdentifier(name, node);
 107.596 -            
 107.597 -            if (newNode != null) {
 107.598 -                rewrite(node, newNode);
 107.599 -                if (NUMBER_LITERAL_KINDS.contains(newNode.getKind())) {
 107.600 -                    return (Number) ((LiteralTree) newNode).getValue();
 107.601 -                }
 107.602 -            }
 107.603 -
 107.604 -            Element e = info.getTrees().getElement(getCurrentPath());
 107.605 -
 107.606 -            if (e != null && isStaticElement(e) && !inImport) {
 107.607 -                rewrite(node, make.QualIdent(e));
 107.608 -            }
 107.609 -
 107.610 -            return super.visitIdentifier(node, p);
 107.611 -        }
 107.612 -
 107.613 -        @Override
 107.614 -        public Number visitTypeParameter(TypeParameterTree node, Void p) {
 107.615 -            String name = node.getName().toString();
 107.616 -            Tree newNode = handleIdentifier(name, node);
 107.617 -            
 107.618 -            if (newNode != null) {
 107.619 -                rewrite(node, newNode);
 107.620 -                if (NUMBER_LITERAL_KINDS.contains(newNode.getKind())) {
 107.621 -                    return (Number) ((LiteralTree) newNode).getValue();
 107.622 -                }
 107.623 -            }
 107.624 -            
 107.625 -            return super.visitTypeParameter(node, p);
 107.626 -        }
 107.627 -        
 107.628 -        private Tree handleIdentifier(String name, Tree node) {
 107.629 -            TreePath tp = parameters.get(name);
 107.630 -
 107.631 -            if (tp != null) {
 107.632 -                if (tp.getLeaf() instanceof Hacks.RenameTree) {
 107.633 -                    Hacks.RenameTree rt = (Hacks.RenameTree) tp.getLeaf();
 107.634 -                    return make.setLabel(rt.originalTree, rt.newName);
 107.635 -                }
 107.636 -                if (!parameterNames.containsKey(name)) {
 107.637 -                    Tree target = tp.getLeaf();
 107.638 -                    if (NUMBER_LITERAL_KINDS.contains(target.getKind())) {
 107.639 -                        return target;
 107.640 -                    }
 107.641 -                    //TODO: might also remove parenthesis, but needs to ensure the diff will still be minimal
 107.642 -//                    while (target.getKind() == Kind.PARENTHESIZED
 107.643 -//                           && !requiresParenthesis(((ParenthesizedTree) target).getExpression(), getCurrentPath().getParentPath().getLeaf())) {
 107.644 -//                        target = ((ParenthesizedTree) target).getExpression();
 107.645 -//                    }
 107.646 -                    if (   getCurrentPath().getParentPath() != null
 107.647 -                        && getCurrentPath().getParentPath().getLeaf().getKind() == Kind.LOGICAL_COMPLEMENT
 107.648 -                        && (   tp.getParentPath() == null
 107.649 -                            || tp.getParentPath().getLeaf().getKind() != Kind.LOGICAL_COMPLEMENT)) {
 107.650 -                        Tree negated = negate((ExpressionTree) tp.getLeaf(), getCurrentPath().getParentPath().getParentPath().getLeaf(), true);
 107.651 -                        
 107.652 -                        if (negated != null) {
 107.653 -                            rewrite(getCurrentPath().getParentPath().getLeaf(), negated);
 107.654 -                        }
 107.655 -                    }
 107.656 -                    if (requiresParenthesis(target, node, getCurrentPath().getParentPath().getLeaf())) {
 107.657 -                        target = make.Parenthesized((ExpressionTree) target);
 107.658 -                    }
 107.659 -                    return target;
 107.660 -                }
 107.661 -            }
 107.662 -
 107.663 -            String variableName = parameterNames.get(name);
 107.664 -
 107.665 -            if (variableName != null) {
 107.666 -                return make.Identifier(variableName);
 107.667 -            }
 107.668 -            
 107.669 -            return null;
 107.670 -        }
 107.671 -
 107.672 -        @Override
 107.673 -        public Number visitMemberSelect(MemberSelectTree node, Void p) {
 107.674 -            Element e = info.getTrees().getElement(getCurrentPath());
 107.675 -
 107.676 -            if (e != null && (e.getKind() != ElementKind.CLASS || ((TypeElement) e).asType().getKind() != TypeKind.ERROR)) {
 107.677 -                //check correct dependency:
 107.678 -                checkDependency(info, e, canShowUI);
 107.679 -
 107.680 -                if (isStaticElement(e) && !inImport) {
 107.681 -                    rewrite(node, make.QualIdent(e));
 107.682 -
 107.683 -                    return null;
 107.684 -                }
 107.685 -            }
 107.686 -            
 107.687 -            MemberSelectTree nue = node;
 107.688 -            String selectedName = node.getIdentifier().toString();
 107.689 -
 107.690 -            if (selectedName.startsWith("$") && parameterNames.get(selectedName) != null) {
 107.691 -                nue = make.MemberSelect(node.getExpression(), parameterNames.get(selectedName));
 107.692 -            }
 107.693 -
 107.694 -            if (nue.getExpression().getKind() == Kind.IDENTIFIER) {
 107.695 -                String name = ((IdentifierTree) nue.getExpression()).getName().toString();
 107.696 -
 107.697 -                if (name.startsWith("$") && parameters.get(name) == null) {
 107.698 -                    //XXX: unbound variable, use identifier instead of member select - may cause problems?
 107.699 -                    rewrite(node, make.Identifier(nue.getIdentifier()));
 107.700 -                    return null;
 107.701 -                }
 107.702 -            }
 107.703 -
 107.704 -            if (nue != node) {
 107.705 -                rewrite(node, nue);
 107.706 -            }
 107.707 -            
 107.708 -            return super.visitMemberSelect(node, p);
 107.709 -        }
 107.710 -
 107.711 -        @Override
 107.712 -        public Number visitVariable(VariableTree node, Void p) {
 107.713 -            String name = node.getName().toString();
 107.714 -
 107.715 -            if (name.startsWith("$")) {
 107.716 -                String nueName = parameterNames.get(name);
 107.717 -
 107.718 -                if (nueName != null) {
 107.719 -                    name = nueName;
 107.720 -                }
 107.721 -            }
 107.722 -            
 107.723 -            VariableTree nue = make.Variable(node.getModifiers(), name, node.getType(), resolveOptionalValue(node.getInitializer()));
 107.724 -
 107.725 -            rewrite(node, nue);
 107.726 -
 107.727 -            return super.visitVariable(nue, p);
 107.728 -        }
 107.729 -
 107.730 -        @Override
 107.731 -        public Number visitIf(IfTree node, Void p) {
 107.732 -            IfTree nue = make.If(node.getCondition(), node.getThenStatement(), resolveOptionalValue(node.getElseStatement()));
 107.733 -            
 107.734 -            rewrite(node, nue);
 107.735 -            
 107.736 -            return super.visitIf(nue, p);
 107.737 -        }
 107.738 -
 107.739 -        @Override
 107.740 -        public Number visitMethod(MethodTree node, Void p) {
 107.741 -            String name = node.getName().toString();
 107.742 -            String newName = name;
 107.743 -
 107.744 -            if (name.startsWith("$")) {
 107.745 -                if (parameterNames.containsKey(name)) {
 107.746 -                    newName = parameterNames.get(name);
 107.747 -                }
 107.748 -            }
 107.749 -
 107.750 -            List<? extends TypeParameterTree> typeParams = resolveMultiParameters(node.getTypeParameters());
 107.751 -            List<? extends VariableTree> params = resolveMultiParameters(node.getParameters());
 107.752 -            List<? extends ExpressionTree> thrown = resolveMultiParameters(node.getThrows());
 107.753 -            
 107.754 -            MethodTree nue = make.Method(node.getModifiers(), newName, node.getReturnType(), typeParams, params, thrown, node.getBody(), (ExpressionTree) node.getDefaultValue());
 107.755 -            
 107.756 -            rewrite(node, nue);
 107.757 -            
 107.758 -            return super.visitMethod(nue, p);
 107.759 -        }
 107.760 -
 107.761 -        @Override
 107.762 -        public Number visitClass(ClassTree node, Void p) {
 107.763 -            String name = node.getSimpleName().toString();
 107.764 -            String newName = name;
 107.765 -
 107.766 -            if (name.startsWith("$")) {
 107.767 -                if (parameterNames.containsKey(name)) {
 107.768 -                    newName = parameterNames.get(name);
 107.769 -                }
 107.770 -            }
 107.771 -
 107.772 -            List<? extends TypeParameterTree> typeParams = resolveMultiParameters(node.getTypeParameters());
 107.773 -            List<? extends Tree> implementsClauses = resolveMultiParameters(node.getImplementsClause());
 107.774 -            List<? extends Tree> members = resolveMultiParameters(Utilities.filterHidden(getCurrentPath(), node.getMembers()));
 107.775 -            Tree extend = resolveOptionalValue(node.getExtendsClause());
 107.776 -            ClassTree nue = make.Class(node.getModifiers(), newName, typeParams, extend, implementsClauses, members);
 107.777 -            
 107.778 -            rewrite(node, nue);
 107.779 -            
 107.780 -            return super.visitClass(nue, p);
 107.781 -        }
 107.782 -
 107.783 -        @Override
 107.784 -        public Number visitExpressionStatement(ExpressionStatementTree node, Void p) {
 107.785 -            CharSequence name = Utilities.getWildcardTreeName(node);
 107.786 -
 107.787 -            if (name != null) {
 107.788 -                TreePath tp = parameters.get(name.toString());
 107.789 -
 107.790 -                if (tp != null) {
 107.791 -                    rewrite(node, tp.getLeaf());
 107.792 -                    return null;
 107.793 -                }
 107.794 -            }
 107.795 -
 107.796 -            return super.visitExpressionStatement(node, p);
 107.797 -        }
 107.798 -
 107.799 -        @Override
 107.800 -        public Number visitLiteral(LiteralTree node, Void p) {
 107.801 -            if (node.getValue() instanceof Number) {
 107.802 -                return (Number) node.getValue();
 107.803 -            }
 107.804 -
 107.805 -            return super.visitLiteral(node, p);
 107.806 -        }
 107.807 -
 107.808 -        @Override
 107.809 -        public Number visitBinary(BinaryTree node, Void p) {
 107.810 -            Number left  = scan(node.getLeftOperand(), p);
 107.811 -            Number right = scan(node.getRightOperand(), p);
 107.812 -
 107.813 -            if (left != null && right != null) {
 107.814 -                Number result = null;
 107.815 -                switch (node.getKind()) {
 107.816 -                    case MULTIPLY:
 107.817 -                            if (left instanceof Double || right instanceof Double) {
 107.818 -                                result = left.doubleValue() * right.doubleValue();
 107.819 -                            } else if (left instanceof Float || right instanceof Float) {
 107.820 -                                result = left.floatValue() * right.floatValue();
 107.821 -                            } else if (left instanceof Long || right instanceof Long) {
 107.822 -                                result = left.longValue() * right.longValue();
 107.823 -                            } else if (left instanceof Integer || right instanceof Integer) {
 107.824 -                                result = left.intValue() * right.intValue();
 107.825 -                            } else {
 107.826 -                                throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
 107.827 -                            }
 107.828 -                            break;
 107.829 -
 107.830 -                    case DIVIDE:
 107.831 -                            if (left instanceof Double || right instanceof Double) {
 107.832 -                                result = left.doubleValue() / right.doubleValue();
 107.833 -                            } else if (left instanceof Float || right instanceof Float) {
 107.834 -                                result = left.floatValue() / right.floatValue();
 107.835 -                            } else if (left instanceof Long || right instanceof Long) {
 107.836 -                                result = left.longValue() / right.longValue();
 107.837 -                            } else if (left instanceof Integer || right instanceof Integer) {
 107.838 -                                result = left.intValue() / right.intValue();
 107.839 -                            } else {
 107.840 -                                throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
 107.841 -                            }
 107.842 -                            break;
 107.843 -
 107.844 -                    case REMAINDER:
 107.845 -                            if (left instanceof Double || right instanceof Double) {
 107.846 -                                result = left.doubleValue() % right.doubleValue();
 107.847 -                            } else if (left instanceof Float || right instanceof Float) {
 107.848 -                                result = left.floatValue() % right.floatValue();
 107.849 -                            } else if (left instanceof Long || right instanceof Long) {
 107.850 -                                result = left.longValue() % right.longValue();
 107.851 -                            } else if (left instanceof Integer || right instanceof Integer) {
 107.852 -                                result = left.intValue() % right.intValue();
 107.853 -                            } else {
 107.854 -                                throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
 107.855 -                            }
 107.856 -                            break;
 107.857 -
 107.858 -                    case PLUS:
 107.859 -                            if (left instanceof Double || right instanceof Double) {
 107.860 -                                result = left.doubleValue() + right.doubleValue();
 107.861 -                            } else if (left instanceof Float || right instanceof Float) {
 107.862 -                                result = left.floatValue() + right.floatValue();
 107.863 -                            } else if (left instanceof Long || right instanceof Long) {
 107.864 -                                result = left.longValue() + right.longValue();
 107.865 -                            } else if (left instanceof Integer || right instanceof Integer) {
 107.866 -                                result = left.intValue() + right.intValue();
 107.867 -                            } else {
 107.868 -                                throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
 107.869 -                            }
 107.870 -                            break;
 107.871 -
 107.872 -                    case MINUS:
 107.873 -                            if (left instanceof Double || right instanceof Double) {
 107.874 -                                result = left.doubleValue() - right.doubleValue();
 107.875 -                            } else if (left instanceof Float || right instanceof Float) {
 107.876 -                                result = left.floatValue() - right.floatValue();
 107.877 -                            } else if (left instanceof Long || right instanceof Long) {
 107.878 -                                result = left.longValue() - right.longValue();
 107.879 -                            } else if (left instanceof Integer || right instanceof Integer) {
 107.880 -                                result = left.intValue() - right.intValue();
 107.881 -                            } else {
 107.882 -                                throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
 107.883 -                            }
 107.884 -                            break;
 107.885 -
 107.886 -                    case LEFT_SHIFT:
 107.887 -                            if (left instanceof Long || right instanceof Long) {
 107.888 -                                result = left.longValue() << right.longValue();
 107.889 -                            } else if (left instanceof Integer || right instanceof Integer) {
 107.890 -                                result = left.intValue() << right.intValue();
 107.891 -                            } else {
 107.892 -                                throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
 107.893 -                            }
 107.894 -                            break;
 107.895 -
 107.896 -                    case RIGHT_SHIFT:
 107.897 -                            if (left instanceof Long || right instanceof Long) {
 107.898 -                                result = left.longValue() >> right.longValue();
 107.899 -                            } else if (left instanceof Integer || right instanceof Integer) {
 107.900 -                                result = left.intValue() >> right.intValue();
 107.901 -                            } else {
 107.902 -                                throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
 107.903 -                            }
 107.904 -                            break;
 107.905 -
 107.906 -                    case UNSIGNED_RIGHT_SHIFT:
 107.907 -                            if (left instanceof Long || right instanceof Long) {
 107.908 -                                result = left.longValue() >>> right.longValue();
 107.909 -                            } else if (left instanceof Integer || right instanceof Integer) {
 107.910 -                                result = left.intValue() >>> right.intValue();
 107.911 -                            } else {
 107.912 -                                throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
 107.913 -                            }
 107.914 -                            break;
 107.915 -
 107.916 -                    case AND:
 107.917 -                            if (left instanceof Long || right instanceof Long) {
 107.918 -                                result = left.longValue() & right.longValue();
 107.919 -                            } else if (left instanceof Integer || right instanceof Integer) {
 107.920 -                                result = left.intValue() & right.intValue();
 107.921 -                            } else {
 107.922 -                                throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
 107.923 -                            }
 107.924 -                            break;
 107.925 -
 107.926 -                    case XOR:
 107.927 -                            if (left instanceof Long || right instanceof Long) {
 107.928 -                                result = left.longValue() ^ right.longValue();
 107.929 -                            } else if (left instanceof Integer || right instanceof Integer) {
 107.930 -                                result = left.intValue() ^ right.intValue();
 107.931 -                            } else {
 107.932 -                                throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
 107.933 -                            }
 107.934 -                            break;
 107.935 -
 107.936 -                    case OR:
 107.937 -                            if (left instanceof Long || right instanceof Long) {
 107.938 -                                result = left.longValue() | right.longValue();
 107.939 -                            } else if (left instanceof Integer || right instanceof Integer) {
 107.940 -                                result = left.intValue() | right.intValue();
 107.941 -                            } else {
 107.942 -                                throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
 107.943 -                            }
 107.944 -                            break;
 107.945 -                }
 107.946 -
 107.947 -                if (result != null) {
 107.948 -                    rewrite(node, make.Literal(result));
 107.949 -
 107.950 -                    return result;
 107.951 -                }
 107.952 -            }
 107.953 -
 107.954 -            return null;
 107.955 -        }
 107.956 -
 107.957 -        @Override
 107.958 -        public Number visitUnary(UnaryTree node, Void p) {
 107.959 -            Number op  = scan(node.getExpression(), p);
 107.960 -
 107.961 -            if (op != null) {
 107.962 -                Number result = null;
 107.963 -                switch (node.getKind()) {
 107.964 -                    case UNARY_MINUS:
 107.965 -                            if (op instanceof Double) {
 107.966 -                                result = -op.doubleValue();
 107.967 -                            } else if (op instanceof Float) {
 107.968 -                                result = -op.floatValue();
 107.969 -                            } else if (op instanceof Long) {
 107.970 -                                result = -op.longValue();
 107.971 -                            } else if (op instanceof Integer) {
 107.972 -                                result = -op.intValue();
 107.973 -                            } else {
 107.974 -                                throw new IllegalStateException("op=" + op.getClass());
 107.975 -                            }
 107.976 -                            break;
 107.977 -                    case UNARY_PLUS:
 107.978 -                        result = op;
 107.979 -                        break;
 107.980 -                }
 107.981 -
 107.982 -                if (result != null) {
 107.983 -                    rewrite(node, make.Literal(result));
 107.984 -
 107.985 -                    return result;
 107.986 -                }
 107.987 -            }
 107.988 -
 107.989 -            return super.visitUnary(node, p);
 107.990 -        }
 107.991 -
 107.992 -        @Override
 107.993 -        public Number visitBlock(BlockTree node, Void p) {
 107.994 -            List<? extends StatementTree> nueStatement = resolveMultiParameters(node.getStatements());
 107.995 -            BlockTree nue = make.Block(nueStatement, node.isStatic());
 107.996 -
 107.997 -            rewrite(node, nue);
 107.998 -
 107.999 -            return super.visitBlock(nue, p);
107.1000 -        }
107.1001 -
107.1002 -        @Override
107.1003 -        public Number visitCase(CaseTree node, Void p) {
107.1004 -            List<? extends StatementTree> statements = (List<? extends StatementTree>) resolveMultiParameters(node.getStatements());
107.1005 -            CaseTree nue = make.Case(node.getExpression(), statements);
107.1006 -
107.1007 -            rewrite(node, nue);
107.1008 -            return super.visitCase(node, p);
107.1009 -        }
107.1010 -
107.1011 -        @Override
107.1012 -        public Number visitMethodInvocation(MethodInvocationTree node, Void p) {
107.1013 -            List<? extends ExpressionTree> typeArgs = (List<? extends ExpressionTree>) resolveMultiParameters(node.getTypeArguments());
107.1014 -            List<? extends ExpressionTree> args = resolveMultiParameters(node.getArguments());
107.1015 -            MethodInvocationTree nue = make.MethodInvocation(typeArgs, node.getMethodSelect(), args);
107.1016 -
107.1017 -            rewrite(node, nue);
107.1018 -
107.1019 -            return super.visitMethodInvocation(nue, p);
107.1020 -        }
107.1021 -
107.1022 -        @Override
107.1023 -        public Number visitNewClass(NewClassTree node, Void p) {
107.1024 -            List<? extends ExpressionTree> typeArgs = (List<? extends ExpressionTree>) resolveMultiParameters(node.getTypeArguments());
107.1025 -            List<? extends ExpressionTree> args = resolveMultiParameters(node.getArguments());
107.1026 -            NewClassTree nue = make.NewClass(node.getEnclosingExpression(), typeArgs, node.getIdentifier(), args, node.getClassBody());
107.1027 -
107.1028 -            rewrite(node, nue);
107.1029 -            return super.visitNewClass(nue, p);
107.1030 -        }
107.1031 -
107.1032 -        @Override
107.1033 -        public Number visitParameterizedType(ParameterizedTypeTree node, Void p) {
107.1034 -            List<? extends ExpressionTree> typeArgs = (List<? extends ExpressionTree>) resolveMultiParameters(node.getTypeArguments());
107.1035 -            ParameterizedTypeTree nue = make.ParameterizedType(node.getType(), typeArgs);
107.1036 -
107.1037 -            rewrite(node, nue);
107.1038 -            return super.visitParameterizedType(node, p);
107.1039 -        }
107.1040 -
107.1041 -        @Override
107.1042 -        public Number visitSwitch(SwitchTree node, Void p) {
107.1043 -            List<? extends CaseTree> cases = (List<? extends CaseTree>) resolveMultiParameters(node.getCases());
107.1044 -            SwitchTree nue = make.Switch(node.getExpression(), cases);
107.1045 -
107.1046 -            rewrite(node, nue);
107.1047 -            return super.visitSwitch(node, p);
107.1048 -        }
107.1049 -
107.1050 -        @Override
107.1051 -        public Number visitTry(TryTree node, Void p) {
107.1052 -            List<? extends Tree> resources = (List<? extends Tree>) resolveMultiParameters(node.getResources());
107.1053 -            List<? extends CatchTree> catches = (List<? extends CatchTree>) resolveMultiParameters(node.getCatches());
107.1054 -            TryTree nue = make.Try(resources, node.getBlock(), catches, node.getFinallyBlock());
107.1055 -
107.1056 -            rewrite(node, nue);
107.1057 -            return super.visitTry(node, p);
107.1058 -        }
107.1059 -
107.1060 -        @Override
107.1061 -        public Number visitModifiers(ModifiersTree node, Void p) {
107.1062 -            List<AnnotationTree> annotations = new ArrayList<AnnotationTree>(node.getAnnotations());
107.1063 -            IdentifierTree ident = !annotations.isEmpty() && annotations.get(0).getAnnotationType().getKind() == Kind.IDENTIFIER ? (IdentifierTree) annotations.get(0).getAnnotationType() : null;
107.1064 -
107.1065 -            if (ident != null) {
107.1066 -                annotations.remove(0);
107.1067 -                
107.1068 -                String name = ident.getName().toString();
107.1069 -                TreePath orig = parameters.get(name);
107.1070 -                ModifiersTree nue;
107.1071 -                
107.1072 -                if (orig != null && orig.getLeaf().getKind() == Kind.MODIFIERS) {
107.1073 -                    ModifiersTree origMods = (ModifiersTree) orig.getLeaf();
107.1074 -                    Object actualContent = extraParamsData.get(name);
107.1075 -                    Set<Modifier> actualFlags = EnumSet.noneOf(Modifier.class);
107.1076 -                    boolean[] actualAnnotationsMask = new boolean[0];
107.1077 -                    
107.1078 -                    if (actualContent instanceof Object[] && ((Object[]) actualContent)[0] instanceof Set) {
107.1079 -                        actualFlags.addAll(NbCollections.checkedSetByFilter((Set) ((Object[]) actualContent)[0], Modifier.class, false));
107.1080 -                    }
107.1081 -                    
107.1082 -                    if (actualContent instanceof Object[] && ((Object[]) actualContent)[1] instanceof boolean[]) {
107.1083 -                        actualAnnotationsMask = (boolean[]) ((Object[]) actualContent)[1];
107.1084 -                    }
107.1085 -                    
107.1086 -                    nue = origMods;
107.1087 -                    
107.1088 -                    for (Modifier m : origMods.getFlags()) {
107.1089 -                        if (actualFlags.contains(m)) continue;
107.1090 -                        nue = make.removeModifiersModifier(nue, m);
107.1091 -                    }
107.1092 -                    
107.1093 -                    for (Modifier m : node.getFlags()) {
107.1094 -                        nue = make.addModifiersModifier(nue, m);
107.1095 -                    }
107.1096 -                    
107.1097 -                    int ai = 0;
107.1098 -                    
107.1099 -                    OUTER: for (AnnotationTree a : origMods.getAnnotations()) {
107.1100 -                        if (actualAnnotationsMask.length <= ai || actualAnnotationsMask[ai++]) continue;
107.1101 -                        for (Iterator<AnnotationTree> it = annotations.iterator(); it.hasNext();) {
107.1102 -                            AnnotationTree toCheck = it.next();
107.1103 -                            Collection<? extends Occurrence> match = org.netbeans.api.java.source.matching.Matcher.create(info).setTreeTopSearch().setSearchRoot(new TreePath(getCurrentPath(), a)).match(Pattern.createSimplePattern(new TreePath(getCurrentPath(), toCheck)));
107.1104 -                            
107.1105 -                            if (!match.isEmpty()) {
107.1106 -                                //should be kept:
107.1107 -                                it.remove();
107.1108 -                                break OUTER;
107.1109 -                            }
107.1110 -                        }
107.1111 -                        
107.1112 -                        nue = make.removeModifiersAnnotation(nue, a);
107.1113 -                    }
107.1114 -                    
107.1115 -                    for (AnnotationTree a : annotations) {
107.1116 -                        nue = make.addModifiersAnnotation(nue, a);
107.1117 -                        scan(a, p);
107.1118 -                    }
107.1119 -                } else {
107.1120 -                    nue = make.removeModifiersAnnotation(node, 0);
107.1121 -                }
107.1122 -                
107.1123 -                rewrite(node, nue);
107.1124 -                
107.1125 -                return null;
107.1126 -            }
107.1127 -            
107.1128 -            return super.visitModifiers(node, p);
107.1129 -        }
107.1130 -
107.1131 -        @Override
107.1132 -        public Number visitNewArray(NewArrayTree node, Void p) {
107.1133 -            List<? extends ExpressionTree> dimensions = (List<? extends ExpressionTree>) resolveMultiParameters(node.getDimensions());
107.1134 -            List<? extends ExpressionTree> initializers = (List<? extends ExpressionTree>) resolveMultiParameters(node.getInitializers());
107.1135 -            NewArrayTree nue = make.NewArray(node.getType(), dimensions, initializers);
107.1136 -
107.1137 -            rewrite(node, nue);
107.1138 -            return super.visitNewArray(node, p);
107.1139 -        }
107.1140 -
107.1141 -        @Override
107.1142 -        public Number visitLambdaExpression(LambdaExpressionTree node, Void p) {
107.1143 -            List<? extends VariableTree> args = resolveMultiParameters(node.getParameters());
107.1144 -            LambdaExpressionTree nue = make.LambdaExpression(args, node.getBody());
107.1145 -
107.1146 -            rewrite(node, nue);
107.1147 -
107.1148 -            return super.visitLambdaExpression(node, p);
107.1149 -        }
107.1150 -
107.1151 -        @Override
107.1152 -        public Number visitAnnotation(AnnotationTree node, Void p) {
107.1153 -            List<? extends ExpressionTree> args = resolveMultiParameters(node.getArguments());
107.1154 -            AnnotationTree nue = make.Annotation(node.getAnnotationType(), args);
107.1155 -
107.1156 -            rewrite(node, nue);
107.1157 -
107.1158 -            return super.visitAnnotation(node, p);
107.1159 -        }
107.1160 -
107.1161 -        private <T extends Tree> List<T> resolveMultiParameters(List<T> list) {
107.1162 -            if (list == null) return null;
107.1163 -            if (!Utilities.containsMultistatementTrees(list)) return list;
107.1164 -
107.1165 -            List<T> result = new LinkedList<T>();
107.1166 -
107.1167 -            for (T t : list) {
107.1168 -                if (Utilities.isMultistatementWildcardTree(t)) {
107.1169 -                    Collection<TreePath> embedded = parametersMulti.get(Utilities.getWildcardTreeName(t).toString());
107.1170 -
107.1171 -                    if (embedded != null) {
107.1172 -                        for (TreePath tp : embedded) {
107.1173 -                            result.add((T) tp.getLeaf());
107.1174 -                        }
107.1175 -                    }
107.1176 -                } else {
107.1177 -                    result.add(t);
107.1178 -                }
107.1179 -            }
107.1180 -
107.1181 -            return result;
107.1182 -        }
107.1183 -        
107.1184 -        private <T extends Tree> T resolveOptionalValue(T in) {
107.1185 -            if (in != null && Utilities.isMultistatementWildcardTree(in)) {
107.1186 -                TreePath out = parameters.get(Utilities.getWildcardTreeName(in).toString());
107.1187 -                if (out != null) return (T) out.getLeaf();
107.1188 -                return null;
107.1189 -            }
107.1190 -            
107.1191 -            return in;
107.1192 -        }
107.1193 -
107.1194 -        private ExpressionTree negate(ExpressionTree original, Tree parent, boolean nullOnPlainNeg) {
107.1195 -            ExpressionTree newTree;
107.1196 -            switch (original.getKind()) {
107.1197 -                case PARENTHESIZED:
107.1198 -                    ExpressionTree expr = ((ParenthesizedTree) original).getExpression();
107.1199 -                    return make.Parenthesized(negate(expr, original, nullOnPlainNeg));
107.1200 -                case LOGICAL_COMPLEMENT:
107.1201 -                    newTree = ((UnaryTree) original).getExpression();
107.1202 -                    while (newTree.getKind() == Kind.PARENTHESIZED && !JavaFixUtilities.requiresParenthesis(((ParenthesizedTree) newTree).getExpression(), original, parent)) {
107.1203 -                        newTree = ((ParenthesizedTree) newTree).getExpression();
107.1204 -                    }
107.1205 -                    break;
107.1206 -                case NOT_EQUAL_TO:
107.1207 -                    newTree = negateBinaryOperator(original, Kind.EQUAL_TO, false);
107.1208 -                    break;
107.1209 -                case EQUAL_TO:
107.1210 -                    newTree = negateBinaryOperator(original, Kind.NOT_EQUAL_TO, false);
107.1211 -                    break;
107.1212 -                case BOOLEAN_LITERAL:
107.1213 -                    newTree = make.Literal(!(Boolean) ((LiteralTree) original).getValue());
107.1214 -                    break;
107.1215 -                case CONDITIONAL_AND:
107.1216 -                    newTree = negateBinaryOperator(original, Kind.CONDITIONAL_OR, true);
107.1217 -                    break;
107.1218 -                case CONDITIONAL_OR:
107.1219 -                    newTree = negateBinaryOperator(original, Kind.CONDITIONAL_AND, true);
107.1220 -                    break;
107.1221 -                case LESS_THAN:
107.1222 -                    newTree = negateBinaryOperator(original, Kind.GREATER_THAN_EQUAL, false);
107.1223 -                    break;
107.1224 -                case LESS_THAN_EQUAL:
107.1225 -                    newTree = negateBinaryOperator(original, Kind.GREATER_THAN, false);
107.1226 -                    break;
107.1227 -                case GREATER_THAN:
107.1228 -                    newTree = negateBinaryOperator(original, Kind.LESS_THAN_EQUAL, false);
107.1229 -                    break;
107.1230 -                case GREATER_THAN_EQUAL:
107.1231 -                    newTree = negateBinaryOperator(original, Kind.LESS_THAN, false);
107.1232 -                    break;
107.1233 -                default:
107.1234 -                    if (nullOnPlainNeg)
107.1235 -                        return null;
107.1236 -                    newTree = make.Unary(Kind.LOGICAL_COMPLEMENT, original);
107.1237 -            }
107.1238 -         
107.1239 -            if (JavaFixUtilities.requiresParenthesis(newTree, original, parent)) {
107.1240 -                newTree = make.Parenthesized(newTree);
107.1241 -            }
107.1242 -            
107.1243 -            return newTree;
107.1244 -        }
107.1245 -        
107.1246 -        private ExpressionTree negateBinaryOperator(Tree original, Kind newKind, boolean negateOperands) {
107.1247 -            BinaryTree bt = (BinaryTree) original;
107.1248 -            BinaryTree nonNegated = make.Binary(newKind,
107.1249 -                                                bt.getLeftOperand(),
107.1250 -                                                bt.getRightOperand());
107.1251 -            if (negateOperands) {
107.1252 -                ExpressionTree lo = negate(bt.getLeftOperand(), nonNegated, false);
107.1253 -                ExpressionTree ro = negate(bt.getRightOperand(), nonNegated, false);
107.1254 -                return make.Binary(newKind,
107.1255 -                                   lo != null ? lo : bt.getLeftOperand(),
107.1256 -                                   ro != null ? ro : bt.getRightOperand());
107.1257 -            }
107.1258 -            return nonNegated;
107.1259 -        }
107.1260 -        
107.1261 -        private void rewrite(Tree from, Tree to) {
107.1262 -            if (originalTrees.contains(from)) return ;
107.1263 -            rewriteFromTo.put(from, to);
107.1264 -        }
107.1265 -    }
107.1266 -
107.1267 -    private static final Map<Kind, Integer> OPERATOR_PRIORITIES;
107.1268 -
107.1269 -    static {
107.1270 -        OPERATOR_PRIORITIES = new EnumMap<Kind, Integer>(Kind.class);
107.1271 -
107.1272 -        OPERATOR_PRIORITIES.put(Kind.IDENTIFIER, 0);
107.1273 -
107.1274 -        for (Kind k : Kind.values()) {
107.1275 -            if (k.asInterface() == LiteralTree.class) {
107.1276 -                OPERATOR_PRIORITIES.put(k, 0);
107.1277 -            }
107.1278 -        }
107.1279 -
107.1280 -        OPERATOR_PRIORITIES.put(Kind.ARRAY_ACCESS, 1);
107.1281 -        OPERATOR_PRIORITIES.put(Kind.METHOD_INVOCATION, 1);
107.1282 -        OPERATOR_PRIORITIES.put(Kind.MEMBER_SELECT, 1);
107.1283 -        OPERATOR_PRIORITIES.put(Kind.POSTFIX_DECREMENT, 1);
107.1284 -        OPERATOR_PRIORITIES.put(Kind.POSTFIX_INCREMENT, 1);
107.1285 -        OPERATOR_PRIORITIES.put(Kind.NEW_ARRAY, 1);
107.1286 -        OPERATOR_PRIORITIES.put(Kind.NEW_CLASS, 1);
107.1287 -
107.1288 -        OPERATOR_PRIORITIES.put(Kind.BITWISE_COMPLEMENT, 2);
107.1289 -        OPERATOR_PRIORITIES.put(Kind.LOGICAL_COMPLEMENT, 2);
107.1290 -        OPERATOR_PRIORITIES.put(Kind.PREFIX_DECREMENT, 2);
107.1291 -        OPERATOR_PRIORITIES.put(Kind.PREFIX_INCREMENT, 2);
107.1292 -        OPERATOR_PRIORITIES.put(Kind.UNARY_MINUS, 2);
107.1293 -        OPERATOR_PRIORITIES.put(Kind.UNARY_PLUS, 2);
107.1294 -
107.1295 -        OPERATOR_PRIORITIES.put(Kind.TYPE_CAST, 3);
107.1296 -
107.1297 -        OPERATOR_PRIORITIES.put(Kind.DIVIDE, 4);
107.1298 -        OPERATOR_PRIORITIES.put(Kind.MULTIPLY, 4);
107.1299 -        OPERATOR_PRIORITIES.put(Kind.REMAINDER, 4);
107.1300 -
107.1301 -        OPERATOR_PRIORITIES.put(Kind.MINUS, 5);
107.1302 -        OPERATOR_PRIORITIES.put(Kind.PLUS, 5);
107.1303 -
107.1304 -        OPERATOR_PRIORITIES.put(Kind.LEFT_SHIFT, 6);
107.1305 -        OPERATOR_PRIORITIES.put(Kind.RIGHT_SHIFT, 6);
107.1306 -        OPERATOR_PRIORITIES.put(Kind.UNSIGNED_RIGHT_SHIFT, 6);
107.1307 -
107.1308 -        OPERATOR_PRIORITIES.put(Kind.INSTANCE_OF, 7);
107.1309 -        OPERATOR_PRIORITIES.put(Kind.GREATER_THAN, 7);
107.1310 -        OPERATOR_PRIORITIES.put(Kind.GREATER_THAN_EQUAL, 7);
107.1311 -        OPERATOR_PRIORITIES.put(Kind.LESS_THAN, 7);
107.1312 -        OPERATOR_PRIORITIES.put(Kind.LESS_THAN_EQUAL, 7);
107.1313 -
107.1314 -        OPERATOR_PRIORITIES.put(Kind.EQUAL_TO, 8);
107.1315 -        OPERATOR_PRIORITIES.put(Kind.NOT_EQUAL_TO, 8);
107.1316 -
107.1317 -        OPERATOR_PRIORITIES.put(Kind.AND, 9);
107.1318 -        OPERATOR_PRIORITIES.put(Kind.OR, 11);
107.1319 -        OPERATOR_PRIORITIES.put(Kind.XOR, 10);
107.1320 -
107.1321 -        OPERATOR_PRIORITIES.put(Kind.CONDITIONAL_AND, 12);
107.1322 -        OPERATOR_PRIORITIES.put(Kind.CONDITIONAL_OR, 13);
107.1323 -
107.1324 -        OPERATOR_PRIORITIES.put(Kind.CONDITIONAL_EXPRESSION, 14);
107.1325 -
107.1326 -        OPERATOR_PRIORITIES.put(Kind.AND_ASSIGNMENT, 15);
107.1327 -        OPERATOR_PRIORITIES.put(Kind.ASSIGNMENT, 15);
107.1328 -        OPERATOR_PRIORITIES.put(Kind.DIVIDE_ASSIGNMENT, 15);
107.1329 -        OPERATOR_PRIORITIES.put(Kind.LEFT_SHIFT_ASSIGNMENT, 15);
107.1330 -        OPERATOR_PRIORITIES.put(Kind.MINUS_ASSIGNMENT, 15);
107.1331 -        OPERATOR_PRIORITIES.put(Kind.MULTIPLY_ASSIGNMENT, 15);
107.1332 -        OPERATOR_PRIORITIES.put(Kind.OR_ASSIGNMENT, 15);
107.1333 -        OPERATOR_PRIORITIES.put(Kind.PLUS_ASSIGNMENT, 15);
107.1334 -        OPERATOR_PRIORITIES.put(Kind.REMAINDER_ASSIGNMENT, 15);
107.1335 -        OPERATOR_PRIORITIES.put(Kind.RIGHT_SHIFT_ASSIGNMENT, 15);
107.1336 -        OPERATOR_PRIORITIES.put(Kind.UNSIGNED_RIGHT_SHIFT_ASSIGNMENT, 15);
107.1337 -        OPERATOR_PRIORITIES.put(Kind.XOR_ASSIGNMENT, 15);
107.1338 -    }
107.1339 -
107.1340 -    /**Checks whether putting {@code inner} tree into {@code outter} tree,
107.1341 -     * when {@code original} is being replaced with {@code inner} requires parentheses.
107.1342 -     *
107.1343 -     * @param inner    the new tree node that will be placed under {@code outter}
107.1344 -     * @param original the tree node that is being replaced with {@code inner}
107.1345 -     * @param outter   the future parent node of {@code inner}
107.1346 -     * @return true if and only if inner needs to be wrapped using {@link TreeMaker#Parenthesized(com.sun.source.tree.ExpressionTree) }
107.1347 -     *              to keep the original meaning.
107.1348 -     */
107.1349 -    public static boolean requiresParenthesis(Tree inner, Tree original, Tree outter) {
107.1350 -        if (!ExpressionTree.class.isAssignableFrom(inner.getKind().asInterface())) return false;
107.1351 -        if (!ExpressionTree.class.isAssignableFrom(outter.getKind().asInterface())) return false;
107.1352 -
107.1353 -        if (outter.getKind() == Kind.PARENTHESIZED || inner.getKind() == Kind.PARENTHESIZED) return false;
107.1354 -
107.1355 -        if (outter.getKind() == Kind.METHOD_INVOCATION) {
107.1356 -            if (((MethodInvocationTree) outter).getArguments().contains(original)) return false;
107.1357 -        }
107.1358 -
107.1359 -        if (outter.getKind() == Kind.NEW_CLASS) {
107.1360 -            if (((NewClassTree) outter).getArguments().contains(original)) return false;
107.1361 -        }
107.1362 -
107.1363 -        Integer innerPriority = OPERATOR_PRIORITIES.get(inner.getKind());
107.1364 -        Integer outterPriority = OPERATOR_PRIORITIES.get(outter.getKind());
107.1365 -
107.1366 -        if (innerPriority == null || outterPriority == null) {
107.1367 -            Logger.getLogger(JavaFix.class.getName()).log(Level.WARNING, "Unknown tree kind(s): {0}/{1}", new Object[] {inner.getKind(), outter.getKind()});
107.1368 -            return true;
107.1369 -        }
107.1370 -
107.1371 -        if (innerPriority > outterPriority) {
107.1372 -            return true;
107.1373 -        }
107.1374 -
107.1375 -        if (innerPriority < outterPriority) {
107.1376 -            return false;
107.1377 -        }
107.1378 -
107.1379 -        //associativity
107.1380 -        if (BinaryTree.class.isAssignableFrom(outter.getKind().asInterface())) {
107.1381 -            BinaryTree ot = (BinaryTree) outter;
107.1382 -
107.1383 -            //TODO: for + it might be possible to skip the parenthesis:
107.1384 -            return ot.getRightOperand() == original;
107.1385 -        }
107.1386 -
107.1387 -        if (CompoundAssignmentTree.class.isAssignableFrom(outter.getKind().asInterface())) {
107.1388 -            CompoundAssignmentTree ot = (CompoundAssignmentTree) outter;
107.1389 -
107.1390 -            return ot.getVariable() == original;
107.1391 -        }
107.1392 -
107.1393 -        if (AssignmentTree.class.isAssignableFrom(outter.getKind().asInterface())) {
107.1394 -            AssignmentTree ot = (AssignmentTree) outter;
107.1395 -
107.1396 -            return ot.getVariable() == original;
107.1397 -        }
107.1398 -
107.1399 -        return false;
107.1400 -    }
107.1401 -
107.1402 -    private static final class RemoveFromParent extends JavaFix {
107.1403 -
107.1404 -        private final String displayName;
107.1405 -
107.1406 -        public RemoveFromParent(String displayName, CompilationInfo info, TreePath toRemove) {
107.1407 -            super(info, toRemove);
107.1408 -            this.displayName = displayName;
107.1409 -        }
107.1410 -
107.1411 -        @Override
107.1412 -        protected String getText() {
107.1413 -            return displayName;
107.1414 -        }
107.1415 -
107.1416 -        @Override
107.1417 -        protected void performRewrite(TransformationContext ctx) {
107.1418 -            WorkingCopy wc = ctx.getWorkingCopy();
107.1419 -            TreePath tp = ctx.getPath();
107.1420 -            
107.1421 -            doRemoveFromParent(wc, tp);
107.1422 -        }
107.1423 -        
107.1424 -        private void doRemoveFromParent(WorkingCopy wc, TreePath what) {
107.1425 -            TreeMaker make = wc.getTreeMaker();
107.1426 -            Tree leaf = what.getLeaf();
107.1427 -            Tree parentLeaf = what.getParentPath().getLeaf();
107.1428 -
107.1429 -            switch (parentLeaf.getKind()) {
107.1430 -                case ANNOTATION:
107.1431 -                    AnnotationTree at = (AnnotationTree) parentLeaf;
107.1432 -                    AnnotationTree newAnnot;
107.1433 -
107.1434 -                    newAnnot = make.removeAnnotationAttrValue(at, (ExpressionTree) leaf);
107.1435 -
107.1436 -                    wc.rewrite(at, newAnnot);
107.1437 -                    break;
107.1438 -                case BLOCK:
107.1439 -                    BlockTree bt = (BlockTree) parentLeaf;
107.1440 -
107.1441 -                    wc.rewrite(bt, make.removeBlockStatement(bt, (StatementTree) leaf));
107.1442 -                    break;
107.1443 -                case CASE:
107.1444 -                    CaseTree caseTree = (CaseTree) parentLeaf;
107.1445 -
107.1446 -                    wc.rewrite(caseTree, make.removeCaseStatement(caseTree, (StatementTree) leaf));
107.1447 -                    break;
107.1448 -                case CLASS:
107.1449 -                    ClassTree classTree = (ClassTree) parentLeaf;
107.1450 -                    ClassTree nueClassTree;
107.1451 -
107.1452 -                    if (classTree.getTypeParameters().contains(leaf)) {
107.1453 -                        nueClassTree = make.removeClassTypeParameter(classTree, (TypeParameterTree) leaf);
107.1454 -                    } else if (classTree.getExtendsClause() == leaf) {
107.1455 -                        nueClassTree = make.Class(classTree.getModifiers(), classTree.getSimpleName(), classTree.getTypeParameters(), null, classTree.getImplementsClause(), classTree.getMembers());
107.1456 -                    } else if (classTree.getImplementsClause().contains(leaf)) {
107.1457 -                        nueClassTree = make.removeClassImplementsClause(classTree, leaf);
107.1458 -                    } else if (classTree.getMembers().contains(leaf)) {
107.1459 -                        nueClassTree = make.removeClassMember(classTree, leaf);
107.1460 -                    } else {
107.1461 -                        throw new UnsupportedOperationException();
107.1462 -                    }
107.1463 -
107.1464 -                    wc.rewrite(classTree, nueClassTree);
107.1465 -                    break;
107.1466 -                case UNION_TYPE:
107.1467 -                    UnionTypeTree disjunct = (UnionTypeTree) parentLeaf;
107.1468 -                    List<? extends Tree> alternatives = new LinkedList<Tree>(disjunct.getTypeAlternatives());
107.1469 -
107.1470 -                    alternatives.remove(leaf);
107.1471 -
107.1472 -                    wc.rewrite(disjunct, make.UnionType(alternatives));
107.1473 -                    break;
107.1474 -                case METHOD:
107.1475 -                    MethodTree mTree = (MethodTree) parentLeaf;
107.1476 -                    MethodTree newMethod;
107.1477 -
107.1478 -                    if (mTree.getTypeParameters().contains(leaf)) {
107.1479 -                        newMethod = make.removeMethodTypeParameter(mTree, (TypeParameterTree) leaf);
107.1480 -                    } else if (mTree.getParameters().contains(leaf)) {
107.1481 -                        newMethod = make.removeMethodParameter(mTree, (VariableTree) leaf);
107.1482 -                    } else if (mTree.getThrows().contains(leaf)) {
107.1483 -                        newMethod = make.removeMethodThrows(mTree, (ExpressionTree) leaf);
107.1484 -                    } else {
107.1485 -                        throw new UnsupportedOperationException();
107.1486 -                    }
107.1487 -
107.1488 -                    wc.rewrite(mTree, newMethod);
107.1489 -                    break;
107.1490 -                case METHOD_INVOCATION:
107.1491 -                    MethodInvocationTree iTree = (MethodInvocationTree) parentLeaf;
107.1492 -                    MethodInvocationTree newInvocation;
107.1493 -
107.1494 -                    if (iTree.getTypeArguments().contains(leaf)) {
107.1495 -                        newInvocation = make.removeMethodInvocationTypeArgument(iTree, (ExpressionTree) leaf);
107.1496 -                    } else if (iTree.getArguments().contains(leaf)) {
107.1497 -                        newInvocation = make.removeMethodInvocationArgument(iTree, (ExpressionTree) leaf);
107.1498 -                    } else {
107.1499 -                        throw new UnsupportedOperationException();
107.1500 -                    }
107.1501 -
107.1502 -                    wc.rewrite(iTree, newInvocation);
107.1503 -                    break;
107.1504 -                case MODIFIERS:
107.1505 -                    ModifiersTree modsTree = (ModifiersTree) parentLeaf;
107.1506 -
107.1507 -                    wc.rewrite(modsTree, make.removeModifiersAnnotation(modsTree, (AnnotationTree) leaf));
107.1508 -                    break;
107.1509 -                case NEW_CLASS:
107.1510 -                    NewClassTree newCTree = (NewClassTree) parentLeaf;
107.1511 -                    NewClassTree newNCT;
107.1512 -
107.1513 -                    if (newCTree.getTypeArguments().contains(leaf)) {
107.1514 -                        newNCT = make.removeNewClassTypeArgument(newCTree, (ExpressionTree) leaf);
107.1515 -                    } else if (newCTree.getArguments().contains(leaf)) {
107.1516 -                        newNCT = make.removeNewClassArgument(newCTree, (ExpressionTree) leaf);
107.1517 -                    } else {
107.1518 -                        throw new UnsupportedOperationException();
107.1519 -                    }
107.1520 -
107.1521 -                    wc.rewrite(newCTree, newNCT);
107.1522 -                    break;
107.1523 -                case PARAMETERIZED_TYPE:
107.1524 -                    ParameterizedTypeTree parTree = (ParameterizedTypeTree) parentLeaf;
107.1525 -
107.1526 -                    wc.rewrite(parTree, make.removeParameterizedTypeTypeArgument(parTree, (ExpressionTree) leaf));
107.1527 -                    break;
107.1528 -                case SWITCH:
107.1529 -                    SwitchTree switchTree = (SwitchTree) parentLeaf;
107.1530 -                    SwitchTree newSwitch;
107.1531 -
107.1532 -                    if (switchTree.getCases().contains(leaf)) {
107.1533 -                        newSwitch = make.removeSwitchCase(switchTree, (CaseTree) leaf);
107.1534 -                    } else {
107.1535 -                        throw new UnsupportedOperationException();
107.1536 -                    }
107.1537 -
107.1538 -                    wc.rewrite(switchTree, newSwitch);
107.1539 -                    break;
107.1540 -                case TRY:
107.1541 -                    TryTree tryTree = (TryTree) parentLeaf;
107.1542 -                    TryTree newTry;
107.1543 -
107.1544 -                    if (tryTree.getResources().contains(leaf)) {
107.1545 -                        LinkedList<Tree> resources = new LinkedList<Tree>(tryTree.getResources());
107.1546 -
107.1547 -                        resources.remove(leaf);
107.1548 -
107.1549 -                        newTry = make.Try(resources, tryTree.getBlock(), tryTree.getCatches(), tryTree.getFinallyBlock());
107.1550 -                    } else if (tryTree.getCatches().contains(leaf)) {
107.1551 -                        newTry = make.removeTryCatch(tryTree, (CatchTree) leaf);
107.1552 -                    } else {
107.1553 -                        throw new UnsupportedOperationException();
107.1554 -                    }
107.1555 -
107.1556 -                    wc.rewrite(tryTree, newTry);
107.1557 -                    break;
107.1558 -                case EXPRESSION_STATEMENT:
107.1559 -                    doRemoveFromParent(wc, what.getParentPath());
107.1560 -                    break;
107.1561 -                default:
107.1562 -                    wc.rewrite(what.getLeaf(), make.Block(Collections.<StatementTree>emptyList(), false));
107.1563 -                    break;
107.1564 -            }
107.1565 -        }
107.1566 -
107.1567 -    }
107.1568 -
107.1569 -    //TODO: from FileMovePlugin
107.1570 -    private static class MoveFile extends SimpleRefactoringElementImplementation {
107.1571 -
107.1572 -        private FileObject toMove;
107.1573 -        private final FileObject sourceRoot;
107.1574 -        private final String targetFolderName;
107.1575 -
107.1576 -        public MoveFile(FileObject toMove, FileObject sourceRoot, String targetFolderName) {
107.1577 -            this.toMove = toMove;
107.1578 -            this.sourceRoot = sourceRoot;
107.1579 -            this.targetFolderName = targetFolderName;
107.1580 -        }
107.1581 -
107.1582 -        @Override
107.1583 -        @Messages({"#{0} - original file name", "TXT_MoveFile=Move {0}"})
107.1584 -        public String getText() {
107.1585 -            return Bundle.TXT_MoveFile(toMove.getNameExt());
107.1586 -        }
107.1587 -
107.1588 -        @Override
107.1589 -        public String getDisplayText() {
107.1590 -            return getText();
107.1591 -        }
107.1592 -
107.1593 -        DataFolder sourceFolder;
107.1594 -        DataObject source;
107.1595 -        @Override
107.1596 -        public void performChange() {
107.1597 -            try {
107.1598 -                FileObject target = FileUtil.createFolder(sourceRoot, targetFolderName);
107.1599 -                DataFolder targetFolder = DataFolder.findFolder(target);
107.1600 -                if (!toMove.isValid()) {
107.1601 -                    String path = FileUtil.getFileDisplayName(toMove);
107.1602 -                    Logger.getLogger(JavaFix.class.getName()).fine("Invalid FileObject " + path + "trying to recreate...");
107.1603 -                    toMove = FileUtil.toFileObject(FileUtil.toFile(toMove));
107.1604 -                    if (toMove==null) {
107.1605 -                        Logger.getLogger(JavaFix.class.getName()).severe("Invalid FileObject " + path + "\n. File not found.");
107.1606 -                        return;
107.1607 -                    }
107.1608 -                }
107.1609 -                source = DataObject.find(toMove);
107.1610 -                sourceFolder = source.getFolder();
107.1611 -                source.move(targetFolder);
107.1612 -            } catch (DataObjectNotFoundException ex) {
107.1613 -                ex.printStackTrace();
107.1614 -            } catch (IOException ex) {
107.1615 -                ex.printStackTrace();
107.1616 -            }
107.1617 -        }
107.1618 -
107.1619 -        @Override
107.1620 -        public void undoChange() {
107.1621 -            try {
107.1622 -                source.move(sourceFolder);
107.1623 -            } catch (DataObjectNotFoundException ex) {
107.1624 -                ex.printStackTrace();
107.1625 -            } catch (IOException ex) {
107.1626 -                ex.printStackTrace();
107.1627 -            }
107.1628 -        }
107.1629 -
107.1630 -        @Override
107.1631 -        public Lookup getLookup() {
107.1632 -            return Lookup.EMPTY;
107.1633 -        }
107.1634 -
107.1635 -        @Override
107.1636 -        public FileObject getParentFile() {
107.1637 -            return toMove;
107.1638 -        }
107.1639 -
107.1640 -        @Override
107.1641 -        public PositionBounds getPosition() {
107.1642 -            return null;
107.1643 -        }
107.1644 -    }
107.1645 -}
   108.1 --- a/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/MatcherUtilities.java	Sun Oct 16 08:01:27 2016 +0200
   108.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   108.3 @@ -1,157 +0,0 @@
   108.4 -/*
   108.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   108.6 - *
   108.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
   108.8 - *
   108.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  108.10 - * Other names may be trademarks of their respective owners.
  108.11 - *
  108.12 - * The contents of this file are subject to the terms of either the GNU
  108.13 - * General Public License Version 2 only ("GPL") or the Common
  108.14 - * Development and Distribution License("CDDL") (collectively, the
  108.15 - * "License"). You may not use this file except in compliance with the
  108.16 - * License. You can obtain a copy of the License at
  108.17 - * http://www.netbeans.org/cddl-gplv2.html
  108.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  108.19 - * specific language governing permissions and limitations under the
  108.20 - * License.  When distributing the software, include this License Header
  108.21 - * Notice in each file and include the License file at
  108.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  108.23 - * particular file as subject to the "Classpath" exception as provided
  108.24 - * by Oracle in the GPL Version 2 section of the License file that
  108.25 - * accompanied this code. If applicable, add the following below the
  108.26 - * License Header, with the fields enclosed by brackets [] replaced by
  108.27 - * your own identifying information:
  108.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  108.29 - *
  108.30 - * If you wish your version of this file to be governed by only the CDDL
  108.31 - * or only the GPL Version 2, indicate your decision by adding
  108.32 - * "[Contributor] elects to include this software in this distribution
  108.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  108.34 - * single choice of license, a recipient has the option to distribute
  108.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  108.36 - * to extend the choice of license to its licensees as provided above.
  108.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  108.38 - * Version 2 license, then the option applies only if the new code is
  108.39 - * made subject to such option by the copyright holder.
  108.40 - *
  108.41 - * Contributor(s):
  108.42 - *
  108.43 - * Portions Copyrighted 2009 Sun Microsystems, Inc.
  108.44 - */
  108.45 -
  108.46 -package org.netbeans.spi.java.hints;
  108.47 -
  108.48 -import com.sun.source.tree.BlockTree;
  108.49 -import com.sun.source.tree.Scope;
  108.50 -import com.sun.source.tree.StatementTree;
  108.51 -import com.sun.source.tree.Tree;
  108.52 -import com.sun.source.util.TreePath;
  108.53 -import java.util.Collection;
  108.54 -import java.util.Collections;
  108.55 -import java.util.HashMap;
  108.56 -import java.util.Iterator;
  108.57 -import java.util.List;
  108.58 -import java.util.Map;
  108.59 -import java.util.concurrent.atomic.AtomicBoolean;
  108.60 -import javax.lang.model.type.TypeMirror;
  108.61 -import org.netbeans.api.annotations.common.NonNull;
  108.62 -import org.netbeans.modules.java.hints.spiimpl.Utilities;
  108.63 -import org.netbeans.modules.java.hints.spiimpl.pm.PatternCompiler;
  108.64 -import org.netbeans.api.java.source.matching.Matcher;
  108.65 -import org.netbeans.api.java.source.matching.Occurrence;
  108.66 -import org.netbeans.api.java.source.matching.Pattern;
  108.67 -
  108.68 -/**XXX: cancelability
  108.69 - * TODO: needed?
  108.70 - *
  108.71 - * @author lahvac
  108.72 - */
  108.73 -public class MatcherUtilities {
  108.74 -
  108.75 -    public static boolean matches(@NonNull HintContext ctx, @NonNull TreePath variable, @NonNull String pattern) {
  108.76 -        return matches(ctx, variable, pattern, null, null, null);
  108.77 -    }
  108.78 -
  108.79 -    public static boolean matches(@NonNull HintContext ctx, @NonNull TreePath variable, @NonNull String pattern, boolean fillInVariablesHack) {
  108.80 -        return matches(ctx, variable, pattern, ctx.getVariables(), ctx.getMultiVariables(), ctx.getVariableNames());
  108.81 -    }
  108.82 -
  108.83 -    public static boolean matches(@NonNull HintContext ctx, @NonNull TreePath variable, @NonNull String pattern, Map<String, TreePath> outVariables, Map<String, Collection<? extends TreePath>> outMultiVariables, Map<String, String> outVariables2Names) {
  108.84 -        Pattern p = PatternCompiler.compile(ctx.getInfo(), pattern, Collections.<String, TypeMirror>emptyMap(), Collections.<String>emptyList());
  108.85 -        Map<String, TreePath> variables = new HashMap<String, TreePath>(ctx.getVariables());
  108.86 -        Map<String, Collection<? extends TreePath>> multiVariables = new HashMap<String, Collection<? extends TreePath>>(ctx.getMultiVariables());
  108.87 -        Map<String, String> variables2Names = new HashMap<String, String>(ctx.getVariableNames());
  108.88 -        Iterable<? extends Occurrence> occurrences = Matcher.create(ctx.getInfo()).setCancel(new AtomicBoolean()).setPresetVariable(variables, multiVariables, variables2Names).setSearchRoot(variable).setTreeTopSearch().match(p);
  108.89 -
  108.90 -        if (occurrences.iterator().hasNext()) {
  108.91 -            Occurrence od = occurrences.iterator().next();
  108.92 -            outVariables(outVariables, od.getVariables(), ctx.getVariables());
  108.93 -            outVariables(outMultiVariables, od.getMultiVariables(), ctx.getMultiVariables());
  108.94 -            outVariables(outVariables2Names, od.getVariables2Names(), ctx.getVariableNames());
  108.95 -
  108.96 -            return true;
  108.97 -        }
  108.98 -
  108.99 -        return false;
 108.100 -    }
 108.101 -
 108.102 -    public static boolean matches(@NonNull HintContext ctx, @NonNull Collection<? extends TreePath> variable, @NonNull String pattern, Map<String, TreePath> outVariables, Map<String, Collection<? extends TreePath>> outMultiVariables, Map<String, String> outVariables2Names) {
 108.103 -        Scope s = Utilities.constructScope(ctx.getInfo(), Collections.<String, TypeMirror>emptyMap());
 108.104 -        Tree  patternTree = Utilities.parseAndAttribute(ctx.getInfo(), pattern, s);
 108.105 -        List<? extends Tree> patternTrees;
 108.106 -
 108.107 -        if (Utilities.isFakeBlock(patternTree)) {
 108.108 -            List<? extends StatementTree> statements = ((BlockTree) patternTree).getStatements();
 108.109 -
 108.110 -            patternTrees = statements.subList(1, statements.size() - 1);
 108.111 -        } else {
 108.112 -            patternTrees = Collections.singletonList(patternTree);
 108.113 -        }
 108.114 -
 108.115 -        if (variable.size() != patternTrees.size()) return false;
 108.116 -        
 108.117 -        Map<String, TreePath> variables = new HashMap<String, TreePath>(ctx.getVariables());
 108.118 -        Map<String, Collection<? extends TreePath>> multiVariables = new HashMap<String, Collection<? extends TreePath>>(ctx.getMultiVariables());
 108.119 -        Map<String, String> variables2Names = new HashMap<String, String>(ctx.getVariableNames());
 108.120 -        Iterator<? extends TreePath> variableIt = variable.iterator();
 108.121 -        Iterator<? extends Tree> patternTreesIt = patternTrees.iterator();
 108.122 -
 108.123 -        while (variableIt.hasNext() && patternTreesIt.hasNext()) {
 108.124 -            TreePath patternTreePath = new TreePath(new TreePath(ctx.getInfo().getCompilationUnit()), patternTreesIt.next());
 108.125 -            Pattern p = Pattern.createPatternWithFreeVariables(patternTreePath, Collections.<String, TypeMirror>emptyMap());
 108.126 -            Iterable<? extends Occurrence> occurrences = Matcher.create(ctx.getInfo()).setCancel(new AtomicBoolean()).setPresetVariable(variables, multiVariables, variables2Names).setSearchRoot(variableIt.next()).setTreeTopSearch().match(p);
 108.127 -
 108.128 -            if (!occurrences.iterator().hasNext()) {
 108.129 -                return false;
 108.130 -            }
 108.131 -
 108.132 -            Occurrence od = occurrences.iterator().next();
 108.133 -
 108.134 -            variables = od.getVariables();
 108.135 -            multiVariables = od.getMultiVariables();
 108.136 -            variables2Names = od.getVariables2Names();
 108.137 -        }
 108.138 -
 108.139 -        if (variableIt.hasNext() == patternTreesIt.hasNext()) {
 108.140 -            outVariables(outVariables, variables, ctx.getVariables());
 108.141 -            outVariables(outMultiVariables, multiVariables, ctx.getMultiVariables());
 108.142 -            outVariables(outVariables2Names, variables2Names, ctx.getVariableNames());
 108.143 -
 108.144 -            return true;
 108.145 -        }
 108.146 -
 108.147 -        return false;
 108.148 -    }
 108.149 -
 108.150 -    private static <T> void outVariables(Map<String, T> outMap, Map<String, T> currentValues, Map<String, T> origValues) {
 108.151 -        if (outMap == null) return;
 108.152 -
 108.153 -        for (String key : origValues.keySet()) {
 108.154 -            currentValues.remove(key);
 108.155 -        }
 108.156 -
 108.157 -        outMap.putAll(currentValues);
 108.158 -    }
 108.159 -
 108.160 -}
   109.1 --- a/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/TriggerDecision.java	Sun Oct 16 08:01:27 2016 +0200
   109.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   109.3 @@ -1,59 +0,0 @@
   109.4 -/*
   109.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   109.6 - *
   109.7 - * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
   109.8 - *
   109.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  109.10 - * Other names may be trademarks of their respective owners.
  109.11 - *
  109.12 - * The contents of this file are subject to the terms of either the GNU
  109.13 - * General Public License Version 2 only ("GPL") or the Common
  109.14 - * Development and Distribution License("CDDL") (collectively, the
  109.15 - * "License"). You may not use this file except in compliance with the
  109.16 - * License. You can obtain a copy of the License at
  109.17 - * http://www.netbeans.org/cddl-gplv2.html
  109.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  109.19 - * specific language governing permissions and limitations under the
  109.20 - * License.  When distributing the software, include this License Header
  109.21 - * Notice in each file and include the License file at
  109.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  109.23 - * particular file as subject to the "Classpath" exception as provided
  109.24 - * by Oracle in the GPL Version 2 section of the License file that
  109.25 - * accompanied this code. If applicable, add the following below the
  109.26 - * License Header, with the fields enclosed by brackets [] replaced by
  109.27 - * your own identifying information:
  109.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  109.29 - *
  109.30 - * If you wish your version of this file to be governed by only the CDDL
  109.31 - * or only the GPL Version 2, indicate your decision by adding
  109.32 - * "[Contributor] elects to include this software in this distribution
  109.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  109.34 - * single choice of license, a recipient has the option to distribute
  109.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  109.36 - * to extend the choice of license to its licensees as provided above.
  109.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  109.38 - * Version 2 license, then the option applies only if the new code is
  109.39 - * made subject to such option by the copyright holder.
  109.40 - *
  109.41 - * Contributor(s):
  109.42 - *
  109.43 - * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
  109.44 - */
  109.45 -
  109.46 -package org.netbeans.spi.java.hints;
  109.47 -
  109.48 -import java.lang.annotation.ElementType;
  109.49 -import java.lang.annotation.Retention;
  109.50 -import java.lang.annotation.RetentionPolicy;
  109.51 -import java.lang.annotation.Target;
  109.52 -
  109.53 -/**
  109.54 - * @author lahvac
  109.55 - */
  109.56 -@Retention(RetentionPolicy.SOURCE)
  109.57 -@Target(ElementType.METHOD)
  109.58 -public @interface TriggerDecision {
  109.59 -
  109.60 -    public Class<? extends Decision<?, ?>> value();
  109.61 -
  109.62 -}
   110.1 --- a/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/TriggerPattern.java	Sun Oct 16 08:01:27 2016 +0200
   110.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   110.3 @@ -1,93 +0,0 @@
   110.4 -/*
   110.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   110.6 - *
   110.7 - * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
   110.8 - *
   110.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  110.10 - * Other names may be trademarks of their respective owners.
  110.11 - *
  110.12 - * The contents of this file are subject to the terms of either the GNU
  110.13 - * General Public License Version 2 only ("GPL") or the Common
  110.14 - * Development and Distribution License("CDDL") (collectively, the
  110.15 - * "License"). You may not use this file except in compliance with the
  110.16 - * License. You can obtain a copy of the License at
  110.17 - * http://www.netbeans.org/cddl-gplv2.html
  110.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  110.19 - * specific language governing permissions and limitations under the
  110.20 - * License.  When distributing the software, include this License Header
  110.21 - * Notice in each file and include the License file at
  110.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  110.23 - * particular file as subject to the "Classpath" exception as provided
  110.24 - * by Oracle in the GPL Version 2 section of the License file that
  110.25 - * accompanied this code. If applicable, add the following below the
  110.26 - * License Header, with the fields enclosed by brackets [] replaced by
  110.27 - * your own identifying information:
  110.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  110.29 - *
  110.30 - * If you wish your version of this file to be governed by only the CDDL
  110.31 - * or only the GPL Version 2, indicate your decision by adding
  110.32 - * "[Contributor] elects to include this software in this distribution
  110.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  110.34 - * single choice of license, a recipient has the option to distribute
  110.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  110.36 - * to extend the choice of license to its licensees as provided above.
  110.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  110.38 - * Version 2 license, then the option applies only if the new code is
  110.39 - * made subject to such option by the copyright holder.
  110.40 - *
  110.41 - * Contributor(s):
  110.42 - *
  110.43 - * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
  110.44 - */
  110.45 -
  110.46 -package org.netbeans.spi.java.hints;
  110.47 -
  110.48 -import java.lang.annotation.ElementType;
  110.49 -import java.lang.annotation.Retention;
  110.50 -import java.lang.annotation.RetentionPolicy;
  110.51 -import java.lang.annotation.Target;
  110.52 -import org.netbeans.spi.editor.hints.ErrorDescription;
  110.53 -
  110.54 -/**Find parts of the source code that satisfy the given pattern, and invoke the method
  110.55 - * that is annotated with this annotation.
  110.56 - *
  110.57 - * The method must be {@code public static}, the return type must either be assignable to
  110.58 - * {@link ErrorDescription} or to {@link Iterable}{@code <? extends }{@link ErrorDescription}{@code >}.
  110.59 - * Its sole parameter must be {@link HintContext}.
  110.60 - *
  110.61 - * @author lahvac
  110.62 - */
  110.63 -@Retention(RetentionPolicy.SOURCE)
  110.64 -@Target(ElementType.METHOD)
  110.65 -public @interface TriggerPattern {
  110.66 -
  110.67 -    /**
  110.68 -     * Pattern to match on.
  110.69 -     * The pattern consists of:
  110.70 -     * <ul>
  110.71 -     *     <li>a single Java expression</li>
  110.72 -     *     <li>a single Java statement</li>
  110.73 -     *     <li>multiple Java statements</li>
  110.74 -     *     <li>a Java field, method or class</li>
  110.75 -     * </ul>
  110.76 -     *
  110.77 -     * Variables (identifiers starting with {@code $}) can be used to replace part of the pattern.
  110.78 -     * During matching, the actual part of the AST that corresponds to the variable in the pattern
  110.79 -     * will be "bound" to the variable. Variables whose names that do not end with a {@code $} ("single" variables)
  110.80 -     * will be bound to exactly one AST node, whereas variables whose names end with a {@code $} ("multi" variables)
  110.81 -     * will be bound to any number of consecutive AST nodes (with the same AST node as a parent).
  110.82 -     *
  110.83 -     * The actual AST nodes that were bound to single variables are available through {@link HintContext#getVariables() },
  110.84 -     * nodes bound to multi variables are available through {@link HintContext#getMultiVariables() }.
  110.85 -     *
  110.86 -     * For variables that represent an expression, a type constraint can be specified using the
  110.87 -     * {@link #constraints() } attribute.
  110.88 -     *
  110.89 -     * All classes should be referred to using FQNs.
  110.90 -     */
  110.91 -    public String value();
  110.92 -    /**Expected types for variables from the {@link #value() pattern}.
  110.93 -     */
  110.94 -    public ConstraintVariableType[] constraints() default {};
  110.95 -
  110.96 -}
   111.1 --- a/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/TriggerPatterns.java	Sun Oct 16 08:01:27 2016 +0200
   111.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   111.3 @@ -1,60 +0,0 @@
   111.4 -/*
   111.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   111.6 - *
   111.7 - * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
   111.8 - *
   111.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  111.10 - * Other names may be trademarks of their respective owners.
  111.11 - *
  111.12 - * The contents of this file are subject to the terms of either the GNU
  111.13 - * General Public License Version 2 only ("GPL") or the Common
  111.14 - * Development and Distribution License("CDDL") (collectively, the
  111.15 - * "License"). You may not use this file except in compliance with the
  111.16 - * License. You can obtain a copy of the License at
  111.17 - * http://www.netbeans.org/cddl-gplv2.html
  111.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  111.19 - * specific language governing permissions and limitations under the
  111.20 - * License.  When distributing the software, include this License Header
  111.21 - * Notice in each file and include the License file at
  111.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  111.23 - * particular file as subject to the "Classpath" exception as provided
  111.24 - * by Oracle in the GPL Version 2 section of the License file that
  111.25 - * accompanied this code. If applicable, add the following below the
  111.26 - * License Header, with the fields enclosed by brackets [] replaced by
  111.27 - * your own identifying information:
  111.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  111.29 - *
  111.30 - * If you wish your version of this file to be governed by only the CDDL
  111.31 - * or only the GPL Version 2, indicate your decision by adding
  111.32 - * "[Contributor] elects to include this software in this distribution
  111.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  111.34 - * single choice of license, a recipient has the option to distribute
  111.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  111.36 - * to extend the choice of license to its licensees as provided above.
  111.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  111.38 - * Version 2 license, then the option applies only if the new code is
  111.39 - * made subject to such option by the copyright holder.
  111.40 - *
  111.41 - * Contributor(s):
  111.42 - *
  111.43 - * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
  111.44 - */
  111.45 -
  111.46 -package org.netbeans.spi.java.hints;
  111.47 -
  111.48 -import java.lang.annotation.ElementType;
  111.49 -import java.lang.annotation.Retention;
  111.50 -import java.lang.annotation.RetentionPolicy;
  111.51 -import java.lang.annotation.Target;
  111.52 -
  111.53 -/**Multiple {@link TriggerPattern}s.
  111.54 - *
  111.55 - * @author lahvac
  111.56 - */
  111.57 -@Retention(RetentionPolicy.SOURCE)
  111.58 -@Target(ElementType.METHOD)
  111.59 -public @interface TriggerPatterns {
  111.60 -
  111.61 -    public TriggerPattern[] value();
  111.62 -    
  111.63 -}
   112.1 --- a/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/TriggerTreeKind.java	Sun Oct 16 08:01:27 2016 +0200
   112.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   112.3 @@ -1,66 +0,0 @@
   112.4 -/*
   112.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   112.6 - *
   112.7 - * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
   112.8 - *
   112.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  112.10 - * Other names may be trademarks of their respective owners.
  112.11 - *
  112.12 - * The contents of this file are subject to the terms of either the GNU
  112.13 - * General Public License Version 2 only ("GPL") or the Common
  112.14 - * Development and Distribution License("CDDL") (collectively, the
  112.15 - * "License"). You may not use this file except in compliance with the
  112.16 - * License. You can obtain a copy of the License at
  112.17 - * http://www.netbeans.org/cddl-gplv2.html
  112.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  112.19 - * specific language governing permissions and limitations under the
  112.20 - * License.  When distributing the software, include this License Header
  112.21 - * Notice in each file and include the License file at
  112.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  112.23 - * particular file as subject to the "Classpath" exception as provided
  112.24 - * by Oracle in the GPL Version 2 section of the License file that
  112.25 - * accompanied this code. If applicable, add the following below the
  112.26 - * License Header, with the fields enclosed by brackets [] replaced by
  112.27 - * your own identifying information:
  112.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  112.29 - *
  112.30 - * If you wish your version of this file to be governed by only the CDDL
  112.31 - * or only the GPL Version 2, indicate your decision by adding
  112.32 - * "[Contributor] elects to include this software in this distribution
  112.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  112.34 - * single choice of license, a recipient has the option to distribute
  112.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  112.36 - * to extend the choice of license to its licensees as provided above.
  112.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  112.38 - * Version 2 license, then the option applies only if the new code is
  112.39 - * made subject to such option by the copyright holder.
  112.40 - *
  112.41 - * Contributor(s):
  112.42 - *
  112.43 - * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
  112.44 - */
  112.45 -
  112.46 -package org.netbeans.spi.java.hints;
  112.47 -
  112.48 -import com.sun.source.tree.Tree.Kind;
  112.49 -import com.sun.source.util.TreePath;
  112.50 -import java.lang.annotation.ElementType;
  112.51 -import java.lang.annotation.Retention;
  112.52 -import java.lang.annotation.RetentionPolicy;
  112.53 -import java.lang.annotation.Target;
  112.54 -
  112.55 -/**Invoke the method for {@link TreePath}s of the given kind.
  112.56 - *
  112.57 - * The method must be {@code public static}, the return type must either be assignable to
  112.58 - * {@link ErrorDescription} or to {@link Iterable}{@code <? extends }{@link ErrorDescription}{@code >}.
  112.59 - * Its sole parameter must be {@link HintContext}.
  112.60 - *
  112.61 - * @author lahvac
  112.62 - */
  112.63 -@Retention(RetentionPolicy.SOURCE)
  112.64 -@Target(ElementType.METHOD)
  112.65 -public @interface TriggerTreeKind {
  112.66 -
  112.67 -    public Kind[] value();
  112.68 -
  112.69 -}
   113.1 --- a/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/UseOptions.java	Sun Oct 16 08:01:27 2016 +0200
   113.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   113.3 @@ -1,64 +0,0 @@
   113.4 -/*
   113.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   113.6 - *
   113.7 - * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
   113.8 - *
   113.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  113.10 - * Other names may be trademarks of their respective owners.
  113.11 - *
  113.12 - * The contents of this file are subject to the terms of either the GNU
  113.13 - * General Public License Version 2 only ("GPL") or the Common
  113.14 - * Development and Distribution License("CDDL") (collectively, the
  113.15 - * "License"). You may not use this file except in compliance with the
  113.16 - * License. You can obtain a copy of the License at
  113.17 - * http://www.netbeans.org/cddl-gplv2.html
  113.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  113.19 - * specific language governing permissions and limitations under the
  113.20 - * License.  When distributing the software, include this License Header
  113.21 - * Notice in each file and include the License file at
  113.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  113.23 - * particular file as subject to the "Classpath" exception as provided
  113.24 - * by Oracle in the GPL Version 2 section of the License file that
  113.25 - * accompanied this code. If applicable, add the following below the
  113.26 - * License Header, with the fields enclosed by brackets [] replaced by
  113.27 - * your own identifying information:
  113.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  113.29 - *
  113.30 - * If you wish your version of this file to be governed by only the CDDL
  113.31 - * or only the GPL Version 2, indicate your decision by adding
  113.32 - * "[Contributor] elects to include this software in this distribution
  113.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  113.34 - * single choice of license, a recipient has the option to distribute
  113.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  113.36 - * to extend the choice of license to its licensees as provided above.
  113.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  113.38 - * Version 2 license, then the option applies only if the new code is
  113.39 - * made subject to such option by the copyright holder.
  113.40 - *
  113.41 - * Contributor(s):
  113.42 - *
  113.43 - * Portions Copyrighted 2012 Sun Microsystems, Inc.
  113.44 - */
  113.45 -package org.netbeans.spi.java.hints;
  113.46 -
  113.47 -import java.lang.annotation.ElementType;
  113.48 -import java.lang.annotation.Retention;
  113.49 -import java.lang.annotation.RetentionPolicy;
  113.50 -import java.lang.annotation.Target;
  113.51 -
  113.52 -/**Specifies which options from the enclosing class should be used for this hint.
  113.53 - *
  113.54 - * Only applies to methods marked with the {@link Hint} annotation.
  113.55 - *
  113.56 - * @author lahvac
  113.57 - */
  113.58 -@Retention(RetentionPolicy.SOURCE)
  113.59 -@Target(ElementType.METHOD)
  113.60 -public @interface UseOptions {
  113.61 -
  113.62 -    /**Keys (values of the compile-time constants) of the options that should be used
  113.63 -     * for this hint method.
  113.64 -     */
  113.65 -    public String[] value();
  113.66 -    
  113.67 -}
   114.1 --- a/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/support/FixFactory.java	Sun Oct 16 08:01:27 2016 +0200
   114.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   114.3 @@ -1,171 +0,0 @@
   114.4 -/*
   114.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   114.6 - *
   114.7 - * Copyright 1997-2012 Oracle and/or its affiliates. All rights reserved.
   114.8 - *
   114.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  114.10 - * Other names may be trademarks of their respective owners.
  114.11 - *
  114.12 - * The contents of this file are subject to the terms of either the GNU
  114.13 - * General Public License Version 2 only ("GPL") or the Common
  114.14 - * Development and Distribution License("CDDL") (collectively, the
  114.15 - * "License"). You may not use this file except in compliance with the
  114.16 - * License. You can obtain a copy of the License at
  114.17 - * http://www.netbeans.org/cddl-gplv2.html
  114.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  114.19 - * specific language governing permissions and limitations under the
  114.20 - * License.  When distributing the software, include this License Header
  114.21 - * Notice in each file and include the License file at
  114.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  114.23 - * particular file as subject to the "Classpath" exception as provided
  114.24 - * by Oracle in the GPL Version 2 section of the License file that
  114.25 - * accompanied this code. If applicable, add the following below the
  114.26 - * License Header, with the fields enclosed by brackets [] replaced by
  114.27 - * your own identifying information:
  114.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  114.29 - *
  114.30 - * Contributor(s):
  114.31 - *
  114.32 - * Portions Copyrighted 2007-2012 Sun Microsystems, Inc.
  114.33 - */
  114.34 -package org.netbeans.spi.java.hints.support;
  114.35 -
  114.36 -import com.sun.source.tree.ModifiersTree;
  114.37 -import com.sun.source.tree.Tree.Kind;
  114.38 -import com.sun.source.util.TreePath;
  114.39 -import java.util.Collections;
  114.40 -import java.util.EnumSet;
  114.41 -import java.util.Set;
  114.42 -import javax.lang.model.element.Modifier;
  114.43 -import org.netbeans.api.java.source.CompilationInfo;
  114.44 -import org.netbeans.api.java.source.TreeMaker;
  114.45 -import org.netbeans.api.java.source.TreePathHandle;
  114.46 -import org.netbeans.api.java.source.WorkingCopy;
  114.47 -import org.netbeans.spi.editor.hints.Fix;
  114.48 -import org.netbeans.spi.java.hints.JavaFix;
  114.49 -import org.openide.util.Parameters;
  114.50 -
  114.51 -/** Factory for creating generally useful fixes. Currently, changes to the modifiers
  114.52 - *  are supported.
  114.53 - *
  114.54 - * @author Dusan Balek
  114.55 - */
  114.56 -public final class FixFactory {
  114.57 -
  114.58 -    private FixFactory() {}
  114.59 -
  114.60 -    /** Creates a fix, which when invoked adds a set of modifiers to the existing ones
  114.61 -     * @param compilationInfo CompilationInfo to work on
  114.62 -     * @param treePath TreePath to a ModifiersTree.
  114.63 -     * @param toAdd set of Modifiers to add
  114.64 -     * @param text text displayed as a fix description
  114.65 -     */
  114.66 -    public static final Fix addModifiersFix(CompilationInfo compilationInfo, TreePath treePath, Set<Modifier> toAdd, String text) {
  114.67 -        Parameters.notNull("compilationInfo", compilationInfo);
  114.68 -        Parameters.notNull("treePath", treePath);
  114.69 -        Parameters.notNull("toAdd", toAdd);
  114.70 -        Parameters.notNull("text", text);
  114.71 -
  114.72 -        return changeModifiersFix(compilationInfo, treePath, toAdd, Collections.<Modifier>emptySet(), text);
  114.73 -    }
  114.74 -
  114.75 -    /** Creates a fix, which when invoked removes a set of modifiers from the existing ones
  114.76 -     * @param compilationInfo CompilationInfo to work on
  114.77 -     * @param treePath TreePath to a ModifiersTree.
  114.78 -     * @param toRemove set of Modifiers to remove
  114.79 -     * @param text text displayed as a fix description
  114.80 -     */
  114.81 -    public static final Fix removeModifiersFix(CompilationInfo compilationInfo, TreePath treePath, Set<Modifier> toRemove, String text) {
  114.82 -        Parameters.notNull("compilationInfo", compilationInfo);
  114.83 -        Parameters.notNull("treePath", treePath);
  114.84 -        Parameters.notNull("toRemove", toRemove);
  114.85 -        Parameters.notNull("text", text);
  114.86 -
  114.87 -        return changeModifiersFix(compilationInfo, treePath, Collections.<Modifier>emptySet(), toRemove, text);
  114.88 -    }
  114.89 -
  114.90 -    /** Creates a fix, which when invoked changes the existing modifiers
  114.91 -     * @param compilationInfo CompilationInfo to work on
  114.92 -     * @param treePath TreePath to a ModifiersTree.
  114.93 -     * @param toAdd set of Modifiers to add
  114.94 -     * @param toRemove set of Modifiers to remove
  114.95 -     * @param text text displayed as a fix description
  114.96 -     */
  114.97 -    public static final Fix changeModifiersFix(CompilationInfo compilationInfo, TreePath treePath, Set<Modifier> toAdd, Set<Modifier> toRemove, String text) {
  114.98 -        Parameters.notNull("compilationInfo", compilationInfo);
  114.99 -        Parameters.notNull("treePath", treePath);
 114.100 -        Parameters.notNull("toAdd", toAdd);
 114.101 -        Parameters.notNull("toRemove", toRemove);
 114.102 -        Parameters.notNull("text", text);
 114.103 -
 114.104 -        if (treePath.getLeaf().getKind() != Kind.MODIFIERS) {
 114.105 -            return null;
 114.106 -        }
 114.107 -        return new ChangeModifiersFixImpl(TreePathHandle.create(treePath, compilationInfo), toAdd, toRemove, text).toEditorFix();
 114.108 -    }
 114.109 -
 114.110 -    private static final class ChangeModifiersFixImpl extends JavaFix {
 114.111 -
 114.112 -        private final TreePathHandle modsHandle;
 114.113 -        private final Set<Modifier> toAdd;
 114.114 -        private final Set<Modifier> toRemove;
 114.115 -        private final String text;
 114.116 -
 114.117 -        public ChangeModifiersFixImpl(TreePathHandle modsHandle, Set<Modifier> toAdd, Set<Modifier> toRemove, String text) {
 114.118 -            super(modsHandle);
 114.119 -            this.modsHandle = modsHandle;
 114.120 -            this.toAdd = toAdd;
 114.121 -            this.toRemove = toRemove;
 114.122 -            this.text = text;
 114.123 -        }
 114.124 -
 114.125 -        public String getText() {
 114.126 -            return text;
 114.127 -        }
 114.128 -
 114.129 -        @Override
 114.130 -        protected void performRewrite(TransformationContext ctx) {
 114.131 -            WorkingCopy wc = ctx.getWorkingCopy();
 114.132 -            TreePath path = ctx.getPath();
 114.133 -            TreeMaker make = wc.getTreeMaker();
 114.134 -            ModifiersTree newMods = (ModifiersTree) path.getLeaf();
 114.135 -            for (Modifier a : toAdd) {
 114.136 -                newMods = make.addModifiersModifier(newMods, a);
 114.137 -            }
 114.138 -            for (Modifier r : toRemove) {
 114.139 -                newMods = make.removeModifiersModifier(newMods, r);
 114.140 -            }
 114.141 -            wc.rewrite(path.getLeaf(), newMods);
 114.142 -        }
 114.143 -
 114.144 -        @Override
 114.145 -        public boolean equals(Object obj) {
 114.146 -            if (obj == null) {
 114.147 -                return false;
 114.148 -            }
 114.149 -            if (getClass() != obj.getClass()) {
 114.150 -                return false;
 114.151 -            }
 114.152 -            final ChangeModifiersFixImpl other = (ChangeModifiersFixImpl) obj;
 114.153 -            if (this.modsHandle != other.modsHandle && (this.modsHandle == null || !this.modsHandle.equals(other.modsHandle))) {
 114.154 -                return false;
 114.155 -            }
 114.156 -            if (this.toAdd != other.toAdd && (this.toAdd == null || !this.toAdd.equals(other.toAdd))) {
 114.157 -                return false;
 114.158 -            }
 114.159 -            if (this.toRemove != other.toRemove && (this.toRemove == null || !this.toRemove.equals(other.toRemove))) {
 114.160 -                return false;
 114.161 -            }
 114.162 -            return true;
 114.163 -        }
 114.164 -
 114.165 -        @Override
 114.166 -        public int hashCode() {
 114.167 -            int hash = 5;
 114.168 -            hash = 71 * hash + (this.modsHandle != null ? this.modsHandle.hashCode() : 0);
 114.169 -            hash = 71 * hash + (this.toAdd != null ? this.toAdd.hashCode() : 0);
 114.170 -            hash = 71 * hash + (this.toRemove != null ? this.toRemove.hashCode() : 0);
 114.171 -            return hash;
 114.172 -        }
 114.173 -    }
 114.174 -}
   115.1 --- a/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/support/TransformationSupport.java	Sun Oct 16 08:01:27 2016 +0200
   115.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   115.3 @@ -1,311 +0,0 @@
   115.4 -/*
   115.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   115.6 - *
   115.7 - * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
   115.8 - *
   115.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  115.10 - * Other names may be trademarks of their respective owners.
  115.11 - *
  115.12 - * The contents of this file are subject to the terms of either the GNU
  115.13 - * General Public License Version 2 only ("GPL") or the Common
  115.14 - * Development and Distribution License("CDDL") (collectively, the
  115.15 - * "License"). You may not use this file except in compliance with the
  115.16 - * License. You can obtain a copy of the License at
  115.17 - * http://www.netbeans.org/cddl-gplv2.html
  115.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  115.19 - * specific language governing permissions and limitations under the
  115.20 - * License.  When distributing the software, include this License Header
  115.21 - * Notice in each file and include the License file at
  115.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  115.23 - * particular file as subject to the "Classpath" exception as provided
  115.24 - * by Oracle in the GPL Version 2 section of the License file that
  115.25 - * accompanied this code. If applicable, add the following below the
  115.26 - * License Header, with the fields enclosed by brackets [] replaced by
  115.27 - * your own identifying information:
  115.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  115.29 - *
  115.30 - * If you wish your version of this file to be governed by only the CDDL
  115.31 - * or only the GPL Version 2, indicate your decision by adding
  115.32 - * "[Contributor] elects to include this software in this distribution
  115.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  115.34 - * single choice of license, a recipient has the option to distribute
  115.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  115.36 - * to extend the choice of license to its licensees as provided above.
  115.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  115.38 - * Version 2 license, then the option applies only if the new code is
  115.39 - * made subject to such option by the copyright holder.
  115.40 - *
  115.41 - * Contributor(s):
  115.42 - *
  115.43 - * Portions Copyrighted 2012 Sun Microsystems, Inc.
  115.44 - */
  115.45 -package org.netbeans.spi.java.hints.support;
  115.46 -
  115.47 -import com.sun.source.util.TreePath;
  115.48 -import java.util.*;
  115.49 -import java.util.Map.Entry;
  115.50 -import java.util.concurrent.atomic.AtomicBoolean;
  115.51 -import javax.lang.model.type.TypeMirror;
  115.52 -import org.netbeans.api.annotations.common.NonNull;
  115.53 -import org.netbeans.api.java.source.CompilationInfo;
  115.54 -import org.netbeans.api.java.source.ModificationResult;
  115.55 -import org.netbeans.api.java.source.TypeMirrorHandle;
  115.56 -import org.netbeans.api.java.source.WorkingCopy;
  115.57 -import org.netbeans.api.java.source.matching.Matcher;
  115.58 -import org.netbeans.api.java.source.matching.Occurrence;
  115.59 -import org.netbeans.api.java.source.matching.Pattern;
  115.60 -import org.netbeans.api.project.Project;
  115.61 -import org.netbeans.modules.java.hints.jackpot.spi.PatternConvertor;
  115.62 -import org.netbeans.modules.java.hints.providers.spi.HintDescription;
  115.63 -import org.netbeans.modules.java.hints.providers.spi.HintDescriptionFactory;
  115.64 -import org.netbeans.modules.java.hints.providers.spi.Trigger;
  115.65 -import org.netbeans.modules.java.hints.spiimpl.JavaFixImpl;
  115.66 -import org.netbeans.modules.java.hints.spiimpl.MessageImpl;
  115.67 -import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch;
  115.68 -import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.BatchResult;
  115.69 -import org.netbeans.modules.java.hints.spiimpl.batch.BatchUtilities;
  115.70 -import org.netbeans.modules.java.hints.spiimpl.batch.ProgressHandleWrapper;
  115.71 -import org.netbeans.modules.java.hints.spiimpl.batch.Scopes;
  115.72 -import org.netbeans.modules.java.hints.spiimpl.hints.HintsInvoker;
  115.73 -import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings;
  115.74 -import org.netbeans.modules.java.hints.spiimpl.pm.PatternCompiler;
  115.75 -import org.netbeans.modules.refactoring.spi.RefactoringElementImplementation;
  115.76 -import org.netbeans.spi.editor.hints.*;
  115.77 -import org.netbeans.spi.java.hints.HintContext;
  115.78 -import org.netbeans.spi.java.hints.JavaFix;
  115.79 -import org.openide.util.Exceptions;
  115.80 -
  115.81 -/**
  115.82 - * Static utility classes for processing jackpot patterns.
  115.83 - * <a href="https://bitbucket.org/jlahoda/jackpot30/wiki/RulesLanguage">Rules Language</a>
  115.84 - * @author Jan Becicka
  115.85 - * @since 1.1
  115.86 - */
  115.87 -public final class TransformationSupport {
  115.88 -
  115.89 -    private String jackpotPattern;
  115.90 -    private Transformer transformer;
  115.91 -    private AtomicBoolean cancel = new AtomicBoolean();
  115.92 -
  115.93 -    private TransformationSupport(String jackpotPattern, Transformer transformer) {
  115.94 -        this.jackpotPattern = jackpotPattern;
  115.95 -        this.transformer = transformer;
  115.96 -    }
  115.97 -    
  115.98 -    /**
  115.99 -     * Creates new TransformationSupport representing given jackpotPattern.
 115.100 -     * @param jackpotPattern
 115.101 -     * @return
 115.102 -     */
 115.103 -    public static @NonNull TransformationSupport create(@NonNull String jackpotPattern) {
 115.104 -        return new TransformationSupport(jackpotPattern, null);
 115.105 -    }
 115.106 -
 115.107 -    /**
 115.108 -     * Creates new TransformationSupport representing given jackpotPattern with custom Transformer.
 115.109 -     * @param inputJackpotPattern
 115.110 -     * @param t
 115.111 -     * @see Transformer
 115.112 -     * @return
 115.113 -     */
 115.114 -    public static @NonNull TransformationSupport create(@NonNull String inputJackpotPattern, @NonNull Transformer t) {
 115.115 -        return new TransformationSupport(inputJackpotPattern, t);
 115.116 -    }
 115.117 -
 115.118 -    /**
 115.119 -     * Option to cancel query.
 115.120 -     * @param cancel
 115.121 -     * @return
 115.122 -     */
 115.123 -    public @NonNull TransformationSupport setCancel(@NonNull AtomicBoolean cancel) {
 115.124 -        this.cancel = cancel;
 115.125 -        return this;
 115.126 -    }
 115.127 -
 115.128 -
 115.129 -    /**
 115.130 -     * Run current transformation on all projects and collect results.
 115.131 -     * @return collection of {@link ModificationResult}
 115.132 -     */
 115.133 -    public @NonNull Collection<? extends ModificationResult> processAllProjects() {
 115.134 -        if (transformer!=null) {
 115.135 -            return performTransformation(jackpotPattern, transformer, cancel);
 115.136 -        } else {
 115.137 -            return performTransformation(jackpotPattern, cancel);
 115.138 -        }
 115.139 -    }
 115.140 -
 115.141 -    
 115.142 -    /**
 115.143 -     * Process current transformation on given treePath and performs rewrite on
 115.144 -     * workingCopy.
 115.145 -     * @param workingCopy
 115.146 -     * @param treePath 
 115.147 -     */
 115.148 -    public void transformTreePath(@NonNull WorkingCopy workingCopy, @NonNull TreePath treePath) {
 115.149 -        if (transformer!=null) {
 115.150 -            throw new UnsupportedOperationException("Not implemented yet");
 115.151 -        } else {
 115.152 -            performTransformation(workingCopy, treePath, jackpotPattern, cancel);
 115.153 -        }
 115.154 -    }
 115.155 -
 115.156 -
 115.157 -    /**
 115.158 -     * Transformer callback which is called for each occurrence during processing 
 115.159 -     * of {@link #performTransformation(java.lang.String, org.netbeans.spi.java.hints.support.JackpotSupport.Transformer, java.util.concurrent.atomic.AtomicBoolean)    
 115.160 -     */
 115.161 -    public interface Transformer {
 115.162 -
 115.163 -        /**
 115.164 -         * Implement custom transformation of occurrence here.
 115.165 -         * @param copy
 115.166 -         * @param occurrence
 115.167 -         */
 115.168 -        public void transform(WorkingCopy copy, Occurrence occurrence);
 115.169 -
 115.170 -    }
 115.171 -    
 115.172 -    
 115.173 -    
 115.174 -    /**
 115.175 -     * Performs transformation described by jackpotPattern on given workingCopy.
 115.176 -     * @param workingCopy
 115.177 -     * @param jackpotPattern
 115.178 -     * @param cancel
 115.179 -     */
 115.180 -    private static void performTransformation(WorkingCopy workingCopy, TreePath on, String jackpotPattern, AtomicBoolean cancel) {
 115.181 -        Iterable<? extends HintDescription> hints = PatternConvertor.create(jackpotPattern);
 115.182 -        HintsInvoker inv = new HintsInvoker(HintsSettings.getSettingsFor(workingCopy.getFileObject()), cancel);
 115.183 -        Map<HintDescription, List<ErrorDescription>> computeHints = inv.computeHints(workingCopy, on, false, hints, new ArrayList<MessageImpl>());
 115.184 -        
 115.185 -        if (computeHints == null || cancel.get()) return ;
 115.186 -        
 115.187 -        List<ErrorDescription> errs = new ArrayList<ErrorDescription>();
 115.188 -        for (Entry<HintDescription, List<ErrorDescription>> entry: computeHints.entrySet()) {
 115.189 -            errs.addAll(entry.getValue());
 115.190 -        }
 115.191 -        List<MessageImpl> problems = new LinkedList<MessageImpl>();
 115.192 -
 115.193 -        try {
 115.194 -            if (BatchUtilities.applyFixes(workingCopy, Collections.<Project, Set<String>>emptyMap(), errs, null, new ArrayList<RefactoringElementImplementation>(), problems)) {
 115.195 -                throw new IllegalStateException();
 115.196 -            }
 115.197 -        } catch (IllegalStateException ex) {
 115.198 -            Exceptions.printStackTrace(ex);
 115.199 -        } catch (Exception ex) {
 115.200 -            Exceptions.printStackTrace(ex);
 115.201 -        }
 115.202 -
 115.203 -        if (!problems.isEmpty()) {
 115.204 -            throw new IllegalStateException(problems.get(0).text);
 115.205 -        }
 115.206 -    }
 115.207 -    
 115.208 -    /**
 115.209 -     * Performs jackpotPattern transformation in all open projects.
 115.210 -     * @param jackpotPattern
 115.211 -     * @param cancel
 115.212 -     * @return
 115.213 -     */
 115.214 -    private static  Collection<? extends ModificationResult> performTransformation(String jackpotPattern, AtomicBoolean cancel) {
 115.215 -        Collection<MessageImpl> problems = new LinkedList<MessageImpl>();
 115.216 -        BatchResult batchResult = BatchSearch.findOccurrences(PatternConvertor.create(jackpotPattern), Scopes.allOpenedProjectsScope());
 115.217 -        return BatchUtilities.applyFixes(batchResult, new ProgressHandleWrapper(1, 1), cancel, problems);
 115.218 -    }
 115.219 -    
 115.220 -    /**
 115.221 -     * Performs transformation defined by transformer on all occurrences, which matches inputJackpotPattern.
 115.222 -     * @param inputJackpotPattern
 115.223 -     * @param transformer
 115.224 -     * @return collection of ModificationResults.
 115.225 -     */
 115.226 -    private static Collection<? extends ModificationResult> performTransformation(final String inputJackpotPattern, final Transformer transformer, AtomicBoolean cancel) {
 115.227 -        List<HintDescription> descriptions = new ArrayList<HintDescription>();
 115.228 -
 115.229 -        for (HintDescription hd : PatternConvertor.create(inputJackpotPattern)) {
 115.230 -            final String triggerPattern = ((Trigger.PatternDescription) hd.getTrigger()).getPattern();
 115.231 -            descriptions.add(HintDescriptionFactory.create().setTrigger(hd.getTrigger()).setWorker(new HintDescription.Worker() {
 115.232 -                @Override public Collection<? extends ErrorDescription> createErrors(HintContext ctx) {
 115.233 -                    final Map<String, TypeMirrorHandle<?>> constraintsHandles = new HashMap<String, TypeMirrorHandle<?>>();
 115.234 -
 115.235 -                    for (Map.Entry<String, TypeMirror> c : ctx.getConstraints().entrySet()) {
 115.236 -                        constraintsHandles.put(c.getKey(), TypeMirrorHandle.create(c.getValue()));
 115.237 -                    }
 115.238 -
 115.239 -                    Fix fix = new JavaFix(ctx.getInfo(), ctx.getPath()) {
 115.240 -                        @Override protected String getText() {
 115.241 -                            return "";
 115.242 -                        }
 115.243 -                        @Override protected void performRewrite(JavaFix.TransformationContext ctx) {
 115.244 -                            WorkingCopy wc = ctx.getWorkingCopy();
 115.245 -                            Map<String, TypeMirror> constraints = new HashMap<String, TypeMirror>();
 115.246 -
 115.247 -                            for (Map.Entry<String, TypeMirrorHandle<?>> c : constraintsHandles.entrySet()) {
 115.248 -                                constraints.put(c.getKey(), c.getValue().resolve(wc));
 115.249 -                            }
 115.250 -
 115.251 -                            Pattern pattern = PatternCompiler.compile(wc, triggerPattern, constraints, Collections.<String>emptyList());
 115.252 -                            Collection<? extends Occurrence> occurrence = Matcher.create(wc).setTreeTopSearch().setSearchRoot(ctx.getPath()).match(pattern);
 115.253 -
 115.254 -                            assert occurrence.size() == 1;
 115.255 -
 115.256 -                            transformer.transform(wc, occurrence.iterator().next());
 115.257 -                        }
 115.258 -                    }.toEditorFix();
 115.259 -                    
 115.260 -                    return Collections.singletonList(ErrorDescriptionFactory.createErrorDescription(Severity.WARNING, "", Collections.singletonList(fix), ctx.getInfo().getFileObject(), 0, 0));
 115.261 -                }
 115.262 -            }).produce());
 115.263 -
 115.264 -        }
 115.265 -        
 115.266 -        BatchSearch.BatchResult batchResult = BatchSearch.findOccurrences(descriptions, Scopes.allOpenedProjectsScope());
 115.267 -        return BatchUtilities.applyFixes(batchResult, new ProgressHandleWrapper(1, 1), cancel, new ArrayList<MessageImpl>());
 115.268 -    }
 115.269 -    
 115.270 -    /**
 115.271 -     * Performs transformation described by transformationJackpotPattern on all occurences described by inputJackpotPattern.
 115.272 -     * @param inputJackpotPattern
 115.273 -     * @param transformationJackpotPattern
 115.274 -     * @param cancel 
 115.275 -     * @return
 115.276 -     */
 115.277 -    private static Collection<? extends ModificationResult> performTransformation(String inputJackpotPattern, final String transformationJackpotPattern, AtomicBoolean cancel) {
 115.278 -        return performTransformation(inputJackpotPattern, new Transformer() {
 115.279 -
 115.280 -            @Override
 115.281 -            public void transform(WorkingCopy copy, Occurrence occurrence) {
 115.282 -                try {
 115.283 -                    Fix toFix = TransformationSupport.rewriteFix(copy, "whatever", occurrence.getOccurrenceRoot(), transformationJackpotPattern, occurrence.getVariables(), occurrence.getMultiVariables(), occurrence.getVariables2Names(), Collections.<String, TypeMirror>emptyMap(), Collections.<String, String>emptyMap());
 115.284 -                    TransformationSupport.process(((JavaFixImpl) toFix).jf, copy, false, null, new ArrayList<RefactoringElementImplementation>());
 115.285 -                } catch (Exception ex) {
 115.286 -                    Exceptions.printStackTrace(ex);
 115.287 -                }
 115.288 -            }
 115.289 -        }, cancel);
 115.290 -    }
 115.291 -
 115.292 -    private static ChangeInfo process(JavaFix jf, WorkingCopy wc, boolean canShowUI, Map<org.openide.filesystems.FileObject, byte[]> resourceContent, Collection<? super RefactoringElementImplementation> fileChanges) throws Exception {
 115.293 -        return JavaFixImpl.Accessor.INSTANCE.process(jf, wc, canShowUI, resourceContent, fileChanges);
 115.294 -    }
 115.295 -
 115.296 -    /**
 115.297 -     * 
 115.298 -     * @param info
 115.299 -     * @param displayName
 115.300 -     * @param what
 115.301 -     * @param to
 115.302 -     * @param parameters
 115.303 -     * @param parametersMulti
 115.304 -     * @param parameterNames
 115.305 -     * @param constraints
 115.306 -     * @param options
 115.307 -     * @param imports
 115.308 -     * @return
 115.309 -     */
 115.310 -    private static Fix rewriteFix(CompilationInfo info, String displayName, TreePath what, final String to, Map<String, TreePath> parameters, Map<String, Collection<? extends TreePath>> parametersMulti, final Map<String, String> parameterNames, Map<String, TypeMirror> constraints, Map<String, String> options, String... imports) {
 115.311 -        return JavaFixImpl.Accessor.INSTANCE.rewriteFix(info, displayName, what, to, parameters, parametersMulti, parameterNames, constraints, options, imports);
 115.312 -    }
 115.313 -    
 115.314 -}
   116.1 --- a/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/providers/code/CodeHintProviderImplTest.java	Sun Oct 16 08:01:27 2016 +0200
   116.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   116.3 @@ -1,114 +0,0 @@
   116.4 -/*
   116.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   116.6 - *
   116.7 - * Copyright 2009-2010 Oracle and/or its affiliates. All rights reserved.
   116.8 - *
   116.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  116.10 - * Other names may be trademarks of their respective owners.
  116.11 - *
  116.12 - * The contents of this file are subject to the terms of either the GNU
  116.13 - * General Public License Version 2 only ("GPL") or the Common
  116.14 - * Development and Distribution License("CDDL") (collectively, the
  116.15 - * "License"). You may not use this file except in compliance with the
  116.16 - * License. You can obtain a copy of the License at
  116.17 - * http://www.netbeans.org/cddl-gplv2.html
  116.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  116.19 - * specific language governing permissions and limitations under the
  116.20 - * License.  When distributing the software, include this License Header
  116.21 - * Notice in each file and include the License file at
  116.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  116.23 - * particular file as subject to the "Classpath" exception as provided
  116.24 - * by Oracle in the GPL Version 2 section of the License file that
  116.25 - * accompanied this code. If applicable, add the following below the
  116.26 - * License Header, with the fields enclosed by brackets [] replaced by
  116.27 - * your own identifying information:
  116.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  116.29 - *
  116.30 - * If you wish your version of this file to be governed by only the CDDL
  116.31 - * or only the GPL Version 2, indicate your decision by adding
  116.32 - * "[Contributor] elects to include this software in this distribution
  116.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  116.34 - * single choice of license, a recipient has the option to distribute
  116.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  116.36 - * to extend the choice of license to its licensees as provided above.
  116.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  116.38 - * Version 2 license, then the option applies only if the new code is
  116.39 - * made subject to such option by the copyright holder.
  116.40 - *
  116.41 - * Contributor(s):
  116.42 - *
  116.43 - * Portions Copyrighted 2009-2010 Sun Microsystems, Inc.
  116.44 - */
  116.45 -
  116.46 -package org.netbeans.modules.java.hints.providers.code;
  116.47 -
  116.48 -import com.sun.source.tree.Tree.Kind;
  116.49 -import java.util.Arrays;
  116.50 -import java.util.Collection;
  116.51 -import java.util.HashSet;
  116.52 -import java.util.Map;
  116.53 -import java.util.Set;
  116.54 -import org.junit.Test;
  116.55 -import org.netbeans.spi.java.hints.ConstraintVariableType;
  116.56 -import org.netbeans.spi.java.hints.Hint;
  116.57 -import org.netbeans.spi.java.hints.TriggerPattern;
  116.58 -import org.netbeans.spi.java.hints.TriggerTreeKind;
  116.59 -import org.netbeans.spi.java.hints.HintContext;
  116.60 -import static org.junit.Assert.*;
  116.61 -import org.netbeans.modules.java.hints.providers.code.CodeHintProviderImpl.WorkerImpl;
  116.62 -import org.netbeans.modules.java.hints.spiimpl.SPIAccessor;
  116.63 -import org.netbeans.modules.java.hints.providers.spi.HintDescription;
  116.64 -import org.netbeans.modules.java.hints.providers.spi.HintMetadata;
  116.65 -import org.netbeans.spi.editor.hints.ErrorDescription;
  116.66 -
  116.67 -/**
  116.68 - *
  116.69 - * @author lahvac
  116.70 - */
  116.71 -@Hint(displayName="foo", description="bar", id="hintPattern", category="general")
  116.72 -public class CodeHintProviderImplTest {
  116.73 -
  116.74 -    public CodeHintProviderImplTest() {
  116.75 -    }
  116.76 -
  116.77 -    @Test
  116.78 -    public void testComputeHints() throws Exception {
  116.79 -        Map<HintMetadata, ? extends Collection<? extends HintDescription>> hints = new CodeHintProviderImpl().computeHints();
  116.80 -
  116.81 -        Set<String> golden = new HashSet<String>(Arrays.asList(
  116.82 -            "$1.toURL():public static org.netbeans.spi.editor.hints.ErrorDescription org.netbeans.modules.java.hints.providers.code.CodeHintProviderImplTest.hintPattern1(org.netbeans.spi.java.hints.HintContext)",
  116.83 -            "[METHOD_INVOCATION]:public static org.netbeans.spi.editor.hints.ErrorDescription org.netbeans.modules.java.hints.providers.code.CodeHintProviderImplTest.hintPattern2(org.netbeans.spi.java.hints.HintContext)"
  116.84 -        ));
  116.85 -
  116.86 -        for (Collection<? extends HintDescription> hds : hints.values()) {
  116.87 -            for (HintDescription d : hds) {
  116.88 -                golden.remove(toString(d));
  116.89 -            }
  116.90 -        }
  116.91 -
  116.92 -        assertTrue(golden.toString(), golden.isEmpty());
  116.93 -    }
  116.94 -
  116.95 -    private static String toString(HintDescription hd) throws Exception {
  116.96 -        StringBuilder sb = new StringBuilder();
  116.97 -
  116.98 -        sb.append(hd.getTrigger());
  116.99 -        sb.append(":");
 116.100 -        
 116.101 -        //TODO: constraints
 116.102 -        sb.append(((WorkerImpl) hd.getWorker()).getMethod().toGenericString());
 116.103 -
 116.104 -        return sb.toString();
 116.105 -    }
 116.106 -
 116.107 -    @TriggerPattern(value="$1.toURL()", constraints=@ConstraintVariableType(variable="$1", type="java.io.File"))
 116.108 -    public static ErrorDescription hintPattern1(HintContext ctx) {
 116.109 -        return null;
 116.110 -    }
 116.111 -
 116.112 -    @TriggerTreeKind(Kind.METHOD_INVOCATION)
 116.113 -    public static ErrorDescription hintPattern2(HintContext ctx) {
 116.114 -        return null;
 116.115 -    }
 116.116 -
 116.117 -}
 116.118 \ No newline at end of file
   117.1 --- a/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/providers/code/FSWrapperTest.java	Sun Oct 16 08:01:27 2016 +0200
   117.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   117.3 @@ -1,221 +0,0 @@
   117.4 -/*
   117.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   117.6 - *
   117.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
   117.8 - *
   117.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  117.10 - * Other names may be trademarks of their respective owners.
  117.11 - *
  117.12 - * The contents of this file are subject to the terms of either the GNU
  117.13 - * General Public License Version 2 only ("GPL") or the Common
  117.14 - * Development and Distribution License("CDDL") (collectively, the
  117.15 - * "License"). You may not use this file except in compliance with the
  117.16 - * License. You can obtain a copy of the License at
  117.17 - * http://www.netbeans.org/cddl-gplv2.html
  117.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  117.19 - * specific language governing permissions and limitations under the
  117.20 - * License.  When distributing the software, include this License Header
  117.21 - * Notice in each file and include the License file at
  117.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  117.23 - * particular file as subject to the "Classpath" exception as provided
  117.24 - * by Oracle in the GPL Version 2 section of the License file that
  117.25 - * accompanied this code. If applicable, add the following below the
  117.26 - * License Header, with the fields enclosed by brackets [] replaced by
  117.27 - * your own identifying information:
  117.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  117.29 - *
  117.30 - * If you wish your version of this file to be governed by only the CDDL
  117.31 - * or only the GPL Version 2, indicate your decision by adding
  117.32 - * "[Contributor] elects to include this software in this distribution
  117.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  117.34 - * single choice of license, a recipient has the option to distribute
  117.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  117.36 - * to extend the choice of license to its licensees as provided above.
  117.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  117.38 - * Version 2 license, then the option applies only if the new code is
  117.39 - * made subject to such option by the copyright holder.
  117.40 - *
  117.41 - * Contributor(s):
  117.42 - *
  117.43 - * Portions Copyrighted 2010 Sun Microsystems, Inc.
  117.44 - */
  117.45 -
  117.46 -package org.netbeans.modules.java.hints.providers.code;
  117.47 -
  117.48 -import java.lang.annotation.Annotation;
  117.49 -import java.lang.reflect.AnnotatedElement;
  117.50 -import java.lang.reflect.Array;
  117.51 -import java.lang.reflect.Method;
  117.52 -import java.util.ArrayList;
  117.53 -import java.util.LinkedList;
  117.54 -import java.util.List;
  117.55 -import java.util.Map;
  117.56 -import java.util.prefs.Preferences;
  117.57 -import javax.sound.sampled.LineListener;
  117.58 -import javax.swing.JComponent;
  117.59 -import javax.swing.JPanel;
  117.60 -import static org.junit.Assert.assertEquals;
  117.61 -import static org.junit.Assert.assertNotNull;
  117.62 -import static org.junit.Assert.fail;
  117.63 -import org.junit.Test;
  117.64 -import org.netbeans.modules.java.hints.providers.code.FSWrapper.AnnotatableWrapper;
  117.65 -import org.netbeans.modules.java.hints.providers.code.FSWrapper.ClassWrapper;
  117.66 -import org.netbeans.modules.java.hints.providers.code.FSWrapper.MethodWrapper;
  117.67 -import org.netbeans.spi.java.hints.CustomizerProvider;
  117.68 -import org.netbeans.spi.java.hints.Hint;
  117.69 -import org.netbeans.spi.java.hints.HintContext;
  117.70 -import org.netbeans.spi.java.hints.TestAnnotations.TestAnnotation1;
  117.71 -import org.netbeans.spi.java.hints.TestAnnotations.TestAnnotation2;
  117.72 -import org.netbeans.spi.java.hints.TestAnnotations.TestAnnotation3;
  117.73 -import org.netbeans.spi.java.hints.TestAnnotations.TestEnum;
  117.74 -
  117.75 -/**
  117.76 - *
  117.77 - * @author lahvac
  117.78 - */
  117.79 -public class FSWrapperTest {
  117.80 -
  117.81 -    public FSWrapperTest() {
  117.82 -    }
  117.83 -
  117.84 -    @Test
  117.85 -    public void testWrappedClasses() throws Exception {
  117.86 -        Class[] classes = new Class[] {TestClass.class};
  117.87 -        Iterable<? extends ClassWrapper> wrapped = FSWrapper.listClasses();
  117.88 -
  117.89 -        OUTER: for (Class<?> c : classes) {
  117.90 -            for (ClassWrapper w : wrapped) {
  117.91 -                if (w.getName().equals(c.getName())) {
  117.92 -                    checkClassWrapper(c, w);
  117.93 -                    continue OUTER;
  117.94 -                }
  117.95 -            }
  117.96 -
  117.97 -            fail(c.getName());
  117.98 -        }
  117.99 -    }
 117.100 -
 117.101 -    private static void checkClassWrapper(Class<?> c, ClassWrapper cw) throws Exception {
 117.102 -        checkAnnotations(c, cw);
 117.103 -
 117.104 -        OUTER: for (Method m : c.getDeclaredMethods()) {
 117.105 -            if (m.getAnnotations().length == 0) continue;
 117.106 -            
 117.107 -            for (MethodWrapper wrapped : cw.getMethods()) {
 117.108 -                if (wrapped.getName().equals(m.getName())) {
 117.109 -                    assertEquals(m, FSWrapper.resolveMethod(wrapped.getClazz().getName(), wrapped.getName()));
 117.110 -                    checkAnnotations(m, wrapped);
 117.111 -                    continue OUTER;
 117.112 -                }
 117.113 -            }
 117.114 -            
 117.115 -            fail(m.getName());
 117.116 -        }
 117.117 -    }
 117.118 -
 117.119 -    private static void checkAnnotations(AnnotatedElement el, AnnotatableWrapper aw) throws Exception {
 117.120 -        for (Annotation ann : el.getAnnotations()) {
 117.121 -            Annotation wrapper = aw.getAnnotation(ann.annotationType());
 117.122 -
 117.123 -            assertNotNull(ann.annotationType().getName(), wrapper);
 117.124 -
 117.125 -            checkAnnotation(ann, wrapper);
 117.126 -        }
 117.127 -    }
 117.128 -
 117.129 -    private static void checkAnnotation(Annotation real, Annotation wrapped) throws Exception {
 117.130 -        for (Method m : real.annotationType().getDeclaredMethods()) {
 117.131 -            Object realValue = m.invoke(real);
 117.132 -            Object wrappedValue = m.invoke(wrapped);
 117.133 -
 117.134 -            checkValue(realValue, wrappedValue);
 117.135 -        }
 117.136 -    }
 117.137 -
 117.138 -    private static void checkValue(Object o1, Object o2) throws Exception {
 117.139 -        assertEquals(o1.getClass().isAnnotation(), o2.getClass().isAnnotation());
 117.140 -        if (o1.getClass().isAnnotation()) {
 117.141 -            assertEquals(((Annotation) o1).annotationType(), ((Annotation) o2).annotationType());
 117.142 -        } else {
 117.143 -            assertEquals(o1.getClass(), o2.getClass());
 117.144 -        }
 117.145 -
 117.146 -        if (o1.getClass().isArray()) {
 117.147 -            assertEquals(Array.getLength(o1), Array.getLength(o2));
 117.148 -
 117.149 -            for (int c = 0; c < Array.getLength(o1); c++) {
 117.150 -                checkValue(Array.get(o1, c), Array.get(o2, c));
 117.151 -            }
 117.152 -        } else if (o1.getClass().isAnnotation()) {
 117.153 -            checkAnnotation((Annotation) o1, (Annotation) o2);
 117.154 -        } else {
 117.155 -            assertEquals(o1, o2);
 117.156 -        }
 117.157 -    }
 117.158 -
 117.159 -    @Hint(displayName="foo", description="bar", category="")
 117.160 -    @TestAnnotation1(
 117.161 -        b1=true,
 117.162 -        b3=true,
 117.163 -        i1=42,
 117.164 -        i3=84,
 117.165 -        s1="a42",
 117.166 -        s3="a84",
 117.167 -        a1=@TestAnnotation2(a1=@TestAnnotation3(as1={"u1a2", "u1b2"}, as3="u1c2")),
 117.168 -//        a3=@TestAnnotation2(a1=@TestAnnotation3(as1={"u1a2", "u1b2"}, as3="u1c2")),
 117.169 -        c1=String.class,
 117.170 -        c3=String.class,
 117.171 -        e1=TestEnum.C,
 117.172 -        e3=TestEnum.D,
 117.173 -        ab1={false, true},
 117.174 -        ab3={false, true, false},
 117.175 -        ai1={84, 42},
 117.176 -        ai3={84, 42, 84},
 117.177 -        as1={"c42", "c84"},
 117.178 -        as3={"c42", "c84", "c42"},
 117.179 -        aa1={@TestAnnotation2(a1=@TestAnnotation3(as1={"u3a2", "u3b2"}, as3="u3c2")), @TestAnnotation2(a1=@TestAnnotation3(as1={"u4a2", "u4b2"}, as3="u4c2"))},
 117.180 -//        aa3={@TestAnnotation2(a1=@TestAnnotation3(as1={"u5a2", "u5b2"}, as3="u5c2")), @TestAnnotation2(a1=@TestAnnotation3(as1={"u6a2", "u6b2"}, as3="u6c2"))},
 117.181 -        ac1={List.class, Integer.class},
 117.182 -        ac3={LineListener.class, LinkedList.class},
 117.183 -        ae1={TestEnum.C, TestEnum.D},
 117.184 -        ae3={TestEnum.D, TestEnum.C}
 117.185 -    )
 117.186 -    public static class TestClass {
 117.187 -        @TestAnnotation1(
 117.188 -            b1=false,
 117.189 -            b2=true,
 117.190 -            i1=43,
 117.191 -            i2=85,
 117.192 -            s1="w42",
 117.193 -            s2="w84",
 117.194 -            a1=@TestAnnotation2(a1=@TestAnnotation3(as1={"u7a2", "u7b2"}, as3="u7c2")),
 117.195 -//            a2=@TestAnnotation2(a1=@TestAnnotation3(as1={"u8a2", "u8b2"}, as3="u8c2")),
 117.196 -            c1=String.class,
 117.197 -            c2=String.class,
 117.198 -            e1=TestEnum.C,
 117.199 -            e3=TestEnum.D,
 117.200 -            ab1={false, true},
 117.201 -            ab2={false, true, false},
 117.202 -            ai1={85, 43},
 117.203 -            ai2={85, 43, 85},
 117.204 -            as1={"d42", "d84"},
 117.205 -            as2={"e42", "e84", "e42"},
 117.206 -            aa1={@TestAnnotation2(a1=@TestAnnotation3(as1={"u9a2", "u9b2"}, as3="u9c2")), @TestAnnotation2(a1=@TestAnnotation3(as1={"uaa2", "u4b2"}, as3="uac2"))},
 117.207 -//            aa2={@TestAnnotation2(a1=@TestAnnotation3(as1={"uba2", "ubb2"}, as3="ubc2")), @TestAnnotation2(a1=@TestAnnotation3(as1={"uca2", "ucb2"}, as3="ucc2"))},
 117.208 -            ac1={ArrayList.class, Float.class},
 117.209 -            ac2={StringBuilder.class, Map.class},
 117.210 -            ae1={TestEnum.C, TestEnum.D},
 117.211 -            ae3={TestEnum.D, TestEnum.C}
 117.212 -        )
 117.213 -        public static void test(HintContext ctx) {
 117.214 -            
 117.215 -        }
 117.216 -    }
 117.217 -
 117.218 -    public static class CustomizerImpl implements CustomizerProvider {
 117.219 -        @Override public JComponent getCustomizer(Preferences prefs) {
 117.220 -            return new JPanel();
 117.221 -        }
 117.222 -    }
 117.223 -
 117.224 -}
   118.1 --- a/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/providers/code/TestAnnotations.java	Sun Oct 16 08:01:27 2016 +0200
   118.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   118.3 @@ -1,109 +0,0 @@
   118.4 -/*
   118.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   118.6 - *
   118.7 - * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
   118.8 - *
   118.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  118.10 - * Other names may be trademarks of their respective owners.
  118.11 - *
  118.12 - * The contents of this file are subject to the terms of either the GNU
  118.13 - * General Public License Version 2 only ("GPL") or the Common
  118.14 - * Development and Distribution License("CDDL") (collectively, the
  118.15 - * "License"). You may not use this file except in compliance with the
  118.16 - * License. You can obtain a copy of the License at
  118.17 - * http://www.netbeans.org/cddl-gplv2.html
  118.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  118.19 - * specific language governing permissions and limitations under the
  118.20 - * License.  When distributing the software, include this License Header
  118.21 - * Notice in each file and include the License file at
  118.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  118.23 - * particular file as subject to the "Classpath" exception as provided
  118.24 - * by Oracle in the GPL Version 2 section of the License file that
  118.25 - * accompanied this code. If applicable, add the following below the
  118.26 - * License Header, with the fields enclosed by brackets [] replaced by
  118.27 - * your own identifying information:
  118.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  118.29 - *
  118.30 - * If you wish your version of this file to be governed by only the CDDL
  118.31 - * or only the GPL Version 2, indicate your decision by adding
  118.32 - * "[Contributor] elects to include this software in this distribution
  118.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  118.34 - * single choice of license, a recipient has the option to distribute
  118.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  118.36 - * to extend the choice of license to its licensees as provided above.
  118.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  118.38 - * Version 2 license, then the option applies only if the new code is
  118.39 - * made subject to such option by the copyright holder.
  118.40 - *
  118.41 - * Contributor(s):
  118.42 - *
  118.43 - * Portions Copyrighted 2012 Sun Microsystems, Inc.
  118.44 - */
  118.45 -//placed in this package intentionally: the JavaHintsAnnotationProcessor ignores all annotations outside this package
  118.46 -package org.netbeans.spi.java.hints;
  118.47 -
  118.48 -import java.lang.annotation.Retention;
  118.49 -import java.lang.annotation.RetentionPolicy;
  118.50 -
  118.51 -/**
  118.52 - *
  118.53 - * @author lahvac
  118.54 - */
  118.55 -public class TestAnnotations {
  118.56 -    
  118.57 -    @Retention(RetentionPolicy.RUNTIME)
  118.58 -    public @interface TestAnnotation1 {
  118.59 -        public boolean b1();
  118.60 -        public boolean b2() default false;
  118.61 -        public boolean b3() default false;
  118.62 -        public int     i1();
  118.63 -        public int     i2() default 1;
  118.64 -        public int     i3() default 1;
  118.65 -        public String  s1();
  118.66 -        public String  s2() default "";
  118.67 -        public String  s3() default "";
  118.68 -        public TestAnnotation2 a1();
  118.69 -//        public TestAnnotation2 a2() default @TestAnnotation2(a1=@TestAnnotation3(as1={"a", "b"}, as3="c"));
  118.70 -//        public TestAnnotation2 a3() default @TestAnnotation2(a1=@TestAnnotation3(as1={"a2", "b2"}, as3="c2"));
  118.71 -        public Class   c1();
  118.72 -        public Class   c2() default Void.class;
  118.73 -        public Class   c3() default Void.class;
  118.74 -        public TestEnum e1();
  118.75 -//        public TestEnum e2() default TestEnum.A;
  118.76 -        public TestEnum e3()/* default TestEnum.A*/;
  118.77 -        public boolean[] ab1();
  118.78 -        public boolean[] ab2() default false;
  118.79 -        public boolean[] ab3() default false;
  118.80 -        public int[]     ai1();
  118.81 -        public int[]     ai2() default 1;
  118.82 -        public int[]     ai3() default 1;
  118.83 -        public String[]  as1();
  118.84 -        public String[]  as2() default "";
  118.85 -        public String[]  as3() default "";
  118.86 -        public TestAnnotation2[] aa1();
  118.87 -//        public TestAnnotation2[] aa2() default @TestAnnotation2(a1=@TestAnnotation3(as1={"a", "b"}, as3="c"));
  118.88 -//        public TestAnnotation2[] aa3() default @TestAnnotation2(a1=@TestAnnotation3(as1={"a2", "b2"}, as3="c2"));
  118.89 -        public Class[]   ac1();
  118.90 -        public Class[]   ac2() default Void.class;
  118.91 -        public Class[]   ac3() default Void.class;
  118.92 -        public TestEnum[] ae1();
  118.93 -//        public TestEnum[] ae2() default TestEnum.A;
  118.94 -        public TestEnum[] ae3()/* default TestEnum.A*/;
  118.95 -    }
  118.96 -
  118.97 -    public @interface TestAnnotation2 {
  118.98 -        public TestAnnotation3 a1();
  118.99 -//        public TestAnnotation3 a2() default @TestAnnotation3(as1={"d", "e"}, as3="f");
 118.100 -//        public TestAnnotation3 a3() default @TestAnnotation3(as1={"g", "h"}, as3="i");
 118.101 -    }
 118.102 -
 118.103 -    public @interface TestAnnotation3 {
 118.104 -        public String[] as1();
 118.105 -        public String[] as2() default {""};
 118.106 -        public String[] as3() default {""};
 118.107 -    }
 118.108 -
 118.109 -    public enum TestEnum {
 118.110 -        A, B, C, D;
 118.111 -    }
 118.112 -}
   119.1 --- a/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/TestBase.java	Sun Oct 16 08:01:27 2016 +0200
   119.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   119.3 @@ -1,124 +0,0 @@
   119.4 -/*
   119.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   119.6 - *
   119.7 - * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
   119.8 - *
   119.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  119.10 - * Other names may be trademarks of their respective owners.
  119.11 - *
  119.12 - * The contents of this file are subject to the terms of either the GNU
  119.13 - * General Public License Version 2 only ("GPL") or the Common
  119.14 - * Development and Distribution License("CDDL") (collectively, the
  119.15 - * "License"). You may not use this file except in compliance with the
  119.16 - * License. You can obtain a copy of the License at
  119.17 - * http://www.netbeans.org/cddl-gplv2.html
  119.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  119.19 - * specific language governing permissions and limitations under the
  119.20 - * License.  When distributing the software, include this License Header
  119.21 - * Notice in each file and include the License file at
  119.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  119.23 - * particular file as subject to the "Classpath" exception as provided
  119.24 - * by Oracle in the GPL Version 2 section of the License file that
  119.25 - * accompanied this code. If applicable, add the following below the
  119.26 - * License Header, with the fields enclosed by brackets [] replaced by
  119.27 - * your own identifying information:
  119.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  119.29 - *
  119.30 - * If you wish your version of this file to be governed by only the CDDL
  119.31 - * or only the GPL Version 2, indicate your decision by adding
  119.32 - * "[Contributor] elects to include this software in this distribution
  119.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  119.34 - * single choice of license, a recipient has the option to distribute
  119.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  119.36 - * to extend the choice of license to its licensees as provided above.
  119.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  119.38 - * Version 2 license, then the option applies only if the new code is
  119.39 - * made subject to such option by the copyright holder.
  119.40 - *
  119.41 - * Contributor(s):
  119.42 - *
  119.43 - * Portions Copyrighted 2008-2009 Sun Microsystems, Inc.
  119.44 - */
  119.45 -
  119.46 -package org.netbeans.modules.java.hints.spiimpl;
  119.47 -
  119.48 -import java.io.File;
  119.49 -import javax.swing.text.Document;
  119.50 -import org.netbeans.api.java.lexer.JavaTokenId;
  119.51 -import org.netbeans.api.java.source.CompilationInfo;
  119.52 -import org.netbeans.api.java.source.JavaSource;
  119.53 -import org.netbeans.api.java.source.JavaSource.Phase;
  119.54 -import org.netbeans.api.java.source.SourceUtilsTestUtil;
  119.55 -import org.netbeans.api.java.source.TestUtilities;
  119.56 -import org.netbeans.api.lexer.Language;
  119.57 -import org.netbeans.junit.NbTestCase;
  119.58 -import org.netbeans.modules.java.source.TreeLoader;
  119.59 -import org.openide.cookies.EditorCookie;
  119.60 -import org.openide.filesystems.FileObject;
  119.61 -import org.openide.filesystems.FileUtil;
  119.62 -import org.openide.loaders.DataObject;
  119.63 -
  119.64 -/**
  119.65 - *
  119.66 - * @author Jan Lahoda
  119.67 - */
  119.68 -public class TestBase extends NbTestCase {
  119.69 -
  119.70 -    public TestBase(String name) {
  119.71 -        super(name);
  119.72 -    }
  119.73 -
  119.74 -    @Override
  119.75 -    protected void setUp() throws Exception {
  119.76 -        super.setUp();
  119.77 -        SourceUtilsTestUtil.prepareTest(new String[0], new Object[0]);
  119.78 -        TreeLoader.DISABLE_CONFINEMENT_TEST = true;
  119.79 -        clearWorkDir();
  119.80 -
  119.81 -        FileUtil.refreshFor(File.listRoots());
  119.82 -    }
  119.83 -
  119.84 -    private int workDirPart = 0;
  119.85 -    
  119.86 -    protected void prepareTest(String fileName, String code) throws Exception {
  119.87 -        FileObject workFO = FileUtil.createFolder(new File(getWorkDir(), String.valueOf(workDirPart++)));
  119.88 -
  119.89 -        assertNotNull(workFO);
  119.90 -
  119.91 -        workFO.refresh();
  119.92 -
  119.93 -        sourceRoot = workFO.createFolder("src");
  119.94 -        FileObject buildRoot  = workFO.createFolder("build");
  119.95 -        FileObject cache = workFO.createFolder("cache");
  119.96 -
  119.97 -        FileObject data = FileUtil.createData(sourceRoot, fileName);
  119.98 -        File dataFile = FileUtil.toFile(data);
  119.99 -
 119.100 -        assertNotNull(dataFile);
 119.101 -
 119.102 -        TestUtilities.copyStringToFile(dataFile, code);
 119.103 -
 119.104 -        SourceUtilsTestUtil.prepareTest(sourceRoot, buildRoot, cache);
 119.105 -
 119.106 -        DataObject od = DataObject.find(data);
 119.107 -        EditorCookie ec = od.getLookup().lookup(EditorCookie.class);
 119.108 -
 119.109 -        assertNotNull(ec);
 119.110 -
 119.111 -        doc = ec.openDocument();
 119.112 -        doc.putProperty(Language.class, JavaTokenId.language());
 119.113 -
 119.114 -        JavaSource js = JavaSource.forFileObject(data);
 119.115 -
 119.116 -        assertNotNull(js);
 119.117 -
 119.118 -        info = SourceUtilsTestUtil.getCompilationInfo(js, Phase.RESOLVED);
 119.119 -
 119.120 -        assertNotNull(info);
 119.121 -    }
 119.122 -
 119.123 -    protected FileObject sourceRoot;
 119.124 -    protected CompilationInfo info;
 119.125 -    protected Document doc;
 119.126 -
 119.127 -}
   120.1 --- a/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/TestCompilerSettings.java	Sun Oct 16 08:01:27 2016 +0200
   120.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   120.3 @@ -1,60 +0,0 @@
   120.4 -/*
   120.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   120.6 - *
   120.7 - * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
   120.8 - *
   120.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  120.10 - * Other names may be trademarks of their respective owners.
  120.11 - *
  120.12 - * The contents of this file are subject to the terms of either the GNU
  120.13 - * General Public License Version 2 only ("GPL") or the Common
  120.14 - * Development and Distribution License("CDDL") (collectively, the
  120.15 - * "License"). You may not use this file except in compliance with the
  120.16 - * License. You can obtain a copy of the License at
  120.17 - * http://www.netbeans.org/cddl-gplv2.html
  120.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  120.19 - * specific language governing permissions and limitations under the
  120.20 - * License.  When distributing the software, include this License Header
  120.21 - * Notice in each file and include the License file at
  120.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  120.23 - * particular file as subject to the "Classpath" exception as provided
  120.24 - * by Oracle in the GPL Version 2 section of the License file that
  120.25 - * accompanied this code. If applicable, add the following below the
  120.26 - * License Header, with the fields enclosed by brackets [] replaced by
  120.27 - * your own identifying information:
  120.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  120.29 - *
  120.30 - * If you wish your version of this file to be governed by only the CDDL
  120.31 - * or only the GPL Version 2, indicate your decision by adding
  120.32 - * "[Contributor] elects to include this software in this distribution
  120.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  120.34 - * single choice of license, a recipient has the option to distribute
  120.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  120.36 - * to extend the choice of license to its licensees as provided above.
  120.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  120.38 - * Version 2 license, then the option applies only if the new code is
  120.39 - * made subject to such option by the copyright holder.
  120.40 - *
  120.41 - * Contributor(s):
  120.42 - *
  120.43 - * Portions Copyrighted 2013 Sun Microsystems, Inc.
  120.44 - */
  120.45 -package org.netbeans.modules.java.hints.spiimpl;
  120.46 -
  120.47 -import org.netbeans.modules.java.source.tasklist.CompilerSettings;
  120.48 -import org.openide.filesystems.FileObject;
  120.49 -import org.openide.util.lookup.ServiceProvider;
  120.50 -
  120.51 -/**
  120.52 - *
  120.53 - * @author lahvac
  120.54 - */
  120.55 -@ServiceProvider(service=CompilerSettings.class, position=0, supersedes="org.netbeans.modules.java.hints.StandardJavacWarnings$CompilerSettingsImpl")
  120.56 -public class TestCompilerSettings extends CompilerSettings {
  120.57 -    public static String commandLine;
  120.58 -    @Override
  120.59 -    protected String buildCommandLine(FileObject file) {
  120.60 -        return commandLine;
  120.61 -    }
  120.62 -    
  120.63 -}
   121.1 --- a/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/TestUtilities.java	Sun Oct 16 08:01:27 2016 +0200
   121.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   121.3 @@ -1,67 +0,0 @@
   121.4 -/*
   121.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   121.6 - *
   121.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
   121.8 - *
   121.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  121.10 - * Other names may be trademarks of their respective owners.
  121.11 - *
  121.12 - * The contents of this file are subject to the terms of either the GNU
  121.13 - * General Public License Version 2 only ("GPL") or the Common
  121.14 - * Development and Distribution License("CDDL") (collectively, the
  121.15 - * "License"). You may not use this file except in compliance with the
  121.16 - * License. You can obtain a copy of the License at
  121.17 - * http://www.netbeans.org/cddl-gplv2.html
  121.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  121.19 - * specific language governing permissions and limitations under the
  121.20 - * License.  When distributing the software, include this License Header
  121.21 - * Notice in each file and include the License file at
  121.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  121.23 - * particular file as subject to the "Classpath" exception as provided
  121.24 - * by Oracle in the GPL Version 2 section of the License file that
  121.25 - * accompanied this code. If applicable, add the following below the
  121.26 - * License Header, with the fields enclosed by brackets [] replaced by
  121.27 - * your own identifying information:
  121.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  121.29 - *
  121.30 - * Contributor(s):
  121.31 - *
  121.32 - * Portions Copyrighted 2007 Sun Microsystems, Inc.
  121.33 - */
  121.34 -package org.netbeans.modules.java.hints.spiimpl;
  121.35 -
  121.36 -import junit.framework.Assert;
  121.37 -
  121.38 -/**
  121.39 - *
  121.40 - * @author Jan Lahoda
  121.41 - */
  121.42 -public class TestUtilities {
  121.43 -
  121.44 -    private TestUtilities() {
  121.45 -    }
  121.46 -
  121.47 -    public static String detectOffsets(String source, int[] positionOrSpan) {
  121.48 -        return detectOffsets(source, positionOrSpan, "\\|");
  121.49 -    }
  121.50 -
  121.51 -    public static String detectOffsets(String source, int[] positionOrSpan, String delimiter) {
  121.52 -        //for now, the position/span delimiter is '|', without possibility of escaping:
  121.53 -        String[] split = source.split(delimiter);
  121.54 -        
  121.55 -        Assert.assertTrue("incorrect number of position markers (|)", positionOrSpan.length == split.length - 1);
  121.56 -        
  121.57 -        StringBuilder sb = new StringBuilder();
  121.58 -        int index = 0;
  121.59 -        int offset = 0;
  121.60 -        
  121.61 -        for (String s : split) {
  121.62 -            sb.append(s);
  121.63 -            if (index < positionOrSpan.length)
  121.64 -                positionOrSpan[index++] = (offset += s.length());
  121.65 -        }
  121.66 -        
  121.67 -        return sb.toString();
  121.68 -    }
  121.69 -
  121.70 -}
   122.1 --- a/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/UtilitiesTest.java	Sun Oct 16 08:01:27 2016 +0200
   122.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   122.3 @@ -1,644 +0,0 @@
   122.4 -/*
   122.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   122.6 - *
   122.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
   122.8 - *
   122.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  122.10 - * Other names may be trademarks of their respective owners.
  122.11 - *
  122.12 - * The contents of this file are subject to the terms of either the GNU
  122.13 - * General Public License Version 2 only ("GPL") or the Common
  122.14 - * Development and Distribution License("CDDL") (collectively, the
  122.15 - * "License"). You may not use this file except in compliance with the
  122.16 - * License. You can obtain a copy of the License at
  122.17 - * http://www.netbeans.org/cddl-gplv2.html
  122.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  122.19 - * specific language governing permissions and limitations under the
  122.20 - * License.  When distributing the software, include this License Header
  122.21 - * Notice in each file and include the License file at
  122.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  122.23 - * particular file as subject to the "Classpath" exception as provided
  122.24 - * by Oracle in the GPL Version 2 section of the License file that
  122.25 - * accompanied this code. If applicable, add the following below the
  122.26 - * License Header, with the fields enclosed by brackets [] replaced by
  122.27 - * your own identifying information:
  122.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  122.29 - *
  122.30 - * If you wish your version of this file to be governed by only the CDDL
  122.31 - * or only the GPL Version 2, indicate your decision by adding
  122.32 - * "[Contributor] elects to include this software in this distribution
  122.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  122.34 - * single choice of license, a recipient has the option to distribute
  122.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  122.36 - * to extend the choice of license to its licensees as provided above.
  122.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  122.38 - * Version 2 license, then the option applies only if the new code is
  122.39 - * made subject to such option by the copyright holder.
  122.40 - *
  122.41 - * Contributor(s):
  122.42 - *
  122.43 - * Portions Copyrighted 2009-2010 Sun Microsystems, Inc.
  122.44 - */
  122.45 -
  122.46 -package org.netbeans.modules.java.hints.spiimpl;
  122.47 -
  122.48 -import com.sun.source.tree.IfTree;
  122.49 -import com.sun.source.tree.LambdaExpressionTree;
  122.50 -import com.sun.source.tree.MemberSelectTree;
  122.51 -import com.sun.source.tree.ModifiersTree;
  122.52 -import com.sun.source.tree.Scope;
  122.53 -import com.sun.source.tree.Tree;
  122.54 -import com.sun.source.tree.Tree.Kind;
  122.55 -import com.sun.source.tree.VariableTree;
  122.56 -import com.sun.source.util.SourcePositions;
  122.57 -import com.sun.source.util.TreePath;
  122.58 -import com.sun.source.util.TreeScanner;
  122.59 -import com.sun.tools.javac.tree.JCTree;
  122.60 -import java.util.ArrayList;
  122.61 -import java.util.Arrays;
  122.62 -import java.util.Collection;
  122.63 -import java.util.Collections;
  122.64 -import java.util.LinkedList;
  122.65 -import java.util.List;
  122.66 -import javax.lang.model.element.Element;
  122.67 -import javax.lang.model.element.ElementKind;
  122.68 -import javax.lang.model.type.TypeMirror;
  122.69 -import javax.tools.Diagnostic;
  122.70 -import javax.tools.JavaFileObject;
  122.71 -import org.netbeans.api.java.classpath.ClassPath;
  122.72 -import org.netbeans.api.java.source.ClasspathInfo;
  122.73 -import org.netbeans.api.java.source.CompilationController;
  122.74 -import org.netbeans.api.java.source.JavaSource;
  122.75 -import org.netbeans.api.java.source.JavaSource.Phase;
  122.76 -import org.netbeans.api.java.source.Task;
  122.77 -import org.netbeans.junit.RandomlyFails;
  122.78 -import org.netbeans.modules.java.source.pretty.VeryPretty;
  122.79 -import org.netbeans.modules.java.source.save.DiffContext;
  122.80 -
  122.81 -/**
  122.82 - *
  122.83 - * @author lahvac
  122.84 - */
  122.85 -public class UtilitiesTest extends TestBase {
  122.86 -
  122.87 -    public UtilitiesTest(String name) {
  122.88 -        super(name);
  122.89 -    }
  122.90 -
  122.91 -    public void testParseAndAttributeExpressionStatement() throws Exception {
  122.92 -        prepareTest("test/Test.java", "package test; public class Test{}");
  122.93 -
  122.94 -        Scope s = Utilities.constructScope(info, Collections.singletonMap("$1", info.getTreeUtilities().parseType("int", info.getTopLevelElements().get(0))));
  122.95 -        Tree result = Utilities.parseAndAttribute(info, "$1 = 1;", s);
  122.96 -
  122.97 -        assertTrue(result.getKind().name(), result.getKind() == Kind.EXPRESSION_STATEMENT);
  122.98 -    }
  122.99 -
 122.100 -    public void testParseAndAttributeVariable() throws Exception {
 122.101 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.102 -
 122.103 -        Scope s = Utilities.constructScope(info, Collections.singletonMap("$1", info.getTreeUtilities().parseType("int", info.getTopLevelElements().get(0))));
 122.104 -        Tree result = Utilities.parseAndAttribute(info, "int $2 = $1;", s);
 122.105 -
 122.106 -        assertTrue(result.getKind().name(), result.getKind() == Kind.VARIABLE);
 122.107 -    }
 122.108 -
 122.109 -    public void testParseAndAttributeMultipleStatements() throws Exception {
 122.110 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.111 -
 122.112 -        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 122.113 -        Tree result = Utilities.parseAndAttribute(info, "String $2 = $1; int $l = $2.length(); System.err.println($l);", s);
 122.114 -
 122.115 -        assertTrue(result.getKind().name(), result.getKind() == Kind.BLOCK);
 122.116 -
 122.117 -        String golden = "{\n" +
 122.118 -                        "    $$1$;\n" +
 122.119 -                        "    String $2 = $1;\n" +
 122.120 -                        "    int $l = $2.length();\n" +
 122.121 -                        "    System.err.println($l);\n" +
 122.122 -                        "    $$2$;\n" +
 122.123 -                        "}";
 122.124 -        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 122.125 -    }
 122.126 -
 122.127 -    public void testParseAndAttributeMethod() throws Exception {
 122.128 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.129 -
 122.130 -        Scope s = Utilities.constructScope(info, Collections.singletonMap("$1", info.getTreeUtilities().parseType("int", info.getTopLevelElements().get(0))));
 122.131 -        String methodCode = "private int test(int i) { return i; }";
 122.132 -        Tree result = Utilities.parseAndAttribute(info, methodCode, s);
 122.133 -
 122.134 -        assertEquals(Kind.METHOD, result.getKind());
 122.135 -        assertEquals(methodCode.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " ").trim());
 122.136 -    }
 122.137 -
 122.138 -    public void testParseAndAttributeMultipleClassMembers() throws Exception {
 122.139 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.140 -
 122.141 -        Scope s = Utilities.constructScope(info, Collections.singletonMap("$1", info.getTreeUtilities().parseType("int", info.getTopLevelElements().get(0))));
 122.142 -        String code = "private int i; private int getI() { return i; } private void setI(int i) { this.i = i; }";
 122.143 -        Tree result = Utilities.parseAndAttribute(info, code, s);
 122.144 -
 122.145 -        String golden = "class $ {\n" +
 122.146 -                        "    $$1$;\n" +
 122.147 -                        "    private int i;\n" +
 122.148 -                        "    private int getI() {\n" +
 122.149 -                        "        return i;\n" +
 122.150 -                        "    }\n" +
 122.151 -                        "    private void setI(int i) {\n" +
 122.152 -                        "        this.i = i;\n" +
 122.153 -                        "    }\n" +
 122.154 -                        "}";
 122.155 -
 122.156 -        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " ").trim());
 122.157 -    }
 122.158 -
 122.159 -    public void testParseAndAttributeFieldModifiersVariable() throws Exception {
 122.160 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.161 -
 122.162 -        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 122.163 -        String code = "$mods$ java.lang.String $name;";
 122.164 -        Tree result = Utilities.parseAndAttribute(info, code, s);
 122.165 -
 122.166 -        String golden = "$mods$ java.lang.String $name";
 122.167 -
 122.168 -        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " ").trim());
 122.169 -    }
 122.170 -
 122.171 -    public void testParseAndAttributeIfWithParenthetised() throws Exception {
 122.172 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.173 -
 122.174 -        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 122.175 -        String code = "if ($c) { $1$; System.err.println('a'); $2$; }";
 122.176 -        Tree result = Utilities.parseAndAttribute(info, code, s);
 122.177 -
 122.178 -        IfTree it = (IfTree) result;
 122.179 -
 122.180 -        assertEquals(Kind.PARENTHESIZED, it.getCondition().getKind());
 122.181 -
 122.182 -        String golden = "if ($c) { $1$; System.err.println('a'); $2$; }";
 122.183 -
 122.184 -        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " ").trim());
 122.185 -    }
 122.186 -
 122.187 -    public void testParseAndAttributeMultipleStatements2() throws Exception {
 122.188 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.189 -
 122.190 -        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 122.191 -        Tree result = Utilities.parseAndAttribute(info, "$type $name = $map.get($key); if ($name == null) { $map.put($key, $name = $init); }", s);
 122.192 -
 122.193 -        assertTrue(result.getKind().name(), result.getKind() == Kind.BLOCK);
 122.194 -
 122.195 -        String golden = "{" +
 122.196 -                        "    $$1$;" +
 122.197 -                        "    $type $name = $map.get($key);" +
 122.198 -                        "    if ($name == null) {" +
 122.199 -                        "        $map.put($key, $name = $init);" +
 122.200 -                        "    }" +
 122.201 -                        "    $$2$;\n" +
 122.202 -                        "}";
 122.203 -        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 122.204 -    }
 122.205 -
 122.206 -    public void testParseAndAttributeMethodDeclarationWithMultiparameters() throws Exception {
 122.207 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.208 -
 122.209 -        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 122.210 -        Tree result = Utilities.parseAndAttribute(info, "public void t($params$) {}", s);
 122.211 -
 122.212 -        assertTrue(result.getKind().name(), result.getKind() == Kind.METHOD);
 122.213 -
 122.214 -        String golden = " public void t($params$) { }";
 122.215 -        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 122.216 -    }
 122.217 -
 122.218 -    public void testParseAndAttributeMethodModifiersVariable() throws Exception {
 122.219 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.220 -
 122.221 -        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 122.222 -        String code = "$mods$ $type $name() { $r$; }";
 122.223 -        Tree result = Utilities.parseAndAttribute(info, code, s);
 122.224 -
 122.225 -        String golden = "$mods$ $type $name() { $r$; }";
 122.226 -
 122.227 -        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " ").trim());
 122.228 -    }
 122.229 -
 122.230 -    public void testSimpleExpression() throws Exception {
 122.231 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.232 -
 122.233 -        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 122.234 -        Tree result = Utilities.parseAndAttribute(info, "$1.isDirectory()", s);
 122.235 -
 122.236 -        assertTrue(result.getKind().name(), result.getKind() == Kind.METHOD_INVOCATION);
 122.237 -
 122.238 -        String golden = "$1.isDirectory()";
 122.239 -        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 122.240 -    }
 122.241 -    
 122.242 -    public void testARMResourceVariable1() throws Exception {
 122.243 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.244 -
 122.245 -        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 122.246 -        Tree result = Utilities.parseAndAttribute(info, "try ($t$) { $stmts$; } catch $catches$", s);
 122.247 -
 122.248 -        assertTrue(result.getKind().name(), result.getKind() == Kind.TRY);
 122.249 -
 122.250 -        String golden = "try ($t$) { $stmts$; }$catches$";
 122.251 -        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 122.252 -    }
 122.253 -    
 122.254 -    public void testARMResourceVariable2() throws Exception {
 122.255 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.256 -
 122.257 -        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 122.258 -        Tree result = Utilities.parseAndAttribute(info, "try ($t$; $type $name = $init) { $stmts$; } catch $catches$", s);
 122.259 -
 122.260 -        assertTrue(result.getKind().name(), result.getKind() == Kind.TRY);
 122.261 -
 122.262 -        String golden = "try ($t$ final $type $name = $init;) { $stmts$; }$catches$";
 122.263 -        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 122.264 -    }
 122.265 -    
 122.266 -    public void testARMResourceNotVariable() throws Exception {
 122.267 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.268 -
 122.269 -        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 122.270 -        Tree result = Utilities.parseAndAttribute(info, "try ($t $n = $init$) { $stmts$; } catch $catches$", s);
 122.271 -
 122.272 -        assertTrue(result.getKind().name(), result.getKind() == Kind.TRY);
 122.273 -
 122.274 -        String golden = "try (final $t $n = $init$;) { $stmts$; }$catches$";
 122.275 -        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 122.276 -    }
 122.277 -
 122.278 -    public void testParseAndAttributeType() throws Exception {
 122.279 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.280 -
 122.281 -        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 122.282 -        Tree result = Utilities.parseAndAttribute(info, "\njava. util \n.List \n", s);
 122.283 -
 122.284 -        assertTrue(result.getKind().name(), result.getKind() == Kind.MEMBER_SELECT);
 122.285 -
 122.286 -        assertEquals(ElementKind.INTERFACE, info.getTrees().getElement(new TreePath(new TreePath(info.getCompilationUnit()), result)).getKind());
 122.287 -        assertEquals(info.getElements().getTypeElement("java.util.List"), info.getTrees().getElement(new TreePath(new TreePath(info.getCompilationUnit()), result)));
 122.288 -    }
 122.289 -    
 122.290 -    public void testCatchMultiparam() throws Exception {
 122.291 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.292 -
 122.293 -        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 122.294 -        Tree result = Utilities.parseAndAttribute(info, "try {\n }\n catch $catch$ finally {\n }\n", s);
 122.295 -
 122.296 -        assertTrue(result.getKind().name(), result.getKind() == Kind.TRY);
 122.297 -
 122.298 -        String golden = "try {\n }$catch$ finally {\n }";
 122.299 -        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 122.300 -    }
 122.301 -
 122.302 -    public void testCaseMultiparam() throws Exception {
 122.303 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.304 -
 122.305 -        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 122.306 -        Tree result = Utilities.parseAndAttribute(info, "switch ($v) {case $c1$ case 1: ; case $c2$; case 3: ;}", s);
 122.307 -
 122.308 -        assertTrue(result.getKind().name(), result.getKind() == Kind.SWITCH);
 122.309 -
 122.310 -        String golden = "switch ($v) { $c1$ case 1: ; $c2$ case 3: ; }";
 122.311 -        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 122.312 -    }
 122.313 -    
 122.314 -    public void testOrdinaryCatch() throws Exception {
 122.315 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.316 -
 122.317 -        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 122.318 -        Tree result = Utilities.parseAndAttribute(info, "try {\n }\n catch (NullPointerException ex) { } finally {\n }\n", s);
 122.319 -
 122.320 -        assertTrue(result.getKind().name(), result.getKind() == Kind.TRY);
 122.321 -
 122.322 -        String golden = "try {\n } catch (NullPointerException ex) { } finally {\n }";
 122.323 -        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 122.324 -    }
 122.325 -    
 122.326 -    public void testClassPattern() throws Exception {
 122.327 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.328 -
 122.329 -        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 122.330 -        Tree result = Utilities.parseAndAttribute(info, "$mods$ class $name extends java.util.LinkedList { $methods$; }\n", s);
 122.331 -
 122.332 -        assertTrue(result.getKind().name(), result.getKind() == Kind.CLASS);
 122.333 -
 122.334 -        String golden = " $mods$ class $name extends java.util.LinkedList { $name() { super(); } $methods$ }";
 122.335 -        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 122.336 -    }
 122.337 -
 122.338 -    public void testErrorsForPatterns1() throws Exception {
 122.339 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.340 -
 122.341 -        SourcePositions[] positions = new SourcePositions[1];
 122.342 -        Collection<Diagnostic<? extends JavaFileObject>> errors = new LinkedList<Diagnostic<? extends JavaFileObject>>();
 122.343 -        String code = "foo bar";
 122.344 -        Tree result = Utilities.parseAndAttribute(info, code, null, positions, errors);
 122.345 -
 122.346 -        assertDiagnostics(errors, "7-7:compiler.err.expected");
 122.347 -        assertPositions(result, positions[0], code, "foo", "foo bar");
 122.348 -    }
 122.349 -
 122.350 -    @RandomlyFails
 122.351 -    public void testErrorsForPatterns2() throws Exception {
 122.352 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.353 -
 122.354 -        SourcePositions[] positions = new SourcePositions[1];
 122.355 -        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 122.356 -        Collection<Diagnostic<? extends JavaFileObject>> errors = new LinkedList<Diagnostic<? extends JavaFileObject>>();
 122.357 -        String code = "$1.isDirectory()";
 122.358 -        Tree result = Utilities.parseAndAttribute(info, code, s, positions, errors);
 122.359 -
 122.360 -        assertDiagnostics(errors, "0-0:compiler.err.cant.resolve.location");
 122.361 -        assertPositions(result, positions[0], code, "$1", "$1.isDirectory", "$1.isDirectory()");
 122.362 -    }
 122.363 -
 122.364 -    public void testErrorsForPatterns3() throws Exception {
 122.365 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.366 -
 122.367 -        SourcePositions[] positions = new SourcePositions[1];
 122.368 -        Collection<Diagnostic<? extends JavaFileObject>> errors = new LinkedList<Diagnostic<? extends JavaFileObject>>();
 122.369 -        String code = "if ($cond) { foo() } else $else;";
 122.370 -        Tree result = Utilities.parseAndAttribute(info, code, null, positions, errors);
 122.371 -
 122.372 -        assertDiagnostics(errors, "18-18:compiler.err.expected");
 122.373 -        assertPositions(result, positions[0], code, "$cond", "$else", "$else;", "($cond)", "foo", "foo()", "foo() ", "if ($cond) { foo() } else $else;", "{ foo() }");
 122.374 -    }
 122.375 -
 122.376 -    public void testPositionsForCorrectStatement() throws Exception {
 122.377 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.378 -
 122.379 -        SourcePositions[] positions = new SourcePositions[1];
 122.380 -        Collection<Diagnostic<? extends JavaFileObject>> errors = new LinkedList<Diagnostic<? extends JavaFileObject>>();
 122.381 -        String code = "assert true;";
 122.382 -        Tree result = Utilities.parseAndAttribute(info, code, null, positions, errors);
 122.383 -
 122.384 -        assertTrue(errors.isEmpty());
 122.385 -        assertPositions(result, positions[0], code, "assert true;", "true");
 122.386 -    }
 122.387 -
 122.388 -    public void testCasePattern() throws Exception {
 122.389 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.390 -
 122.391 -        SourcePositions[] positions = new SourcePositions[1];
 122.392 -        Collection<Diagnostic<? extends JavaFileObject>> errors = new LinkedList<Diagnostic<? extends JavaFileObject>>();
 122.393 -        String code = "case $expr: foo bar $stmts$;\n";
 122.394 -        Tree result = Utilities.parseAndAttribute(info, code, null, positions, errors);
 122.395 -
 122.396 -        assertTrue(result.getKind().name(), result.getKind() == Kind.CASE);
 122.397 -
 122.398 -        String golden = "case $expr: foo bar; $stmts$; ";
 122.399 -        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 122.400 -        assertDiagnostics(errors, "19-19:compiler.err.expected");
 122.401 -        assertPositions(result, positions[0], code, "$expr", "$stmts$", "$stmts$;", "case $expr: foo bar $stmts$;", "foo", "foo bar ");
 122.402 -    }
 122.403 -
 122.404 -    public void testLambdaPattern() throws Exception {
 122.405 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.406 -
 122.407 -        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 122.408 -        Tree result = Utilities.parseAndAttribute(info, "new $type() {\n $mods$ $resultType $methodName($args$) {\n $statements$;\n }\n }\n", s);
 122.409 -
 122.410 -        assertTrue(result.getKind().name(), result.getKind() == Kind.NEW_CLASS);
 122.411 -
 122.412 -        String golden = "new $type(){ $mods$ $resultType $methodName($args$) { $statements$; } }";
 122.413 -        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 122.414 -
 122.415 -        Collection<Diagnostic<? extends JavaFileObject>> errors = new LinkedList<Diagnostic<? extends JavaFileObject>>();
 122.416 -
 122.417 -        result = Utilities.parseAndAttribute(info, "new $type() {\n $mods$ $resultType $methodName($args$) {\n $statements$;\n }\n }\n", null, errors);
 122.418 -        assertTrue(result.getKind().name(), result.getKind() == Kind.NEW_CLASS);
 122.419 -
 122.420 -        golden = "new $type(){ $mods$ $resultType $methodName($args$) { $statements$; } }";
 122.421 -        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 122.422 -        assertTrue(errors.toString(), errors.isEmpty());
 122.423 -    }
 122.424 -    
 122.425 -    public void testPackagePattern() throws Exception {
 122.426 -        prepareTest("test/a/Test.java", "package test.a; public class Test{}");
 122.427 -
 122.428 -        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 122.429 -        Tree result = Utilities.parseAndAttribute(info, "test.$1", s);
 122.430 -
 122.431 -        assertTrue(result.getKind().name(), result.getKind() == Kind.MEMBER_SELECT);
 122.432 -
 122.433 -        String golden = "test.$1";
 122.434 -        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 122.435 -        
 122.436 -        Element total = info.getTrees().getElement(new TreePath(new TreePath(info.getCompilationUnit()), result));
 122.437 -        
 122.438 -        assertTrue(Utilities.isError(total));
 122.439 -        
 122.440 -        Element testPack = info.getTrees().getElement(new TreePath(new TreePath(info.getCompilationUnit()), ((MemberSelectTree) result).getExpression()));
 122.441 -
 122.442 -        assertFalse(Utilities.isError(testPack));
 122.443 -        assertEquals(info.getElements().getPackageElement("test"), testPack);
 122.444 -    }
 122.445 -
 122.446 -    public void DtestMultiStatementVarWithModifiers() throws Exception {
 122.447 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.448 -
 122.449 -        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 122.450 -        Tree result = Utilities.parseAndAttribute(info, "$mods$ $type $name; $name = $init;", s);
 122.451 -
 122.452 -        assertTrue(result.getKind().name(), result.getKind() == Kind.BLOCK);
 122.453 -
 122.454 -        String golden = "{ $$1$; $mods$$type $name; $name = $init; $$2$; }";
 122.455 -        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 122.456 -    }
 122.457 -    
 122.458 -    public void testAnnotation() throws Exception {
 122.459 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.460 -
 122.461 -        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 122.462 -        Tree result = Utilities.parseAndAttribute(info, "@$annotation($args$)", s);
 122.463 -
 122.464 -        assertTrue(result.getKind().name(), result.getKind() == Kind.ANNOTATION);
 122.465 -
 122.466 -        String golden = "@$annotation(value = $args$)";
 122.467 -        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 122.468 -    }
 122.469 -
 122.470 -    public void testParseAndAttributeMultipleStatementsWithBefore() throws Exception {
 122.471 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.472 -
 122.473 -        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 122.474 -        Tree result = Utilities.parseAndAttribute(info, "$before$; String $2 = $1; int $l = $2.length(); System.err.println($l);", s);
 122.475 -
 122.476 -        assertTrue(result.getKind().name(), result.getKind() == Kind.BLOCK);
 122.477 -
 122.478 -        String golden = "{\n" +
 122.479 -                        "    $before$;\n" +
 122.480 -                        "    String $2 = $1;\n" +
 122.481 -                        "    int $l = $2.length();\n" +
 122.482 -                        "    System.err.println($l);\n" +
 122.483 -                        "    $$2$;\n" +
 122.484 -                        "}";
 122.485 -        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 122.486 -    }
 122.487 -    
 122.488 -    public void testParseAndAttributeMultipleStatementsWithAfter() throws Exception {
 122.489 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.490 -
 122.491 -        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 122.492 -        Tree result = Utilities.parseAndAttribute(info, "String $2 = $1; int $l = $2.length(); System.err.println($l); $after$;", s);
 122.493 -
 122.494 -        assertTrue(result.getKind().name(), result.getKind() == Kind.BLOCK);
 122.495 -
 122.496 -        String golden = "{\n" +
 122.497 -                        "    $$1$;\n" +
 122.498 -                        "    String $2 = $1;\n" +
 122.499 -                        "    int $l = $2.length();\n" +
 122.500 -                        "    System.err.println($l);\n" +
 122.501 -                        "    $after$;\n" +
 122.502 -                        "}";
 122.503 -        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 122.504 -    }
 122.505 -    
 122.506 -    public void testMethodFormalParams() throws Exception {
 122.507 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.508 -
 122.509 -        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 122.510 -        Tree result = Utilities.parseAndAttribute(info, "$mods$ $ret $name($pref$, $type $name, $suff$) throws $throws$ { $body$; }", s);
 122.511 -
 122.512 -        assertTrue(result.getKind().name(), result.getKind() == Kind.METHOD);
 122.513 -
 122.514 -        String golden = " $mods$ $ret $name($pref$, $type $name, $suff$) throws $throws$ { $body$; }";
 122.515 -        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 122.516 -    }
 122.517 -    
 122.518 -    public void testPartialModifiers() throws Exception {
 122.519 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.520 -
 122.521 -        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 122.522 -        Tree result = Utilities.parseAndAttribute(info, "$mods$ @Deprecated public $type $name;", s);
 122.523 -
 122.524 -        assertTrue(result.getKind().name(), result.getKind() == Kind.VARIABLE);
 122.525 -
 122.526 -        ModifiersTree mods = ((VariableTree) result).getModifiers();
 122.527 -        String golden = "$mods$,@Deprecated(), [public]";
 122.528 -        
 122.529 -        assertEquals(golden.replaceAll("[ \n\r]+", " "), mods.getAnnotations().toString() + ", " + mods.getFlags().toString());
 122.530 -    }
 122.531 -    
 122.532 -    public void testBrokenPlatform226678() throws Exception {
 122.533 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.534 -
 122.535 -        JavaSource.create(ClasspathInfo.create(ClassPath.EMPTY, ClassPath.EMPTY, ClassPath.EMPTY), info.getFileObject()).runUserActionTask(new Task<CompilationController>() {
 122.536 -            @Override public void run(CompilationController parameter) throws Exception {
 122.537 -                parameter.toPhase(Phase.RESOLVED);
 122.538 -                info = parameter;
 122.539 -            }
 122.540 -        }, true);
 122.541 -        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 122.542 -        String methodCode = "private int test(int i) { return i; }";
 122.543 -        Tree result = Utilities.parseAndAttribute(info, methodCode, s);
 122.544 -
 122.545 -        assertEquals(Kind.METHOD, result.getKind());
 122.546 -        assertEquals(methodCode.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " ").trim());
 122.547 -    }
 122.548 -    
 122.549 -    public void testLambdaExpression1() throws Exception {
 122.550 -        prepareTest("test/Test.java", "package test; public class Test{}");
 122.551 -
 122.552 -        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 122.553 -        Tree result = Utilities.parseAndAttribute(info, "($args$) -> $expression", s);
 122.554 -
 122.555 -        assertTrue(result.getKind().name(), result.getKind() == Kind.LAMBDA_EXPRESSION);
 122.556 -
 122.557 -        LambdaExpressionTree let = (LambdaExpressionTree) result;
 122.558 -        
 122.559 -        assertEquals(Kind.IDENTIFIER, let.getParameters().get(0).getKind());
 122.560 -        String golden = "($args$)->$expression";
 122.561 -        
 122.562 -        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString());
 122.563 -    }
 122.564 -    
 122.565 -    public void testToHumanReadableTime() {
 122.566 -        long time = 202;
 122.567 -        assertEquals(    "5s", Utilities.toHumanReadableTime(time +=           5 * 1000));
 122.568 -        assertEquals(  "3m5s", Utilities.toHumanReadableTime(time +=      3 * 60 * 1000));
 122.569 -        assertEquals("7h3m5s", Utilities.toHumanReadableTime(time += 7 * 60 * 60 * 1000));
 122.570 -    }
 122.571 -
 122.572 -    public void testGeneralization() throws Exception {
 122.573 -        performGeneralizationTest("package test;\n" +
 122.574 -                                  "public class Test {\n" +
 122.575 -                                  "    class Inner {\n" +
 122.576 -                                  "        Inner(int i) {}\n" +
 122.577 -                                  "    }\n" +
 122.578 -                                  "    public static void main(String[] args) {\n" +
 122.579 -                                  "        int i = 1;\n" +
 122.580 -                                  "        Test c = null;\n" +
 122.581 -                                  "        c.new Inner(i++) {};\n" +
 122.582 -                                  "    }\n" +
 122.583 -                                  "}\n",
 122.584 -                                  "package test;\n" +
 122.585 -                                  "public class Test {\n" +
 122.586 -                                  "    class Inner {\n" +
 122.587 -                                  "        Inner(int $0) { super(); }\n" +
 122.588 -                                  "    }\n" +
 122.589 -                                  "    public static void main(String[] $1) {\n" +
 122.590 -                                  "        int $2 = 1;\n" +
 122.591 -                                  "        Test $3 = null;\n" +
 122.592 -                                  "        $4;\n" + //XXX
 122.593 -                                  "    }\n" +
 122.594 -                                  "}\n");
 122.595 -    }
 122.596 -    private void performGeneralizationTest(String code, String generalized) throws Exception {
 122.597 -        prepareTest("test/Test.java", code);
 122.598 -
 122.599 -        Tree generalizedTree = Utilities.generalizePattern(info, new TreePath(info.getCompilationUnit()));
 122.600 -        VeryPretty vp = new VeryPretty(new DiffContext(info));
 122.601 -
 122.602 -        vp.print((JCTree) generalizedTree);
 122.603 -
 122.604 -        String repr = vp.toString();
 122.605 -
 122.606 -        assertEquals(generalized.replaceAll("[ \n\t]+", " "),
 122.607 -                     repr.replaceAll("[ \n\t]+", " "));
 122.608 -    }
 122.609 -
 122.610 -    private void assertDiagnostics(Collection<Diagnostic<? extends JavaFileObject>> errors, String... golden) {
 122.611 -        List<String> actual = new ArrayList<String>(errors.size());
 122.612 -
 122.613 -        for (Diagnostic<? extends JavaFileObject> d : errors) {
 122.614 -            actual.add(d.getStartPosition() + "-" + d.getEndPosition() + ":" + d.getCode());
 122.615 -        }
 122.616 -
 122.617 -        assertEquals(Arrays.asList(golden), actual);
 122.618 -    }
 122.619 -
 122.620 -    private void assertPositions(Tree t, final SourcePositions sp, final String code, String... golden) {
 122.621 -        final List<String> actual = new ArrayList<String>(golden.length);
 122.622 -
 122.623 -        new TreeScanner<Void, Void>() {
 122.624 -            @Override
 122.625 -            public Void scan(Tree node, Void p) {
 122.626 -                if (node != null) {
 122.627 -                    int start = (int) sp.getStartPosition(null, node);
 122.628 -                    int end = (int) sp.getEndPosition(null, node);
 122.629 -
 122.630 -                    if (start >= 0 && end >= 0) {
 122.631 -                        actual.add(code.substring(start, end));
 122.632 -                    }
 122.633 -                }
 122.634 -                return super.scan(node, p);
 122.635 -            }
 122.636 -        }.scan(t, null);
 122.637 -
 122.638 -        Collections.sort(actual);
 122.639 -
 122.640 -        List<String> goldenList = new ArrayList<String>(Arrays.asList(golden));
 122.641 -
 122.642 -        Collections.sort(goldenList);
 122.643 -
 122.644 -        assertEquals(goldenList, actual);
 122.645 -    }
 122.646 -
 122.647 -}
   123.1 --- a/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/batch/BatchSearchTest.java	Sun Oct 16 08:01:27 2016 +0200
   123.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   123.3 @@ -1,458 +0,0 @@
   123.4 -/*
   123.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   123.6 - *
   123.7 - * Copyright 2009-2011 Oracle and/or its affiliates. All rights reserved.
   123.8 - *
   123.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  123.10 - * Other names may be trademarks of their respective owners.
  123.11 - *
  123.12 - * The contents of this file are subject to the terms of either the GNU
  123.13 - * General Public License Version 2 only ("GPL") or the Common
  123.14 - * Development and Distribution License("CDDL") (collectively, the
  123.15 - * "License"). You may not use this file except in compliance with the
  123.16 - * License. You can obtain a copy of the License at
  123.17 - * http://www.netbeans.org/cddl-gplv2.html
  123.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  123.19 - * specific language governing permissions and limitations under the
  123.20 - * License.  When distributing the software, include this License Header
  123.21 - * Notice in each file and include the License file at
  123.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  123.23 - * particular file as subject to the "Classpath" exception as provided
  123.24 - * by Oracle in the GPL Version 2 section of the License file that
  123.25 - * accompanied this code. If applicable, add the following below the
  123.26 - * License Header, with the fields enclosed by brackets [] replaced by
  123.27 - * your own identifying information:
  123.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  123.29 - *
  123.30 - * If you wish your version of this file to be governed by only the CDDL
  123.31 - * or only the GPL Version 2, indicate your decision by adding
  123.32 - * "[Contributor] elects to include this software in this distribution
  123.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  123.34 - * single choice of license, a recipient has the option to distribute
  123.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  123.36 - * to extend the choice of license to its licensees as provided above.
  123.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  123.38 - * Version 2 license, then the option applies only if the new code is
  123.39 - * made subject to such option by the copyright holder.
  123.40 - *
  123.41 - * Contributor(s):
  123.42 - *
  123.43 - * Portions Copyrighted 2009-2011 Sun Microsystems, Inc.
  123.44 - */
  123.45 -package org.netbeans.modules.java.hints.spiimpl.batch;
  123.46 -
  123.47 -import org.netbeans.modules.java.hints.spiimpl.batch.TestUtils.File;
  123.48 -import org.netbeans.modules.java.hints.spiimpl.MessageImpl;
  123.49 -import org.netbeans.modules.java.hints.providers.spi.HintDescription;
  123.50 -import java.net.URL;
  123.51 -import java.util.ArrayList;
  123.52 -import java.util.Arrays;
  123.53 -import java.util.Collection;
  123.54 -import java.util.Collections;
  123.55 -import java.util.HashMap;
  123.56 -import java.util.HashSet;
  123.57 -import java.util.Iterator;
  123.58 -import java.util.LinkedList;
  123.59 -import java.util.List;
  123.60 -import java.util.Map;
  123.61 -import java.util.Map.Entry;
  123.62 -import java.util.Set;
  123.63 -import java.util.concurrent.atomic.AtomicBoolean;
  123.64 -import java.util.regex.Pattern;
  123.65 -import junit.framework.TestSuite;
  123.66 -import org.netbeans.api.java.classpath.ClassPath;
  123.67 -import org.netbeans.api.java.classpath.GlobalPathRegistry;
  123.68 -import org.netbeans.api.java.classpath.GlobalPathRegistryEvent;
  123.69 -import org.netbeans.api.java.classpath.GlobalPathRegistryListener;
  123.70 -import org.netbeans.api.java.source.CompilationController;
  123.71 -import org.netbeans.api.java.source.SourceUtilsTestUtil;
  123.72 -import org.netbeans.core.startup.Main;
  123.73 -import org.netbeans.junit.NbTestCase;
  123.74 -import org.netbeans.junit.NbTestSuite;
  123.75 -import org.netbeans.junit.RandomlyFails;
  123.76 -import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.BatchResult;
  123.77 -import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.Folder;
  123.78 -import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.Resource;
  123.79 -import org.netbeans.modules.parsing.impl.indexing.CacheFolder;
  123.80 -import org.netbeans.modules.parsing.impl.indexing.MimeTypes;
  123.81 -import org.netbeans.modules.parsing.impl.indexing.RepositoryUpdater;
  123.82 -import org.netbeans.spi.editor.hints.ErrorDescription;
  123.83 -import org.netbeans.spi.java.classpath.ClassPathProvider;
  123.84 -import org.netbeans.spi.java.classpath.support.ClassPathSupport;
  123.85 -import org.openide.filesystems.FileObject;
  123.86 -import org.openide.filesystems.FileStateInvalidException;
  123.87 -import org.openide.filesystems.FileUtil;
  123.88 -
  123.89 -import org.openide.util.Exceptions;
  123.90 -import org.openide.util.lookup.ServiceProvider;
  123.91 -import static org.netbeans.modules.java.hints.spiimpl.batch.TestUtils.writeFilesAndWaitForScan;
  123.92 -import static org.netbeans.modules.java.hints.spiimpl.batch.TestUtils.prepareHints;
  123.93 -
  123.94 -/**
  123.95 - *
  123.96 - * @author lahvac
  123.97 - */
  123.98 -public class BatchSearchTest extends NbTestCase {
  123.99 -
 123.100 -    public BatchSearchTest(String name) {
 123.101 -        super(name);
 123.102 -    }
 123.103 -
 123.104 -    public static TestSuite suite() {
 123.105 -        TestSuite result = new NbTestSuite();
 123.106 -
 123.107 -        result.addTestSuite(BatchSearchTest.class);
 123.108 -//        result.addTest(new BatchSearchTest("testBatchSearchFolderRemoteIndex"));
 123.109 -
 123.110 -        return result;
 123.111 -    }
 123.112 -
 123.113 -    //XXX: copied from CustomIndexerImplTest:
 123.114 -    @Override
 123.115 -    protected void setUp() throws Exception {
 123.116 -        SourceUtilsTestUtil.prepareTest(new String[0], new Object[0]);
 123.117 -        Main.initializeURLFactory();
 123.118 -        org.netbeans.api.project.ui.OpenProjects.getDefault().getOpenProjects();
 123.119 -        prepareTest();
 123.120 -        MimeTypes.setAllMimeTypes(Collections.singleton("text/x-java"));
 123.121 -        sourceCP = ClassPathSupport.createClassPath(src1, src2);
 123.122 -        GlobalPathRegistry.getDefault().register(ClassPath.SOURCE, new ClassPath[] {sourceCP});
 123.123 -        RepositoryUpdater.getDefault().start(true);
 123.124 -        super.setUp();
 123.125 -    }
 123.126 -
 123.127 -    @Override
 123.128 -    protected void tearDown() throws Exception {
 123.129 -        super.tearDown();
 123.130 -        GlobalPathRegistry.getDefault().unregister(ClassPath.SOURCE, new ClassPath[] {sourceCP});
 123.131 -    }
 123.132 -
 123.133 -    public void testBatchSearch1() throws Exception {
 123.134 -        writeFilesAndWaitForScan(src1,
 123.135 -                                 new File("test/Test1.java", "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); } }"),
 123.136 -                                 new File("test/Test2.java", "package test; public class Test2 { private void test() { new javax.swing.ImageIcon(null); } }"));
 123.137 -        writeFilesAndWaitForScan(src2,
 123.138 -                                 new File("test/Test1.java", "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); } }"),
 123.139 -                                 new File("test/Test2.java", "package test; public class Test2 { private void test() { new javax.swing.ImageIcon(null); } }"));
 123.140 -
 123.141 -        Iterable<? extends HintDescription> hints = prepareHints("$1.isDirectory()");
 123.142 -        BatchResult result = BatchSearch.findOccurrences(hints, Scopes.allOpenedProjectsScope());
 123.143 -        Map<String, Iterable<String>> output = new HashMap<String, Iterable<String>>();
 123.144 -
 123.145 -        for (Entry<FileObject, Collection<? extends Resource>> e : result.getResourcesWithRoots().entrySet()) {
 123.146 -            Collection<String> resourcesRepr = new LinkedList<String>();
 123.147 -
 123.148 -            for (Resource r : e.getValue()) {
 123.149 -                resourcesRepr.add(r.getRelativePath());
 123.150 -            }
 123.151 -
 123.152 -            output.put(e.getKey().getURL().toExternalForm(), resourcesRepr);
 123.153 -        }
 123.154 -
 123.155 -        Map<String, Iterable<String>> golden = new HashMap<String, Iterable<String>>();
 123.156 -
 123.157 -        golden.put(src1.getURL().toExternalForm(), Arrays.asList("test/Test1.java"));
 123.158 -        golden.put(src2.getURL().toExternalForm(), Arrays.asList("test/Test1.java"));
 123.159 -
 123.160 -        assertEquals(golden, output);
 123.161 -    }
 123.162 -
 123.163 -    public void testBatchSearchSpan() throws Exception {
 123.164 -        String code = "package test;\n" +
 123.165 -                      "public class Test {\n" +
 123.166 -                      "    private void m() {\n" +
 123.167 -                      "        a(c.i().getFileObject());\n" +
 123.168 -                      "        if (span != null && span[0] != (-1) && span[1] != (-1));\n" +
 123.169 -                      "        c.i().getFileObject(\"\");\n" +
 123.170 -                      "    }\n" +
 123.171 -                      "}\n";
 123.172 -
 123.173 -        writeFilesAndWaitForScan(src1, new File("test/Test.java", code));
 123.174 -
 123.175 -        Iterable<? extends HintDescription> hints = prepareHints("$0.getFileObject($1)");
 123.176 -        BatchResult result = BatchSearch.findOccurrences(hints, Scopes.allOpenedProjectsScope());
 123.177 -
 123.178 -        assertEquals(1, result.getResources().size());
 123.179 -        Iterator<? extends Resource> resources = result.getResources().iterator().next().iterator();
 123.180 -        Resource r = resources.next();
 123.181 -
 123.182 -        assertFalse(resources.hasNext());
 123.183 -
 123.184 -        Set<String> snipets = new HashSet<String>();
 123.185 -
 123.186 -        for (int[] span : r.getCandidateSpans()) {
 123.187 -            snipets.add(code.substring(span[0], span[1]));
 123.188 -        }
 123.189 -
 123.190 -        Set<String> golden = new HashSet<String>(Arrays.asList("c.i().getFileObject(\"\")"));
 123.191 -        assertEquals(golden, snipets);
 123.192 -    }
 123.193 -
 123.194 -    @RandomlyFails
 123.195 -    public void testBatchSearchNotIndexed() throws Exception {
 123.196 -        writeFilesAndWaitForScan(src1,
 123.197 -                                 new File("test/Test1.java", "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); } }"),
 123.198 -                                 new File("test/Test2.java", "package test; public class Test2 { private void test() { new javax.swing.ImageIcon(null); } }"));
 123.199 -        writeFilesAndWaitForScan(src3,
 123.200 -                                 new File("test/Test1.java", "package test; public class Test1 { private void test() { Test2 f = null; f.isDirectory(); } }"),
 123.201 -                                 new File("test/Test2.java", "package test; public class Test2 { public boolean isDirectory() {return false} }"));
 123.202 -
 123.203 -        Iterable<? extends HintDescription> hints = prepareHints("$1.isDirectory()", "$1", "test.Test2");
 123.204 -        BatchResult result = BatchSearch.findOccurrences(hints, Scopes.specifiedFoldersScope(Folder.convert(src1, src3, empty)));
 123.205 -        Map<String, Iterable<String>> output = new HashMap<String, Iterable<String>>();
 123.206 -
 123.207 -        for (Entry<FileObject, Collection<? extends Resource>> e : result.getResourcesWithRoots().entrySet()) {
 123.208 -            Collection<String> resourcesRepr = new LinkedList<String>();
 123.209 -
 123.210 -            for (Resource r : e.getValue()) {
 123.211 -                resourcesRepr.add(r.getRelativePath());
 123.212 -            }
 123.213 -
 123.214 -            output.put(e.getKey().getURL().toExternalForm(), resourcesRepr);
 123.215 -        }
 123.216 -
 123.217 -        Map<String, Iterable<String>> golden = new HashMap<String, Iterable<String>>();
 123.218 -
 123.219 -        golden.put(src1.getURL().toExternalForm(), Arrays.asList("test/Test1.java"));
 123.220 -        golden.put(src3.getURL().toExternalForm(), Arrays.asList("test/Test1.java"));
 123.221 -
 123.222 -        assertEquals(golden, output);
 123.223 -
 123.224 -        //check verification:
 123.225 -        Map<String, Map<String, Iterable<String>>> verifiedOutput = verifiedSpans(result, false);
 123.226 -        Map<String, Map<String, Iterable<String>>> verifiedGolden = new HashMap<String, Map<String, Iterable<String>>>();
 123.227 -
 123.228 -        verifiedGolden.put(src1.getURL().toExternalForm(), Collections.<String, Iterable<String>>singletonMap("test/Test1.java", Arrays.<String>asList()));
 123.229 -        verifiedGolden.put(src3.getURL().toExternalForm(), Collections.<String, Iterable<String>>singletonMap("test/Test1.java", Arrays.asList("0:75-0:86:verifier:")));
 123.230 -
 123.231 -        assertEquals(verifiedGolden, verifiedOutput);
 123.232 -    }
 123.233 -
 123.234 -    public void testBatchSearchForceIndexingOfProperDirectory() throws Exception {
 123.235 -        FileObject data = FileUtil.createFolder(workdir, "data");
 123.236 -        FileObject dataSrc1 = FileUtil.createFolder(data, "src1");
 123.237 -        FileObject dataSrc2 = FileUtil.createFolder(data, "src2");
 123.238 -        writeFilesAndWaitForScan(dataSrc1,
 123.239 -                                 new File("test/Test1.java", "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); } }"),
 123.240 -                                 new File("test/Test2.java", "package test; public class Test2 { private void test() { new javax.swing.ImageIcon(null); } }"));
 123.241 -        writeFilesAndWaitForScan(dataSrc2,
 123.242 -                                 new File("test/Test1.java", "package test; public class Test1 { private void test() { Test2 f = null; f.isDirectory(); } }"),
 123.243 -                                 new File("test/Test2.java", "package test; public class Test2 { public boolean isDirectory() {return false} }"));
 123.244 -
 123.245 -        ClassPathProviderImpl.setSourceRoots(Arrays.asList(dataSrc1, dataSrc2));
 123.246 -
 123.247 -        Iterable<? extends HintDescription> hints = prepareHints("$1.isDirectory()", "$1", "test.Test2");
 123.248 -        BatchResult result = BatchSearch.findOccurrences(hints, Scopes.specifiedFoldersScope(Folder.convert(data)));
 123.249 -        Map<String, Iterable<String>> output = new HashMap<String, Iterable<String>>();
 123.250 -
 123.251 -        for (Entry<FileObject, Collection<? extends Resource>> e : result.getResourcesWithRoots().entrySet()) {
 123.252 -            Collection<String> resourcesRepr = new HashSet<String>();
 123.253 -
 123.254 -            for (Resource r : e.getValue()) {
 123.255 -                resourcesRepr.add(r.getRelativePath());
 123.256 -            }
 123.257 -
 123.258 -            output.put(e.getKey().getURL().toExternalForm(), resourcesRepr);
 123.259 -        }
 123.260 -
 123.261 -        Map<String, Iterable<String>> golden = new HashMap<String, Iterable<String>>();
 123.262 -
 123.263 -        golden.put(data.getURL().toExternalForm(), new HashSet<String>(Arrays.asList("src1/test/Test1.java", "src2/test/Test1.java")));
 123.264 -
 123.265 -        assertEquals(golden, output);
 123.266 -
 123.267 -        //check verification:
 123.268 -        final Set<FileObject> added = new HashSet<FileObject>();
 123.269 -        final Set<FileObject> removed = new HashSet<FileObject>();
 123.270 -
 123.271 -        GlobalPathRegistry.getDefault().addGlobalPathRegistryListener(new GlobalPathRegistryListener() {
 123.272 -            public void pathsAdded(GlobalPathRegistryEvent event) {
 123.273 -                for (ClassPath cp : event.getChangedPaths()) {
 123.274 -                    added.addAll(Arrays.asList(cp.getRoots()));
 123.275 -                }
 123.276 -            }
 123.277 -            public void pathsRemoved(GlobalPathRegistryEvent event) {
 123.278 -                for (ClassPath cp : event.getChangedPaths()) {
 123.279 -                    removed.addAll(Arrays.asList(cp.getRoots()));
 123.280 -                }
 123.281 -            }
 123.282 -        });
 123.283 -
 123.284 -//        verifiedGolden.put(data.getURL().toExternalForm(), Arrays.asList("0:75-0:86:verifier:TODO: No display name"));
 123.285 -        Map<String, Map<String, Iterable<String>>> verifiedOutput = verifiedSpans(result, false);
 123.286 -        Map<String, Map<String, Iterable<String>>> verifiedGolden = new HashMap<String, Map<String, Iterable<String>>>();
 123.287 -
 123.288 -        Map<String, Iterable<String>> verifiedGoldenPart = new HashMap<String, Iterable<String>>();
 123.289 -
 123.290 -        verifiedGoldenPart.put("src1/test/Test1.java", Arrays.<String>asList());
 123.291 -        verifiedGoldenPart.put("src2/test/Test1.java", Arrays.<String>asList("0:75-0:86:verifier:"));
 123.292 -
 123.293 -        verifiedGolden.put(data.getURL().toExternalForm(), verifiedGoldenPart);
 123.294 -
 123.295 -        assertEquals(verifiedGolden, verifiedOutput);
 123.296 -        assertEquals(new HashSet<FileObject>(Arrays.asList(dataSrc1, dataSrc2)), added);
 123.297 -        assertEquals(new HashSet<FileObject>(Arrays.asList(dataSrc1, dataSrc2)), removed);
 123.298 -    }
 123.299 -
 123.300 -    public void testBatchSearchFolderNoIndex() throws Exception {
 123.301 -        FileObject data = FileUtil.createFolder(workdir, "data");
 123.302 -        FileObject dataSrc1 = FileUtil.createFolder(data, "src1");
 123.303 -        FileObject dataSrc2 = FileUtil.createFolder(data, "src2");
 123.304 -        writeFilesAndWaitForScan(dataSrc1,
 123.305 -                                 new File("test/Test1.java", "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); } }"),
 123.306 -                                 new File("test/Test2.java", "package test; public class Test2 { private void test() { new javax.swing.ImageIcon(null); } }"));
 123.307 -        writeFilesAndWaitForScan(dataSrc2,
 123.308 -                                 new File("test/Test1.java", "package test; public class Test1 { private void test() { Test2 f = null; f.isDirectory(); } }"),
 123.309 -                                 new File("test/Test2.java", "package test; public class Test2 { public boolean isDirectory() {return false} }"));
 123.310 -
 123.311 -        Iterable<? extends HintDescription> hints = prepareHints("$1.isDirectory()");
 123.312 -        BatchResult result = BatchSearch.findOccurrences(hints, Scopes.specifiedFoldersScope(Folder.convert(Collections.singleton(data)))); //XXX: should be a no-index variant!
 123.313 -        Map<String, Iterable<String>> output = toDebugOutput(result);
 123.314 -        Map<String, Iterable<String>> golden = new HashMap<String, Iterable<String>>();
 123.315 -
 123.316 -        golden.put(data.getURL().toExternalForm(), new HashSet<String>(Arrays.asList("src1/test/Test1.java", "src2/test/Test1.java")));
 123.317 -
 123.318 -        assertEquals(golden, output);
 123.319 -    }
 123.320 -
 123.321 -    private FileObject workdir;
 123.322 -    private FileObject src1;
 123.323 -    private FileObject src2;
 123.324 -    private FileObject src3;
 123.325 -    private FileObject empty;
 123.326 -    private ClassPath sourceCP;
 123.327 -
 123.328 -    private void prepareTest() throws Exception {
 123.329 -        workdir = SourceUtilsTestUtil.makeScratchDir(this);
 123.330 -
 123.331 -        src1 = FileUtil.createFolder(workdir, "src1");
 123.332 -        src2 = FileUtil.createFolder(workdir, "src2");
 123.333 -        src3 = FileUtil.createFolder(workdir, "src3");
 123.334 -        empty = FileUtil.createFolder(workdir, "empty");
 123.335 -
 123.336 -        ClassPathProviderImpl.setSourceRoots(Arrays.asList(src1, src2, src3));
 123.337 -
 123.338 -        FileObject cache = FileUtil.createFolder(workdir, "cache");
 123.339 -
 123.340 -        CacheFolder.setCacheFolder(cache);
 123.341 -    }
 123.342 -
 123.343 -    private Map<String, Iterable<String>> toDebugOutput(BatchResult result) throws Exception {
 123.344 -        Map<String, Iterable<String>> output = new HashMap<String, Iterable<String>>();
 123.345 -
 123.346 -        for (Entry<FileObject, Collection<? extends Resource>> e : result.getResourcesWithRoots().entrySet()) {
 123.347 -            Collection<String> resourcesRepr = new HashSet<String>();
 123.348 -
 123.349 -            for (Resource r : e.getValue()) {
 123.350 -                resourcesRepr.add(r.getRelativePath());
 123.351 -            }
 123.352 -
 123.353 -            output.put(e.getKey().getURL().toExternalForm(), resourcesRepr);
 123.354 -        }
 123.355 -
 123.356 -        return output;
 123.357 -    }
 123.358 -
 123.359 -    private Map<String, Map<String, Iterable<String>>> verifiedSpans(BatchResult candidates, boolean doNotRegisterClassPath) throws Exception {
 123.360 -        final Map<String, Map<String, Iterable<String>>> result = new HashMap<String, Map<String, Iterable<String>>>();
 123.361 -        List<MessageImpl> errors = new LinkedList<MessageImpl>();
 123.362 -        BatchSearch.getVerifiedSpans(candidates, new ProgressHandleWrapper(1), new BatchSearch.VerifiedSpansCallBack() {
 123.363 -            public void groupStarted() {}
 123.364 -            public boolean spansVerified(CompilationController wc, Resource r, Collection<? extends ErrorDescription> hints) throws Exception {
 123.365 -                Map<String, Iterable<String>> files = result.get(r.getRoot().getURL().toExternalForm());
 123.366 -
 123.367 -                if (files == null) {
 123.368 -                    result.put(r.getRoot().getURL().toExternalForm(), files = new HashMap<String, Iterable<String>>());
 123.369 -                }
 123.370 -
 123.371 -                Collection<String> currentHints = new LinkedList<String>();
 123.372 -
 123.373 -                for (ErrorDescription ed : hints) {
 123.374 -                    currentHints.add(ed.toString());
 123.375 -                }
 123.376 -
 123.377 -                files.put(r.getRelativePath(), currentHints);
 123.378 -
 123.379 -                return true;
 123.380 -            }
 123.381 -            public void groupFinished() {}
 123.382 -            public void cannotVerifySpan(Resource r) {
 123.383 -                fail("Cannot verify: " +r.getRelativePath());
 123.384 -            }
 123.385 -        }, doNotRegisterClassPath, errors, new AtomicBoolean());
 123.386 -
 123.387 -        return result;
 123.388 -    }
 123.389 -
 123.390 -    @ServiceProvider(service=ClassPathProvider.class)
 123.391 -    public static final class ClassPathProviderImpl implements ClassPathProvider {
 123.392 -
 123.393 -        private static Collection<FileObject> sourceRoots;
 123.394 -
 123.395 -        public synchronized static void setSourceRoots(Collection<FileObject> sourceRoots) {
 123.396 -            ClassPathProviderImpl.sourceRoots = sourceRoots;
 123.397 -        }
 123.398 -
 123.399 -        public synchronized static Collection<FileObject> getSourceRoots() {
 123.400 -            return sourceRoots;
 123.401 -        }
 123.402 -
 123.403 -        public synchronized ClassPath findClassPath(FileObject file, String type) {
 123.404 -            if (ClassPath.BOOT.equals(type)) {
 123.405 -                return ClassPathSupport.createClassPath(getBootClassPath().toArray(new URL[0]));
 123.406 -            }
 123.407 -
 123.408 -            if (ClassPath.COMPILE.equals(type)) {
 123.409 -                return ClassPathSupport.createClassPath(new URL[0]);
 123.410 -            }
 123.411 -
 123.412 -            if (ClassPath.SOURCE.equals(type) && sourceRoots != null) {
 123.413 -                for (FileObject sr : sourceRoots) {
 123.414 -                    if (file.equals(sr) || FileUtil.isParentOf(sr, file)) {
 123.415 -                        return ClassPathSupport.createClassPath(sr);
 123.416 -                    }
 123.417 -                }
 123.418 -            }
 123.419 -
 123.420 -            return null;
 123.421 -        }
 123.422 -
 123.423 -    }
 123.424 -
 123.425 -    //TODO: copied from SourceUtilsTestUtil:
 123.426 -    private static List<URL> bootClassPath;
 123.427 -
 123.428 -    public static synchronized List<URL> getBootClassPath() {
 123.429 -        if (bootClassPath == null) {
 123.430 -            try {
 123.431 -                String cp = System.getProperty("sun.boot.class.path");
 123.432 -                List<URL> urls = new ArrayList<URL>();
 123.433 -                String[] paths = cp.split(Pattern.quote(System.getProperty("path.separator")));
 123.434 -
 123.435 -                for (String path : paths) {
 123.436 -                    java.io.File f = new java.io.File(path);
 123.437 -
 123.438 -                    if (!f.canRead())
 123.439 -                        continue;
 123.440 -
 123.441 -                    FileObject fo = FileUtil.toFileObject(f);
 123.442 -
 123.443 -                    if (FileUtil.isArchiveFile(fo)) {
 123.444 -                        fo = FileUtil.getArchiveRoot(fo);
 123.445 -                    }
 123.446 -
 123.447 -                    if (fo != null) {
 123.448 -                        urls.add(fo.getURL());
 123.449 -                    }
 123.450 -                }
 123.451 -
 123.452 -                bootClassPath = urls;
 123.453 -            } catch (FileStateInvalidException e) {
 123.454 -                Exceptions.printStackTrace(e);
 123.455 -            }
 123.456 -        }
 123.457 -
 123.458 -        return bootClassPath;
 123.459 -    }
 123.460 -
 123.461 -}
   124.1 --- a/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/batch/BatchUtilitiesTest.java	Sun Oct 16 08:01:27 2016 +0200
   124.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   124.3 @@ -1,222 +0,0 @@
   124.4 -/*
   124.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   124.6 - *
   124.7 - * Copyright 2009-2011 Oracle and/or its affiliates. All rights reserved.
   124.8 - *
   124.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  124.10 - * Other names may be trademarks of their respective owners.
  124.11 - *
  124.12 - * The contents of this file are subject to the terms of either the GNU
  124.13 - * General Public License Version 2 only ("GPL") or the Common
  124.14 - * Development and Distribution License("CDDL") (collectively, the
  124.15 - * "License"). You may not use this file except in compliance with the
  124.16 - * License. You can obtain a copy of the License at
  124.17 - * http://www.netbeans.org/cddl-gplv2.html
  124.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  124.19 - * specific language governing permissions and limitations under the
  124.20 - * License.  When distributing the software, include this License Header
  124.21 - * Notice in each file and include the License file at
  124.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  124.23 - * particular file as subject to the "Classpath" exception as provided
  124.24 - * by Oracle in the GPL Version 2 section of the License file that
  124.25 - * accompanied this code. If applicable, add the following below the
  124.26 - * License Header, with the fields enclosed by brackets [] replaced by
  124.27 - * your own identifying information:
  124.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  124.29 - *
  124.30 - * If you wish your version of this file to be governed by only the CDDL
  124.31 - * or only the GPL Version 2, indicate your decision by adding
  124.32 - * "[Contributor] elects to include this software in this distribution
  124.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  124.34 - * single choice of license, a recipient has the option to distribute
  124.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  124.36 - * to extend the choice of license to its licensees as provided above.
  124.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  124.38 - * Version 2 license, then the option applies only if the new code is
  124.39 - * made subject to such option by the copyright holder.
  124.40 - *
  124.41 - * Contributor(s):
  124.42 - *
  124.43 - * Portions Copyrighted 2009-2011 Sun Microsystems, Inc.
  124.44 - */
  124.45 -package org.netbeans.modules.java.hints.spiimpl.batch;
  124.46 -
  124.47 -import org.netbeans.modules.java.hints.spiimpl.batch.TestUtils.File;
  124.48 -import org.netbeans.modules.java.hints.spiimpl.MessageImpl;
  124.49 -import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearchTest.ClassPathProviderImpl;
  124.50 -import org.netbeans.modules.java.hints.providers.spi.HintDescription;
  124.51 -import java.util.Arrays;
  124.52 -import java.util.Collection;
  124.53 -import java.util.Collections;
  124.54 -import java.util.HashMap;
  124.55 -import java.util.LinkedList;
  124.56 -import java.util.List;
  124.57 -import java.util.Map;
  124.58 -import java.util.concurrent.atomic.AtomicBoolean;
  124.59 -import org.netbeans.api.editor.mimelookup.MimePath;
  124.60 -import org.netbeans.api.java.classpath.ClassPath;
  124.61 -import org.netbeans.api.java.classpath.GlobalPathRegistry;
  124.62 -import org.netbeans.api.java.lexer.JavaTokenId;
  124.63 -import org.netbeans.api.java.source.ModificationResult;
  124.64 -import org.netbeans.api.java.source.SourceUtilsTestUtil;
  124.65 -import org.netbeans.api.java.source.TestUtilities;
  124.66 -import org.netbeans.api.lexer.InputAttributes;
  124.67 -import org.netbeans.api.lexer.Language;
  124.68 -import org.netbeans.api.lexer.LanguagePath;
  124.69 -import org.netbeans.api.lexer.Token;
  124.70 -import org.netbeans.core.startup.Main;
  124.71 -import org.netbeans.junit.NbTestCase;
  124.72 -import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.BatchResult;
  124.73 -import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.Folder;
  124.74 -import org.netbeans.modules.java.source.parsing.JavacParser;
  124.75 -import org.netbeans.modules.parsing.impl.indexing.CacheFolder;
  124.76 -import org.netbeans.modules.parsing.impl.indexing.RepositoryUpdater;
  124.77 -import org.netbeans.spi.editor.mimelookup.MimeDataProvider;
  124.78 -import org.netbeans.spi.java.classpath.support.ClassPathSupport;
  124.79 -import org.netbeans.spi.lexer.LanguageEmbedding;
  124.80 -import org.netbeans.spi.lexer.LanguageProvider;
  124.81 -import org.openide.LifecycleManager;
  124.82 -import org.openide.filesystems.FileObject;
  124.83 -import org.openide.filesystems.FileUtil;
  124.84 -
  124.85 -import org.openide.loaders.DataObject;
  124.86 -import org.openide.util.Lookup;
  124.87 -import org.openide.util.lookup.Lookups;
  124.88 -import org.openide.util.lookup.ServiceProvider;
  124.89 -import static org.netbeans.modules.java.hints.spiimpl.batch.TestUtils.writeFilesAndWaitForScan;
  124.90 -import static org.netbeans.modules.java.hints.spiimpl.batch.TestUtils.prepareHints;
  124.91 -import org.netbeans.modules.parsing.impl.indexing.MimeTypes;
  124.92 -
  124.93 -/**
  124.94 - *
  124.95 - * @author lahvac
  124.96 - */
  124.97 -public class BatchUtilitiesTest extends NbTestCase {
  124.98 -
  124.99 -    public BatchUtilitiesTest(String name) {
 124.100 -        super(name);
 124.101 -    }
 124.102 -
 124.103 -    //XXX: copied from CustomIndexerImplTest:
 124.104 -    @Override
 124.105 -    protected void setUp() throws Exception {
 124.106 -        SourceUtilsTestUtil.prepareTest(new String[] {"org/netbeans/modules/java/source/resources/layer.xml", "org/netbeans/lib/java/lexer/layer.xml"}, new Object[0]);
 124.107 -        Main.initializeURLFactory();
 124.108 -        org.netbeans.api.project.ui.OpenProjects.getDefault().getOpenProjects();
 124.109 -        prepareTest();
 124.110 -        MimeTypes.setAllMimeTypes(Collections.singleton("text/x-java"));
 124.111 -        GlobalPathRegistry.getDefault().register(ClassPath.SOURCE, new ClassPath[] {ClassPathSupport.createClassPath(src1, src2)});
 124.112 -        RepositoryUpdater.getDefault().start(true);
 124.113 -        super.setUp();
 124.114 -    }
 124.115 -
 124.116 -    public void testBatchSearchNotIndexed() throws Exception {
 124.117 -        writeFilesAndWaitForScan(src1,
 124.118 -                                 new File("test/Test1.java", "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); } }"),
 124.119 -                                 new File("test/Test2.java", "package test; public class Test2 { private void test() { new javax.swing.ImageIcon(null); } }"));
 124.120 -        writeFilesAndWaitForScan(src3,
 124.121 -                                 new File("test/Test1.java", "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); } }"),
 124.122 -                                 new File("test/Test2.java", "package test; public class Test2 { public boolean isDirectory() {return false} }"));
 124.123 -
 124.124 -        Iterable<? extends HintDescription> hints = prepareHints("$1.isDirectory() => !$1.isFile()", "$1", "java.io.File");
 124.125 -        BatchResult result = BatchSearch.findOccurrences(hints, Scopes.specifiedFoldersScope(Folder.convert(src1, src3, empty)));
 124.126 -        List<MessageImpl> problems = new LinkedList<MessageImpl>();
 124.127 -        Collection<? extends ModificationResult> changes = BatchUtilities.applyFixes(result, new ProgressHandleWrapper(100), new AtomicBoolean(), problems);
 124.128 -
 124.129 -        assertTrue(problems.toString(), problems.isEmpty());
 124.130 -
 124.131 -        Map<FileObject, String> file2New = new HashMap<FileObject, String>();
 124.132 -
 124.133 -        for (ModificationResult mr : changes) {
 124.134 -            for (FileObject file : mr.getModifiedFileObjects()) {
 124.135 -                assertNull(file2New.put(file, mr.getResultingSource(file)));
 124.136 -            }
 124.137 -        }
 124.138 -
 124.139 -        FileObject src1Test1 = src1.getFileObject("test/Test1.java");
 124.140 -        String src1Test1Real = file2New.remove(src1Test1);
 124.141 -        String src1Test1Golden = "package test; public class Test1 { private void test() { java.io.File f = null; !f.isFile(); } }";
 124.142 -
 124.143 -        assertEquals(src1Test1Golden, src1Test1Real);
 124.144 -
 124.145 -        FileObject src3Test1 = src3.getFileObject("test/Test1.java");
 124.146 -        String src3Test1Real = file2New.remove(src3Test1);
 124.147 -        String src3Test1Golden = "package test; public class Test1 { private void test() { java.io.File f = null; !f.isFile(); } }";
 124.148 -
 124.149 -        assertEquals(src3Test1Golden, src3Test1Real);
 124.150 -
 124.151 -        assertTrue(file2New.toString(), file2New.isEmpty());
 124.152 -    }
 124.153 -
 124.154 -//    public void testRemoveUnusedImports() throws Exception {
 124.155 -//        writeFilesAndWaitForScan(src1,
 124.156 -//                                 new File("test/Test1.java", "package test;\n import java.util.List;\n public class Test1 { }"));
 124.157 -//        writeFilesAndWaitForScan(src2,
 124.158 -//                                 new File("test/Test2.java", "package test;\n import java.util.LinkedList;\n public class Test2 { }"));
 124.159 -//
 124.160 -//        FileObject test1 = src1.getFileObject("test/Test1.java");
 124.161 -//        FileObject test2 = src2.getFileObject("test/Test2.java");
 124.162 -//
 124.163 -//        System.err.println(DataObject.find(test1).getClass());
 124.164 -//        BatchUtilities.removeUnusedImports(Arrays.asList(test1, test2));
 124.165 -//
 124.166 -//        LifecycleManager.getDefault().saveAll();
 124.167 -//
 124.168 -//        assertEquals("package test;\n public class Test1 { }", TestUtilities.copyFileToString(FileUtil.toFile(test1)));
 124.169 -//        assertEquals("package test;\n public class Test2 { }", TestUtilities.copyFileToString(FileUtil.toFile(test2)));
 124.170 -//    }
 124.171 -
 124.172 -    private FileObject src1;
 124.173 -    private FileObject src2;
 124.174 -    private FileObject src3;
 124.175 -    private FileObject empty;
 124.176 -
 124.177 -    private void prepareTest() throws Exception {
 124.178 -        FileObject workdir = SourceUtilsTestUtil.makeScratchDir(this);
 124.179 -
 124.180 -        src1 = FileUtil.createFolder(workdir, "src1");
 124.181 -        src2 = FileUtil.createFolder(workdir, "src2");
 124.182 -        src3 = FileUtil.createFolder(workdir, "src3");
 124.183 -        empty = FileUtil.createFolder(workdir, "empty");
 124.184 -
 124.185 -        ClassPathProviderImpl.setSourceRoots(Arrays.asList(src1, src2, src3));
 124.186 -
 124.187 -        FileObject cache = FileUtil.createFolder(workdir, "cache");
 124.188 -
 124.189 -        CacheFolder.setCacheFolder(cache);
 124.190 -    }
 124.191 -
 124.192 -    @ServiceProvider(service=MimeDataProvider.class)
 124.193 -    public static final class JavaLexerProvider implements MimeDataProvider {
 124.194 -
 124.195 -        private Lookup javaLookup = Lookups.fixed(JavaTokenId.language());
 124.196 -
 124.197 -        public Lookup getLookup(MimePath mimePath) {
 124.198 -            if (mimePath.getPath().endsWith(JavacParser.MIME_TYPE)) {
 124.199 -                return javaLookup;
 124.200 -            }
 124.201 -
 124.202 -            return Lookup.EMPTY;
 124.203 -        }
 124.204 -
 124.205 -    }
 124.206 -
 124.207 -    @ServiceProvider(service=LanguageProvider.class)
 124.208 -    public static final class JavaLanguageProvider extends LanguageProvider {
 124.209 -
 124.210 -        @Override
 124.211 -        public Language<?> findLanguage(String mimeType) {
 124.212 -            if ("text/x-java".equals(mimeType)) {
 124.213 -                return JavaTokenId.language();
 124.214 -            }
 124.215 -
 124.216 -            return null;
 124.217 -        }
 124.218 -
 124.219 -        @Override
 124.220 -        public LanguageEmbedding<?> findLanguageEmbedding(Token<?> token, LanguagePath languagePath, InputAttributes inputAttributes) {
 124.221 -            return null;
 124.222 -        }
 124.223 -
 124.224 -    }
 124.225 -}
   125.1 --- a/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/batch/ProgressHandleWrapperTest.java	Sun Oct 16 08:01:27 2016 +0200
   125.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   125.3 @@ -1,66 +0,0 @@
   125.4 -/*
   125.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   125.6 - *
   125.7 - * Copyright 2009-2011 Oracle and/or its affiliates. All rights reserved.
   125.8 - *
   125.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  125.10 - * Other names may be trademarks of their respective owners.
  125.11 - *
  125.12 - * The contents of this file are subject to the terms of either the GNU
  125.13 - * General Public License Version 2 only ("GPL") or the Common
  125.14 - * Development and Distribution License("CDDL") (collectively, the
  125.15 - * "License"). You may not use this file except in compliance with the
  125.16 - * License. You can obtain a copy of the License at
  125.17 - * http://www.netbeans.org/cddl-gplv2.html
  125.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  125.19 - * specific language governing permissions and limitations under the
  125.20 - * License.  When distributing the software, include this License Header
  125.21 - * Notice in each file and include the License file at
  125.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  125.23 - * particular file as subject to the "Classpath" exception as provided
  125.24 - * by Oracle in the GPL Version 2 section of the License file that
  125.25 - * accompanied this code. If applicable, add the following below the
  125.26 - * License Header, with the fields enclosed by brackets [] replaced by
  125.27 - * your own identifying information:
  125.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  125.29 - *
  125.30 - * If you wish your version of this file to be governed by only the CDDL
  125.31 - * or only the GPL Version 2, indicate your decision by adding
  125.32 - * "[Contributor] elects to include this software in this distribution
  125.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  125.34 - * single choice of license, a recipient has the option to distribute
  125.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  125.36 - * to extend the choice of license to its licensees as provided above.
  125.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  125.38 - * Version 2 license, then the option applies only if the new code is
  125.39 - * made subject to such option by the copyright holder.
  125.40 - *
  125.41 - * Contributor(s):
  125.42 - *
  125.43 - * Portions Copyrighted 2009-2011 Sun Microsystems, Inc.
  125.44 - */
  125.45 -package org.netbeans.modules.java.hints.spiimpl.batch;
  125.46 -
  125.47 -import org.netbeans.junit.NbTestCase;
  125.48 -
  125.49 -/**
  125.50 - *
  125.51 - * @author lahvac
  125.52 - */
  125.53 -public class ProgressHandleWrapperTest extends NbTestCase {
  125.54 -
  125.55 -    public ProgressHandleWrapperTest(String name) {
  125.56 -        super(name);
  125.57 -    }
  125.58 -
  125.59 -    public void testNoProgress() {
  125.60 -        ProgressHandleWrapper w = new ProgressHandleWrapper(new ProgressHandleWrapper.ProgressHandleAbstraction() {
  125.61 -            public void start(int totalWork) {}
  125.62 -            public void progress(int currentWorkDone) {}
  125.63 -            public void progress(String message) {}
  125.64 -            public void finish() {}
  125.65 -        }, 1);
  125.66 -        
  125.67 -        w.finish();
  125.68 -    }
  125.69 -}
   126.1 --- a/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/batch/TestUtils.java	Sun Oct 16 08:01:27 2016 +0200
   126.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   126.3 @@ -1,135 +0,0 @@
   126.4 -/*
   126.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   126.6 - *
   126.7 - * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
   126.8 - *
   126.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  126.10 - * Other names may be trademarks of their respective owners.
  126.11 - *
  126.12 - * The contents of this file are subject to the terms of either the GNU
  126.13 - * General Public License Version 2 only ("GPL") or the Common
  126.14 - * Development and Distribution License("CDDL") (collectively, the
  126.15 - * "License"). You may not use this file except in compliance with the
  126.16 - * License. You can obtain a copy of the License at
  126.17 - * http://www.netbeans.org/cddl-gplv2.html
  126.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  126.19 - * specific language governing permissions and limitations under the
  126.20 - * License.  When distributing the software, include this License Header
  126.21 - * Notice in each file and include the License file at
  126.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  126.23 - * particular file as subject to the "Classpath" exception as provided
  126.24 - * by Oracle in the GPL Version 2 section of the License file that
  126.25 - * accompanied this code. If applicable, add the following below the
  126.26 - * License Header, with the fields enclosed by brackets [] replaced by
  126.27 - * your own identifying information:
  126.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  126.29 - *
  126.30 - * If you wish your version of this file to be governed by only the CDDL
  126.31 - * or only the GPL Version 2, indicate your decision by adding
  126.32 - * "[Contributor] elects to include this software in this distribution
  126.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  126.34 - * single choice of license, a recipient has the option to distribute
  126.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  126.36 - * to extend the choice of license to its licensees as provided above.
  126.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  126.38 - * Version 2 license, then the option applies only if the new code is
  126.39 - * made subject to such option by the copyright holder.
  126.40 - *
  126.41 - * Contributor(s):
  126.42 - *
  126.43 - * Portions Copyrighted 2011 Sun Microsystems, Inc.
  126.44 - */
  126.45 -package org.netbeans.modules.java.hints.spiimpl.batch;
  126.46 -
  126.47 -import java.util.Collection;
  126.48 -import java.util.Collections;
  126.49 -import org.netbeans.spi.java.hints.HintContext;
  126.50 -import org.netbeans.modules.java.hints.providers.spi.HintDescription.Worker;
  126.51 -import org.netbeans.modules.java.hints.providers.spi.Trigger.PatternDescription;
  126.52 -import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
  126.53 -import org.netbeans.spi.editor.hints.ErrorDescription;
  126.54 -import org.netbeans.modules.java.hints.providers.spi.HintDescriptionFactory;
  126.55 -import java.util.HashMap;
  126.56 -import java.util.Map;
  126.57 -import org.netbeans.api.java.source.SourceUtils;
  126.58 -import org.netbeans.api.java.source.TestUtilities;
  126.59 -import org.netbeans.modules.java.hints.providers.spi.HintDescription;
  126.60 -import org.openide.filesystems.FileObject;
  126.61 -import org.openide.filesystems.FileUtil;
  126.62 -
  126.63 -import static org.junit.Assert.*;
  126.64 -import org.netbeans.spi.java.hints.JavaFixUtilities;
  126.65 -
  126.66 -/**
  126.67 - *
  126.68 - * @author lahvac
  126.69 - */
  126.70 -public class TestUtils {
  126.71 -
  126.72 -    public static void writeFiles(FileObject sourceRoot, File... files) throws Exception {
  126.73 -        for (FileObject c : sourceRoot.getChildren()) {
  126.74 -            c.delete();
  126.75 -        }
  126.76 -
  126.77 -        for (File f : files) {
  126.78 -            FileObject fo = FileUtil.createData(sourceRoot, f.filename);
  126.79 -            TestUtilities.copyStringToFile(fo, f.content);
  126.80 -        }
  126.81 -    }
  126.82 -
  126.83 -    public static void writeFilesAndWaitForScan(FileObject sourceRoot, File... files) throws Exception {
  126.84 -        writeFiles(sourceRoot, files);
  126.85 -        SourceUtils.waitScanFinished();
  126.86 -    }
  126.87 -    
  126.88 -    public static final class File {
  126.89 -        public final String filename;
  126.90 -        public final String content;
  126.91 -        public final boolean index;
  126.92 -
  126.93 -        public File(String filename, String content) {
  126.94 -            this(filename, content, true);
  126.95 -        }
  126.96 -
  126.97 -        public File(String filename, String content, boolean index) {
  126.98 -            this.filename = filename;
  126.99 -            this.content = content;
 126.100 -            this.index = index;
 126.101 -        }
 126.102 -    }
 126.103 -
 126.104 -    public static Iterable<? extends HintDescription> prepareHints(String rule, String... constraints) {
 126.105 -        final String[] split = rule.split("=>");
 126.106 -
 126.107 -        Worker w;
 126.108 -
 126.109 -        if (split.length == 2) {
 126.110 -            w = new HintDescription.Worker() {
 126.111 -                @Override public Collection<? extends ErrorDescription> createErrors(HintContext ctx) {
 126.112 -                    return Collections.singletonList(ErrorDescriptionFactory.forName(ctx, ctx.getPath(), "", JavaFixUtilities.rewriteFix(ctx, "", ctx.getPath(), split[1])));
 126.113 -                }
 126.114 -            };
 126.115 -        } else {
 126.116 -            w = new HintDescription.Worker() {
 126.117 -                @Override public Collection<? extends ErrorDescription> createErrors(HintContext ctx) {
 126.118 -                    return Collections.singletonList(ErrorDescriptionFactory.forName(ctx, ctx.getPath(), ""));
 126.119 -                }
 126.120 -            };
 126.121 -        }
 126.122 -
 126.123 -        assertTrue(constraints.length % 2 == 0);
 126.124 -
 126.125 -        Map<String, String> constr = new HashMap<String, String>();
 126.126 -
 126.127 -        for (int i = 0; i < constraints.length; i += 2) {
 126.128 -            constr.put(constraints[i], constraints[i + 1]);
 126.129 -        }
 126.130 -
 126.131 -        HintDescription hd = HintDescriptionFactory.create()
 126.132 -                                                   .setTrigger(PatternDescription.create(split[0], constr))
 126.133 -                                                   .setWorker(w)
 126.134 -                                                   .produce();
 126.135 -
 126.136 -        return Collections.singletonList(hd);
 126.137 -    }
 126.138 -}
   127.1 --- a/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/hints/HintsInvokerTest.java	Sun Oct 16 08:01:27 2016 +0200
   127.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   127.3 @@ -1,895 +0,0 @@
   127.4 -/*
   127.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   127.6 - *
   127.7 - * Copyright 2009-2010 Oracle and/or its affiliates. All rights reserved.
   127.8 - *
   127.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  127.10 - * Other names may be trademarks of their respective owners.
  127.11 - *
  127.12 - * The contents of this file are subject to the terms of either the GNU
  127.13 - * General Public License Version 2 only ("GPL") or the Common
  127.14 - * Development and Distribution License("CDDL") (collectively, the
  127.15 - * "License"). You may not use this file except in compliance with the
  127.16 - * License. You can obtain a copy of the License at
  127.17 - * http://www.netbeans.org/cddl-gplv2.html
  127.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  127.19 - * specific language governing permissions and limitations under the
  127.20 - * License.  When distributing the software, include this License Header
  127.21 - * Notice in each file and include the License file at
  127.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  127.23 - * particular file as subject to the "Classpath" exception as provided
  127.24 - * by Oracle in the GPL Version 2 section of the License file that
  127.25 - * accompanied this code. If applicable, add the following below the
  127.26 - * License Header, with the fields enclosed by brackets [] replaced by
  127.27 - * your own identifying information:
  127.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  127.29 - *
  127.30 - * If you wish your version of this file to be governed by only the CDDL
  127.31 - * or only the GPL Version 2, indicate your decision by adding
  127.32 - * "[Contributor] elects to include this software in this distribution
  127.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  127.34 - * single choice of license, a recipient has the option to distribute
  127.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  127.36 - * to extend the choice of license to its licensees as provided above.
  127.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  127.38 - * Version 2 license, then the option applies only if the new code is
  127.39 - * made subject to such option by the copyright holder.
  127.40 - *
  127.41 - * Contributor(s):
  127.42 - *
  127.43 - * Portions Copyrighted 2009-2010 Sun Microsystems, Inc.
  127.44 - */
  127.45 -
  127.46 -package org.netbeans.modules.java.hints.spiimpl.hints;
  127.47 -
  127.48 -import com.sun.source.tree.Tree.Kind;
  127.49 -import com.sun.source.util.TreePath;
  127.50 -import java.util.Arrays;
  127.51 -import java.util.Collection;
  127.52 -import java.util.Collections;
  127.53 -import java.util.EnumSet;
  127.54 -import java.util.HashMap;
  127.55 -import java.util.LinkedList;
  127.56 -import java.util.List;
  127.57 -import java.util.Map;
  127.58 -import java.util.concurrent.atomic.AtomicBoolean;
  127.59 -import javax.swing.text.Document;
  127.60 -import static org.junit.Assert.*;
  127.61 -import org.netbeans.api.java.source.CompilationInfo;
  127.62 -import org.netbeans.modules.java.hints.spiimpl.TestBase;
  127.63 -import org.netbeans.spi.java.hints.HintContext;
  127.64 -import org.netbeans.modules.java.hints.providers.spi.HintDescription;
  127.65 -import org.netbeans.modules.java.hints.providers.spi.HintDescription.Worker;
  127.66 -import org.netbeans.modules.java.hints.providers.spi.HintDescriptionFactory;
  127.67 -import org.netbeans.modules.java.hints.providers.spi.HintMetadata;
  127.68 -import org.netbeans.modules.java.hints.providers.spi.HintMetadata.Options;
  127.69 -import org.netbeans.modules.java.hints.providers.spi.Trigger.Kinds;
  127.70 -import org.netbeans.modules.java.hints.providers.spi.Trigger.PatternDescription;
  127.71 -import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings;
  127.72 -import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
  127.73 -import org.netbeans.spi.editor.hints.ErrorDescription;
  127.74 -import org.netbeans.spi.editor.hints.Fix;
  127.75 -import org.netbeans.spi.java.hints.JavaFixUtilities;
  127.76 -import org.openide.LifecycleManager;
  127.77 -import org.openide.cookies.EditorCookie;
  127.78 -import org.openide.filesystems.FileObject;
  127.79 -import org.openide.loaders.DataObject;
  127.80 -
  127.81 -/**
  127.82 - *
  127.83 - * @author user
  127.84 - */
  127.85 -public class HintsInvokerTest extends TestBase {
  127.86 -
  127.87 -    public HintsInvokerTest(String name) {
  127.88 -        super(name);
  127.89 -    }
  127.90 -
  127.91 -//    public static TestSuite suite() {
  127.92 -//        NbTestSuite r = new NbTestSuite();
  127.93 -//        r.addTest(new HintsInvokerTest("testPatternVariable1"));
  127.94 -//        return r;
  127.95 -//    }
  127.96 -
  127.97 -    public void testPattern1() throws Exception {
  127.98 -        performAnalysisTest("test/Test.java",
  127.99 -                            "|package test;\n" +
 127.100 -                            "import java.io.File;\n" +
 127.101 -                            "public class Test {\n" +
 127.102 -                            "     private void test(File f) {\n" +
 127.103 -                            "         f.toURL();\n" +
 127.104 -                            "     }\n" +
 127.105 -                            "}\n",
 127.106 -                            "4:11-4:16:verifier:HINT");
 127.107 -    }
 127.108 -
 127.109 -    public void testPattern2() throws Exception {
 127.110 -        performAnalysisTest("test/Test.java",
 127.111 -                            "|package test;\n" +
 127.112 -                            "\n" +
 127.113 -                            "public class Test {\n" +
 127.114 -                            "     private void test(java.io.File f) {\n" +
 127.115 -                            "         f.toURL();\n" +
 127.116 -                            "     }\n" +
 127.117 -                            "}\n",
 127.118 -                            "4:11-4:16:verifier:HINT");
 127.119 -    }
 127.120 -
 127.121 -    public void testKind1() throws Exception {
 127.122 -        performAnalysisTest("test/Test.java",
 127.123 -                            "|package test;\n" +
 127.124 -                            "\n" +
 127.125 -                            "public class Test {\n" +
 127.126 -                            "     private void test(java.io.File f) {\n" +
 127.127 -                            "         f.toURL();\n" +
 127.128 -                            "     }\n" +
 127.129 -                            "}\n",
 127.130 -                            "4:11-4:16:verifier:HINT");
 127.131 -    }
 127.132 -
 127.133 -    public void DISABLEDtestPatternVariable1() throws Exception {
 127.134 -        performFixTest("test/Test.java",
 127.135 -                       "|package test;\n" +
 127.136 -                       "\n" +
 127.137 -                       "public class Test {\n" +
 127.138 -                       "     private void test() {\n" +
 127.139 -                       "         {\n" +
 127.140 -                       "             int y;\n" +
 127.141 -                       "             y = 1;\n" +
 127.142 -                       "         }\n" +
 127.143 -                       "         int z;\n" +
 127.144 -                       "         {\n" +
 127.145 -                       "             int y;\n" +
 127.146 -                       "             z = 1;\n" +
 127.147 -                       "         }\n" +
 127.148 -                       "     }\n" +
 127.149 -                       "}\n",
 127.150 -                       "4:9-7:10:verifier:HINT",
 127.151 -                       "FixImpl",
 127.152 -                       "package test; public class Test { private void test() { { int y = 1; } int z; { int y; z = 1; } } } ");
 127.153 -    }
 127.154 -
 127.155 -    public void testPatternAssert1() throws Exception {
 127.156 -        performAnalysisTest("test/Test.java",
 127.157 -                            "|package test;\n" +
 127.158 -                            "\n" +
 127.159 -                            "public class Test {\n" +
 127.160 -                            "     private void test() {\n" +
 127.161 -                            "         assert true : \"\";\n" +
 127.162 -                            "     }\n" +
 127.163 -                            "}\n",
 127.164 -                            "4:9-4:15:verifier:HINT");
 127.165 -    }
 127.166 -
 127.167 -    public void testPatternStatementAndSingleStatementBlockAreSame() throws Exception {
 127.168 -        performAnalysisTest("test/Test.java",
 127.169 -                            "|package test;\n" +
 127.170 -                            "\n" +
 127.171 -                            "public class Test {\n" +
 127.172 -                            "     private int test() {\n" +
 127.173 -                            "         if (true) {\n" +
 127.174 -                            "             return 0;\n" +
 127.175 -                            "         }\n" +
 127.176 -                            "     }\n" +
 127.177 -                            "}\n",
 127.178 -                            "4:9-4:11:verifier:HINT");
 127.179 -    }
 127.180 -
 127.181 -    public void testPatternFalseOccurrence() throws Exception {
 127.182 -        performAnalysisTest("test/Test.java",
 127.183 -                            "|package test;\n" +
 127.184 -                            "\n" +
 127.185 -                            "public class Test {\n" +
 127.186 -                            "     private int test(java.io.File f) {\n" +
 127.187 -                            "         f.toURI().toURL();\n" +
 127.188 -                            "     }\n" +
 127.189 -                            "}\n");
 127.190 -    }
 127.191 -
 127.192 -    public void testStatementVariables1() throws Exception {
 127.193 -        performFixTest("test/Test.java",
 127.194 -                       "|package test;\n" +
 127.195 -                       "\n" +
 127.196 -                       "public class Test {\n" +
 127.197 -                       "     private int test(java.io.File f) {\n" +
 127.198 -                       "         if (true)\n" +
 127.199 -                       "             System.err.println(1);\n" +
 127.200 -                       "         else\n" +
 127.201 -                       "             System.err.println(2);\n" +
 127.202 -                       "     }\n" +
 127.203 -                       "}\n",
 127.204 -                       "4:9-4:11:verifier:HINT",
 127.205 -                       "FixImpl",
 127.206 -                       ("package test;\n" +
 127.207 -                       "\n" +
 127.208 -                       "public class Test {\n" +
 127.209 -                       "     private int test(java.io.File f) {\n" +
 127.210 -                       "         if (false)\n" +
 127.211 -                       "             System.err.println(2);\n" +
 127.212 -                       "         else\n" +
 127.213 -                       "             System.err.println(1);\n" +
 127.214 -                       "     }\n" +
 127.215 -                       "}\n").replaceAll("[ \t\n]+", " "));
 127.216 -    }
 127.217 -
 127.218 -    public void testStatementVariables2() throws Exception {
 127.219 -        performFixTest("test/Test.java",
 127.220 -                       "|package test;\n" +
 127.221 -                       "\n" +
 127.222 -                       "public class Test {\n" +
 127.223 -                       "     private int test(java.io.File f) {\n" +
 127.224 -                       "         if (true)\n" +
 127.225 -                       "             return 1;\n" +
 127.226 -                       "         else\n" +
 127.227 -                       "             return 2;\n" +
 127.228 -                       "     }\n" +
 127.229 -                       "}\n",
 127.230 -                       "4:9-4:11:verifier:HINT",
 127.231 -                       "FixImpl",
 127.232 -                       ("package test;\n" +
 127.233 -                       "\n" +
 127.234 -                       "public class Test {\n" +
 127.235 -                       "     private int test(java.io.File f) {\n" +
 127.236 -                       "         if (false)\n" +
 127.237 -                       "             return 2;\n" +
 127.238 -                       "         else\n" +
 127.239 -                       "             return 1;\n" +
 127.240 -                       "     }\n" +
 127.241 -                       "}\n").replaceAll("[ \t\n]+", " "));
 127.242 -    }
 127.243 -
 127.244 -    public void testMultiStatementVariables1() throws Exception {
 127.245 -        performFixTest("test/Test.java",
 127.246 -                       "|package test;\n" +
 127.247 -                       "\n" +
 127.248 -                       "public class Test {\n" +
 127.249 -                       "     private int test(int j) {\n" +
 127.250 -                       "         j++;\n" +
 127.251 -                       "         j++;\n" +
 127.252 -                       "         int i = 3;\n" +
 127.253 -                       "         j++;\n" +
 127.254 -                       "         j++;\n" +
 127.255 -                       "         return i;\n" +
 127.256 -                       "     }\n" +
 127.257 -                       "}\n",
 127.258 -                       "3:29-10:6:verifier:HINT",
 127.259 -                       "FixImpl",
 127.260 -                       ("package test;\n" +
 127.261 -                       "\n" +
 127.262 -                       "public class Test {\n" +
 127.263 -                       "     private int test(int j) {\n" +
 127.264 -                       "         j++;\n" +
 127.265 -                       "         j++;\n" +
 127.266 -                       "         float i = 3;\n" +
 127.267 -                       "         j++;\n" +
 127.268 -                       "         j++;\n" +
 127.269 -                       "         return i;\n" +
 127.270 -                       "     }\n" +
 127.271 -                       "}\n").replaceAll("[ \t\n]+", " "));
 127.272 -    }
 127.273 -
 127.274 -    public void testMultiStatementVariables2() throws Exception {
 127.275 -        performFixTest("test/Test.java",
 127.276 -                       "|package test;\n" +
 127.277 -                       "\n" +
 127.278 -                       "public class Test {\n" +
 127.279 -                       "     private int test(int j) {\n" +
 127.280 -                       "         int i = 3;\n" +
 127.281 -                       "         return i;\n" +
 127.282 -                       "     }\n" +
 127.283 -                       "}\n",
 127.284 -                       "3:29-6:6:verifier:HINT",
 127.285 -                       "FixImpl",
 127.286 -                       ("package test;\n" +
 127.287 -                       "\n" +
 127.288 -                       "public class Test {\n" +
 127.289 -                       "     private int test(int j) {\n" +
 127.290 -                       "         float i = 3;\n" +
 127.291 -                       "         return i;\n" +
 127.292 -                       "     }\n" +
 127.293 -                       "}\n").replaceAll("[ \t\n]+", " "));
 127.294 -    }
 127.295 -
 127.296 -    public void testMultiStatementVariables3() throws Exception {
 127.297 -        performFixTest("test/Test.java",
 127.298 -                       "|package test;\n" +
 127.299 -                       "\n" +
 127.300 -                       "public class Test {\n" +
 127.301 -                       "     private int test() {\n" +
 127.302 -                       "         System.err.println();\n" +
 127.303 -                       "         System.err.println();\n" +
 127.304 -                       "         int i = 3;\n" +
 127.305 -                       "         System.err.println(i);\n" +
 127.306 -                       "         System.err.println(i);\n" +
 127.307 -                       "         return i;\n" +
 127.308 -                       "     }\n" +
 127.309 -                       "}\n",
 127.310 -                       "3:24-10:6:verifier:HINT",
 127.311 -                       "FixImpl",
 127.312 -                       ("package test;\n" +
 127.313 -                       "\n" +
 127.314 -                       "public class Test {\n" +
 127.315 -                       "     private int test() {\n" +
 127.316 -                       "         System.err.println();\n" +
 127.317 -                       "         System.err.println();\n" +
 127.318 -                       "         float i = 3;\n" +
 127.319 -                       "         System.err.println(i);\n" +
 127.320 -                       "         System.err.println(i);\n" +
 127.321 -                       "         return i;\n" +
 127.322 -                       "     }\n" +
 127.323 -                       "}\n").replaceAll("[ \t\n]+", " "));
 127.324 -    }
 127.325 -
 127.326 -    public void testMultiStatementVariablesAndBlocks() throws Exception {
 127.327 -        performFixTest("test/Test.java",
 127.328 -                       "|package test;\n" +
 127.329 -                       "\n" +
 127.330 -                       "public class Test {\n" +
 127.331 -                       "     private void test() {" +
 127.332 -                       "         if (true)\n" +
 127.333 -                       "             System.err.println();\n" +
 127.334 -                       "     }\n" +
 127.335 -                       "}\n",
 127.336 -                       "3:35-3:37:verifier:HINT",
 127.337 -                       "FixImpl",
 127.338 -                       ("package test;\n" +
 127.339 -                       "\n" +
 127.340 -                       "public class Test {\n" +
 127.341 -                       "     private void test() {" +
 127.342 -                       "         if (false) {\n" +
 127.343 -                       "             System.err.println();\n" +
 127.344 -                       "         }\n" +
 127.345 -                       "     }\n" +
 127.346 -                       "}\n").replaceAll("[ \t\n]+", " "));
 127.347 -    }
 127.348 -
 127.349 -    public void testOneStatement2MultipleBlock() throws Exception {
 127.350 -        performFixTest("test/Test.java",
 127.351 -                       "|package test;\n" +
 127.352 -                       "\n" +
 127.353 -                       "public class Test {\n" +
 127.354 -                       "     private void test() {\n" +
 127.355 -                       "         System.err.println(\"\");\n" +
 127.356 -                       "     }\n" +
 127.357 -                       "}\n",
 127.358 -                       "4:9-4:32:verifier:HINT",
 127.359 -                       "FixImpl",
 127.360 -                       ("package test;\n" +
 127.361 -                       "\n" +
 127.362 -                       "public class Test {\n" +
 127.363 -                       "     private void test() {\n" +
 127.364 -                       "         System.err.println(\"\");\n" +
 127.365 -                       "         System.err.println(\"\");\n" +
 127.366 -                       "     }\n" +
 127.367 -                       "}\n").replaceAll("[ \t\n]+", " "));
 127.368 -    }
 127.369 -
 127.370 -    public void testOneStatement2MultipleStatement() throws Exception {
 127.371 -        performFixTest("test/Test.java",
 127.372 -                       "|package test;\n" +
 127.373 -                       "\n" +
 127.374 -                       "public class Test {\n" +
 127.375 -                       "     private void test() {\n" +
 127.376 -                       "         if (true)\n" +
 127.377 -                       "             System.err.println(\"\");\n" +
 127.378 -                       "     }\n" +
 127.379 -                       "}\n",
 127.380 -                       "5:13-5:36:verifier:HINT",
 127.381 -                       "FixImpl",
 127.382 -                       ("package test;\n" +
 127.383 -                       "\n" +
 127.384 -                       "public class Test {\n" +
 127.385 -                       "     private void test() {\n" +
 127.386 -                       "         if (true) {\n" +
 127.387 -                       "             System.err.println(\"\");\n" +
 127.388 -                       "             System.err.println(\"\");\n" +
 127.389 -                       "         }\n" +
 127.390 -                       "     }\n" +
 127.391 -                       "}\n").replaceAll("[ \t\n]+", " "));
 127.392 -    }
 127.393 -
 127.394 -    public void testMultiple2OneStatement1() throws Exception {
 127.395 -        performFixTest("test/Test.java",
 127.396 -                       "|package test;\n" +
 127.397 -                       "\n" +
 127.398 -                       "public class Test {\n" +
 127.399 -                       "     private void test() {\n" +
 127.400 -                       "         System.err.println(\"\");\n" +
 127.401 -                       "         System.err.println(\"\");\n" +
 127.402 -                       "     }\n" +
 127.403 -                       "}\n",
 127.404 -                       "4:9-4:32:verifier:HINT",
 127.405 -                       "FixImpl",
 127.406 -                       ("package test;\n" +
 127.407 -                       "\n" +
 127.408 -                       "public class Test {\n" +
 127.409 -                       "     private void test() {\n" +
 127.410 -                       "         System.err.println(\"\");\n" +
 127.411 -                       "     }\n" +
 127.412 -                       "}\n").replaceAll("[ \t\n]+", " "));
 127.413 -    }
 127.414 -
 127.415 -    public void testMultiple2OneStatement2() throws Exception {
 127.416 -        performFixTest("test/Test.java",
 127.417 -                       "|package test;\n" +
 127.418 -                       "\n" +
 127.419 -                       "public class Test {\n" +
 127.420 -                       "     private void test() {\n" +
 127.421 -                       "         int i = 0;\n" +
 127.422 -                       "         System.err.println(\"\");\n" +
 127.423 -                       "         System.err.println(\"\");\n" +
 127.424 -                       "         i++;\n" +
 127.425 -                       "     }\n" +
 127.426 -                       "}\n",
 127.427 -                       "5:9-5:32:verifier:HINT",
 127.428 -                       "FixImpl",
 127.429 -                       ("package test;\n" +
 127.430 -                       "\n" +
 127.431 -                       "public class Test {\n" +
 127.432 -                       "     private void test() {\n" +
 127.433 -                       "         int i = 0;\n" +
 127.434 -                       "         System.err.println(\"\");\n" +
 127.435 -                       "         i++;\n" +
 127.436 -                       "     }\n" +
 127.437 -                       "}\n").replaceAll("[ \t\n]+", " "));
 127.438 -    }
 127.439 -
 127.440 -    public void testMemberSelectInsideMemberSelect() throws Exception {
 127.441 -        performFixTest("test/Test.java",
 127.442 -                       "|package test;\n" +
 127.443 -                       "\n" +
 127.444 -                       "public class Test {\n" +
 127.445 -                       "     public Test test;\n" +
 127.446 -                       "     public String name;\n" +
 127.447 -                       "     private void test() {\n" +
 127.448 -                       "         Test t = null;\n" +
 127.449 -                       "         String s = t.test.toString();\n" +
 127.450 -                       "     }\n" +
 127.451 -                       "}\n",
 127.452 -                       "7:22-7:26:verifier:HINT",
 127.453 -                       "FixImpl",
 127.454 -                       ("package test;\n" +
 127.455 -                       "\n" +
 127.456 -                       "public class Test {\n" +
 127.457 -                       "     public Test test;\n" +
 127.458 -                       "     public String name;\n" +
 127.459 -                       "     private void test() {\n" +
 127.460 -                       "         Test t = null;\n" +
 127.461 -                       "         String s = t.getTest().toString();\n" +
 127.462 -                       "     }\n" +
 127.463 -                       "}\n").replaceAll("[ \t\n]+", " "));
 127.464 -    }
 127.465 -
 127.466 -    public void testPackageInfo() throws Exception {
 127.467 -        performAnalysisTest("test/package-info.java",
 127.468 -                            "|package test;\n");
 127.469 -    }
 127.470 -
 127.471 -    public void testSuppressWarnings() throws Exception {
 127.472 -        performAnalysisTest("test/Test.java",
 127.473 -                            "|package test;\n" +
 127.474 -                            "@SuppressWarnings(\"test\")\n" +
 127.475 -                            "public class Test {\n" +
 127.476 -                            "     public Test test;\n" +
 127.477 -                            "     public String name;\n" +
 127.478 -                            "     private void test() {\n" +
 127.479 -                            "         Test t = null;\n" +
 127.480 -                            "         String s = t.test.toString();\n" +
 127.481 -                            "     }\n" +
 127.482 -                            "}\n");
 127.483 -    }
 127.484 -
 127.485 -    public void testRewriteOneToMultipleClassMembers() throws Exception {
 127.486 -        performFixTest("test/Test.java",
 127.487 -                       "|package test;\n" +
 127.488 -                       "\n" +
 127.489 -                       "public class Test {\n" +
 127.490 -                       "     private int i;\n" +
 127.491 -                       "}\n",
 127.492 -                       "3:17-3:18:verifier:HINT",
 127.493 -                       "FixImpl",
 127.494 -                       ("package test;\n" +
 127.495 -                       "\n" +
 127.496 -                       "public class Test {\n" +
 127.497 -                       "     private int i;\n" +
 127.498 -                       "     public int getI() {\n" +
 127.499 -                       "         return i;\n" +
 127.500 -                       "     }\n" +
 127.501 -                       "}\n").replaceAll("[ \t\n]+", " "));
 127.502 -    }
 127.503 -
 127.504 -    public void testImports1() throws Exception {
 127.505 -        performFixTest("test/Test.java",
 127.506 -                       "|package test;\n" +
 127.507 -                       "\n" +
 127.508 -                       "public class Test {\n" +
 127.509 -                       "     private void test() {\n" +
 127.510 -                       "         new java.util.LinkedList();\n" +
 127.511 -                       "     }" +
 127.512 -                       "}\n",
 127.513 -                       "4:9-4:35:verifier:HINT",
 127.514 -                       "FixImpl",
 127.515 -                       ("package test;\n" +
 127.516 -                       "import java.util.ArrayList;\n" +
 127.517 -                       "public class Test {\n" +
 127.518 -                       "     private void test() {\n" +
 127.519 -                       "         new ArrayList();\n" +
 127.520 -                       "     }" +
 127.521 -                       "}\n").replaceAll("[ \t\n]+", " "));
 127.522 -    }
 127.523 -
 127.524 -    public void testImports2() throws Exception {
 127.525 -        performFixTest("test/Test.java",
 127.526 -                       "|package test;\n" +
 127.527 -                       "import java.util.LinkedList;\n" +
 127.528 -                       "public class Test {\n" +
 127.529 -                       "     private void test() {\n" +
 127.530 -                       "         LinkedList l;\n" +
 127.531 -                       "     }" +
 127.532 -                       "}\n",
 127.533 -                       "4:20-4:21:verifier:HINT",
 127.534 -                       "FixImpl",
 127.535 -                       ("package test;\n" +
 127.536 -                       "import java.util.ArrayList;\n" +
 127.537 -                       "import java.util.LinkedList;\n" +
 127.538 -                       "public class Test {\n" +
 127.539 -                       "     private void test() {\n" +
 127.540 -                       "         ArrayList l;\n" +
 127.541 -                       "     }" +
 127.542 -                       "}\n").replaceAll("[ \t\n]+", " "));
 127.543 -    }
 127.544 -
 127.545 -    public void testMultiParameters() throws Exception {
 127.546 -        performFixTest("test/Test.java",
 127.547 -                       "|package test;\n" +
 127.548 -                       "import java.util.Arrays;\n" +
 127.549 -                       "public class Test {\n" +
 127.550 -                       "     { Arrays.asList(\"a\", \"b\", \"c\"); }\n" +
 127.551 -                       "}\n",
 127.552 -                       "3:14-3:20:verifier:HINT",
 127.553 -                       "FixImpl",
 127.554 -                       ("package test;\n" +
 127.555 -                       "import java.util.Arrays;\n" +
 127.556 -                       "public class Test {\n" +
 127.557 -                       "     { Arrays.asList(\"d\", \"a\", \"b\", \"c\"); }\n" +
 127.558 -                       "}\n").replaceAll("[ \t\n]+", " "));
 127.559 -    }
 127.560 -
 127.561 -    public void testTypeParametersMethod() throws Exception {
 127.562 -        performFixTest("test/Test.java",
 127.563 -                       "|package test;\n" +
 127.564 -                       "import java.util.Arrays;\n" +
 127.565 -                       "public class Test {\n" +
 127.566 -                       "     { Arrays.<String>asList(\"a\", \"b\", \"c\"); }\n" +
 127.567 -                       "}\n",
 127.568 -                       "3:22-3:28:verifier:HINT",
 127.569 -                       "FixImpl",
 127.570 -                       ("package test;\n" +
 127.571 -                       "import java.util.Arrays;\n" +
 127.572 -                       "public class Test {\n" +
 127.573 -                       "     { Arrays.<String>asList(\"d\", \"a\", \"b\", \"c\"); }\n" +
 127.574 -                       "}\n").replaceAll("[ \t\n]+", " "));
 127.575 -    }
 127.576 -
 127.577 -    public void testTypeParametersNewClass() throws Exception {
 127.578 -        performFixTest("test/Test.java",
 127.579 -                       "|package test;\n" +
 127.580 -                       "import java.util.Arrays;\n" +
 127.581 -                       "import java.util.HashSet;\n" +
 127.582 -                       "public class Test {\n" +
 127.583 -                       "     { new HashSet<String>(Arrays.<String>asList(\"a\", \"b\", \"c\")); }\n" +
 127.584 -                       "}\n",
 127.585 -                       "4:7-4:64:verifier:HINT",
 127.586 -                       "FixImpl",
 127.587 -                       ("package test;\n" +
 127.588 -                       "import java.util.Arrays;\n" +
 127.589 -                       "import java.util.HashSet;\n" +
 127.590 -                       "public class Test {\n" +
 127.591 -                       "     { new HashSet<String>(Arrays.<String>asList(\"d\", \"a\", \"b\", \"c\")); }\n" +
 127.592 -                       "}\n").replaceAll("[ \t\n]+", " "));
 127.593 -    }
 127.594 -
 127.595 -    public void testChangeFieldType1() throws Exception {
 127.596 -        performFixTest("test/Test.java",
 127.597 -                       "|package test;\n" +
 127.598 -                       "public class Test {\n" +
 127.599 -                       "     private String name = null;\n" +
 127.600 -                       "}\n",
 127.601 -                       "2:20-2:24:verifier:HINT",
 127.602 -                       "FixImpl",
 127.603 -                       ("package test;\n" +
 127.604 -                       "public class Test {\n" +
 127.605 -                       "     private CharSequence name = null;\n" +
 127.606 -                       "}\n").replaceAll("[ \t\n]+", " "));
 127.607 -    }
 127.608 -
 127.609 -    public void testChangeFieldType2() throws Exception {
 127.610 -        performFixTest("test/Test.java",
 127.611 -                       "|package test;\n" +
 127.612 -                       "public class Test {\n" +
 127.613 -                       "     String name = null;\n" +
 127.614 -                       "}\n",
 127.615 -                       "2:12-2:16:verifier:HINT",
 127.616 -                       "FixImpl",
 127.617 -                       ("package test;\n" +
 127.618 -                       "public class Test {\n" +
 127.619 -                       "     CharSequence name = null;\n" +
 127.620 -                       "}\n").replaceAll("[ \t\n]+", " "));
 127.621 -    }
 127.622 -
 127.623 -    public void testChangeFieldType3() throws Exception {
 127.624 -        performFixTest("test/Test.java",
 127.625 -                       "|package test;\n" +
 127.626 -                       "public class Test {\n" +
 127.627 -                       "     private static final String name = \"test\".substring(0, 4);\n" +
 127.628 -                       "}\n",
 127.629 -                       "2:33-2:37:verifier:HINT",
 127.630 -                       "FixImpl",
 127.631 -                       ("package test;\n" +
 127.632 -                       "public class Test {\n" +
 127.633 -                       "     private static final CharSequence name = \"test\".substring(0, 4);\n" +
 127.634 -                       "}\n").replaceAll("[ \t\n]+", " "));
 127.635 -    }
 127.636 -
 127.637 -    public void testIdentifier() throws Exception {
 127.638 -        performFixTest("test/Test.java",
 127.639 -                       "|package test;\n" +
 127.640 -                       "public class Test {\n" +
 127.641 -                       "     private int l;" +
 127.642 -                       "     {System.err.println(l);}\n" +
 127.643 -                       "}\n",
 127.644 -                       "2:44-2:45:verifier:HINT",
 127.645 -                       "FixImpl",
 127.646 -                       ("package test;\n" +
 127.647 -                       "public class Test {\n" +
 127.648 -                       "     private int l;" +
 127.649 -                       "     {System.err.println(2);}\n" +
 127.650 -                       "}\n").replaceAll("[ \t\n]+", " "));
 127.651 -    }
 127.652 -
 127.653 -    public void testLambda() throws Exception {
 127.654 -        performAnalysisTest("test/Test.java",
 127.655 -                       "|package test;\n" +
 127.656 -                       "public class Test {\n" +
 127.657 -                       "     { new java.io.FileFilter() {public boolean accept(java.io.File f) { return true; } } }\n" +
 127.658 -                       "}\n",
 127.659 -                       "2:7-2:89:verifier:HINT");
 127.660 -    }
 127.661 -
 127.662 -    public void testAddCasesToSwitch() throws Exception {
 127.663 -        performFixTest("test/Test.java",
 127.664 -                       "|package test;\n" +
 127.665 -                       "public class Test {\n" +
 127.666 -                       "     {\n" +
 127.667 -                       "         E e = null;\n" +
 127.668 -                       "         switch (e) {\n" +
 127.669 -                       "             case A: System.err.println(1); break;\n" +
 127.670 -                       "             case D: System.err.println(2); break;\n" +
 127.671 -                       "             case E: System.err.println(3); break;\n" +
 127.672 -                       "         }\n" +
 127.673 -                       "     }\n" +
 127.674 -                       "     public enum E {A, B, C, D, E, F;}\n" +
 127.675 -                       "}\n",
 127.676 -                       "4:9-4:15:verifier:HINT",
 127.677 -                       "FixImpl",
 127.678 -                       ("package test;\n" +
 127.679 -                       "public class Test {\n" +
 127.680 -                       "     {\n" +
 127.681 -                       "         E e = null;\n" +
 127.682 -                       "         switch (e) {\n" +
 127.683 -                       "             case A: System.err.println(1); break;\n" +
 127.684 -                       "             case B:case C:\n" +
 127.685 -//                       "             case C:\n" +
 127.686 -                       "             case D: System.err.println(2); break;\n" +
 127.687 -                       "             case E: System.err.println(3); break;\n" +
 127.688 -                       "         }\n" +
 127.689 -                       "     }\n" +
 127.690 -                       "     public enum E {A, B, C, D, E, F;}\n" +
 127.691 -                       "}\n").replaceAll("[ \t\n]+", " "));
 127.692 -    }
 127.693 -
 127.694 -    private static final Map<String, HintDescription> test2Hint;
 127.695 -
 127.696 -    static {
 127.697 -        test2Hint = new HashMap<String, HintDescription>();
 127.698 -        test2Hint.put("testPattern1", HintDescriptionFactory.create().setTrigger(PatternDescription.create("$1.toURL()", Collections.singletonMap("$1", "java.io.File"))).setWorker(new WorkerImpl()).produce());
 127.699 -        test2Hint.put("testPattern2", test2Hint.get("testPattern1"));
 127.700 -        test2Hint.put("testKind1", HintDescriptionFactory.create().setTrigger(new Kinds(EnumSet.of(Kind.METHOD_INVOCATION))).setWorker(new WorkerImpl()).produce());
 127.701 -        test2Hint.put("testPatternVariable1", HintDescriptionFactory.create().setTrigger(PatternDescription.create("{ $1 $2; $2 = $3; }", Collections.<String, String>emptyMap())).setWorker(new WorkerImpl("{ $1 $2 = $3; }")).produce());
 127.702 -        Map<String, String> constraints = new HashMap<String, String>();
 127.703 -
 127.704 -        constraints.put("$1", "boolean");
 127.705 -        constraints.put("$2", "java.lang.Object");
 127.706 -
 127.707 -        test2Hint.put("testPatternAssert1", HintDescriptionFactory.create().setTrigger(PatternDescription.create("assert $1 : $2;", constraints)).setWorker(new WorkerImpl()).produce());
 127.708 -        test2Hint.put("testPatternStatementAndSingleStatementBlockAreSame", HintDescriptionFactory.create().setTrigger(PatternDescription.create("if ($1) return $2;", Collections.<String, String>emptyMap())).setWorker(new WorkerImpl()).produce());
 127.709 -        test2Hint.put("testPatternFalseOccurrence", HintDescriptionFactory.create().setTrigger(PatternDescription.create("$1.toURL()", Collections.singletonMap("$1", "java.io.File"))).setWorker(new WorkerImpl()).produce());
 127.710 -        test2Hint.put("testStatementVariables1", HintDescriptionFactory.create().setTrigger(PatternDescription.create("if ($1) $2; else $3;", constraints)).setWorker(new WorkerImpl("if (!$1) $3; else $2;")).produce());
 127.711 -        test2Hint.put("testStatementVariables2", test2Hint.get("testStatementVariables1"));
 127.712 -        test2Hint.put("testMultiStatementVariables1", HintDescriptionFactory.create().setTrigger(PatternDescription.create("{ $pref$; int $i = 3; $inf$; return $i; }", Collections.<String, String>emptyMap())).setWorker(new WorkerImpl("{ $pref$; float $i = 3; $inf$; return $i; }")).produce());
 127.713 -        test2Hint.put("testMultiStatementVariables2", test2Hint.get("testMultiStatementVariables1"));
 127.714 -        test2Hint.put("testMultiStatementVariables3", test2Hint.get("testMultiStatementVariables1"));
 127.715 -        test2Hint.put("testMultiStatementVariablesAndBlocks", HintDescriptionFactory.create().setTrigger(PatternDescription.create("if ($c) {$s1$; System.err.println(); $s2$; }", Collections.<String, String>emptyMap())).setWorker(new WorkerImpl("if (!$c) {$s1$; System.err.println(); $s2$; }")).produce());
 127.716 -        test2Hint.put("testOneStatement2MultipleBlock", HintDescriptionFactory.create().setTrigger(PatternDescription.create("System.err.println($1);", Collections.<String, String>emptyMap())).setWorker(new WorkerImpl("System.err.println($1); System.err.println($1);")).produce());
 127.717 -        test2Hint.put("testOneStatement2MultipleStatement", test2Hint.get("testOneStatement2MultipleBlock"));
 127.718 -        test2Hint.put("testMultiple2OneStatement1", HintDescriptionFactory.create().setTrigger(PatternDescription.create("System.err.println($1); System.err.println($2);", Collections.<String, String>emptyMap())).setWorker(new WorkerImpl("System.err.println($1);")).produce());
 127.719 -        test2Hint.put("testMultiple2OneStatement2", test2Hint.get("testMultiple2OneStatement1"));
 127.720 -        test2Hint.put("testMemberSelectInsideMemberSelect", HintDescriptionFactory.create().setTrigger(PatternDescription.create("$Test.test", Collections.<String, String>singletonMap("$Test", "test.Test"))).setWorker(new WorkerImpl("$Test.getTest()")).produce());
 127.721 -        test2Hint.put("testPackageInfo", HintDescriptionFactory.create().setTrigger(PatternDescription.create("$Test.test", Collections.<String, String>singletonMap("$Test", "test.Test"))).setWorker(new WorkerImpl("$Test.getTest()")).produce());
 127.722 -        HintMetadata metadata = HintMetadata.Builder.create("no-id").addOptions(Options.NON_GUI).addSuppressWarnings("test").build();
 127.723 -        test2Hint.put("testSuppressWarnings", HintDescriptionFactory.create().setTrigger(PatternDescription.create("$Test.test", Collections.<String, String>singletonMap("$Test", "test.Test"))).setWorker(new WorkerImpl("$Test.getTest()")).setMetadata(metadata).produce());
 127.724 -        test2Hint.put("testRewriteOneToMultipleClassMembers", HintDescriptionFactory.create().setTrigger(PatternDescription.create("private int i;", Collections.<String, String>emptyMap())).setWorker(new WorkerImpl("private int i; public int getI() { return i; }")).produce());
 127.725 -//        test2Hint.put("testImports1", HintDescriptionFactory.create().setTrigger(PatternDescription.create("new LinkedList()", Collections.<String, String>emptyMap(), "import java.util.LinkedList;")).setWorker(new WorkerImpl("new ArrayList()", "import java.util.ArrayList;\n")).produce());
 127.726 -//        test2Hint.put("testImports2", HintDescriptionFactory.create().setTrigger(PatternDescription.create("LinkedList $0;", Collections.<String, String>emptyMap(), "import java.util.LinkedList;")).setWorker(new WorkerImpl("ArrayList $0;", "import java.util.ArrayList;\n")).produce());
 127.727 -        test2Hint.put("testImports1", HintDescriptionFactory.create().setTrigger(PatternDescription.create("new LinkedList()", Collections.<String, String>emptyMap(), "import java.util.LinkedList;")).setWorker(new WorkerImpl("new java.util.ArrayList()")).produce());
 127.728 -        test2Hint.put("testImports2", HintDescriptionFactory.create().setTrigger(PatternDescription.create("LinkedList $0;", Collections.<String, String>emptyMap(), "import java.util.LinkedList;")).setWorker(new WorkerImpl("java.util.ArrayList $0;")).produce());
 127.729 -        test2Hint.put("testMultiParameters", HintDescriptionFactory.create().setTrigger(PatternDescription.create("java.util.Arrays.asList($1$)", Collections.<String,String>emptyMap())).setWorker(new WorkerImpl("java.util.Arrays.asList(\"d\", $1$)")).produce());
 127.730 -        test2Hint.put("testTypeParametersMethod", HintDescriptionFactory.create().setTrigger(PatternDescription.create("java.util.Arrays.<$T>asList($1$)", Collections.<String,String>emptyMap())).setWorker(new WorkerImpl("java.util.Arrays.<$T>asList(\"d\", $1$)")).produce());
 127.731 -        test2Hint.put("testTypeParametersNewClass", HintDescriptionFactory.create().setTrigger(PatternDescription.create("new java.util.HashSet<$T1$>(java.util.Arrays.<$T$>asList($1$))", Collections.<String,String>emptyMap())).setWorker(new WorkerImpl("new java.util.HashSet<$T1$>(java.util.Arrays.<$T$>asList(\"d\", $1$))")).produce());
 127.732 -        test2Hint.put("testChangeFieldType1", HintDescriptionFactory.create().setTrigger(PatternDescription.create("$modifiers$ java.lang.String $name = $initializer;", Collections.<String, String>emptyMap())).setWorker(new WorkerImpl("$modifiers$ java.lang.CharSequence $name = $initializer;")).produce());
 127.733 -        test2Hint.put("testChangeFieldType2", test2Hint.get("testChangeFieldType1"));
 127.734 -        test2Hint.put("testChangeFieldType3", test2Hint.get("testChangeFieldType1"));
 127.735 -        test2Hint.put("testIdentifier", HintDescriptionFactory.create().setTrigger(PatternDescription.create("$i", Collections.<String, String>singletonMap("$i", "int"))).setWorker(new WorkerImpl("2")).produce());
 127.736 -        test2Hint.put("testLambda", HintDescriptionFactory.create().setTrigger(PatternDescription.create("new $type() { $mods$ $retType $name($params$) { $body$; } }", Collections.<String, String>emptyMap())).setWorker(new WorkerImpl()).produce());
 127.737 -        test2Hint.put("testAddCasesToSwitch", HintDescriptionFactory.create().setTrigger(PatternDescription.create("switch ($var) { case $c1$; case D: $stmts$; case $c2$; }", Collections.<String,String>singletonMap("$var", "test.Test.E"))).setWorker(new WorkerImpl("switch ($var) { case $c1$ case B: case C: case D: $stmts$; case $c2$ }")).produce());
 127.738 -    }
 127.739 -
 127.740 -//    @Override
 127.741 -    protected List<ErrorDescription> computeErrors(CompilationInfo info, TreePath path, int pos) {
 127.742 -        HintDescription hd = test2Hint.get(getName());
 127.743 -
 127.744 -        assertNotNull(hd);
 127.745 -
 127.746 -        return new HintsInvoker(HintsSettings.getGlobalSettings(), new AtomicBoolean()).computeHints(info, Collections.singletonList(hd));
 127.747 -    }
 127.748 -
 127.749 -//    @Override
 127.750 -    protected String toDebugString(CompilationInfo info, Fix f) {
 127.751 -        return "FixImpl";
 127.752 -    }
 127.753 -
 127.754 -//    @Override
 127.755 -//    public void testIssue105979() throws Exception {}
 127.756 -//
 127.757 -//    @Override
 127.758 -//    public void testIssue108246() throws Exception {}
 127.759 -//
 127.760 -//    @Override
 127.761 -//    public void testIssue113933() throws Exception {}
 127.762 -//
 127.763 -//    @Override
 127.764 -//    public void testNoHintsForSimpleInitialize() throws Exception {}
 127.765 -
 127.766 -    private static final class WorkerImpl implements Worker {
 127.767 -
 127.768 -        private final String fix;
 127.769 -
 127.770 -        public WorkerImpl() {
 127.771 -            this(null);
 127.772 -        }
 127.773 -
 127.774 -        public WorkerImpl(String fix) {
 127.775 -            this.fix = fix;
 127.776 -        }
 127.777 -
 127.778 -        public Collection<? extends ErrorDescription> createErrors(HintContext ctx) {
 127.779 -            if (ctx.getInfo().getTreeUtilities().isSynthetic(ctx.getPath())) {
 127.780 -                return null;
 127.781 -            }
 127.782 -
 127.783 -            List<Fix> fixes = new LinkedList<Fix>();
 127.784 -
 127.785 -            if (fix != null) {
 127.786 -                fixes.add(JavaFixUtilities.rewriteFix(ctx, "Rewrite", ctx.getPath(), fix));
 127.787 -            }
 127.788 -            
 127.789 -            return Collections.singletonList(ErrorDescriptionFactory.forName(ctx, ctx.getPath(), "HINT", fixes.toArray(new Fix[0])));
 127.790 -        }
 127.791 -    }
 127.792 -
 127.793 -
 127.794 -    //XXX:copied from TreeRuleTestBase:
 127.795 -
 127.796 -    protected void performAnalysisTest(String fileName, String code, String... golden) throws Exception {
 127.797 -        int[] offset = new int[1];
 127.798 -
 127.799 -        code = org.netbeans.modules.java.hints.spiimpl.TestUtilities.detectOffsets(code, offset);
 127.800 -
 127.801 -        performAnalysisTest(fileName, code, offset[0], golden);
 127.802 -    }
 127.803 -
 127.804 -    protected void performAnalysisTest(String fileName, String code, int pos, String... golden) throws Exception {
 127.805 -        prepareTest(fileName, code);
 127.806 -
 127.807 -        TreePath path = info.getTreeUtilities().pathFor(pos);
 127.808 -
 127.809 -        List<ErrorDescription> errors = computeErrors(info, path, pos);
 127.810 -        List<String> errorsNames = new LinkedList<String>();
 127.811 -
 127.812 -        errors = errors != null ? errors : Collections.<ErrorDescription>emptyList();
 127.813 -
 127.814 -        for (ErrorDescription e : errors) {
 127.815 -            errorsNames.add(e.toString());
 127.816 -        }
 127.817 -
 127.818 -        assertTrue("The warnings provided by the hint do not match expected warnings. Provided warnings: " + errorsNames.toString(), Arrays.equals(golden, errorsNames.toArray(new String[0])));
 127.819 -    }
 127.820 -
 127.821 -    protected String performFixTest(String fileName, String code, String errorDescriptionToString, String fixDebugString, String golden) throws Exception {
 127.822 -        int[] offset = new int[1];
 127.823 -
 127.824 -        code = org.netbeans.modules.java.hints.spiimpl.TestUtilities.detectOffsets(code, offset);
 127.825 -
 127.826 -        return performFixTest(fileName, code, offset[0], errorDescriptionToString, fixDebugString, golden);
 127.827 -    }
 127.828 -
 127.829 -    protected String performFixTest(String fileName, String code, int pos, String errorDescriptionToString, String fixDebugString, String golden) throws Exception {
 127.830 -        return performFixTest(fileName, code, pos, errorDescriptionToString, fixDebugString, fileName, golden);
 127.831 -    }
 127.832 -
 127.833 -    protected String performFixTest(String fileName, String code, String errorDescriptionToString, String fixDebugString, String goldenFileName, String golden) throws Exception {
 127.834 -        int[] offset = new int[1];
 127.835 -
 127.836 -        code = org.netbeans.modules.java.hints.spiimpl.TestUtilities.detectOffsets(code, offset);
 127.837 -
 127.838 -        return performFixTest(fileName, code, offset[0], errorDescriptionToString, fixDebugString, goldenFileName, golden);
 127.839 -    }
 127.840 -
 127.841 -    protected String performFixTest(String fileName, String code, int pos, String errorDescriptionToString, String fixDebugString, String goldenFileName, String golden) throws Exception {
 127.842 -        prepareTest(fileName, code);
 127.843 -
 127.844 -        TreePath path = info.getTreeUtilities().pathFor(pos);
 127.845 -
 127.846 -        List<ErrorDescription> errors = computeErrors(info, path, pos);
 127.847 -
 127.848 -        ErrorDescription toFix = null;
 127.849 -
 127.850 -        for (ErrorDescription d : errors) {
 127.851 -            if (errorDescriptionToString.equals(d.toString())) {
 127.852 -                toFix = d;
 127.853 -                break;
 127.854 -            }
 127.855 -        }
 127.856 -
 127.857 -        assertNotNull("Error: \"" + errorDescriptionToString + "\" not found. All ErrorDescriptions: " + errors.toString(), toFix);
 127.858 -
 127.859 -        assertTrue("Must be computed", toFix.getFixes().isComputed());
 127.860 -
 127.861 -        List<Fix> fixes = toFix.getFixes().getFixes();
 127.862 -        List<String> fixNames = new LinkedList<String>();
 127.863 -        Fix toApply = null;
 127.864 -
 127.865 -        for (Fix f : fixes) {
 127.866 -            if (fixDebugString.equals(toDebugString(info, f))) {
 127.867 -                toApply = f;
 127.868 -            }
 127.869 -
 127.870 -            fixNames.add(toDebugString(info, f));
 127.871 -        }
 127.872 -
 127.873 -        assertNotNull("Cannot find fix to invoke: " + fixNames.toString(), toApply);
 127.874 -
 127.875 -        toApply.implement();
 127.876 -
 127.877 -        FileObject toCheck = sourceRoot.getFileObject(goldenFileName);
 127.878 -
 127.879 -        assertNotNull(toCheck);
 127.880 -
 127.881 -        DataObject toCheckDO = DataObject.find(toCheck);
 127.882 -        EditorCookie ec = toCheckDO.getLookup().lookup(EditorCookie.class);
 127.883 -        Document toCheckDocument = ec.openDocument();
 127.884 -
 127.885 -        String realCode = toCheckDocument.getText(0, toCheckDocument.getLength());
 127.886 -
 127.887 -        //ignore whitespaces:
 127.888 -        realCode = realCode.replaceAll("[ \t\n]+", " ");
 127.889 -
 127.890 -        if (golden != null) {
 127.891 -            assertEquals("The output code does not match the expected code.", golden, realCode);
 127.892 -        }
 127.893 -
 127.894 -        LifecycleManager.getDefault().saveAll();
 127.895 -
 127.896 -        return realCode;
 127.897 -    }
 127.898 -}
 127.899 \ No newline at end of file
   128.1 --- a/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/pm/BulkSearchTestPerformer.java	Sun Oct 16 08:01:27 2016 +0200
   128.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   128.3 @@ -1,694 +0,0 @@
   128.4 -/*
   128.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   128.6 - *
   128.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
   128.8 - *
   128.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  128.10 - * Other names may be trademarks of their respective owners.
  128.11 - *
  128.12 - * The contents of this file are subject to the terms of either the GNU
  128.13 - * General Public License Version 2 only ("GPL") or the Common
  128.14 - * Development and Distribution License("CDDL") (collectively, the
  128.15 - * "License"). You may not use this file except in compliance with the
  128.16 - * License. You can obtain a copy of the License at
  128.17 - * http://www.netbeans.org/cddl-gplv2.html
  128.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  128.19 - * specific language governing permissions and limitations under the
  128.20 - * License.  When distributing the software, include this License Header
  128.21 - * Notice in each file and include the License file at
  128.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  128.23 - * particular file as subject to the "Classpath" exception as provided
  128.24 - * by Oracle in the GPL Version 2 section of the License file that
  128.25 - * accompanied this code. If applicable, add the following below the
  128.26 - * License Header, with the fields enclosed by brackets [] replaced by
  128.27 - * your own identifying information:
  128.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  128.29 - *
  128.30 - * If you wish your version of this file to be governed by only the CDDL
  128.31 - * or only the GPL Version 2, indicate your decision by adding
  128.32 - * "[Contributor] elects to include this software in this distribution
  128.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  128.34 - * single choice of license, a recipient has the option to distribute
  128.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  128.36 - * to extend the choice of license to its licensees as provided above.
  128.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  128.38 - * Version 2 license, then the option applies only if the new code is
  128.39 - * made subject to such option by the copyright holder.
  128.40 - *
  128.41 - * Contributor(s):
  128.42 - *
  128.43 - * Portions Copyrighted 2009 Sun Microsystems, Inc.
  128.44 - */
  128.45 -
  128.46 -package org.netbeans.modules.java.hints.spiimpl.pm;
  128.47 -
  128.48 -import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch.BulkPattern;
  128.49 -import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch.EncodingContext;
  128.50 -import com.sun.source.util.TreePath;
  128.51 -import java.io.ByteArrayInputStream;
  128.52 -import java.io.ByteArrayOutputStream;
  128.53 -import java.io.File;
  128.54 -import java.util.Arrays;
  128.55 -import java.util.Collection;
  128.56 -import java.util.Collections;
  128.57 -import java.util.HashMap;
  128.58 -import java.util.HashSet;
  128.59 -import java.util.LinkedList;
  128.60 -import java.util.List;
  128.61 -import java.util.Map;
  128.62 -import java.util.Map.Entry;
  128.63 -import java.util.Set;
  128.64 -import java.util.concurrent.atomic.AtomicBoolean;
  128.65 -import java.util.regex.Pattern;
  128.66 -import javax.swing.text.Document;
  128.67 -import org.netbeans.api.java.lexer.JavaTokenId;
  128.68 -import org.netbeans.api.java.source.CompilationInfo;
  128.69 -import org.netbeans.api.java.source.JavaSource;
  128.70 -import org.netbeans.api.java.source.JavaSource.Phase;
  128.71 -import org.netbeans.api.java.source.SourceUtilsTestUtil;
  128.72 -import org.netbeans.api.java.source.TestUtilities;
  128.73 -import org.netbeans.api.java.source.TreePathHandle;
  128.74 -import org.netbeans.api.lexer.Language;
  128.75 -import org.netbeans.junit.NbTestCase;
  128.76 -import org.netbeans.modules.java.source.TreeLoader;
  128.77 -import org.openide.cookies.EditorCookie;
  128.78 -import org.openide.filesystems.FileObject;
  128.79 -import org.openide.filesystems.FileUtil;
  128.80 -import org.openide.loaders.DataObject;
  128.81 -import static org.junit.Assert.*;
  128.82 -import org.netbeans.junit.RandomlyFails;
  128.83 -
  128.84 -/**
  128.85 - *
  128.86 - * @author lahvac
  128.87 - */
  128.88 -public abstract class BulkSearchTestPerformer extends NbTestCase {
  128.89 -
  128.90 -    public BulkSearchTestPerformer(String name) {
  128.91 -        super(name);
  128.92 -    }
  128.93 -
  128.94 -    @Override
  128.95 -    protected void setUp() throws Exception {
  128.96 -        super.setUp();
  128.97 -        SourceUtilsTestUtil.prepareTest(new String[] {"org/netbeans/modules/java/editor/resources/layer.xml"}, new Object[0]);
  128.98 -        TreeLoader.DISABLE_CONFINEMENT_TEST = true;
  128.99 -    }
 128.100 -
 128.101 -//    public static TestSuite suite() {
 128.102 -//        NbTestSuite s = new NbTestSuite();
 128.103 -//
 128.104 -//        s.addTestSuite(NFABasedBulkSearchTest.class);
 128.105 -//
 128.106 -//        return s;
 128.107 -//    }
 128.108 -
 128.109 -    public void testSimple1() throws Exception {
 128.110 -        performTest("package test; public class Test { private void test() { System.err./**/println(\"\");}}",
 128.111 -                    Collections.singletonMap("System.err.println(\"\")", Arrays.asList("System.err./**/println(\"\")")),
 128.112 -                    Arrays.asList("System.err.println(\"\" + \"\")"));
 128.113 -    }
 128.114 -
 128.115 -    public void testDontCare() throws Exception {
 128.116 -        performTest("package test; public class Test { private void test() { System.err./**/println(\"\" + \"\");}}",
 128.117 -                    Collections.singletonMap("System.err.println($1)", Arrays.asList("System.err./**/println(\"\" + \"\")")),
 128.118 -                    Collections.<String>emptyList());
 128.119 -    }
 128.120 -
 128.121 -    public void testMemberSelectAndIdentifier() throws Exception {
 128.122 -        performTest("package test; public class Test { private static void test() { test();}}",
 128.123 -                    Collections.singletonMap("test.Test.test()", Arrays.asList("test()")),
 128.124 -                    Collections.<String>emptyList());
 128.125 -    }
 128.126 -
 128.127 -    public void testUnpureMemberSelect() throws Exception {
 128.128 -        performTest("package test; public class Test { private static void test() { new StringBuilder().append(\"\");}}",
 128.129 -                    Collections.<String, List<String>>emptyMap(),
 128.130 -                    Arrays.asList("test.append(\"\")"));
 128.131 -    }
 128.132 -
 128.133 -    public void testMemberSelectWithVariables1() throws Exception {
 128.134 -        performTest("package test; public class Test { private static void test() { new StringBuilder().append(\"\");}}",
 128.135 -                    Collections.singletonMap("$0.append(\"\")", Arrays.asList("new StringBuilder().append(\"\")")),
 128.136 -                    Collections.<String>emptyList());
 128.137 -    }
 128.138 -
 128.139 -    public void testMemberSelectWithVariables2() throws Exception {
 128.140 -        performTest("package test; public class Test { private void append(char c) { append(\"\");}}",
 128.141 -                    Collections.singletonMap("$0.append(\"\")", Arrays.asList("append(\"\")")),
 128.142 -                    Collections.<String>emptyList());
 128.143 -    }
 128.144 -
 128.145 -    public void testLocalVariables() throws Exception {
 128.146 -        performTest("package test; public class Test { private void test() { { int y; y = 1; } }}",
 128.147 -                    Collections.singletonMap("{ int $1; $1 = 1; }", Arrays.asList("{ int y; y = 1; }")),
 128.148 -                    Collections.<String>emptyList());
 128.149 -    }
 128.150 -
 128.151 -    public void testAssert() throws Exception {
 128.152 -        performTest("package test; public class Test { private void test() { assert true : \"\"; }}",
 128.153 -                    Collections.singletonMap("assert $1 : $2;", Arrays.asList("assert true : \"\";")),
 128.154 -                    Collections.<String>emptyList());
 128.155 -    }
 128.156 -
 128.157 -    public void testStatementAndSingleBlockStatementAreSame1() throws Exception {
 128.158 -        performTest("package test; public class Test { private void test() { { int y; { y = 1; } } }}",
 128.159 -                    Collections.singletonMap("{ int $1; $1 = 1; }", Arrays.asList("{ int y; { y = 1; } }")),
 128.160 -                    Collections.<String>emptyList());
 128.161 -    }
 128.162 -
 128.163 -    public void testStatementAndSingleBlockStatementAreSame2() throws Exception {
 128.164 -        performTest("package test; public class Test { private void test() { { int y; y = 1; } }}",
 128.165 -                    Collections.singletonMap("{ int $1; { $1 = 1; } }", Arrays.asList("{ int y; y = 1; }")),
 128.166 -                    Collections.<String>emptyList());
 128.167 -    }
 128.168 -
 128.169 -    public void testStatementVariables1() throws Exception {
 128.170 -        performTest("package test; public class Test { public int test1() { if (true) return 1; else return 2; } }",
 128.171 -                    Collections.singletonMap("if ($1) $2; else $3;", Arrays.asList("if (true) return 1; else return 2;")),
 128.172 -                    Collections.<String>emptyList());
 128.173 -    }
 128.174 -
 128.175 -    public void testMultiStatementVariables1() throws Exception {
 128.176 -        performTest("package test; public class Test { public int test1(int i) { System.err.println(i); System.err.println(i); i = 3; System.err.println(i); System.err.println(i); return i; } }",
 128.177 -                    Collections.singletonMap("{ $s1$; i = 3; $s2$; return i; }", Arrays.asList("{ System.err.println(i); System.err.println(i); i = 3; System.err.println(i); System.err.println(i); return i; }")),
 128.178 -                    Collections.<String>emptyList());
 128.179 -    }
 128.180 -
 128.181 -    public void testMultiStatementVariables2() throws Exception {
 128.182 -        performTest("package test; public class Test { public int test1(int i) { i = 3; return i; } }",
 128.183 -                    Collections.singletonMap("{ $s1$; i = 3; $s2$; return i; }", Arrays.asList("{ i = 3; return i; }")),
 128.184 -                    Collections.<String>emptyList());
 128.185 -    }
 128.186 -
 128.187 -    public void testMultiStatementVariablesAndBlocks1() throws Exception {
 128.188 -        performTest("package test; public class Test { public void test1() { if (true) System.err.println(); } }",
 128.189 -                    Collections.singletonMap("if ($c) {$s1$; System.err.println(); $s2$; }", Arrays.asList("if (true) System.err.println();")),
 128.190 -                    Collections.<String>emptyList());
 128.191 -    }
 128.192 -
 128.193 -    public void testMultiStatementVariablesAndBlocks2() throws Exception {
 128.194 -        performTest("package test; public class Test { public void test1() { if (true) System.err.println(); } }",
 128.195 -                    Collections.singletonMap("if ($c) {$s1$; System.err.println(); }", Arrays.asList("if (true) System.err.println();")),
 128.196 -                    Collections.<String>emptyList());
 128.197 -    }
 128.198 -
 128.199 -    public void testMultiStatementVariablesAndBlocks3() throws Exception {
 128.200 -        performTest("package test; public class Test { public void test1() { if (true) System.err.println(); } }",
 128.201 -                    Collections.singletonMap("if ($c) {System.err.println(); $s2$; }", Arrays.asList("if (true) System.err.println();")),
 128.202 -                    Collections.<String>emptyList());
 128.203 -    }
 128.204 -
 128.205 -    public void testMultiStatementVariablesAndBlocks4() throws Exception {
 128.206 -        performTest("package test; public class Test { public void test1() { if (true) System.err.println(); } }",
 128.207 -                    Collections.singletonMap("{ $s1$; System.err.println(); $s2$; }", Arrays.asList("System.err.println();")),
 128.208 -                    Collections.<String>emptyList());
 128.209 -    }
 128.210 -
 128.211 -    public void testTwoPatterns() throws Exception {
 128.212 -        Map<String, List<String>> contained = new HashMap<String, List<String>>();
 128.213 -
 128.214 -        contained.put("if ($a) $ret = $b; else $ret = $c;", Arrays.asList("if (b) q = 2; else q = 3;"));
 128.215 -        contained.put("{ $p$; $T $v; if($a) $v = $b; else $v = $c; $q$; }", Arrays.asList("{ int q; if (b) q = 2; else q = 3; }"));
 128.216 -
 128.217 -        performTest("package test; public class Test { public void test1(boolean b) { int q; if (b) q = 2; else q = 3; } }",
 128.218 -                    contained,
 128.219 -                    Collections.<String>emptyList());
 128.220 -    }
 128.221 -
 128.222 -    public void testEffectiveNewClass() throws Exception {
 128.223 -        performTest("package test; import javax.swing.ImageIcon; public class Test { public void test1(java.awt.Image i) { new ImageIcon(i); new String(i); } }",
 128.224 -                    Collections.singletonMap("new javax.swing.ImageIcon($1)", Arrays.asList("new ImageIcon(i)")),
 128.225 -                    Collections.<String>emptyList());
 128.226 -    }
 128.227 -
 128.228 -    public void testSynchronizedAndMultiStatementVariables() throws Exception {
 128.229 -        performTest("package test; public class Test {public void test() { Object o = null; int i = 0; synchronized (o) {} } }",
 128.230 -                    Collections.singletonMap("synchronized($var) {$stmts$;}", Arrays.asList("synchronized (o) {}")),
 128.231 -                    Collections.<String>emptyList());
 128.232 -    }
 128.233 -
 128.234 -    public void testJackpot30_2() throws Exception {
 128.235 -        String code = "package test;\n" +
 128.236 -                      "public class Test {\n" +
 128.237 -                      "    private void m() {\n" +
 128.238 -                      "        a(c.i().getFileObject());\n" +
 128.239 -                      "        if (span != null && span[0] != (-1) && span[1] != (-1));\n" +
 128.240 -                      "    }\n" +
 128.241 -                      "}\n";
 128.242 -
 128.243 -        performTest(code,
 128.244 -                    Collections.<String, List<String>>emptyMap(),
 128.245 -                    Arrays.asList("$0.getFileObject($1)"));
 128.246 -    }
 128.247 -
 128.248 -    public void testIdentifierInPureMemberSelect() throws Exception {
 128.249 -        String code = "package test;\n" +
 128.250 -                       "public class Test {\n" +
 128.251 -                       "     public Test test;\n" +
 128.252 -                       "     public String name;\n" +
 128.253 -                       "     private void test() {\n" +
 128.254 -                       "         Test t = null;\n" +
 128.255 -                       "         String s = t.test.name;\n" +
 128.256 -                       "     }\n" +
 128.257 -                       "}\n";
 128.258 -
 128.259 -        performTest(code,
 128.260 -                    Collections.singletonMap("$Test.test", Arrays.asList("test", "t.test")),
 128.261 -                    Collections.<String>emptyList());
 128.262 -    }
 128.263 -
 128.264 -    @RandomlyFails
 128.265 -    public void testNoExponentialTimeComplexity() throws Exception {
 128.266 -        try {
 128.267 -        String code = "package test;\n" +
 128.268 -                      "public class Test {\n" +
 128.269 -                      "    private void test() {\n" +
 128.270 -                      "        Object o;\n" +
 128.271 -                      "        if(o == null) {\n" +
 128.272 -                      "            f(\"\");\n" +
 128.273 -                      "        }|\n" +
 128.274 -                      "    }\n" +
 128.275 -                      "}";
 128.276 -        String pattern = "{ $p$; $T $v; if($a) $v = $b; else $v = $c; }";
 128.277 -
 128.278 -        measure(code, "\na(\"\");", 5, pattern); //to load needed classes, etc.
 128.279 -
 128.280 -        int rep = 1;
 128.281 -        long baseline;
 128.282 -
 128.283 -        while (true) {
 128.284 -            baseline = measure(code, "\na(\"\");", rep, pattern);
 128.285 -
 128.286 -            if (baseline >= 2000) {
 128.287 -                break;
 128.288 -            }
 128.289 -
 128.290 -            rep *= 2;
 128.291 -        }
 128.292 -
 128.293 -        long doubleSize = measure(code, "\na(\"\");", 2 * rep, pattern);
 128.294 -
 128.295 -        assertTrue("baseline=" + baseline + ", actual=" + String.valueOf(doubleSize), doubleSize <= 4 * baseline);
 128.296 -        } catch (OutOfMemoryError oome) {
 128.297 -            //OK
 128.298 -        }
 128.299 -    }
 128.300 -
 128.301 -    public void testMultiParameter1() throws Exception {
 128.302 -        performTest("package test; public class Test { { java.util.Arrays.asList(\"a\", \"b\", \"c\"); } }",
 128.303 -                    Collections.singletonMap("java.util.Arrays.asList($params$)", Arrays.asList("java.util.Arrays.asList(\"a\", \"b\", \"c\")")),
 128.304 -                    Collections.<String>emptyList());
 128.305 -    }
 128.306 -
 128.307 -    public void testMultiParameter2() throws Exception {
 128.308 -        performTest("package test; public class Test { { java.util.Arrays.asList(); } }",
 128.309 -                    Collections.singletonMap("java.util.Arrays.asList($params$)", Arrays.asList("java.util.Arrays.asList()")),
 128.310 -                    Collections.<String>emptyList());
 128.311 -    }
 128.312 -
 128.313 -    public void testTypeParameter() throws Exception {
 128.314 -        performTest("package test; public class Test { { java.util.Arrays.<String>asList(); } }",
 128.315 -                    Collections.singletonMap("java.util.Arrays.<$1>asList($params$)", Arrays.asList("java.util.Arrays.<String>asList()")),
 128.316 -                    Collections.<String>emptyList());
 128.317 -    }
 128.318 -
 128.319 -    public void testField1() throws Exception {
 128.320 -        String code = "package test;\n" +
 128.321 -                       "public class Test {\n" +
 128.322 -                       "     String name = null;\n" +
 128.323 -                       "}\n";
 128.324 -
 128.325 -        performTest(code,
 128.326 -                    Collections.singletonMap("$modifiers$ java.lang.String $name = $initializer;", Arrays.asList("String name = null;")),
 128.327 -                    Collections.<String>emptyList());
 128.328 -    }
 128.329 -
 128.330 -    public void testField2() throws Exception {
 128.331 -        String code = "package test;\n" +
 128.332 -                       "public class Test {\n" +
 128.333 -                       "     private String name = null;\n" +
 128.334 -                       "}\n";
 128.335 -
 128.336 -        performTest(code,
 128.337 -                    Collections.singletonMap("$modifiers$ java.lang.String $name = $initializer;", Arrays.asList("private String name = null;")),
 128.338 -                    Collections.<String>emptyList());
 128.339 -    }
 128.340 -
 128.341 -    public void testMemberSelectWithVariable() throws Exception {
 128.342 -        String code = "package test;\n" +
 128.343 -                      "import java.util.Arrays;\n" +
 128.344 -                      "public class Test {" +
 128.345 -                      "     {\n" +
 128.346 -                      "          foo.bar(0, 3, 4);\n" +
 128.347 -                      "     }\n" +
 128.348 -                      "}\n";
 128.349 -
 128.350 -        performTest(code,
 128.351 -                    Collections.singletonMap("$foo.$bar($p1, $p2$)", Arrays.asList("foo.bar(0, 3, 4)")),
 128.352 -                    Collections.<String>emptyList());
 128.353 -    }
 128.354 -
 128.355 -    public void testCheckIdentifiers1() throws Exception {
 128.356 -        String code = "package test;\n" +
 128.357 -                      "import static java.util.Arrays.*;\n" +
 128.358 -                      "public class Test {" +
 128.359 -                      "     {\n" +
 128.360 -                      "          toString(new int[] {0, 3, 4});\n" +
 128.361 -                      "     }\n" +
 128.362 -                      "}\n";
 128.363 -
 128.364 -        performTest(code,
 128.365 -                    Collections.singletonMap("java.util.Arrays.toString($x)", Arrays.asList("toString(new int[] {0, 3, 4})")),
 128.366 -                    Collections.<String>emptyList());
 128.367 -    }
 128.368 -
 128.369 -    public void testCheckIdentifiers2() throws Exception {
 128.370 -        String code = "package test;\n" +
 128.371 -                      "public class Test {" +
 128.372 -                      "     {\n" +
 128.373 -                      "          toString(new int[] {0, 3, 4});\n" +
 128.374 -                      "     }\n" +
 128.375 -                      "}\n";
 128.376 -
 128.377 -        performTest(code,
 128.378 -                    Collections.<String, List<String>>emptyMap(),
 128.379 -                    Collections.singletonList("java.util.Arrays.toString($x)"));
 128.380 -    }
 128.381 -
 128.382 -    public void testCheckIdentifiers3() throws Exception {
 128.383 -        String code = "package test;\n" +
 128.384 -                      "import static java.util.Arrays.*;\n" +
 128.385 -                      "public class Test {" +
 128.386 -                      "     {\n" +
 128.387 -                      "          Foo.toString(new int[] {0, 3, 4});\n" +
 128.388 -                      "     }\n" +
 128.389 -                      "}\n";
 128.390 -
 128.391 -        performTest(code,
 128.392 -                    Collections.<String, List<String>>emptyMap(),
 128.393 -                    Collections.singletonList("java.util.Arrays.toString($x)"));
 128.394 -    }
 128.395 -
 128.396 -    public void testCheckIdentifiers4() throws Exception {
 128.397 -        String code = "package test;\n" +
 128.398 -                      "public class Test {" +
 128.399 -                      "     {\n" +
 128.400 -                      "          java.util.Arrays.toString(new int[] {0, 3, 4});\n" +
 128.401 -                      "     }\n" +
 128.402 -                      "}\n";
 128.403 -
 128.404 -        performTest(code,
 128.405 -                    Collections.singletonMap("Arrays", Arrays.asList("java.util.Arrays")), //could be imported in the input pattern
 128.406 -                    Collections.<String>emptyList());
 128.407 -    }
 128.408 -
 128.409 -    public void testLambdaInput() throws Exception {
 128.410 -        String code = "package test; public class Test {public void test() { new java.io.FilenameFilter() { public boolean accept(java.io.File dir, String name) { return true; } }; } }";
 128.411 -
 128.412 -        performTest(code,
 128.413 -                    Collections.singletonMap("new $type() {public $retType $name($params$) { $body$; } }", Arrays.asList("new java.io.FilenameFilter() { public boolean accept(java.io.File dir, String name) { return true; } }")),
 128.414 -
 128.415 -                    Collections.<String>emptyList());
 128.416 -    }
 128.417 -
 128.418 -    public void testDoubleCheckedLockingWithVariable() throws Exception {
 128.419 -        String dcl =  "if (o == null) {\n" +
 128.420 -                      "              Object o1 = new Object();\n" +
 128.421 -                      "              synchronized (Test.class) {\n" +
 128.422 -                      "                  if (o == null) {\n" +
 128.423 -                      "                      o = o1;\n" +
 128.424 -                      "                  }\n" +
 128.425 -                      "              }\n" +
 128.426 -                      "          }";
 128.427 -        String code = "package test;\n" +
 128.428 -                      "public class Test {\n" +
 128.429 -                      "     private Object o;\n" +
 128.430 -                      "     private void t() {\n" +
 128.431 -                      "          " + dcl + "\n" +
 128.432 -                      "     }\n" +
 128.433 -                      "}\n";
 128.434 -
 128.435 -        performTest(code,
 128.436 -                    Collections.singletonMap("if ($var == null) {$pref$; synchronized ($lock) { if ($var == null) { $init$; } } }", Arrays.asList(dcl)),
 128.437 -                    Collections.<String>emptyList());
 128.438 -    }
 128.439 -
 128.440 -    public void testMethodName1() throws Exception {
 128.441 -        String code = "package test; public class Test {public void test() { clone(); } }";
 128.442 -
 128.443 -        performTest(code,
 128.444 -                    Collections.<String, List<String>>emptyMap(),
 128.445 -                    Collections.<String>singletonList("public void clone() {$stmts$;}"));
 128.446 -    }
 128.447 -
 128.448 -    public void testMethodName2() throws Exception {
 128.449 -        String code = "package test; public class Test {public void test() { clone(); } }";
 128.450 -
 128.451 -        performTest(code,
 128.452 -                    Collections.singletonMap("public void test() {$stmts$;}", Arrays.asList("public void test() { clone(); }")),
 128.453 -                    Collections.<String>emptyList());
 128.454 -    }
 128.455 -    
 128.456 -    public void testBooleanLiterals() throws Exception {
 128.457 -        String code = "package test; public class Test { public void test() { if (false) { System.err.println(\"false\"); } if (true) { System.err.println(\"true\"); } } }";
 128.458 -
 128.459 -        performTest(code,
 128.460 -                    Collections.singletonMap("if (true) $then; else $else$;", Arrays.asList("if (true) { System.err.println(\"true\"); }")),
 128.461 -                    Collections.<String>emptyList());
 128.462 -    }
 128.463 -    
 128.464 -    public void testEfficientMultiMatching() throws Exception {
 128.465 -        String code = "package test; public class Test { private void m() {} }";
 128.466 -
 128.467 -        performTest(code,
 128.468 -                    Collections.<String, List<String>>emptyMap(),
 128.469 -                    Collections.singletonList("$mods$ class $name implements $i$ { }"));
 128.470 -    }
 128.471 -
 128.472 -    private long measure(String baseCode, String toInsert, int repetitions, String pattern) throws Exception {
 128.473 -        int pos = baseCode.indexOf('|');
 128.474 -
 128.475 -        assertTrue(pos != (-1));
 128.476 -
 128.477 -        baseCode = baseCode.replaceAll(Pattern.quote("|"), "");
 128.478 -        
 128.479 -        StringBuilder code = new StringBuilder(baseCode.length() + repetitions * toInsert.length());
 128.480 -
 128.481 -        code.append(baseCode);
 128.482 -        
 128.483 -        while (repetitions-- > 0) {
 128.484 -            code.insert(pos, toInsert);
 128.485 -        }
 128.486 -
 128.487 -        long startTime = System.currentTimeMillis();
 128.488 -
 128.489 -        performTest(code.toString(),
 128.490 -                    Collections.<String, List<String>>emptyMap(),
 128.491 -                    Arrays.asList(pattern));
 128.492 -
 128.493 -        long endTime = System.currentTimeMillis();
 128.494 -
 128.495 -        return endTime - startTime;
 128.496 -    }
 128.497 -
 128.498 -    public void XtestMeasureTime() throws Exception {
 128.499 -        String code = TestUtilities.copyFileToString(new File("/usr/local/home/lahvac/src/nb//outgoing/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionProvider.java"));
 128.500 -        List<String> patterns = new LinkedList<String>();
 128.501 -
 128.502 -        for (int cntr = 0; cntr < 1000; cntr++) {
 128.503 -            patterns.add("System.err.println($1)");
 128.504 -        }
 128.505 -
 128.506 -        performTest(code,
 128.507 -                    Collections.<String, List<String>>emptyMap(),
 128.508 -                    patterns);
 128.509 -    }
 128.510 -
 128.511 -    public void testMatches1() throws Exception {
 128.512 -        performMatchesTest("package test; public class Test { private void test() { f.isDirectory(); } }", Arrays.asList("$1.isDirectory()", "new ImageIcon($1)"), true);
 128.513 -    }
 128.514 -
 128.515 -    public void testSerialization() throws Exception {
 128.516 -        String text = "package test; public class Test { public void test1(boolean b) { int q; if (b) q = 2; else q = 3; } }";
 128.517 -
 128.518 -        prepareTest("test/Test.java", text);
 128.519 -
 128.520 -        ByteArrayOutputStream out = new ByteArrayOutputStream();
 128.521 -        EncodingContext ec = new EncodingContext(out, false);
 128.522 -
 128.523 -        createSearch().encode(info.getCompilationUnit(), ec, new AtomicBoolean());
 128.524 -        
 128.525 -        boolean matches = createSearch().matches(new ByteArrayInputStream(out.toByteArray()), new AtomicBoolean(), createSearch().create(info, new AtomicBoolean(), "{ $p$; $T $v; if($a) $v = $b; else $v = $c; $q$; }"));
 128.526 -
 128.527 -        assertTrue(matches);
 128.528 -    }
 128.529 -
 128.530 -    public void testFrequencies() throws Exception {
 128.531 -        String text = "package test; public class Test { public void test1(boolean b) { java.io.File f = null; f.isDirectory(); f.isDirectory(); new javax.swing.ImageIcon(null); } }";
 128.532 -
 128.533 -        prepareTest("test/Test.java", text);
 128.534 -
 128.535 -        ByteArrayOutputStream out = new ByteArrayOutputStream();
 128.536 -        EncodingContext ec = new EncodingContext(out, false);
 128.537 -
 128.538 -        createSearch().encode(info.getCompilationUnit(), ec, new AtomicBoolean());
 128.539 -        
 128.540 -        Map<String, Integer> actual = createSearch().matchesWithFrequencies(new ByteArrayInputStream(out.toByteArray()), createSearch().create(info, new AtomicBoolean(), "$1.isDirectory()", "new ImageIcon($1)"), new AtomicBoolean());
 128.541 -        Map<String, Integer> golden = new HashMap<String, Integer>();
 128.542 -
 128.543 -        golden.put("$1.isDirectory()", 2);
 128.544 -        golden.put("new ImageIcon($1)", 1);
 128.545 -
 128.546 -        assertEquals(golden, actual);
 128.547 -    }
 128.548 -
 128.549 -    public void testPatternEncodingAndIdentifiers() throws Exception {
 128.550 -        String text = "package test; public class Test { }";
 128.551 -
 128.552 -        prepareTest("test/Test.java", text);
 128.553 -
 128.554 -        BulkPattern bp = createSearch().create(info, new AtomicBoolean(), "$0.isDirectory()");
 128.555 -
 128.556 -        assertEquals(Arrays.asList(new HashSet<String>(Arrays.asList("isDirectory"))), bp.getIdentifiers());
 128.557 -        //TODO: the actual code for kinds differs for NFABased search and REBased search:
 128.558 -//        assertEquals(Arrays.asList(new HashSet<String>(Arrays.asList(Kind.METHOD_INVOCATION.name()))), bp.getKinds());
 128.559 -    }
 128.560 -    
 128.561 -    public void testModifiersMultiVariable() throws Exception {
 128.562 -        String code = "package test;\n" +
 128.563 -                       "public class Test {\n" +
 128.564 -                       "     @Deprecated @Override public Test test;\n" +
 128.565 -                       "}\n";
 128.566 -
 128.567 -        performTest(code,
 128.568 -                    Collections.singletonMap("$mods$ @Deprecated public $type $name = $init$;", Arrays.asList("@Deprecated @Override public Test test;")),
 128.569 -                    Collections.<String>emptyList());
 128.570 -    }
 128.571 -
 128.572 -    protected abstract BulkSearch createSearch();
 128.573 -    
 128.574 -    private void performMatchesTest(String text, List<String> patterns, boolean golden) throws Exception {
 128.575 -        prepareTest("test/Test.java", text);
 128.576 -
 128.577 -        BulkPattern p = createSearch().create(info, new AtomicBoolean(), patterns);
 128.578 -
 128.579 -        boolean result = createSearch().matches(info, new AtomicBoolean(), new TreePath(info.getCompilationUnit()), p);
 128.580 -
 128.581 -        assertEquals(golden, result);
 128.582 -    }
 128.583 -    
 128.584 -    private void performTest(String text, Map<String, List<String>> containedPatterns, Collection<String> notContainedPatterns) throws Exception {
 128.585 -        prepareTest("test/Test.java", text);
 128.586 -
 128.587 -        List<String> patterns = new LinkedList<String>();
 128.588 -
 128.589 -        patterns.addAll(containedPatterns.keySet());
 128.590 -        patterns.addAll(notContainedPatterns);
 128.591 -
 128.592 -        long s1 = System.currentTimeMillis();
 128.593 -        BulkPattern p = createSearch().create(info, new AtomicBoolean(), patterns);
 128.594 -        long e1 = System.currentTimeMillis();
 128.595 -
 128.596 -//        System.err.println("create: " + (e1 - s1));
 128.597 -
 128.598 -        long s2 = System.currentTimeMillis();
 128.599 -        Map<String, Collection<TreePath>> result = createSearch().match(info, new AtomicBoolean(), new TreePath(info.getCompilationUnit()), p);
 128.600 -        long e2 = System.currentTimeMillis();
 128.601 -
 128.602 -//        System.err.println("match: " + (e2 - s2));
 128.603 -
 128.604 -        assertTrue(result.toString(), result.keySet().containsAll(containedPatterns.keySet()));
 128.605 -
 128.606 -        for (Entry<String, Collection<TreePath>> e : result.entrySet()) {
 128.607 -            List<String> actual = new LinkedList<String>();
 128.608 -
 128.609 -            for (TreePath tp : e.getValue()) {
 128.610 -                assertNotNull(TreePathHandle.create(tp, info).resolve(info));
 128.611 -                
 128.612 -                int start = (int) info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), tp.getLeaf());
 128.613 -                int end   = (int) info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), tp.getLeaf());
 128.614 -
 128.615 -                actual.add(info.getText().substring(start, end));
 128.616 -            }
 128.617 -
 128.618 -            assertEquals(e.getKey(), containedPatterns.get(e.getKey()), actual);
 128.619 -        }
 128.620 -
 128.621 -
 128.622 -        Set<String> none = new HashSet<String>(result.keySet());
 128.623 -
 128.624 -        none.retainAll(notContainedPatterns);
 128.625 -
 128.626 -        assertTrue(none.isEmpty());
 128.627 -
 128.628 -        if (!verifyIndexingData())
 128.629 -            return ;
 128.630 -        
 128.631 -        //ensure the returned identifiers/treeKinds are correct:
 128.632 -        ByteArrayOutputStream data = new ByteArrayOutputStream();
 128.633 -        EncodingContext ec = new EncodingContext(data, false);
 128.634 -        
 128.635 -        createSearch().encode(info.getCompilationUnit(), ec, new AtomicBoolean());
 128.636 -
 128.637 -        for (int i = 0; i < containedPatterns.size(); i++) {
 128.638 -            assertTrue("expected: " + p.getIdentifiers().get(i) + ", but exist only: " + ec.getIdentifiers(), ec.getIdentifiers().containsAll(p.getIdentifiers().get(i)));
 128.639 -            
 128.640 -            for (List<String> phrase : p.getRequiredContent().get(i)) {
 128.641 -                assertTrue("expected: " + phrase + ", but exist only: " + ec.getContent() + "(all phrases: " + p.getRequiredContent().get(i) + ")", Collections.indexOfSubList(ec.getContent(), phrase) != (-1));
 128.642 -            }
 128.643 -        }
 128.644 -
 128.645 -        data.close();
 128.646 -        assertEquals(!containedPatterns.isEmpty(), createSearch().matches(new ByteArrayInputStream(data.toByteArray()), new AtomicBoolean(), p));
 128.647 -    }
 128.648 -    
 128.649 -    private void prepareTest(String fileName, String code) throws Exception {
 128.650 -        clearWorkDir();
 128.651 -
 128.652 -        FileUtil.refreshFor(File.listRoots());
 128.653 -
 128.654 -        FileObject workFO = FileUtil.toFileObject(getWorkDir());
 128.655 -
 128.656 -        assertNotNull(workFO);
 128.657 -
 128.658 -        workFO.refresh();
 128.659 -
 128.660 -        sourceRoot = workFO.createFolder("src");
 128.661 -        FileObject buildRoot  = workFO.createFolder("build");
 128.662 -        FileObject cache = workFO.createFolder("cache");
 128.663 -
 128.664 -        FileObject data = FileUtil.createData(sourceRoot, fileName);
 128.665 -        File dataFile = FileUtil.toFile(data);
 128.666 -
 128.667 -        assertNotNull(dataFile);
 128.668 -
 128.669 -        TestUtilities.copyStringToFile(dataFile, code);
 128.670 -
 128.671 -        SourceUtilsTestUtil.prepareTest(sourceRoot, buildRoot, cache);
 128.672 -
 128.673 -        DataObject od = DataObject.find(data);
 128.674 -        EditorCookie ec = od.getLookup().lookup(EditorCookie.class);
 128.675 -
 128.676 -        assertNotNull(ec);
 128.677 -
 128.678 -        doc = ec.openDocument();
 128.679 -        doc.putProperty(Language.class, JavaTokenId.language());
 128.680 -
 128.681 -        JavaSource js = JavaSource.forFileObject(data);
 128.682 -
 128.683 -        assertNotNull(js);
 128.684 -
 128.685 -        info = SourceUtilsTestUtil.getCompilationInfo(js, Phase.RESOLVED);
 128.686 -
 128.687 -        assertNotNull(info);
 128.688 -    }
 128.689 -
 128.690 -    private FileObject sourceRoot;
 128.691 -    private CompilationInfo info;
 128.692 -    private Document doc;
 128.693 -
 128.694 -    protected boolean verifyIndexingData() {
 128.695 -        return true;
 128.696 -    }
 128.697 -}
   129.1 --- a/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/pm/CopyFinderBasedBulkSearchTest.java	Sun Oct 16 08:01:27 2016 +0200
   129.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   129.3 @@ -1,99 +0,0 @@
   129.4 -/*
   129.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   129.6 - *
   129.7 - * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
   129.8 - *
   129.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  129.10 - * Other names may be trademarks of their respective owners.
  129.11 - *
  129.12 - * The contents of this file are subject to the terms of either the GNU
  129.13 - * General Public License Version 2 only ("GPL") or the Common
  129.14 - * Development and Distribution License("CDDL") (collectively, the
  129.15 - * "License"). You may not use this file except in compliance with the
  129.16 - * License. You can obtain a copy of the License at
  129.17 - * http://www.netbeans.org/cddl-gplv2.html
  129.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  129.19 - * specific language governing permissions and limitations under the
  129.20 - * License.  When distributing the software, include this License Header
  129.21 - * Notice in each file and include the License file at
  129.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  129.23 - * particular file as subject to the "Classpath" exception as provided
  129.24 - * by Oracle in the GPL Version 2 section of the License file that
  129.25 - * accompanied this code. If applicable, add the following below the
  129.26 - * License Header, with the fields enclosed by brackets [] replaced by
  129.27 - * your own identifying information:
  129.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  129.29 - *
  129.30 - * If you wish your version of this file to be governed by only the CDDL
  129.31 - * or only the GPL Version 2, indicate your decision by adding
  129.32 - * "[Contributor] elects to include this software in this distribution
  129.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  129.34 - * single choice of license, a recipient has the option to distribute
  129.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  129.36 - * to extend the choice of license to its licensees as provided above.
  129.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  129.38 - * Version 2 license, then the option applies only if the new code is
  129.39 - * made subject to such option by the copyright holder.
  129.40 - *
  129.41 - * Contributor(s):
  129.42 - *
  129.43 - * Portions Copyrighted 2009 Sun Microsystems, Inc.
  129.44 - */
  129.45 -
  129.46 -package org.netbeans.modules.java.hints.spiimpl.pm;
  129.47 -
  129.48 -/**
  129.49 - *
  129.50 - * @author lahvac
  129.51 - */
  129.52 -public class CopyFinderBasedBulkSearchTest extends BulkSearchTestPerformer {
  129.53 -
  129.54 -    public CopyFinderBasedBulkSearchTest(String name) {
  129.55 -        super(name);
  129.56 -    }
  129.57 -
  129.58 -    @Override
  129.59 -    protected BulkSearch createSearch() {
  129.60 -        return new CopyFinderBasedBulkSearch();
  129.61 -    }
  129.62 -
  129.63 -    @Override
  129.64 -    protected boolean verifyIndexingData() {
  129.65 -        return false;
  129.66 -    }
  129.67 -
  129.68 -    @Override
  129.69 -    public void testSerialization() throws Exception {
  129.70 -        //XXX
  129.71 -    }
  129.72 -
  129.73 -    @Override
  129.74 -    public void testFrequencies() throws Exception {
  129.75 -        //XXX: serialization is a prerequisite
  129.76 -    }
  129.77 -
  129.78 -    @Override
  129.79 -    public void testPatternEncodingAndIdentifiers() throws Exception {
  129.80 -        //XXX
  129.81 -    }
  129.82 -
  129.83 -    @Override
  129.84 -    public void testNoExponentialTimeComplexity() throws Exception {
  129.85 -        //XXX
  129.86 -    }
  129.87 -
  129.88 -    @Override
  129.89 -    public void testCheckIdentifiers2() throws Exception {
  129.90 -        //not critical, only improves performance on vast amounts of sources,
  129.91 -        //and NFA based search is used in such case anyway.
  129.92 -        //XXX
  129.93 -    }
  129.94 -
  129.95 -    @Override
  129.96 -    public void testCheckIdentifiers3() throws Exception {
  129.97 -        //not critical, only improves performance on vast amounts of sources,
  129.98 -        //and NFA based search is used in such case anyway.
  129.99 -        //XXX
 129.100 -    }
 129.101 -
 129.102 -}
 129.103 \ No newline at end of file
   130.1 --- a/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/pm/NFABasedBulkSearchTest.java	Sun Oct 16 08:01:27 2016 +0200
   130.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   130.3 @@ -1,69 +0,0 @@
   130.4 -/*
   130.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   130.6 - *
   130.7 - * Copyright 2009-2010 Oracle and/or its affiliates. All rights reserved.
   130.8 - *
   130.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  130.10 - * Other names may be trademarks of their respective owners.
  130.11 - *
  130.12 - * The contents of this file are subject to the terms of either the GNU
  130.13 - * General Public License Version 2 only ("GPL") or the Common
  130.14 - * Development and Distribution License("CDDL") (collectively, the
  130.15 - * "License"). You may not use this file except in compliance with the
  130.16 - * License. You can obtain a copy of the License at
  130.17 - * http://www.netbeans.org/cddl-gplv2.html
  130.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  130.19 - * specific language governing permissions and limitations under the
  130.20 - * License.  When distributing the software, include this License Header
  130.21 - * Notice in each file and include the License file at
  130.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  130.23 - * particular file as subject to the "Classpath" exception as provided
  130.24 - * by Oracle in the GPL Version 2 section of the License file that
  130.25 - * accompanied this code. If applicable, add the following below the
  130.26 - * License Header, with the fields enclosed by brackets [] replaced by
  130.27 - * your own identifying information:
  130.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  130.29 - *
  130.30 - * If you wish your version of this file to be governed by only the CDDL
  130.31 - * or only the GPL Version 2, indicate your decision by adding
  130.32 - * "[Contributor] elects to include this software in this distribution
  130.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  130.34 - * single choice of license, a recipient has the option to distribute
  130.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  130.36 - * to extend the choice of license to its licensees as provided above.
  130.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  130.38 - * Version 2 license, then the option applies only if the new code is
  130.39 - * made subject to such option by the copyright holder.
  130.40 - *
  130.41 - * Contributor(s):
  130.42 - *
  130.43 - * Portions Copyrighted 2009-2010 Sun Microsystems, Inc.
  130.44 - */
  130.45 -
  130.46 -package org.netbeans.modules.java.hints.spiimpl.pm;
  130.47 -
  130.48 -/**
  130.49 - *
  130.50 - * @author lahvac
  130.51 - */
  130.52 -public class NFABasedBulkSearchTest extends BulkSearchTestPerformer {
  130.53 -
  130.54 -    public NFABasedBulkSearchTest(String name) {
  130.55 -        super(name);
  130.56 -    }
  130.57 -
  130.58 -//    public static TestSuite suite() {
  130.59 -//        NbTestSuite r = new NbTestSuite();
  130.60 -//
  130.61 -//        r.addTest(new NFABasedBulkSearchTest("testField1"));
  130.62 -//        r.addTest(new NFABasedBulkSearchTest("testField2"));
  130.63 -//
  130.64 -//        return r;
  130.65 -//    }
  130.66 -
  130.67 -    @Override
  130.68 -    protected BulkSearch createSearch() {
  130.69 -        return new NFABasedBulkSearch();
  130.70 -    }
  130.71 -
  130.72 -}
   131.1 --- a/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/pm/PatternCompilerTest.java	Sun Oct 16 08:01:27 2016 +0200
   131.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   131.3 @@ -1,203 +0,0 @@
   131.4 -/*
   131.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   131.6 - *
   131.7 - * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
   131.8 - *
   131.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  131.10 - * Other names may be trademarks of their respective owners.
  131.11 - *
  131.12 - * The contents of this file are subject to the terms of either the GNU
  131.13 - * General Public License Version 2 only ("GPL") or the Common
  131.14 - * Development and Distribution License("CDDL") (collectively, the
  131.15 - * "License"). You may not use this file except in compliance with the
  131.16 - * License. You can obtain a copy of the License at
  131.17 - * http://www.netbeans.org/cddl-gplv2.html
  131.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  131.19 - * specific language governing permissions and limitations under the
  131.20 - * License.  When distributing the software, include this License Header
  131.21 - * Notice in each file and include the License file at
  131.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  131.23 - * particular file as subject to the "Classpath" exception as provided
  131.24 - * by Oracle in the GPL Version 2 section of the License file that
  131.25 - * accompanied this code. If applicable, add the following below the
  131.26 - * License Header, with the fields enclosed by brackets [] replaced by
  131.27 - * your own identifying information:
  131.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  131.29 - *
  131.30 - * If you wish your version of this file to be governed by only the CDDL
  131.31 - * or only the GPL Version 2, indicate your decision by adding
  131.32 - * "[Contributor] elects to include this software in this distribution
  131.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  131.34 - * single choice of license, a recipient has the option to distribute
  131.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  131.36 - * to extend the choice of license to its licensees as provided above.
  131.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  131.38 - * Version 2 license, then the option applies only if the new code is
  131.39 - * made subject to such option by the copyright holder.
  131.40 - *
  131.41 - * Contributor(s):
  131.42 - *
  131.43 - * Portions Copyrighted 2008-2009 Sun Microsystems, Inc.
  131.44 - */
  131.45 -
  131.46 -package org.netbeans.modules.java.hints.spiimpl.pm;
  131.47 -
  131.48 -import com.sun.source.tree.Tree;
  131.49 -import com.sun.source.util.SourcePositions;
  131.50 -import com.sun.source.util.TreePath;
  131.51 -import java.util.Arrays;
  131.52 -import java.util.HashMap;
  131.53 -import java.util.Iterator;
  131.54 -import java.util.Map;
  131.55 -import java.util.Map.Entry;
  131.56 -import java.util.concurrent.atomic.AtomicBoolean;
  131.57 -import org.netbeans.modules.java.hints.spiimpl.TestBase;
  131.58 -import org.netbeans.api.java.source.matching.Matcher;
  131.59 -import org.netbeans.api.java.source.matching.Occurrence;
  131.60 -import org.openide.util.Pair;
  131.61 -
  131.62 -/**
  131.63 - *
  131.64 - * @author Jan Lahoda
  131.65 - */
  131.66 -public class PatternCompilerTest extends TestBase {
  131.67 -
  131.68 -    public PatternCompilerTest(String name) {
  131.69 -        super(name);
  131.70 -    }
  131.71 -
  131.72 -    public void testSimple1() throws Exception {
  131.73 -        performVariablesTest("package test; public class Test {public void test() {int i = |1 + 2|;}}", "$1+$2",
  131.74 -                             Pair.<String, String>of("$1", "1"),
  131.75 -                             Pair.<String, String>of("$2", "2"));
  131.76 -    }
  131.77 -
  131.78 -    public void testTyped1() throws Exception {
  131.79 -        performVariablesTest("package test; public class Test {public void test() {|String.valueOf(\"t\")|;}}", "String.valueOf($1{String})",
  131.80 -                             Pair.<String, String>of("$1", "\"t\""));
  131.81 -    }
  131.82 -
  131.83 -//    public void testTyped2() throws Exception {
  131.84 -//        performVariablesTest("package test; public class Test {public void test() {|String.valueOf(\"t\")|;}}", "$2{java.lang.String}.valueOf($1{String})",
  131.85 -//                             new Pair<String, String>("$1", "\"t\""),
  131.86 -//                             new Pair<String, String>("$2", "String"));
  131.87 -//    }
  131.88 -
  131.89 -    public void testTyped3() throws Exception {
  131.90 -        performVariablesTest("package test; public class Test {public void test(String str) {|str.valueOf(\"t\")|;}}", "String.valueOf($1{String})",
  131.91 -                             Pair.<String, String>of("$1", "\"t\""));
  131.92 -    }
  131.93 -
  131.94 -    public void testTyped4() throws Exception {
  131.95 -        performVariablesTest("package test; public class Test {public void test() {|Integer.bitCount(1)|;}}", "$2{java.lang.String}.valueOf($1{String})",
  131.96 -                             (Pair[]) null);
  131.97 -    }
  131.98 -
  131.99 -    public void testTyped5() throws Exception {
 131.100 -        performVariablesTest("package test; public class Test {public void test() {java.io.File f = null; |f.toURI().toURL()|;}}", "$1{java.io.File}.toURL()",
 131.101 -                             (Pair[]) null);
 131.102 -    }
 131.103 -
 131.104 -    public void testTypedPrimitiveType() throws Exception {
 131.105 -        performVariablesTest("package test; public class Test {public void test(int i) {|test(1)|;}}", "$0{test.Test}.test($1{int})",
 131.106 -                             Pair.<String, String>of("$1", "1"));
 131.107 -    }
 131.108 -
 131.109 -    public void testMemberSelectVSIdentifier() throws Exception {
 131.110 -        performVariablesTest("package test; public class Test {void test1() {} void test2() {|test1()|;}}", "$1{test.Test}.test1()",
 131.111 -                             new Pair[0]);
 131.112 -    }
 131.113 -
 131.114 -    public void testSubClass() throws Exception {
 131.115 -        performVariablesTest("package test; public class Test {void test() {String s = null; |s.toString()|;}}", "$1{java.lang.CharSequence}.toString()",
 131.116 -                             Pair.<String, String>of("$1", "s"));
 131.117 -    }
 131.118 -
 131.119 -    public void testEquality1() throws Exception {
 131.120 -        performVariablesTest("package test; public class Test {void test() {|test()|;}}", "$1{test.Test}.test()",
 131.121 -                             new Pair[0]);
 131.122 -    }
 131.123 -
 131.124 -    public void testEquality2() throws Exception {
 131.125 -        performVariablesTest("package test; public class Test {void test() {String s = null; |String.valueOf(1).charAt(0)|;}}", "$1{java.lang.String}.charAt(0)",
 131.126 -                             Pair.<String, String>of("$1", "String.valueOf(1)"));
 131.127 -    }
 131.128 -
 131.129 -    public void testEquality3() throws Exception {
 131.130 -        performVariablesTest("package test; public class Test {void test() {String s = null; |s.charAt(0)|;}}", "java.lang.String.valueOf(1).charAt(0)",
 131.131 -                             (Pair[]) null);
 131.132 -    }
 131.133 -
 131.134 -    public void testType1() throws Exception {
 131.135 -        performVariablesTest("package test; public class Test {void test() {|String| s;}}", "java.lang.String",
 131.136 -                             new Pair[0]);
 131.137 -    }
 131.138 -
 131.139 -    public void testStatements1() throws Exception {
 131.140 -        performVariablesTest("package test; public class Test {void test() {|assert true : \"\";|}}", "assert $1{boolean} : $2{java.lang.Object};",
 131.141 -                             new Pair[0]);
 131.142 -    }
 131.143 -
 131.144 -    protected void performVariablesTest(String code, String pattern, Pair<String, String>... duplicates) throws Exception {
 131.145 -        String[] split = code.split("\\|");
 131.146 -
 131.147 -        assertEquals(Arrays.toString(split), 3, split.length);
 131.148 -
 131.149 -        int      start = split[0].length();
 131.150 -        int      end   = start + split[1].length();
 131.151 -
 131.152 -        code = split[0] + split[1] + split[2];
 131.153 -
 131.154 -        prepareTest("test/Test.java", code);
 131.155 -
 131.156 -        TreePath tp = info.getTreeUtilities().pathFor((start + end) / 2);
 131.157 -
 131.158 -        while (tp != null) {
 131.159 -            Tree t = tp.getLeaf();
 131.160 -            SourcePositions sp = info.getTrees().getSourcePositions();
 131.161 -
 131.162 -            if (   start == sp.getStartPosition(info.getCompilationUnit(), t)
 131.163 -                && end   == sp.getEndPosition(info.getCompilationUnit(), t)) {
 131.164 -                break;
 131.165 -            }
 131.166 -
 131.167 -            tp = tp.getParentPath();
 131.168 -        }
 131.169 -
 131.170 -        assertNotNull(tp);
 131.171 -
 131.172 -        //XXX:
 131.173 -        Iterator<? extends Occurrence> vars = Matcher.create(info).setCancel(new AtomicBoolean()).setSearchRoot(tp).setTreeTopSearch().match(PatternCompilerUtilities.compile(info, pattern)).iterator();
 131.174 -
 131.175 -        if (duplicates == null) {
 131.176 -            assertFalse(vars.hasNext());
 131.177 -            return ;
 131.178 -        }
 131.179 -
 131.180 -        assertNotNull(vars);
 131.181 -        assertTrue(vars.hasNext());
 131.182 -
 131.183 -        Map<String, String> actual = new HashMap<String, String>();
 131.184 -
 131.185 -        for (Entry<String, TreePath> e : vars.next().getVariables().entrySet()) {
 131.186 -            int[] span = new int[] {
 131.187 -                (int) info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), e.getValue().getLeaf()),
 131.188 -                (int) info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), e.getValue().getLeaf())
 131.189 -            };
 131.190 -
 131.191 -            actual.put(e.getKey(), info.getText().substring(span[0], span[1]));
 131.192 -        }
 131.193 -
 131.194 -        assertFalse(vars.hasNext());
 131.195 -
 131.196 -        for (Pair<String, String> dup : duplicates) {
 131.197 -            String span = actual.remove(dup.first());
 131.198 -
 131.199 -            if (span == null) {
 131.200 -                fail(dup.first());
 131.201 -            }
 131.202 -            assertEquals(dup.first()+ ":" + span, span, dup.second());
 131.203 -        }
 131.204 -    }
 131.205 -
 131.206 -}
   132.1 --- a/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/pm/PatternCompilerUtilities.java	Sun Oct 16 08:01:27 2016 +0200
   132.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   132.3 @@ -1,88 +0,0 @@
   132.4 -/*
   132.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   132.6 - *
   132.7 - * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
   132.8 - *
   132.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  132.10 - * Other names may be trademarks of their respective owners.
  132.11 - *
  132.12 - * The contents of this file are subject to the terms of either the GNU
  132.13 - * General Public License Version 2 only ("GPL") or the Common
  132.14 - * Development and Distribution License("CDDL") (collectively, the
  132.15 - * "License"). You may not use this file except in compliance with the
  132.16 - * License. You can obtain a copy of the License at
  132.17 - * http://www.netbeans.org/cddl-gplv2.html
  132.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  132.19 - * specific language governing permissions and limitations under the
  132.20 - * License.  When distributing the software, include this License Header
  132.21 - * Notice in each file and include the License file at
  132.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  132.23 - * particular file as subject to the "Classpath" exception as provided
  132.24 - * by Oracle in the GPL Version 2 section of the License file that
  132.25 - * accompanied this code. If applicable, add the following below the
  132.26 - * License Header, with the fields enclosed by brackets [] replaced by
  132.27 - * your own identifying information:
  132.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  132.29 - *
  132.30 - * If you wish your version of this file to be governed by only the CDDL
  132.31 - * or only the GPL Version 2, indicate your decision by adding
  132.32 - * "[Contributor] elects to include this software in this distribution
  132.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  132.34 - * single choice of license, a recipient has the option to distribute
  132.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  132.36 - * to extend the choice of license to its licensees as provided above.
  132.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  132.38 - * Version 2 license, then the option applies only if the new code is
  132.39 - * made subject to such option by the copyright holder.
  132.40 - *
  132.41 - * Contributor(s):
  132.42 - *
  132.43 - * Portions Copyrighted 2011 Sun Microsystems, Inc.
  132.44 - */
  132.45 -package org.netbeans.modules.java.hints.spiimpl.pm;
  132.46 -
  132.47 -import java.util.Collections;
  132.48 -import java.util.HashMap;
  132.49 -import java.util.Map;
  132.50 -import java.util.regex.Matcher;
  132.51 -import javax.lang.model.type.TypeMirror;
  132.52 -import org.netbeans.api.java.source.CompilationInfo;
  132.53 -import org.netbeans.modules.java.hints.spiimpl.pm.PatternCompiler;
  132.54 -import org.netbeans.api.java.source.matching.Pattern;
  132.55 -import org.netbeans.modules.java.hints.spiimpl.Hacks;
  132.56 -
  132.57 -/**
  132.58 - *
  132.59 - * @author lahvac
  132.60 - */
  132.61 -public class PatternCompilerUtilities {
  132.62 -
  132.63 -    public static Pattern compile(CompilationInfo info, String pattern) {
  132.64 -        Map<String, TypeMirror> constraints = new HashMap<String, TypeMirror>();
  132.65 -        pattern = parseOutTypesFromPattern(info, pattern, constraints);
  132.66 -
  132.67 -        return PatternCompiler.compile(info, pattern, constraints, Collections.<String>emptyList());
  132.68 -    }
  132.69 -
  132.70 -    public static String parseOutTypesFromPattern(CompilationInfo info, String pattern, Map<String, TypeMirror> variablesToTypes) {
  132.71 -        java.util.regex.Pattern p = java.util.regex.Pattern.compile("(\\$[0-9])(\\{([^}]*)\\})?");
  132.72 -        StringBuilder filtered = new StringBuilder();
  132.73 -        Matcher m = p.matcher(pattern);
  132.74 -        int i = 0;
  132.75 -
  132.76 -        while (m.find()) {
  132.77 -            filtered.append(pattern.substring(i, m.start()));
  132.78 -            i = m.end();
  132.79 -
  132.80 -            String var  = m.group(1);
  132.81 -            String type = m.group(3);
  132.82 -
  132.83 -            filtered.append(var);
  132.84 -            variablesToTypes.put(var, type != null ? Hacks.parseFQNType(info, type) : null);
  132.85 -        }
  132.86 -
  132.87 -        filtered.append(pattern.substring(i));
  132.88 -
  132.89 -        return filtered.toString();
  132.90 -    }
  132.91 -}
   133.1 --- a/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/processor/JavaHintsAnnotationProcessorTest.java	Sun Oct 16 08:01:27 2016 +0200
   133.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   133.3 @@ -1,149 +0,0 @@
   133.4 -/*
   133.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   133.6 - *
   133.7 - * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
   133.8 - *
   133.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  133.10 - * Other names may be trademarks of their respective owners.
  133.11 - *
  133.12 - * The contents of this file are subject to the terms of either the GNU
  133.13 - * General Public License Version 2 only ("GPL") or the Common
  133.14 - * Development and Distribution License("CDDL") (collectively, the
  133.15 - * "License"). You may not use this file except in compliance with the
  133.16 - * License. You can obtain a copy of the License at
  133.17 - * http://www.netbeans.org/cddl-gplv2.html
  133.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  133.19 - * specific language governing permissions and limitations under the
  133.20 - * License.  When distributing the software, include this License Header
  133.21 - * Notice in each file and include the License file at
  133.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  133.23 - * particular file as subject to the "Classpath" exception as provided
  133.24 - * by Oracle in the GPL Version 2 section of the License file that
  133.25 - * accompanied this code. If applicable, add the following below the
  133.26 - * License Header, with the fields enclosed by brackets [] replaced by
  133.27 - * your own identifying information:
  133.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  133.29 - *
  133.30 - * If you wish your version of this file to be governed by only the CDDL
  133.31 - * or only the GPL Version 2, indicate your decision by adding
  133.32 - * "[Contributor] elects to include this software in this distribution
  133.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  133.34 - * single choice of license, a recipient has the option to distribute
  133.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  133.36 - * to extend the choice of license to its licensees as provided above.
  133.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  133.38 - * Version 2 license, then the option applies only if the new code is
  133.39 - * made subject to such option by the copyright holder.
  133.40 - *
  133.41 - * Contributor(s):
  133.42 - *
  133.43 - * Portions Copyrighted 2012 Sun Microsystems, Inc.
  133.44 - */
  133.45 -package org.netbeans.modules.java.hints.spiimpl.processor;
  133.46 -
  133.47 -import java.io.ByteArrayOutputStream;
  133.48 -import java.io.File;
  133.49 -import org.netbeans.junit.NbTestCase;
  133.50 -import org.openide.util.test.AnnotationProcessorTestUtils;
  133.51 -import org.openide.util.test.TestFileUtils;
  133.52 -
  133.53 -/**
  133.54 - *
  133.55 - * @author lahvac
  133.56 - */
  133.57 -public class JavaHintsAnnotationProcessorTest extends NbTestCase {
  133.58 -
  133.59 -    public JavaHintsAnnotationProcessorTest(String name) {
  133.60 -        super(name);
  133.61 -    }
  133.62 -
  133.63 -    public void testErrors1() throws Exception {
  133.64 -        File src = new File(getWorkDir(), "src");
  133.65 -        File dest = new File(getWorkDir(), "classes");
  133.66 -        AnnotationProcessorTestUtils.makeSource(src, "p.H",
  133.67 -                "import org.netbeans.spi.java.hints.*;\n",
  133.68 -                "import org.netbeans.spi.editor.hints.*;\n",
  133.69 -                "@Hint(displayName=\"\", description=\"\", category=\"general\")\n",
  133.70 -                "public class H {\n",
  133.71 -                "    @TriggerPattern(\"$1.$2\")\n",
  133.72 -                "    public static String h1(HintContext ctx) { return null;}\n",
  133.73 -                "    @TriggerPattern(\"$1.$2.$3\")\n",
  133.74 -                "    public static ErrorDescription h2() { return null;}\n",
  133.75 -                "    @TriggerPatterns({@TriggerPattern(\"$1.$2.$3.$4\")})\n",
  133.76 -                "    private ErrorDescription h3(HintContext ctx) { return null;}\n",
  133.77 -                "    @TriggerPattern(value=\"$1.isEmpty()\", constraints=@ConstraintVariableType(variable=\"$unknown\", type=\"java.lang.String\"))\n",
  133.78 -                "    public static ErrorDescription h4(HintContext ctx) { return null;}\n",
  133.79 -                "}\n");
  133.80 -        TestFileUtils.writeFile(new File(src, "p/Bundle.properties"), "");
  133.81 -        ByteArrayOutputStream err = new ByteArrayOutputStream();
  133.82 -        assertFalse(AnnotationProcessorTestUtils.runJavac(src, null, dest, null, err));
  133.83 -        String errors = err.toString();
  133.84 -        assertTrue(errors.contains("error: The return type must be either org.netbeans.spi.editor.hints.ErrorDescription or java.util.List<org.netbeans.spi.editor.hints.ErrorDescription>"));
  133.85 -        assertTrue(errors.contains("error: The method must have exactly one parameter of type org.netbeans.spi.java.hints.HintContext"));
  133.86 -        assertTrue(errors.contains("error: The method must be static"));
  133.87 -        assertTrue(errors.contains("warning: Variable $unknown not used in the pattern"));
  133.88 -    }
  133.89 -
  133.90 -    public void testErrors2() throws Exception {
  133.91 -        File src = new File(getWorkDir(), "src");
  133.92 -        File dest = new File(getWorkDir(), "classes");
  133.93 -        AnnotationProcessorTestUtils.makeSource(src, "p.H",
  133.94 -                "import org.netbeans.spi.java.hints.*;\n",
  133.95 -                "import org.netbeans.spi.editor.hints.*;\n",
  133.96 -                "import java.util.*;\n",
  133.97 -                "@Hint(displayName=\"#DN_p.H\", description=\"#DESC_p.H\", category=\"general\")\n",
  133.98 -                "public class H {\n",
  133.99 -                "    @TriggerPattern(\"$1.$2.$3\")\n",
 133.100 -                "    public static List<ErrorDescription> hint(HintContext ctx) { return null;}\n",
 133.101 -                "}\n");
 133.102 -        TestFileUtils.writeFile(new File(src, "p/Bundle.properties"), "DN_p.H=DN_p.H\nDESC_p.H=DESC_p.H\n");
 133.103 -        ByteArrayOutputStream err = new ByteArrayOutputStream();
 133.104 -        assertTrue(AnnotationProcessorTestUtils.runJavac(src, null, dest, null, err));
 133.105 -    }
 133.106 -
 133.107 -    public void testCustomizerProvider() throws Exception {
 133.108 -        File src = new File(getWorkDir(), "src");
 133.109 -        File dest = new File(getWorkDir(), "classes");
 133.110 -        AnnotationProcessorTestUtils.makeSource(src, "p.H",
 133.111 -                "import org.netbeans.spi.java.hints.*;\n",
 133.112 -                "import org.netbeans.spi.editor.hints.*;\n",
 133.113 -                "import java.util.*;\n",
 133.114 -                "import java.util.prefs.*;\n",
 133.115 -                "import javax.swing.*;\n",
 133.116 -                "@Hint(displayName=\"dn\", description=\"desc\", category=\"general\", customizerProvider=H.Customizer.class)\n",
 133.117 -                "public class H {\n",
 133.118 -                "    @TriggerPattern(\"$1.$2.$3\")\n",
 133.119 -                "    public static List<ErrorDescription> hint(HintContext ctx) { return null;}\n",
 133.120 -                "    static final class Customizer implements CustomizerProvider {\n",
 133.121 -                "        @Override public JComponent getCustomizer(Preferences prefs) {\n",
 133.122 -                "            return new JPanel();\n",
 133.123 -                "        }\n",
 133.124 -                "    }\n",
 133.125 -                "}\n");
 133.126 -        TestFileUtils.writeFile(new File(src, "p/Bundle.properties"), "DN_p.H=DN_p.H\nDESC_p.H=DESC_p.H\n");
 133.127 -        ByteArrayOutputStream err = new ByteArrayOutputStream();
 133.128 -        assertFalse(AnnotationProcessorTestUtils.runJavac(src, null, dest, null, err));
 133.129 -        String errors = err.toString();
 133.130 -        assertTrue(errors.contains("error: Customizer provider must be public"));
 133.131 -        assertTrue(errors.contains("error: Customizer provider must provide a public default constructor"));
 133.132 -    }
 133.133 -
 133.134 -    public void testErrorsMessagesOnMethod() throws Exception {
 133.135 -        File src = new File(getWorkDir(), "src");
 133.136 -        File dest = new File(getWorkDir(), "classes");
 133.137 -        AnnotationProcessorTestUtils.makeSource(src, "p.H",
 133.138 -                "import org.netbeans.spi.java.hints.*;\n",
 133.139 -                "import org.netbeans.spi.editor.hints.*;\n",
 133.140 -                "import org.openide.util.NbBundle.Messages;\n",
 133.141 -                "import java.util.*;\n",
 133.142 -                "public class H {\n",
 133.143 -                "    @Hint(displayName=\"#DN_p.H\", description=\"#DESC_p.H\", category=\"general\")\n",
 133.144 -                "    @TriggerPattern(\"$1.$2.$3\")\n",
 133.145 -                "    @Messages({\"DN_p.H=1\", \"DESC_p.H=2\"})\n",
 133.146 -                "    public static List<ErrorDescription> hint(HintContext ctx) { return null;}\n",
 133.147 -                "}\n");
 133.148 -        ByteArrayOutputStream err = new ByteArrayOutputStream();
 133.149 -        boolean result = AnnotationProcessorTestUtils.runJavac(src, null, dest, null, err);
 133.150 -        assertTrue(err.toString(), result);
 133.151 -    }
 133.152 -}
   134.1 --- a/java.hints/spi.java.hints/test/unit/src/org/netbeans/spi/java/hints/JavaFixUtilitiesTest.java	Sun Oct 16 08:01:27 2016 +0200
   134.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   134.3 @@ -1,1169 +0,0 @@
   134.4 -/*
   134.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   134.6 - *
   134.7 - * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
   134.8 - *
   134.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  134.10 - * Other names may be trademarks of their respective owners.
  134.11 - *
  134.12 - * The contents of this file are subject to the terms of either the GNU
  134.13 - * General Public License Version 2 only ("GPL") or the Common
  134.14 - * Development and Distribution License("CDDL") (collectively, the
  134.15 - * "License"). You may not use this file except in compliance with the
  134.16 - * License. You can obtain a copy of the License at
  134.17 - * http://www.netbeans.org/cddl-gplv2.html
  134.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  134.19 - * specific language governing permissions and limitations under the
  134.20 - * License.  When distributing the software, include this License Header
  134.21 - * Notice in each file and include the License file at
  134.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  134.23 - * particular file as subject to the "Classpath" exception as provided
  134.24 - * by Oracle in the GPL Version 2 section of the License file that
  134.25 - * accompanied this code. If applicable, add the following below the
  134.26 - * License Header, with the fields enclosed by brackets [] replaced by
  134.27 - * your own identifying information:
  134.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  134.29 - *
  134.30 - * If you wish your version of this file to be governed by only the CDDL
  134.31 - * or only the GPL Version 2, indicate your decision by adding
  134.32 - * "[Contributor] elects to include this software in this distribution
  134.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  134.34 - * single choice of license, a recipient has the option to distribute
  134.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  134.36 - * to extend the choice of license to its licensees as provided above.
  134.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  134.38 - * Version 2 license, then the option applies only if the new code is
  134.39 - * made subject to such option by the copyright holder.
  134.40 - *
  134.41 - * Contributor(s):
  134.42 - *
  134.43 - * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
  134.44 - */
  134.45 -
  134.46 -package org.netbeans.spi.java.hints;
  134.47 -
  134.48 -import org.netbeans.modules.java.hints.providers.spi.HintDescriptionFactory;
  134.49 -import org.netbeans.modules.java.hints.providers.spi.HintDescription;
  134.50 -import com.sun.source.tree.ClassTree;
  134.51 -import com.sun.source.tree.ExpressionTree;
  134.52 -import com.sun.source.tree.VariableTree;
  134.53 -import com.sun.source.util.TreePath;
  134.54 -import java.util.Collection;
  134.55 -import java.util.Collections;
  134.56 -import java.util.HashMap;
  134.57 -import java.util.List;
  134.58 -import java.util.Map;
  134.59 -import java.util.Map.Entry;
  134.60 -import java.util.concurrent.atomic.AtomicBoolean;
  134.61 -import javax.lang.model.element.ExecutableElement;
  134.62 -import javax.lang.model.element.TypeElement;
  134.63 -import javax.lang.model.type.TypeMirror;
  134.64 -import javax.lang.model.util.ElementFilter;
  134.65 -import org.netbeans.modules.java.hints.spiimpl.TestBase;
  134.66 -import org.netbeans.modules.java.hints.spiimpl.hints.HintsInvoker;
  134.67 -import org.netbeans.modules.java.hints.providers.spi.Trigger.PatternDescription;
  134.68 -import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings;
  134.69 -import org.netbeans.modules.java.hints.spiimpl.pm.PatternCompilerUtilities;
  134.70 -import org.netbeans.spi.editor.hints.ErrorDescription;
  134.71 -import org.netbeans.spi.editor.hints.Fix;
  134.72 -import org.openide.LifecycleManager;
  134.73 -import org.openide.modules.SpecificationVersion;
  134.74 -import org.openide.util.MapFormat;
  134.75 -
  134.76 -/**
  134.77 - *
  134.78 - * @author Jan Lahoda
  134.79 - */
  134.80 -public class JavaFixUtilitiesTest extends TestBase {
  134.81 -
  134.82 -    public JavaFixUtilitiesTest(String name) {
  134.83 -        super(name);
  134.84 -    }
  134.85 -
  134.86 -    public void testSimple() throws Exception {
  134.87 -        SpecificationVersion v = computeSpecVersion("/**\n" +
  134.88 -                                                    " * @since 1.5\n" +
  134.89 -                                                    " */\n");
  134.90 -
  134.91 -        assertEquals(0, v.compareTo(new SpecificationVersion("1.5")));
  134.92 -    }
  134.93 -
  134.94 -    public void testSimpleDate() throws Exception {
  134.95 -        SpecificationVersion v = computeSpecVersion("/**\n" +
  134.96 -                                                    " * @since 1.5 (16 May 2005)\n" +
  134.97 -                                                    " */\n");
  134.98 -
  134.99 -        assertEquals(0, v.compareTo(new SpecificationVersion("1.5")));
 134.100 -    }
 134.101 -
 134.102 -    public void testLongText() throws Exception {
 134.103 -        SpecificationVersion v = computeSpecVersion("/**\n" +
 134.104 -                                                    " * @since 1.123.2.1 - branch propsheet_issue_29447\n" +
 134.105 -                                                    " */\n");
 134.106 -
 134.107 -        assertEquals(0, v.compareTo(new SpecificationVersion("1.123.2.1")));
 134.108 -    }
 134.109 -
 134.110 -    public void testModuleName() throws Exception {
 134.111 -        SpecificationVersion v = computeSpecVersion("/**\n" +
 134.112 -                                                    " * @since org.openide.filesystems 7.15\n" +
 134.113 -                                                    " */\n");
 134.114 -
 134.115 -        assertEquals(0, v.compareTo(new SpecificationVersion("7.15")));
 134.116 -    }
 134.117 -
 134.118 -    public void testModuleNameMajor() throws Exception {
 134.119 -        SpecificationVersion v = computeSpecVersion("/**\n" +
 134.120 -                                                    " * @since org.openide/1 4.42\n" +
 134.121 -                                                    " */\n");
 134.122 -
 134.123 -        assertEquals(0, v.compareTo(new SpecificationVersion("4.42")));
 134.124 -    }
 134.125 -
 134.126 -    public void testEnd() throws Exception {
 134.127 -        SpecificationVersion v = computeSpecVersion("/**\n" +
 134.128 -                                                    " * @since 1.5 */\n");
 134.129 -
 134.130 -        assertEquals(0, v.compareTo(new SpecificationVersion("1.5")));
 134.131 -    }
 134.132 -
 134.133 -    public void testOpenAPI() throws Exception {
 134.134 -        SpecificationVersion v = computeSpecVersion("/**\n" +
 134.135 -                                                    " * @since OpenAPI version 2.12" +
 134.136 -                                                    " */\n");
 134.137 -
 134.138 -        assertEquals(0, v.compareTo(new SpecificationVersion("2.12")));
 134.139 -
 134.140 -    }
 134.141 -
 134.142 -    private SpecificationVersion computeSpecVersion(String javadoc) throws Exception {
 134.143 -        prepareTest("test/Test.java",
 134.144 -                    "package test;\n" +
 134.145 -                    "public class Test {\n" +
 134.146 -                    javadoc +
 134.147 -                    "     public void test() {\n" +
 134.148 -                    "     }\n" +
 134.149 -                    "}\n");
 134.150 -
 134.151 -        TypeElement te = info.getElements().getTypeElement("test.Test");
 134.152 -        ExecutableElement method = ElementFilter.methodsIn(te.getEnclosedElements()).iterator().next();
 134.153 -
 134.154 -        return JavaFixUtilities.computeSpecVersion(info, method);
 134.155 -    }
 134.156 -
 134.157 -    public void testArithmetic1() throws Exception {
 134.158 -        performArithmeticTest("1 + 2", "3");
 134.159 -        performArithmeticTest("1f + 2", "3.0F");
 134.160 -        performArithmeticTest("1 + 2f", "3.0F");
 134.161 -        performArithmeticTest("1.0 + 2f", "3.0");
 134.162 -        performArithmeticTest("1 + 2.0", "3.0");
 134.163 -        performArithmeticTest("1L + 2", "3L");
 134.164 -    }
 134.165 -
 134.166 -    public void testArithmetic2() throws Exception {
 134.167 -        performArithmeticTest("1 * 2", "2");
 134.168 -        performArithmeticTest("1f * 2", "2.0F");
 134.169 -        performArithmeticTest("1 * 2f", "2.0F");
 134.170 -        performArithmeticTest("1.0 * 2f", "2.0");
 134.171 -        performArithmeticTest("1 * 2.0", "2.0");
 134.172 -        performArithmeticTest("1L * 2", "2L");
 134.173 -    }
 134.174 -
 134.175 -    public void testArithmetic3() throws Exception {
 134.176 -        performArithmeticTest("4 / 2", "2");
 134.177 -        performArithmeticTest("4f / 2", "2.0F");
 134.178 -        performArithmeticTest("4 / 2f", "2.0F");
 134.179 -        performArithmeticTest("4.0 / 2f", "2.0");
 134.180 -        performArithmeticTest("4 / 2.0", "2.0");
 134.181 -        performArithmeticTest("4L / 2", "2L");
 134.182 -    }
 134.183 -
 134.184 -    public void testArithmetic4() throws Exception {
 134.185 -        performArithmeticTest("5 % 2", "1");
 134.186 -        performArithmeticTest("5f % 2", "1.0F");
 134.187 -        performArithmeticTest("5 % 2f", "1.0F");
 134.188 -        performArithmeticTest("5.0 % 2f", "1.0");
 134.189 -        performArithmeticTest("5 % 2.0", "1.0");
 134.190 -        performArithmeticTest("5L % 2", "1L");
 134.191 -    }
 134.192 -
 134.193 -    public void testArithmetic5() throws Exception {
 134.194 -        performArithmeticTest("5 - 2", "3");
 134.195 -        performArithmeticTest("5f - 2", "3.0F");
 134.196 -        performArithmeticTest("5 - 2f", "3.0F");
 134.197 -        performArithmeticTest("5.0 - 2f", "3.0");
 134.198 -        performArithmeticTest("5 - 2.0", "3.0");
 134.199 -        performArithmeticTest("5L - 2", "3L");
 134.200 -    }
 134.201 -
 134.202 -    public void testArithmetic6() throws Exception {
 134.203 -        performArithmeticTest("5 | 2", "7");
 134.204 -        performArithmeticTest("5L | 2", "7L");
 134.205 -        performArithmeticTest("5 | 2L", "7L");
 134.206 -    }
 134.207 -
 134.208 -    public void testArithmetic7() throws Exception {
 134.209 -        performArithmeticTest("5 & 4", "4");
 134.210 -        performArithmeticTest("5L & 4", "4L");
 134.211 -        performArithmeticTest("5 & 4L", "4L");
 134.212 -    }
 134.213 -
 134.214 -    public void testArithmetic8() throws Exception {
 134.215 -        performArithmeticTest("5 ^ 4", "1");
 134.216 -        performArithmeticTest("5L ^ 4", "1L");
 134.217 -        performArithmeticTest("5 ^ 4L", "1L");
 134.218 -    }
 134.219 -
 134.220 -    public void testArithmetic9() throws Exception {
 134.221 -        performArithmeticTest("5 << 2", "20");
 134.222 -        performArithmeticTest("5L << 2", "20L");
 134.223 -        performArithmeticTest("5 << 2L", "20L");
 134.224 -    }
 134.225 -
 134.226 -    public void testArithmeticA() throws Exception {
 134.227 -        performArithmeticTest("-20 >> 2", "-5");
 134.228 -        performArithmeticTest("-20L >> 2", "-5L");
 134.229 -        performArithmeticTest("-20 >> 2L", "-5L");
 134.230 -    }
 134.231 -
 134.232 -    public void testArithmeticB() throws Exception {
 134.233 -        performArithmeticTest("-20 >>> 2", "1073741819");
 134.234 -    }
 134.235 -
 134.236 -    public void testArithmeticC() throws Exception {
 134.237 -        performArithmeticTest("0 + -20", "-20");
 134.238 -        performArithmeticTest("0 + +20", "20");
 134.239 -    }
 134.240 -
 134.241 -    public void testArithmeticComplex() throws Exception {
 134.242 -        performArithmeticTest("1 + 2 * 4 - 5", "4");
 134.243 -        performArithmeticTest("1f + 2 * 4.0 - 5", "4.0");
 134.244 -        performArithmeticTest("1L + 2 * 4 - 5", "4L");
 134.245 -    }
 134.246 -
 134.247 -    private static final String ARITHMETIC = "public class Test { private Object o = __VAL__; }";
 134.248 -    private void performArithmeticTest(String orig, String nue) throws Exception {
 134.249 -        String code = replace("0");
 134.250 -
 134.251 -        prepareTest("Test.java", code);
 134.252 -        ClassTree clazz = (ClassTree) info.getCompilationUnit().getTypeDecls().get(0);
 134.253 -        VariableTree variable = (VariableTree) clazz.getMembers().get(1);
 134.254 -        ExpressionTree init = variable.getInitializer();
 134.255 -        TreePath tp = new TreePath(new TreePath(new TreePath(new TreePath(info.getCompilationUnit()), clazz), variable), init);
 134.256 -        Fix fix = JavaFixUtilities.rewriteFix(info, "A", tp, orig, Collections.<String, TreePath>emptyMap(), Collections.<String, Collection<? extends TreePath>>emptyMap(), Collections.<String, String>emptyMap(), Collections.<String, TypeMirror>emptyMap(), Collections.<String, String>emptyMap());
 134.257 -        fix.implement();
 134.258 -
 134.259 -        String golden = replace(nue);
 134.260 -        String out = doc.getText(0, doc.getLength());
 134.261 -
 134.262 -        assertEquals(golden, out);
 134.263 -
 134.264 -        LifecycleManager.getDefault().saveAll();
 134.265 -    }
 134.266 -
 134.267 -    private static String replace(String val) {
 134.268 -        MapFormat f = new MapFormat(Collections.singletonMap("VAL", val));
 134.269 -
 134.270 -        f.setLeftBrace("__");
 134.271 -        f.setRightBrace("__");
 134.272 -
 134.273 -        return f.format(ARITHMETIC);
 134.274 -    }
 134.275 -
 134.276 -    public void testRewriteWithParenthesis1() throws Exception {
 134.277 -        performRewriteTest("package test;\n" +
 134.278 -                           "public class Test {\n" +
 134.279 -                           "    int i = new String(\"a\" + \"b\").length();\n" +
 134.280 -                           "}\n",
 134.281 -                           "new String($1)=>$1",
 134.282 -                           "package test;\n" +
 134.283 -                           "public class Test {\n" +
 134.284 -		           "    int i = (\"a\" + \"b\").length();\n" +
 134.285 -		           "}\n");
 134.286 -    }
 134.287 -
 134.288 -    public void testRewriteWithParenthesis2() throws Exception {
 134.289 -        performRewriteTest("package test;\n" +
 134.290 -                           "public class Test {\n" +
 134.291 -                           "    int i = Integer.valueOf(1 + 2) * 3;\n" +
 134.292 -                           "}\n",
 134.293 -                           "Integer.valueOf($1)=>$1",
 134.294 -                           "package test;\n" +
 134.295 -                           "public class Test {\n" +
 134.296 -		           "    int i = (1 + 2) * 3;\n" +
 134.297 -		           "}\n");
 134.298 -    }
 134.299 -
 134.300 -    public void testRewriteWithoutParenthesis1() throws Exception {
 134.301 -        performRewriteTest("package test;\n" +
 134.302 -                           "public class Test {\n" +
 134.303 -                           "    int i = new String(\"a\" + \"b\").length();\n" +
 134.304 -                           "}\n",
 134.305 -                           "new String($1)=>java.lang.String.format(\"%s%s\", $1, \"\")",
 134.306 -                           "package test;\n" +
 134.307 -                           "public class Test {\n" +
 134.308 -		           "    int i = String.format(\"%s%s\", \"a\" + \"b\", \"\").length();\n" +
 134.309 -		           "}\n");
 134.310 -    }
 134.311 -
 134.312 -    public void testRewriteWithoutParenthesis2() throws Exception {
 134.313 -        performRewriteTest("package test;\n" +
 134.314 -                           "public class Test {\n" +
 134.315 -                           "    String s = (\"a\" + \"b\").intern();\n" +
 134.316 -                           "}\n",
 134.317 -                           "($1).intern()=>$1",
 134.318 -                           "package test;\n" +
 134.319 -                           "public class Test {\n" +
 134.320 -		           "    String s = \"a\" + \"b\";\n" +
 134.321 -		           "}\n");
 134.322 -    }
 134.323 -
 134.324 -    public void testRewriteWithoutParenthesis3() throws Exception {
 134.325 -        performRewriteTest("package test;\n" +
 134.326 -                           "public class Test {\n" +
 134.327 -                           "    int i = Integer.valueOf(1 + 2) + 3;\n" +
 134.328 -                           "}\n",
 134.329 -                           "Integer.valueOf($1)=>$1",
 134.330 -                           "package test;\n" +
 134.331 -                           "public class Test {\n" +
 134.332 -		           "    int i = 1 + 2 + 3;\n" +
 134.333 -		           "}\n");
 134.334 -    }
 134.335 -
 134.336 -    public void testRewriteWithoutParenthesis4() throws Exception {
 134.337 -        performRewriteTest("package test;\n" +
 134.338 -                           "public class Test {\n" +
 134.339 -                           "    int i = Integer.valueOf(1 * 2) + 3;\n" +
 134.340 -                           "}\n",
 134.341 -                           "Integer.valueOf($1)=>$1",
 134.342 -                           "package test;\n" +
 134.343 -                           "public class Test {\n" +
 134.344 -		           "    int i = 1 * 2 + 3;\n" +
 134.345 -		           "}\n");
 134.346 -    }
 134.347 -
 134.348 -    public void testRewriteWithoutParenthesis5() throws Exception {
 134.349 -        performRewriteTest("package test;\n" +
 134.350 -                           "public class Test {\n" +
 134.351 -                           "    int i = new Integer(1 * 2).hashCode();\n" +
 134.352 -                           "}\n",
 134.353 -                           "$1.hashCode()=>$1.hashCode()",
 134.354 -                           "package test;\n" +
 134.355 -                           "public class Test {\n" +
 134.356 -		           "    int i = new Integer(1 * 2).hashCode();\n" +
 134.357 -		           "}\n");
 134.358 -    }
 134.359 -
 134.360 -    public void testRewriteWithoutParenthesis6() throws Exception {
 134.361 -        performRewriteTest("package test;\n" +
 134.362 -                           "public class Test {\n" +
 134.363 -                           "    {\n" +
 134.364 -                           "        System.err.println(\"a\" + 1);\n" +
 134.365 -                           "    }\n" +
 134.366 -                           "}\n",
 134.367 -                           "System.err.println($t)=>D.println($t)",
 134.368 -                           "package test;\n" +
 134.369 -                           "public class Test {\n" +
 134.370 -                           "    {\n" +
 134.371 -                           "        D.println(\"a\" + 1);\n" +
 134.372 -                           "    }\n" +
 134.373 -		           "}\n");
 134.374 -    }
 134.375 -
 134.376 -    public void testRewriteWithoutParenthesis7() throws Exception {
 134.377 -        performRewriteTest("package test;\n" +
 134.378 -                           "public class Test {\n" +
 134.379 -                           "    {\n" +
 134.380 -                           "        new String(\"a\" + 1);\n" +
 134.381 -                           "    }\n" +
 134.382 -                           "}\n",
 134.383 -                           "new String($t)=>new D($t)",
 134.384 -                           "package test;\n" +
 134.385 -                           "public class Test {\n" +
 134.386 -                           "    {\n" +
 134.387 -                           "        new D(\"a\" + 1);\n" +
 134.388 -                           "    }\n" +
 134.389 -		           "}\n");
 134.390 -    }
 134.391 -
 134.392 -    public void testTopLevelRewriteWithoutParenthesis1() throws Exception {
 134.393 -        performRewriteTest("package test;\n" +
 134.394 -                           "public class Test {\n" +
 134.395 -                           "    int i = (1 + 2) * 2;\n" +
 134.396 -                           "}\n",
 134.397 -                           "$1 + $2=>3",
 134.398 -                           "package test;\n" +
 134.399 -                           "public class Test {\n" +
 134.400 -		           "    int i = 3 * 2;\n" +
 134.401 -		           "}\n");
 134.402 -    }
 134.403 -
 134.404 -    public void testTopLevelRewriteKeepParenthesis1() throws Exception {
 134.405 -        performRewriteTest("package test;\n" +
 134.406 -                           "public class Test {\n" +
 134.407 -                           "    int i = (1 * 2) + 2;\n" +
 134.408 -                           "}\n",
 134.409 -                           "$1 * $2=>2",
 134.410 -                           "package test;\n" +
 134.411 -                           "public class Test {\n" +
 134.412 -		           "    int i = (2) + 2;\n" +
 134.413 -		           "}\n");
 134.414 -    }
 134.415 -
 134.416 -    public void testTopLevelRewriteKeepParenthesis2() throws Exception {
 134.417 -        performRewriteTest("package test;\n" +
 134.418 -                           "public class Test {\n" +
 134.419 -                           "    { if (1 > 2) ; }\n" +
 134.420 -                           "}\n",
 134.421 -                           "$1 > $2=>false",
 134.422 -                           "package test;\n" +
 134.423 -                           "public class Test {\n" +
 134.424 -                           "    { if (false) ; }\n" +
 134.425 -		           "}\n");
 134.426 -    }
 134.427 -    
 134.428 -    public void testRewriteCatchMultiVariable() throws Exception {
 134.429 -        performRewriteTest("package test;\n" +
 134.430 -                           "public class Test {\n" +
 134.431 -                           "    { try { } catch {NullPointerException ex} { } }\n" +
 134.432 -                           "}\n",
 134.433 -                           "try { } catch $catches$ => try { new Object(); } catch $catches$",
 134.434 -                           "package test;\n" +
 134.435 -                           "public class Test {\n" +
 134.436 -                           //XXX: whitespaces:
 134.437 -                           "    {  try {new Object();\n } catch {NullPointerException ex} { } }\n" +
 134.438 -//                           "    { try {      new Object();\n } catch {NullPointerException ex} { } }\n" +
 134.439 -		           "}\n");
 134.440 -    }
 134.441 -
 134.442 -    public void testRewriteCaseMultiVariable() throws Exception {
 134.443 -        performRewriteTest("package test;\n" +
 134.444 -                           "public class Test {\n" +
 134.445 -                           "    { int i = 0; switch (i) {case 0: System.err.println(1); break; case 1: System.err.println(2); break; case 2: System.err.println(3); break; }\n" +
 134.446 -                           "}\n",
 134.447 -                           "switch ($v) { case $p$ case 2: $stmts$; } => switch ($v) { case $p$ case 3: $stmts$; }",
 134.448 -                           "package test;\n" +
 134.449 -                           "public class Test {\n" +
 134.450 -                           "    { int i = 0; switch (i) {case 0: System.err.println(1); break; case 1: System.err.println(2); break; case 3: System.err.println(3); break; }\n" +
 134.451 -		           "}\n");
 134.452 -    }
 134.453 -
 134.454 -    public void testRewriteMemberSelectVariable() throws Exception {
 134.455 -        performRewriteTest("package test;\n" +
 134.456 -                           "public class Test {\n" +
 134.457 -                           "    { java.io.File f = null; boolean b = f.isDirectory(); }\n" +
 134.458 -                           "}\n",
 134.459 -                           "$file.$m() => foo.Bar.$m($file)",
 134.460 -                           "package test;\n" +
 134.461 -                           "public class Test {\n" +
 134.462 -                           "    { java.io.File f = null; boolean b = foo.Bar.isDirectory(f); }\n" +
 134.463 -		           "}\n");
 134.464 -    }
 134.465 -    
 134.466 -    public void testRewriteIdent2IdentMemberSelectPattern() throws Exception {
 134.467 -        performRewriteTest("package test;\n" +
 134.468 -                           "public class Test {\n" +
 134.469 -                           "    private boolean b; private void t() { boolean c = b; }\n" +
 134.470 -                           "}\n",
 134.471 -                           "$0{test.Test}.b => !$0.b",
 134.472 -                           "package test;\n" +
 134.473 -                           "public class Test {\n" +
 134.474 -                           "    private boolean b; private void t() { boolean c = !b; }\n" +
 134.475 -		           "}\n");
 134.476 -    }
 134.477 -
 134.478 -    public void testCarefulRewriteInImports() throws Exception {
 134.479 -        performRewriteTest("package test;\n" +
 134.480 -                           "import javax.swing.text.AbstractDocument;\n" +
 134.481 -                           "public class Test {\n" +
 134.482 -                           "}\n",
 134.483 -                           "javax.swing.text.AbstractDocument => javax.swing.text.Document",
 134.484 -                           "package test;\n" +
 134.485 -                           "import javax.swing.text.Document;\n" +
 134.486 -                           "public class Test {\n" +
 134.487 -		           "}\n");
 134.488 -    }
 134.489 -
 134.490 -    public void testRemoveFromParent1() throws Exception {
 134.491 -        performRemoveFromParentTest("package test;\n" +
 134.492 -                                    "public class Test {\n" +
 134.493 -                                    "    private int I;" +
 134.494 -                                    "}\n",
 134.495 -                                    "$mods$ int $f;",
 134.496 -                                    "package test;\n" +
 134.497 -                                    "public class Test {\n" +
 134.498 -                                    "}\n");
 134.499 -    }
 134.500 -
 134.501 -    public void testRemoveFromParent2() throws Exception {
 134.502 -        performRemoveFromParentTest("package test;\n" +
 134.503 -                                    "public class Test extends java.util.ArrayList {\n" +
 134.504 -                                    "}\n",
 134.505 -                                    "java.util.ArrayList",
 134.506 -                                    "package test;\n" +
 134.507 -                                    "public class Test {\n" +
 134.508 -                                    "}\n");
 134.509 -    }
 134.510 -    
 134.511 -    public void testRemoveFromParentExpressionStatement206116() throws Exception {
 134.512 -        performRemoveFromParentTest("package test;\n" +
 134.513 -                           "import java.io.InputStream;\n" +
 134.514 -                           "public class Test {\n" +
 134.515 -                           "    private void t() throws Exception {\n" +
 134.516 -                           "        System.err.println();\n" +
 134.517 -                           "        System.err.println(\"a\");\n" +
 134.518 -                           "    }\n" +
 134.519 -                           "}\n",
 134.520 -                           "System.err.println()",
 134.521 -                           "package test;\n" +
 134.522 -                           "import java.io.InputStream;\n" +
 134.523 -                           "public class Test {\n" +
 134.524 -                           "    private void t() throws Exception {\n" +
 134.525 -                           "        System.err.println(\"a\");\n" +
 134.526 -                           "    }\n" +
 134.527 -		           "}\n");
 134.528 -    }
 134.529 -
 134.530 -    public void testUnresolvableTarget() throws Exception {
 134.531 -        performRewriteTest("package test;\n" +
 134.532 -                           "public class Test extends java.util.ArrayList {\n" +
 134.533 -                           "}\n",
 134.534 -                           "java.util.ArrayList => Test",
 134.535 -                           "package test;\n" +
 134.536 -                           "public class Test extends Test {\n" +
 134.537 -                           "}\n");
 134.538 -    }
 134.539 -
 134.540 -    public void testTryWithResourceTarget() throws Exception {
 134.541 -        performRewriteTest("package test;\n" +
 134.542 -                           "import java.io.InputStream;\n" +
 134.543 -                           "public class Test {\n" +
 134.544 -                           "    private void t() throws Exception {\n" +
 134.545 -                           "        InputStream in = null;\n" +
 134.546 -                           "        try {\n" +
 134.547 -                           "        } finally {\n" +
 134.548 -                           "            in.close()\n" +
 134.549 -                           "        }\n" +
 134.550 -                           "    }\n" +
 134.551 -                           "}\n",
 134.552 -                           "$type $var = $init; try {} finally {$var.close();} => try ($type $var = $init) {} finally {$var.close();}",
 134.553 -                           "package test;\n" +
 134.554 -                           "import java.io.InputStream;\n" +
 134.555 -                           "public class Test {\n" +
 134.556 -                           "    private void t() throws Exception {\n" +
 134.557 -//                           "        try (InputStream in = null) {\n" +
 134.558 -                           //XXX:
 134.559 -                           "        try (final InputStream in = null) {\n" +
 134.560 -                           "        } finally {\n" +
 134.561 -                           "            in.close()\n" +
 134.562 -                           "        }\n" +
 134.563 -                           "    }\n" +
 134.564 -		           "}\n");
 134.565 -    }
 134.566 -
 134.567 -    public void testSingle2MultipleStatements() throws Exception {
 134.568 -        performRewriteTest("package test;\n" +
 134.569 -                           "import java.io.InputStream;\n" +
 134.570 -                           "public class Test {\n" +
 134.571 -                           "    private void t() throws Exception {\n" +
 134.572 -                           "        int i = 0;\n" +
 134.573 -                           "    }\n" +
 134.574 -                           "}\n",
 134.575 -                           "$type $var = $init; => $type $var; $var = $init;",
 134.576 -                           "package test;\n" +
 134.577 -                           "import java.io.InputStream;\n" +
 134.578 -                           "public class Test {\n" +
 134.579 -                           "    private void t() throws Exception {\n" +
 134.580 -                           "        int i;\n" +
 134.581 -                           "        i = 0;\n" +
 134.582 -                           "    }\n" +
 134.583 -		           "}\n");
 134.584 -    }
 134.585 -    
 134.586 -    public void testSingle2MultipleStatements2() throws Exception {
 134.587 -        performRewriteTest("package test;\n" +
 134.588 -                           "import java.io.InputStream;\n" +
 134.589 -                           "public class Test {\n" +
 134.590 -                           "    private void t() throws Exception {\n" +
 134.591 -                           "        while (true)\n" +
 134.592 -                           "            if (true) {\n" +
 134.593 -                           "                System.err.println();\n" +
 134.594 -                           "            }\n" +
 134.595 -                           "    }\n" +
 134.596 -                           "}\n",
 134.597 -                           "if (true) $then; => if (true) $then; System.err.println();",
 134.598 -                           "package test;\n" +
 134.599 -                           "import java.io.InputStream;\n" +
 134.600 -                           "public class Test {\n" +
 134.601 -                           "    private void t() throws Exception {\n" +
 134.602 -                           "        while (true) {\n" +
 134.603 -                           "            if (true) {\n" +
 134.604 -                           "                System.err.println();\n" +
 134.605 -                           "            }\n" +
 134.606 -                           "            System.err.println();\n" +
 134.607 -                           "        }\n" +
 134.608 -                           "    }\n" +
 134.609 -		           "}\n");
 134.610 -    }
 134.611 -    
 134.612 -    public void testMultipleStatementsWrapComments1() throws Exception {
 134.613 -        performRewriteTest("package test;\n" +
 134.614 -                           "import java.io.InputStream;\n" +
 134.615 -                           "public class Test {\n" +
 134.616 -                           "    private void t() throws Exception {\n" +
 134.617 -                           "        if (1 == 1) {\n" +
 134.618 -                           "            System.err.println();\n" +
 134.619 -                           "            System.err.println(\"a\");\n" +
 134.620 -                           "            \n" +
 134.621 -                           "            \n" +
 134.622 -                           "            //C\n" +
 134.623 -                           "            System.err.println(\"b\");\n" +
 134.624 -                           "        }\n" +
 134.625 -                           "    }\n" +
 134.626 -                           "}\n",
 134.627 -                           "if ($cond) { System.err.println(); $stmts$;} => while ($cond) { $stmts$;}",
 134.628 -                           "package test;\n" +
 134.629 -                           "import java.io.InputStream;\n" +
 134.630 -                           "public class Test {\n" +
 134.631 -                           "    private void t() throws Exception {\n" +
 134.632 -                           "        while (1 == 1) {\n" +
 134.633 -                           "            System.err.println(\"a\");\n" +
 134.634 -                           "            \n" +
 134.635 -                           "            \n" +
 134.636 -                           "            //C\n" +
 134.637 -                           "            System.err.println(\"b\");\n" +
 134.638 -                           "        }\n" +
 134.639 -                           "    }\n" +
 134.640 -		           "}\n");
 134.641 -    }
 134.642 -    
 134.643 -    public void testMultipleStatementsWrapComments2() throws Exception {
 134.644 -        performRewriteTest("package test;\n" +
 134.645 -                           "import java.io.InputStream;\n" +
 134.646 -                           "public class Test {\n" +
 134.647 -                           "    private void t() throws Exception {\n" +
 134.648 -                           "        if (1 == 1) {\n" +
 134.649 -                           "            System.err.println();\n" +
 134.650 -                           "            System.err.println(\"a\");\n" +
 134.651 -                           "            \n" +
 134.652 -                           "            \n" +
 134.653 -                           "            //C\n" +
 134.654 -                           "            System.err.println(\"b\");\n" +
 134.655 -                           "        }\n" +
 134.656 -                           "    }\n" +
 134.657 -                           "}\n",
 134.658 -                           "if ($cond) { $stmts$;} => while ($cond) { $stmts$;}",
 134.659 -                           "package test;\n" +
 134.660 -                           "import java.io.InputStream;\n" +
 134.661 -                           "public class Test {\n" +
 134.662 -                           "    private void t() throws Exception {\n" +
 134.663 -                           "        while (1 == 1) {\n" +
 134.664 -                           "            System.err.println();\n" +
 134.665 -                           "            System.err.println(\"a\");\n" +
 134.666 -                           "            \n" +
 134.667 -                           "            \n" +
 134.668 -                           "            //C\n" +
 134.669 -                           "            System.err.println(\"b\");\n" +
 134.670 -                           "        }\n" +
 134.671 -                           "    }\n" +
 134.672 -		           "}\n");
 134.673 -    }
 134.674 -    
 134.675 -    public void testReplaceTypeParameters1() throws Exception {
 134.676 -        performRewriteTest("package test;\n" +
 134.677 -                           "import java.io.InputStream;\n" +
 134.678 -                           "public class Test {\n" +
 134.679 -                           "    private <A, B> void t() {\n" +
 134.680 -                           "    }\n" +
 134.681 -                           "}\n",
 134.682 -                           "$mods$ <$O, $T> $ret $name() { $body$; } => $mods$ <$T, $O> $ret $name() { $body$; }",
 134.683 -                           "package test;\n" +
 134.684 -                           "import java.io.InputStream;\n" +
 134.685 -                           "public class Test {\n" +
 134.686 -                           "    private <B, A> void t() {\n" +
 134.687 -                           "    }\n" +
 134.688 -		           "}\n");
 134.689 -    }
 134.690 -    
 134.691 -    public void testReplaceTypeParameters2() throws Exception {
 134.692 -        performRewriteTest("package test;\n" +
 134.693 -                           "import java.io.InputStream;\n" +
 134.694 -                           "public class Test {\n" +
 134.695 -                           "    private <A, B> void t() {\n" +
 134.696 -                           "    }\n" +
 134.697 -                           "}\n",
 134.698 -                           "$mods$ <$T$> $ret $name() { $body$; } => $mods$ <C, $T$> $ret $name() { $body$; }",
 134.699 -                           "package test;\n" +
 134.700 -                           "import java.io.InputStream;\n" +
 134.701 -                           "public class Test {\n" +
 134.702 -                           "    private <C, A, B> void t() {\n" +
 134.703 -                           "    }\n" +
 134.704 -		           "}\n");
 134.705 -    }
 134.706 -    
 134.707 -    public void testAdd2Modifiers() throws Exception {
 134.708 -        performRewriteTest("package test;\n" +
 134.709 -                           "import java.io.InputStream;\n" +
 134.710 -                           "public class Test {\n" +
 134.711 -                           "    void t() {\n" +
 134.712 -                           "    }\n" +
 134.713 -                           "}\n",
 134.714 -                           "$mods$ $ret $name() { $body$; } => $mods$ @java.lang.Deprecated private $ret $name() { $body$; }",
 134.715 -                           "package test;\n" +
 134.716 -                           "import java.io.InputStream;\n" +
 134.717 -                           "public class Test {\n" +
 134.718 -                           "    @Deprecated\n" +
 134.719 -                           "    private void t() {\n" +
 134.720 -                           "    }\n" +
 134.721 -		           "}\n");
 134.722 -    }
 134.723 -    
 134.724 -    public void testReplaceInModifiers() throws Exception {
 134.725 -        performRewriteTest("package test;\n" +
 134.726 -                           "import java.io.InputStream;\n" +
 134.727 -                           "public class Test {\n" +
 134.728 -                           "    public @Override void t() {\n" +
 134.729 -                           "    }\n" +
 134.730 -                           "}\n",
 134.731 -                           "$mods$ public @Override $ret $name() { $body$; } => $mods$ private @Deprecated $ret $name() { $body$; }",
 134.732 -                           "package test;\n" +
 134.733 -                           "import java.io.InputStream;\n" +
 134.734 -                           "public class Test {\n" +
 134.735 -                           "    private @Deprecated void t() {\n" +
 134.736 -                           "    }\n" +
 134.737 -		           "}\n");
 134.738 -    }
 134.739 -    
 134.740 -    public void testKeepInModifiers() throws Exception {
 134.741 -        performRewriteTest("package test;\n" +
 134.742 -                           "import java.io.InputStream;\n" +
 134.743 -                           "public class Test {\n" +
 134.744 -                           "    public @Override void t() {\n" +
 134.745 -                           "    }\n" +
 134.746 -                           "}\n",
 134.747 -                           "$mods$ public @Override $ret $name() { $body$; } => $mods$ public @Override $ret $name() { $body$; }",
 134.748 -                           "package test;\n" +
 134.749 -                           "import java.io.InputStream;\n" +
 134.750 -                           "public class Test {\n" +
 134.751 -                           "    public @Override void t() {\n" +
 134.752 -                           "    }\n" +
 134.753 -		           "}\n");
 134.754 -    }
 134.755 -    
 134.756 -    public void testRemoveInModifiers() throws Exception {
 134.757 -        performRewriteTest("package test;\n" +
 134.758 -                           "import java.io.InputStream;\n" +
 134.759 -                           "public class Test {\n" +
 134.760 -                           "    public static @Deprecated @Override void t() {\n" +
 134.761 -                           "    }\n" +
 134.762 -                           "}\n",
 134.763 -                           "$mods$ public @Override $ret $name() { $body$; } => $mods$ $ret $name() { $body$; }",
 134.764 -                           "package test;\n" +
 134.765 -                           "import java.io.InputStream;\n" +
 134.766 -                           "public class Test {\n" +
 134.767 -                           "    static @Deprecated void t() {\n" +
 134.768 -                           "    }\n" +
 134.769 -		           "}\n");
 134.770 -    }
 134.771 -    
 134.772 -    public void testRewriteMethodParametersWildcard() throws Exception {
 134.773 -        performRewriteTest("package test;\n" +
 134.774 -                           "import java.io.InputStream;\n" +
 134.775 -                           "public class Test {\n" +
 134.776 -                           "    public static void t() {\n" +
 134.777 -                           "    }\n" +
 134.778 -                           "}\n",
 134.779 -                           "$mods$ void $name($args$) { $body$; } => $mods$ int $name($args$) { $body$; }",
 134.780 -                           "package test;\n" +
 134.781 -                           "import java.io.InputStream;\n" +
 134.782 -                           "public class Test {\n" +
 134.783 -                           "    public static int t() {\n" +
 134.784 -                           "    }\n" +
 134.785 -		           "}\n");
 134.786 -    }
 134.787 -    
 134.788 -    public void testRewriteClass() throws Exception {
 134.789 -        performRewriteTest("package test;\n" +
 134.790 -                           "public class Test {\n" +
 134.791 -                           "}\n",
 134.792 -                           "$mods$ class $name<$tp$> extends $e$ implements $i$ { $members$; } => $mods$ @java.lang.Deprecated class $name<$tp$> extends $e$ implements $i$ { $members$; }",
 134.793 -                           "package test;\n" +
 134.794 -                           "@Deprecated\n" +
 134.795 -                           "public class Test {\n" +
 134.796 -		           "}\n");
 134.797 -    }
 134.798 -    
 134.799 -    public void testOptionalVariableInitializer1() throws Exception {
 134.800 -        performRewriteTest("package test;\n" +
 134.801 -                           "public class Test {\n" +
 134.802 -                           "    private int I;\n" +
 134.803 -                           "}\n",
 134.804 -                           "$mods$ int $name = $init$; => $mods$ long $name = $init$;",
 134.805 -                           "package test;\n" +
 134.806 -                           "public class Test {\n" +
 134.807 -                           "    private long I;\n" +
 134.808 -		           "}\n");
 134.809 -    }
 134.810 -    
 134.811 -    public void testOptionalVariableInitializer2() throws Exception {
 134.812 -        performRewriteTest("package test;\n" +
 134.813 -                           "public class Test {\n" +
 134.814 -                           "    private int I = 1;\n" +
 134.815 -                           "}\n",
 134.816 -                           "$mods$ int $name = $init$; => $mods$ long $name = $init$;",
 134.817 -                           "package test;\n" +
 134.818 -                           "public class Test {\n" +
 134.819 -                           "    private long I = 1;\n" +
 134.820 -		           "}\n");
 134.821 -    }
 134.822 -    
 134.823 -    public void testOptionalElse1() throws Exception {
 134.824 -        performRewriteTest("package test;\n" +
 134.825 -                           "public class Test {\n" +
 134.826 -                           "    {\n" +
 134.827 -                           "        if (true) System.err.println(\"a\");\n" +
 134.828 -                           "    }\n" +
 134.829 -                           "}\n",
 134.830 -                           "if (true) $then else $else$; => if (false) $then else $else$;",
 134.831 -                           "package test;\n" +
 134.832 -                           "public class Test {\n" +
 134.833 -                           "    {\n" +
 134.834 -                           "        if (false) System.err.println(\"a\");\n" +
 134.835 -                           "    }\n" +
 134.836 -		           "}\n");
 134.837 -    }
 134.838 -    
 134.839 -    public void testOptionalElse2() throws Exception {
 134.840 -        performRewriteTest("package test;\n" +
 134.841 -                           "public class Test {\n" +
 134.842 -                           "    {\n" +
 134.843 -                           "        if (true) System.err.println(\"a\");\n" +
 134.844 -                           "        else System.err.println(\"b\");\n" +
 134.845 -                           "    }\n" +
 134.846 -                           "}\n",
 134.847 -                           "if (true) $then else $else$; => if (false) $then else $else$;",
 134.848 -                           "package test;\n" +
 134.849 -                           "public class Test {\n" +
 134.850 -                           "    {\n" +
 134.851 -                           "        if (false) System.err.println(\"a\");\n" +
 134.852 -                           "        else System.err.println(\"b\");\n" +
 134.853 -                           "    }\n" +
 134.854 -		           "}\n");
 134.855 -    }
 134.856 -    
 134.857 -    public void testMultiNewArray() throws Exception {
 134.858 -        performRewriteTest("package test;\n" +
 134.859 -                           "public class Test {\n" +
 134.860 -                           "    private static void t(Object... obj) {\n" +
 134.861 -                           "        Test.t(1);\n" +
 134.862 -                           "    }\n" +
 134.863 -                           "}\n",
 134.864 -                           "test.Test.t($args$) => test.Test.t(new Object[] {$args$})",
 134.865 -                           "package test;\n" +
 134.866 -                           "public class Test {\n" +
 134.867 -                           "    private static void t(Object... obj) {\n" +
 134.868 -                           "        Test.t(new Object[]{1});\n" +
 134.869 -                           "    }\n" +
 134.870 -		           "}\n");
 134.871 -    }
 134.872 -
 134.873 -    public void testFakeBlock2FakeBlock191283() throws Exception {
 134.874 -        performRewriteTest("package test;\n" +
 134.875 -                           "import java.io.InputStream;\n" +
 134.876 -                           "public class Test {\n" +
 134.877 -                           "    private void t() throws Exception {\n" +
 134.878 -                           "        System.err.println(1);\n" +
 134.879 -                           "        lock();\n" +
 134.880 -                           "        System.err.println(2);\n" +
 134.881 -                           "        unlock();\n" +
 134.882 -                           "        System.err.println(3);\n" +
 134.883 -                           "    }\n" +
 134.884 -                           "    private static void lock() {}\n" +
 134.885 -                           "    private static void unlock() {}\n" +
 134.886 -                           "}\n",
 134.887 -                           "test.Test.lock(); $i$; test.Test.unlock(); => lock(); try { $i$; } finally { unlock(); }",
 134.888 -                           "package test;\n" +
 134.889 -                           "import java.io.InputStream;\n" +
 134.890 -                           "public class Test {\n" +
 134.891 -                           "    private void t() throws Exception {\n" +
 134.892 -                           "        System.err.println(1);\n" +
 134.893 -                           "        lock();\n" +
 134.894 -                           "        try {\n" +
 134.895 -                           "            System.err.println(2);\n" +
 134.896 -                           "        } finally {\n" +
 134.897 -                           "            unlock();\n" +
 134.898 -                           "        }\n" +
 134.899 -                           "        System.err.println(3);\n" +
 134.900 -                           "    }\n" +
 134.901 -                           "    private static void lock() {}\n" +
 134.902 -                           "    private static void unlock() {}\n" +
 134.903 -		           "}\n");
 134.904 -    }
 134.905 -    
 134.906 -    public void testOptimizeNegExpression() throws Exception {
 134.907 -        performRewriteTest("package test;\n" +
 134.908 -                           "public class Test {\n" +
 134.909 -                           "    private static void t(int i) {\n" +
 134.910 -                           "        if (i == 0) {\n" +
 134.911 -                           "            System.err.println(1);\n" +
 134.912 -                           "        } else {\n" +
 134.913 -                           "            System.err.println(2);\n" +
 134.914 -                           "        }\n" +
 134.915 -                           "    }\n" +
 134.916 -                           "}\n",
 134.917 -                           "if ($cond) $then; else $else; => if (!$cond) $else; else $then;",
 134.918 -                           "package test;\n" +
 134.919 -                           "public class Test {\n" +
 134.920 -                           "    private static void t(int i) {\n" +
 134.921 -                           "        if (i != 0) {\n" +
 134.922 -                           "            System.err.println(2);\n" +
 134.923 -                           "        } else {\n" +
 134.924 -                           "            System.err.println(1);\n" +
 134.925 -                           "        }\n" +
 134.926 -                           "    }\n" +
 134.927 -		           "}\n");
 134.928 -    }
 134.929 -    
 134.930 -    public void testDontOptimizeNegExpression() throws Exception {
 134.931 -        performRewriteTest("package test;\n" +
 134.932 -                           "public class Test {\n" +
 134.933 -                           "    private static void t(int i) {\n" +
 134.934 -                           "        if (!(i == 0)) {\n" +
 134.935 -                           "            System.err.println(1);\n" +
 134.936 -                           "        } else {\n" +
 134.937 -                           "            System.err.println(2);\n" +
 134.938 -                           "        }\n" +
 134.939 -                           "    }\n" +
 134.940 -                           "}\n",
 134.941 -                           "if (!$cond) $then; else $else; => if (!$cond) $else; else $then;",
 134.942 -                           "package test;\n" +
 134.943 -                           "public class Test {\n" +
 134.944 -                           "    private static void t(int i) {\n" +
 134.945 -                           "        if (!(i == 0)) {\n" +
 134.946 -                           "            System.err.println(2);\n" +
 134.947 -                           "        } else {\n" +
 134.948 -                           "            System.err.println(1);\n" +
 134.949 -                           "        }\n" +
 134.950 -                           "    }\n" +
 134.951 -		           "}\n");
 134.952 -    }
 134.953 -    
 134.954 -    public void testCannotOptimizeNegExpression() throws Exception {
 134.955 -        performRewriteTest("package test;\n" +
 134.956 -                           "public class Test {\n" +
 134.957 -                           "    private static void t(String str) {\n" +
 134.958 -                           "        if (str.isEmpty()) {\n" +
 134.959 -                           "            System.err.println(1);\n" +
 134.960 -                           "        } else {\n" +
 134.961 -                           "            System.err.println(2);\n" +
 134.962 -                           "        }\n" +
 134.963 -                           "    }\n" +
 134.964 -                           "}\n",
 134.965 -                           "if ($cond) $then; else $else; => if (!$cond) $else; else $then;",
 134.966 -                           "package test;\n" +
 134.967 -                           "public class Test {\n" +
 134.968 -                           "    private static void t(String str) {\n" +
 134.969 -                           "        if (!str.isEmpty()) {\n" +
 134.970 -                           "            System.err.println(2);\n" +
 134.971 -                           "        } else {\n" +
 134.972 -                           "            System.err.println(1);\n" +
 134.973 -                           "        }\n" +
 134.974 -                           "    }\n" +
 134.975 -		           "}\n");
 134.976 -    }
 134.977 -    
 134.978 -    public void testOptimizeNegExpressionNeg() throws Exception {
 134.979 -        performOptimizeNegExpressionTest("!s.isEmpty()", "s.isEmpty()");
 134.980 -    }
 134.981 -    
 134.982 -    public void testOptimizeNegExpressionParens() throws Exception {
 134.983 -        performOptimizeNegExpressionTest("!(a.length == 0)", "a.length == 0");
 134.984 -    }
 134.985 -    
 134.986 -    public void testOptimizeNegExpressionEquals() throws Exception {
 134.987 -        performOptimizeNegExpressionTest("i == 0", "i != 0");
 134.988 -    }
 134.989 -    
 134.990 -    public void testOptimizeNegExpressionNotEquals() throws Exception {
 134.991 -        performOptimizeNegExpressionTest("i != 0", "i == 0");
 134.992 -    }
 134.993 -    
 134.994 -    public void testOptimizeNegExpressionTrue() throws Exception {
 134.995 -        performOptimizeNegExpressionTest("true", "false");
 134.996 -    }
 134.997 -    
 134.998 -    public void testOptimizeNegExpressionFalse() throws Exception {
 134.999 -        performOptimizeNegExpressionTest("false", "true");
134.1000 -    }
134.1001 -    
134.1002 -    public void testOptimizeNegExpressionDeMorganAnd() throws Exception {
134.1003 -        performOptimizeNegExpressionTest("a.length != 0 && true", "a.length == 0 || false");
134.1004 -    }
134.1005 -    
134.1006 -    public void testOptimizeNegExpressionDeMorganOr() throws Exception {
134.1007 -        performOptimizeNegExpressionTest("args.length != 0 || false", "args.length == 0 && true");
134.1008 -    }
134.1009 -    
134.1010 -    public void testOptimizeNegExpressionLess() throws Exception {
134.1011 -        performOptimizeNegExpressionTest("i < 0", "i >= 0");
134.1012 -    }
134.1013 -    
134.1014 -    public void testOptimizeNegExpressionLessEq() throws Exception {
134.1015 -        performOptimizeNegExpressionTest("i <= 0", "i > 0");
134.1016 -    }
134.1017 -    
134.1018 -    public void testOptimizeNegExpressionGreater() throws Exception {
134.1019 -        performOptimizeNegExpressionTest("i > 0", "i <= 0");
134.1020 -    }
134.1021 -    
134.1022 -    public void testOptimizeNegExpressionGreaterEq() throws Exception {
134.1023 -        performOptimizeNegExpressionTest("i >= 0", "i < 0");
134.1024 -    }
134.1025 -    
134.1026 -    public void testOptimizeNegExpressionAnd() throws Exception {
134.1027 -        performOptimizeNegExpressionTest("b1 && b2", "!b1 || !b2");
134.1028 -    }
134.1029 -    
134.1030 -    public void test229785a() throws Exception {
134.1031 -        performOptimizeNegExpressionTest("(a[0] == null && a[1] != null) || (a[0] != null && !a[0].equals(a[1]))", "(a[0] != null || a[1] == null) && (a[0] == null || a[0].equals(a[1]))");
134.1032 -    }
134.1033 -    
134.1034 -    public void test229785b() throws Exception {
134.1035 -        performOptimizeNegExpressionTest("a[0] == null && a[1] != null || a[0] != null && !a[0].equals(a[1])", "(a[0] != null || a[1] == null) && (a[0] == null || a[0].equals(a[1]))");
134.1036 -    }
134.1037 -    
134.1038 -    private void performOptimizeNegExpressionTest(String origExpr, String newExpr) throws Exception {
134.1039 -        performRewriteTest("package test;\n" +
134.1040 -                           "public class Test {\n" +
134.1041 -                           "    private static void t(String s, int i, boolean b1, boolean b2, String... a) {\n" +
134.1042 -                           "        if (" + origExpr + ") {\n" +
134.1043 -                           "            System.err.println(1);\n" +
134.1044 -                           "        } else {\n" +
134.1045 -                           "            System.err.println(2);\n" +
134.1046 -                           "        }\n" +
134.1047 -                           "    }\n" +
134.1048 -                           "}\n",
134.1049 -                           "if ($cond) $then; else $else; => if (!$cond) $else; else $then;",
134.1050 -                           "package test;\n" +
134.1051 -                           "public class Test {\n" +
134.1052 -                           "    private static void t(String s, int i, boolean b1, boolean b2, String... a) {\n" +
134.1053 -                           "        if (" + newExpr + ") {\n" +
134.1054 -                           "            System.err.println(2);\n" +
134.1055 -                           "        } else {\n" +
134.1056 -                           "            System.err.println(1);\n" +
134.1057 -                           "        }\n" +
134.1058 -                           "    }\n" +
134.1059 -		           "}\n");
134.1060 -    }
134.1061 -    
134.1062 -    public void testExpression2ExpressionStatementTolerance227429() throws Exception {
134.1063 -        performRewriteTest("package test;\n" +
134.1064 -                           "public class Test {\n" +
134.1065 -                           "    private static void t() {\n" +
134.1066 -                           "        System.err.println(1);\n" +
134.1067 -                           "    }\n" +
134.1068 -                           "}\n",
134.1069 -                           "java.lang.System.err.println($args$) => java.lang.System.out.println($args$);",
134.1070 -                           "package test;\n" +
134.1071 -                           "public class Test {\n" +
134.1072 -                           "    private static void t() {\n" +
134.1073 -                           "        System.out.println(1);\n" +
134.1074 -                           "    }\n" +
134.1075 -		           "}\n");
134.1076 -    }
134.1077 -    
134.1078 -    public void testSplitIfOr() throws Exception {
134.1079 -        performRewriteTest("package test;\n" +
134.1080 -                           "public class Test {\n" +
134.1081 -                           "    private static void t(int i) {\n" +
134.1082 -                           "        if (i == 0 || i == 1) {\n" +
134.1083 -                           "            System.err.println();\n" +
134.1084 -                           "        }\n" +
134.1085 -                           "    }\n" +
134.1086 -                           "}\n",
134.1087 -                           "if ($cond1 || $cond2) $then; => if ($cond1) $then; else if ($cond2) $then;",
134.1088 -                           "package test;\n" +
134.1089 -                           "public class Test {\n" +
134.1090 -                           "    private static void t(int i) {\n" +
134.1091 -                           "        if (i == 0) {\n" +
134.1092 -                           "            System.err.println();\n" +
134.1093 -                           "        } else if (i == 1) {\n" +
134.1094 -                           "            System.err.println();\n" +
134.1095 -                           "        }\n" +
134.1096 -                           "    }\n" +
134.1097 -		           "}\n");
134.1098 -    }
134.1099 -    
134.1100 -    public void testLambdaExpr2Block() throws Exception {
134.1101 -        performRewriteTest("package test;\n" +
134.1102 -                           "import java.util.*;\n" +
134.1103 -                           "public class Test {\n" +
134.1104 -                           "    public void main(List<String> list) {\n" +
134.1105 -                           "        Collections.sort(list, (l, r) -> l.compareTo(r));\n" +
134.1106 -                           "    }\n" +
134.1107 -                           "}\n",
134.1108 -                           "($args$) -> $expr => ($args$) -> { return $expr; }",
134.1109 -                           "package test;\n" +
134.1110 -                           "import java.util.*;\n" +
134.1111 -                           "public class Test {\n" +
134.1112 -                           "    public void main(List<String> list) {\n" +
134.1113 -                           "        Collections.sort(list, (l, r) -> {\n" +
134.1114 -                           "            return l.compareTo(r);\n" +
134.1115 -                           "        });\n" +
134.1116 -                           "    }\n" +
134.1117 -		           "}\n");
134.1118 -    }
134.1119 -    
134.1120 -    public void performRewriteTest(String code, String rule, String golden) throws Exception {
134.1121 -	prepareTest("test/Test.java", code);
134.1122 -
134.1123 -        final String[] split = rule.split("=>");
134.1124 -        assertEquals(2, split.length);
134.1125 -        Map<String, TypeMirror> variablesToTypesTM = new HashMap<String, TypeMirror>();
134.1126 -        String plainRule = PatternCompilerUtilities.parseOutTypesFromPattern(info, split[0], variablesToTypesTM);
134.1127 -        Map<String, String> variablesToTypes = new HashMap<String, String>();
134.1128 -        for (Entry<String, TypeMirror> e : variablesToTypesTM.entrySet()) {
134.1129 -            if (e.getValue() == null) continue;
134.1130 -            variablesToTypes.put(e.getKey(), e.getValue().toString());
134.1131 -        }
134.1132 -        HintDescription hd = HintDescriptionFactory.create()
134.1133 -                                                   .setTrigger(PatternDescription.create(plainRule, variablesToTypes))
134.1134 -                                                   .setWorker(new HintDescription.Worker() {
134.1135 -            @Override public Collection<? extends ErrorDescription> createErrors(HintContext ctx) {
134.1136 -                return Collections.singletonList(ErrorDescriptionFactory.forName(ctx, ctx.getPath(), "", JavaFixUtilities.rewriteFix(ctx, "", ctx.getPath(), split[1])));
134.1137 -            }
134.1138 -        }).produce();
134.1139 -
134.1140 -        List<ErrorDescription> computeHints = new HintsInvoker(HintsSettings.getGlobalSettings(), new AtomicBoolean()).computeHints(info, Collections.singleton(hd));
134.1141 -
134.1142 -        assertEquals(computeHints.toString(), 1, computeHints.size());
134.1143 -
134.1144 -        Fix fix = computeHints.get(0).getFixes().getFixes().get(0);
134.1145 -
134.1146 -	fix.implement();
134.1147 -
134.1148 -        assertEquals(golden, doc.getText(0, doc.getLength()));
134.1149 -    }
134.1150 -
134.1151 -    public void performRemoveFromParentTest(String code, String rule, String golden) throws Exception {
134.1152 -	prepareTest("test/Test.java", code);
134.1153 -
134.1154 -        HintDescription hd = HintDescriptionFactory.create()
134.1155 -                                                   .setTrigger(PatternDescription.create(rule, Collections.<String, String>emptyMap()))
134.1156 -                                                   .setWorker(new HintDescription.Worker() {
134.1157 -            @Override public Collection<? extends ErrorDescription> createErrors(HintContext ctx) {
134.1158 -                return Collections.singletonList(ErrorDescriptionFactory.forName(ctx, ctx.getPath(), "", JavaFixUtilities.removeFromParent(ctx, "", ctx.getPath())));
134.1159 -            }
134.1160 -        }).produce();
134.1161 -
134.1162 -        List<ErrorDescription> computeHints = new HintsInvoker(HintsSettings.getGlobalSettings(), new AtomicBoolean()).computeHints(info, Collections.singleton(hd));
134.1163 -
134.1164 -        assertEquals(computeHints.toString(), 1, computeHints.size());
134.1165 -
134.1166 -        Fix fix = computeHints.get(0).getFixes().getFixes().get(0);
134.1167 -
134.1168 -	fix.implement();
134.1169 -
134.1170 -        assertEquals(golden, doc.getText(0, doc.getLength()));
134.1171 -    }
134.1172 -}
   135.1 --- a/java.hints/spi.java.hints/test/unit/src/org/netbeans/spi/java/hints/MatcherUtilitiesTest.java	Sun Oct 16 08:01:27 2016 +0200
   135.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   135.3 @@ -1,113 +0,0 @@
   135.4 -/*
   135.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   135.6 - *
   135.7 - * Copyright 2009-2010 Oracle and/or its affiliates. All rights reserved.
   135.8 - *
   135.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  135.10 - * Other names may be trademarks of their respective owners.
  135.11 - *
  135.12 - * The contents of this file are subject to the terms of either the GNU
  135.13 - * General Public License Version 2 only ("GPL") or the Common
  135.14 - * Development and Distribution License("CDDL") (collectively, the
  135.15 - * "License"). You may not use this file except in compliance with the
  135.16 - * License. You can obtain a copy of the License at
  135.17 - * http://www.netbeans.org/cddl-gplv2.html
  135.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  135.19 - * specific language governing permissions and limitations under the
  135.20 - * License.  When distributing the software, include this License Header
  135.21 - * Notice in each file and include the License file at
  135.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  135.23 - * particular file as subject to the "Classpath" exception as provided
  135.24 - * by Oracle in the GPL Version 2 section of the License file that
  135.25 - * accompanied this code. If applicable, add the following below the
  135.26 - * License Header, with the fields enclosed by brackets [] replaced by
  135.27 - * your own identifying information:
  135.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  135.29 - *
  135.30 - * If you wish your version of this file to be governed by only the CDDL
  135.31 - * or only the GPL Version 2, indicate your decision by adding
  135.32 - * "[Contributor] elects to include this software in this distribution
  135.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  135.34 - * single choice of license, a recipient has the option to distribute
  135.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  135.36 - * to extend the choice of license to its licensees as provided above.
  135.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  135.38 - * Version 2 license, then the option applies only if the new code is
  135.39 - * made subject to such option by the copyright holder.
  135.40 - *
  135.41 - * Contributor(s):
  135.42 - *
  135.43 - * Portions Copyrighted 2009-2010 Sun Microsystems, Inc.
  135.44 - */
  135.45 -
  135.46 -package org.netbeans.spi.java.hints;
  135.47 -
  135.48 -import com.sun.source.util.TreePath;
  135.49 -import java.util.Collection;
  135.50 -import java.util.Collections;
  135.51 -import java.util.HashMap;
  135.52 -import java.util.Map;
  135.53 -import java.util.regex.Pattern;
  135.54 -import org.netbeans.modules.java.hints.spiimpl.SPIAccessor;
  135.55 -import org.netbeans.modules.java.hints.spiimpl.TestBase;
  135.56 -import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings;
  135.57 -
  135.58 -/**
  135.59 - *
  135.60 - * @author lahvac
  135.61 - */
  135.62 -public class MatcherUtilitiesTest extends TestBase {
  135.63 -
  135.64 -    public MatcherUtilitiesTest(String name) {
  135.65 -        super(name);
  135.66 -    }
  135.67 -
  135.68 -    public void testParentMatches1() throws Exception {
  135.69 -        String code = "package test; public class Test { private int test() { int i = 0; i = test(|); } }";
  135.70 -        int pos = code.indexOf("|");
  135.71 -
  135.72 -        code = code.replaceAll(Pattern.quote("|"), "");
  135.73 -
  135.74 -        prepareTest("test/Test.java", code);
  135.75 -
  135.76 -        TreePath tp = info.getTreeUtilities().pathFor(pos);
  135.77 -        HintContext ctx = SPIAccessor.getINSTANCE().createHintContext(info, HintsSettings.getGlobalSettings(), null, null, tp, Collections.<String, TreePath>emptyMap(), Collections.<String, Collection<? extends TreePath>>emptyMap(), Collections.<String, String>emptyMap());
  135.78 -
  135.79 -        assertTrue(MatcherUtilities.matches(ctx, ctx.getPath().getParentPath(), "$0 = $_"));
  135.80 -    }
  135.81 -
  135.82 -    public void testParentMatches2() throws Exception {
  135.83 -        String code = "package test; public class Test { private int test() { int i = test(|); } }";
  135.84 -        int pos = code.indexOf("|");
  135.85 -
  135.86 -        code = code.replaceAll(Pattern.quote("|"), "");
  135.87 -
  135.88 -        prepareTest("test/Test.java", code);
  135.89 -
  135.90 -        TreePath tp = info.getTreeUtilities().pathFor(pos);
  135.91 -        HintContext ctx = SPIAccessor.getINSTANCE().createHintContext(info, HintsSettings.getGlobalSettings(), null, null, tp, Collections.<String, TreePath>emptyMap(), Collections.<String, Collection<? extends TreePath>>emptyMap(), Collections.<String, String>emptyMap());
  135.92 -
  135.93 -        assertTrue(MatcherUtilities.matches(ctx, ctx.getPath().getParentPath(), "$1 $0 = $_;"));
  135.94 -    }
  135.95 -
  135.96 -    public void testOutVariables1() throws Exception {
  135.97 -        String code = "package test; public class Test { private int test() { int i = test(|); } }";
  135.98 -        int pos = code.indexOf("|");
  135.99 -
 135.100 -        code = code.replaceAll(Pattern.quote("|"), "");
 135.101 -
 135.102 -        prepareTest("test/Test.java", code);
 135.103 -
 135.104 -        TreePath tp = info.getTreeUtilities().pathFor(pos);
 135.105 -        HintContext ctx = SPIAccessor.getINSTANCE().createHintContext(info, HintsSettings.getGlobalSettings(), null, null, tp, Collections.<String, TreePath>emptyMap(), Collections.<String, Collection<? extends TreePath>>emptyMap(), Collections.<String, String>emptyMap());
 135.106 -
 135.107 -        Map<String, TreePath> outVariables = new HashMap<String, TreePath>();
 135.108 -        Map<String, Collection<? extends TreePath>> outMultiVariables = new HashMap<String, Collection<? extends TreePath>>();
 135.109 -        Map<String, String> outVariables2Names = new HashMap<String, String>();
 135.110 -
 135.111 -        assertTrue(MatcherUtilities.matches(ctx, ctx.getPath().getParentPath(), "$1 $0 = $_;", outVariables, outMultiVariables, outVariables2Names));
 135.112 -        assertEquals("int", outVariables.get("$1").getLeaf().toString());
 135.113 -        assertEquals("i", outVariables2Names.get("$0"));
 135.114 -    }
 135.115 -
 135.116 -}
 135.117 \ No newline at end of file
   136.1 --- a/java.hints/spi.java.hints/test/unit/src/org/netbeans/spi/java/hints/TestUtils.java	Sun Oct 16 08:01:27 2016 +0200
   136.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   136.3 @@ -1,69 +0,0 @@
   136.4 -/*
   136.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   136.6 - *
   136.7 - * Copyright 2015 Oracle and/or its affiliates. All rights reserved.
   136.8 - *
   136.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  136.10 - * Other names may be trademarks of their respective owners.
  136.11 - *
  136.12 - * The contents of this file are subject to the terms of either the GNU
  136.13 - * General Public License Version 2 only ("GPL") or the Common
  136.14 - * Development and Distribution License("CDDL") (collectively, the
  136.15 - * "License"). You may not use this file except in compliance with the
  136.16 - * License. You can obtain a copy of the License at
  136.17 - * http://www.netbeans.org/cddl-gplv2.html
  136.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  136.19 - * specific language governing permissions and limitations under the
  136.20 - * License.  When distributing the software, include this License Header
  136.21 - * Notice in each file and include the License file at
  136.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  136.23 - * particular file as subject to the "Classpath" exception as provided
  136.24 - * by Oracle in the GPL Version 2 section of the License file that
  136.25 - * accompanied this code. If applicable, add the following below the
  136.26 - * License Header, with the fields enclosed by brackets [] replaced by
  136.27 - * your own identifying information:
  136.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  136.29 - *
  136.30 - * If you wish your version of this file to be governed by only the CDDL
  136.31 - * or only the GPL Version 2, indicate your decision by adding
  136.32 - * "[Contributor] elects to include this software in this distribution
  136.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  136.34 - * single choice of license, a recipient has the option to distribute
  136.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  136.36 - * to extend the choice of license to its licensees as provided above.
  136.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  136.38 - * Version 2 license, then the option applies only if the new code is
  136.39 - * made subject to such option by the copyright holder.
  136.40 - *
  136.41 - * Contributor(s):
  136.42 - *
  136.43 - * Portions Copyrighted 2015 Sun Microsystems, Inc.
  136.44 - */
  136.45 -package org.netbeans.spi.java.hints;
  136.46 -
  136.47 -import org.netbeans.api.editor.mimelookup.MimePath;
  136.48 -import org.netbeans.modules.editor.impl.DocumentFactoryImpl;
  136.49 -import org.netbeans.spi.editor.mimelookup.MimeDataProvider;
  136.50 -import org.openide.util.Lookup;
  136.51 -import org.openide.util.lookup.Lookups;
  136.52 -import org.openide.util.lookup.ServiceProvider;
  136.53 -
  136.54 -/**
  136.55 - *
  136.56 - * @author lahvac
  136.57 - */
  136.58 -public class TestUtils {
  136.59 -
  136.60 -    @ServiceProvider(service = MimeDataProvider.class)
  136.61 -    public static final class MimeDataProviderImpl implements MimeDataProvider {
  136.62 -
  136.63 -        private final Lookup l = Lookups.singleton(new DocumentFactoryImpl());
  136.64 -
  136.65 -        @Override
  136.66 -        public Lookup getLookup(MimePath mimePath) {
  136.67 -            return "text/x-java".equals(mimePath.getPath()) ? l : Lookup.EMPTY;
  136.68 -        }
  136.69 -
  136.70 -    }
  136.71 -
  136.72 -}
   137.1 --- a/java.hints/spi.java.hints/test/unit/src/org/netbeans/spi/java/hints/matching/CopyFinderTest.java	Sun Oct 16 08:01:27 2016 +0200
   137.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   137.3 @@ -1,1612 +0,0 @@
   137.4 -/*
   137.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   137.6 - *
   137.7 - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
   137.8 - *
   137.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  137.10 - * Other names may be trademarks of their respective owners.
  137.11 - *
  137.12 - * The contents of this file are subject to the terms of either the GNU
  137.13 - * General Public License Version 2 only ("GPL") or the Common
  137.14 - * Development and Distribution License("CDDL") (collectively, the
  137.15 - * "License"). You may not use this file except in compliance with the
  137.16 - * License. You can obtain a copy of the License at
  137.17 - * http://www.netbeans.org/cddl-gplv2.html
  137.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  137.19 - * specific language governing permissions and limitations under the
  137.20 - * License.  When distributing the software, include this License Header
  137.21 - * Notice in each file and include the License file at
  137.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  137.23 - * particular file as subject to the "Classpath" exception as provided
  137.24 - * by Oracle in the GPL Version 2 section of the License file that
  137.25 - * accompanied this code. If applicable, add the following below the
  137.26 - * License Header, with the fields enclosed by brackets [] replaced by
  137.27 - * your own identifying information:
  137.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  137.29 - *
  137.30 - * Contributor(s):
  137.31 - *
  137.32 - * Portions Copyrighted 2007-2010 Sun Microsystems, Inc.
  137.33 - */
  137.34 -package org.netbeans.spi.java.hints.matching;
  137.35 -
  137.36 -import com.sun.source.tree.BlockTree;
  137.37 -import com.sun.source.tree.StatementTree;
  137.38 -import com.sun.source.tree.Tree;
  137.39 -import com.sun.source.tree.VariableTree;
  137.40 -import com.sun.source.util.SourcePositions;
  137.41 -import com.sun.source.util.TreePath;
  137.42 -import com.sun.source.util.TreePathScanner;
  137.43 -import java.io.File;
  137.44 -import java.util.Arrays;
  137.45 -import java.util.Collection;
  137.46 -import java.util.Collections;
  137.47 -import java.util.EnumSet;
  137.48 -import java.util.HashMap;
  137.49 -import java.util.HashSet;
  137.50 -import java.util.LinkedList;
  137.51 -import java.util.List;
  137.52 -import java.util.Map;
  137.53 -import java.util.Map.Entry;
  137.54 -import java.util.Set;
  137.55 -import java.util.concurrent.atomic.AtomicBoolean;
  137.56 -import javax.lang.model.element.VariableElement;
  137.57 -import javax.lang.model.type.TypeMirror;
  137.58 -import javax.swing.text.Document;
  137.59 -import org.netbeans.api.java.lexer.JavaTokenId;
  137.60 -import org.netbeans.api.java.source.CompilationInfo;
  137.61 -import org.netbeans.api.java.source.JavaSource;
  137.62 -import org.netbeans.api.java.source.JavaSource.Phase;
  137.63 -import org.netbeans.api.java.source.SourceUtilsTestUtil;
  137.64 -import org.netbeans.api.java.source.TestUtilities;
  137.65 -import org.netbeans.api.java.source.TreePathHandle;
  137.66 -import org.netbeans.api.java.source.matching.MatchingTestAccessor;
  137.67 -import org.netbeans.api.java.source.matching.Pattern;
  137.68 -import org.netbeans.api.lexer.Language;
  137.69 -import org.netbeans.junit.NbTestCase;
  137.70 -import org.netbeans.modules.java.hints.introduce.IntroduceMethodFix;
  137.71 -import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch;
  137.72 -import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch.BulkPattern;
  137.73 -import org.netbeans.modules.java.hints.spiimpl.pm.PatternCompiler;
  137.74 -import org.netbeans.modules.java.hints.spiimpl.pm.PatternCompilerUtilities;
  137.75 -import org.netbeans.modules.java.source.matching.CopyFinder;
  137.76 -import org.netbeans.modules.java.source.matching.CopyFinder.Cancel;
  137.77 -import org.netbeans.modules.java.source.matching.CopyFinder.Options;
  137.78 -import org.netbeans.modules.java.source.matching.CopyFinder.VariableAssignments;
  137.79 -import org.openide.cookies.EditorCookie;
  137.80 -import org.openide.filesystems.FileObject;
  137.81 -import org.openide.filesystems.FileUtil;
  137.82 -import org.openide.loaders.DataObject;
  137.83 -
  137.84 -/**
  137.85 - *
  137.86 - * @author Jan Lahoda
  137.87 - */
  137.88 -public class CopyFinderTest extends NbTestCase {
  137.89 -
  137.90 -    public CopyFinderTest(String testName) {
  137.91 -        super(testName);
  137.92 -    }
  137.93 -
  137.94 -//    public static TestSuite suite() {
  137.95 -//        NbTestSuite nb = new NbTestSuite();
  137.96 -//
  137.97 -//        nb.addTest(new CopyFinderTest("testCorrectSite3"));
  137.98 -//
  137.99 -//        return nb;
 137.100 -//    }
 137.101 -
 137.102 -    @Override
 137.103 -    protected void setUp() throws Exception {
 137.104 -        SourceUtilsTestUtil.prepareTest(new String[0], new Object[0]);
 137.105 -        super.setUp();
 137.106 -    }
 137.107 -
 137.108 -    public void testSimple1() throws Exception {
 137.109 -        performTest("package test; public class Test {public void test() {int i = 0; y = i + i; y = i + i;}}", 90 - 22, 95 - 22, 101 - 22, 106 - 22);
 137.110 -    }
 137.111 -
 137.112 -//    public void testSimple2() throws Exception {
 137.113 -//        performTest("package test; public class Test {public void test() {int i = 0; y = i + i; y = i + i + i;}}", 90 - 22, 95 - 22, 101 - 22, 106 - 22);
 137.114 -//    }
 137.115 -
 137.116 -    public void testSimple3() throws Exception {
 137.117 -        performTest("package test; public class Test {public void test() {int i = System.currentTimeMillis(); y = System.currentTimeMillis();}}", 83 - 22, 109 - 22, 115 - 22, 141 - 22);
 137.118 -    }
 137.119 -
 137.120 -    public void testSimple4() throws Exception {
 137.121 -        performTest("package test; import java.util.ArrayList; public class Test {public void test() {Object o = new ArrayList<String>();o = new ArrayList<String>();}}", 114 - 22, 137- 22, 142 - 22, 165 - 22);
 137.122 -    }
 137.123 -
 137.124 -    public void testSimple5() throws Exception {
 137.125 -        performTest("package test; public class Test {public void test() {Object o = null; String s = (String) o; s = (String) o; s = (String) null; o = (Object) o;}}", 103 - 22, 113 - 22, 119 - 22, 129 - 22);
 137.126 -    }
 137.127 -
 137.128 -    public void testSimple6() throws Exception {
 137.129 -        performTest("package test; public class Test {public void test() {int i = 0; y = i + i; y = i + i;} public void test2() {int i = 0; y = i + i; y = i + i;}}", 90 - 22, 95 - 22, 101 - 22, 106 - 22);
 137.130 -    }
 137.131 -
 137.132 -    public void testSimple7() throws Exception {
 137.133 -        performTest("package test; public class Test {public void test() {int i = 0; y = i != 0 ? i + i : i * i; y = i != 0 ? i + i : i * i; y = i != 1 ? i + i : i * i; y = i == 0 ? i + i : i * i; y = i != 0 ? i * i : i * i; y = i != 0 ? i + i : i + i; y = i != 0 ? i + i : i * 1;}}", 90 - 22, 112 - 22, 118 - 22, 140 - 22);
 137.134 -    }
 137.135 -
 137.136 -    public void testSimple8() throws Exception {
 137.137 -        performTest("package test; public class Test {public void test() {int i = 0; int y = -i; y = -i; y = +i; y = +y;}}", 94 - 22, 96 - 22, 102 - 22, 104 - 22);
 137.138 -    }
 137.139 -
 137.140 -    public void testSimple9() throws Exception {
 137.141 -        performTest("package test; public class Test {public void test() {int i = 0; int y = i *= 9; y = i *= 9; y = i /= 9; y = i *= 8; y = y *= 9;}}", 94 - 22, 100 - 22, 106 - 22, 112 - 22);
 137.142 -    }
 137.143 -
 137.144 -    public void testSimple10() throws Exception {
 137.145 -        performTest("package test; public class Test {public void test() {int[] i = null; int y = i[1]; y = i[1]; y = i[y]; y = i[0];}}", 99 - 22, 103 - 22, 109 - 22, 113 - 22);
 137.146 -    }
 137.147 -
 137.148 -    public void testSimple11() throws Exception {
 137.149 -        performTest("package test; public class Test {public void test() {int[] i = new int[0]; i = new int[0]; i = new int[1];}}", 85 - 22, 95 - 22, 101 - 22, 111 - 22);
 137.150 -    }
 137.151 -
 137.152 -    public void testSimple12() throws Exception {
 137.153 -        performTest("package test; public class Test {public void test() {int[] i = new int[1]; i = new int[1]; i = new int[0];}}", 85 - 22, 95 - 22, 101 - 22, 111 - 22);
 137.154 -    }
 137.155 -
 137.156 -    public void testSimple13() throws Exception {
 137.157 -        performTest("package test; public class Test {public void test() {int i = 0; int y = (i); y = (i); y = i;}}", 94 - 22, 97 - 22, 103 - 22, 106 - 22);
 137.158 -    }
 137.159 -
 137.160 -    public void testSimple14() throws Exception {
 137.161 -        performTest("package test; public class Test {public void test() {Object o = null; boolean b = o instanceof String; b = o instanceof String; b = o instanceof Object;}}", 104 - 22, 123 - 22, 129 - 22, 148 - 22);
 137.162 -    }
 137.163 -
 137.164 -    public void testSimple15() throws Exception {
 137.165 -        performTest("package test; public class Test {private int x = 1; private int y = 1; public void test() {int x = 1; int y = 1;}}", 90 - 22, 91 - 22, 71 - 22, 72 - 22, 121 - 22, 122 - 22, 132 - 22, 133 - 22);
 137.166 -    }
 137.167 -
 137.168 -    public void testSimple16() throws Exception {
 137.169 -        performTest("package test; public class Test {public void test(int i) {int y = \"\".length(); test(\"\".length());} }", 88 - 22, 99 - 22, 106 - 22, 117 - 22);
 137.170 -    }
 137.171 -
 137.172 -    public void testSimple17() throws Exception {
 137.173 -        performTest("package test; public class Test {public void test2() {int a = test(test(test(1))); a = test(test(test(1))); a = test(test(test(1)));} public int test(int i) {return 0;} }", 94 - 22, 101 - 22, 119 - 22, 126 - 22, 144 - 22, 151 - 22);
 137.174 -    }
 137.175 -
 137.176 -    public void testMemberSelectAndIdentifierAreSame() throws Exception {
 137.177 -        performTest("package test; import static java.lang.String.*; public class Test {public void test1() {|String.valueOf(2)|; |valueOf(2)|;} }");
 137.178 -    }
 137.179 -
 137.180 -    public void testVariables1() throws Exception {
 137.181 -        performVariablesTest("package test; import static java.lang.String.*; public class Test {public void test1() {String.valueOf(2+4);} }",
 137.182 -                             "java.lang.String.valueOf($1)",
 137.183 -                             new Pair[] {new Pair<String, int[]>("$1", new int[] {134 - 31, 137 - 31})},
 137.184 -                             new Pair[0]);
 137.185 -    }
 137.186 -
 137.187 -    public void testAssert1() throws Exception {
 137.188 -        performTest("package test; public class Test {public void test() {int i = 0; |assert i == 1;| |assert i == 1;|}}");
 137.189 -    }
 137.190 -
 137.191 -    public void testReturn1() throws Exception {
 137.192 -        performTest("package test; public class Test {public int test1() {|return 1;|} public int test2() {|return 1;|}}");
 137.193 -    }
 137.194 -
 137.195 -    public void testIf1() throws Exception {
 137.196 -        performTest("package test; public class Test {public void test() { int i = 0; int j; |if (i == 0) {j = 1;} else {j = 2;}| |if (i == 0) {j = 1;} else {j = 2;}| } }");
 137.197 -    }
 137.198 -
 137.199 -    public void testExpressionStatement1() throws Exception {
 137.200 -        performTest("package test; public class Test {public void test() { int i = 0; |i = 1;| |i = 1;| } }");
 137.201 -    }
 137.202 -
 137.203 -    public void testBlock1() throws Exception {
 137.204 -        performTest("package test; public class Test {public void test() { int i = 0; |{i = 1;}| |{i = 1;}| } }");
 137.205 -    }
 137.206 -
 137.207 -    public void testSynchronized1() throws Exception {
 137.208 -        performTest("package test; public class Test {public void test() { Object o = null; int i = 0; |synchronized (o) {i = 1;}| |synchronized (o) {i = 1;}| } }");
 137.209 -    }
 137.210 -
 137.211 -//    public void testEnhancedForLoop() throws Exception {
 137.212 -//        performTest("package test; public class Test {public void test(Iterable<String> i) { |for (String s : i) { System.err.println(); }| |for (String s : i) { System.err.println(); }| }");
 137.213 -//    }
 137.214 -
 137.215 -//    public void testConstants() throws Exception {
 137.216 -//        performTest("package test; public class Test {public static final int A = 3; public void test() { int i = |3|; i = |test.Test.A|; } }");
 137.217 -//    }
 137.218 -
 137.219 -    public void testOverridingImplementing1() throws Exception {
 137.220 -        performVariablesTest("package test; public class Test implements Runnable { { this.run(); } public void run() { } } }",
 137.221 -                             "$0{java.lang.Runnable}.run()",
 137.222 -                             new Pair[] {new Pair<String, int[]>("$0", new int[] {56, 60})},
 137.223 -                             new Pair[0]);
 137.224 -    }
 137.225 -
 137.226 -    public void testMemberSelectCCE() throws Exception {
 137.227 -        //should not throw a CCE
 137.228 -        //(selected regions are not duplicates)
 137.229 -        performTest("package test; public class Test {public static class T extends Test { public void test() { |Test.test|(); |System.err.println|(); } } }", false);
 137.230 -    }
 137.231 -
 137.232 -    public void testLocalVariable() throws Exception {
 137.233 -        performVariablesTest("package test; public class Test {public void test1() { { int y; y = 1; } int z; { int y; z = 1; } } }",
 137.234 -                             "{ int $1; $1 = 1; }",
 137.235 -                             new Pair[0],
 137.236 -                             new Pair[] {new Pair<String, String>("$1", "y")});
 137.237 -    }
 137.238 -
 137.239 -    public void testStatementAndSingleBlockStatementAreSame1() throws Exception {
 137.240 -        performVariablesTest("package test; public class Test {public void test1() { { int x; { x = 1; } } } }",
 137.241 -                             "{ int $1; $1 = 1; }",
 137.242 -                             new Pair[0],
 137.243 -                             new Pair[] {new Pair<String, String>("$1", "x")});
 137.244 -    }
 137.245 -
 137.246 -    public void testStatementAndSingleBlockStatementAreSame2() throws Exception {
 137.247 -        performVariablesTest("package test; public class Test {public void test1() { { int x; x = 1; } } }",
 137.248 -                             "{ int $1; { $1 = 1; } }",
 137.249 -                             new Pair[0],
 137.250 -                             new Pair[] {new Pair<String, String>("$1", "x")});
 137.251 -    }
 137.252 -
 137.253 -    public void testStatementVariables() throws Exception {
 137.254 -        performVariablesTest("package test; public class Test {public int test1() { if (true) return 1; else return 2; } }",
 137.255 -                             "if ($1) $2; else $3;",
 137.256 -                             new Pair[] {
 137.257 -                                  new Pair<String, int[]>("$1", new int[] {89 - 31, 93 - 31}),
 137.258 -                                  new Pair<String, int[]>("$2", new int[] {95 - 31, 104 - 31}),
 137.259 -                                  new Pair<String, int[]>("$3", new int[] {110 - 31, 119 - 31})
 137.260 -                             },
 137.261 -                             new Pair[0]);
 137.262 -    }
 137.263 -
 137.264 -    public void testThrowStatement() throws Exception {
 137.265 -        performVariablesTest("package test; public class Test {public void test() { throw new NullPointerException(); throw new IllegalStateException();} }",
 137.266 -                             "throw new NullPointerException()",
 137.267 -                             new Pair[0],
 137.268 -                             new Pair[0]);
 137.269 -    }
 137.270 -
 137.271 -    public void testMultiStatementVariables1() throws Exception {
 137.272 -        performVariablesTest("package test; public class Test { public int test1() { System.err.println(); System.err.println(); int i = 3; System.err.println(i); System.err.println(i); return i; } }",
 137.273 -                             "{ $s1$; int $i = 3; $s2$; return $i; }",
 137.274 -                             new Pair[0],
 137.275 -                             new Pair[] {
 137.276 -                                  new Pair<String, int[]>("$s1$", new int[] {55, 76, 77, 98}),
 137.277 -                                  new Pair<String, int[]>("$s2$", new int[] {110, 132, 133, 155})
 137.278 -                             },
 137.279 -                             new Pair[] {new Pair<String, String>("$i", "i")});
 137.280 -    }
 137.281 -
 137.282 -    public void testMultiStatementVariables2() throws Exception {
 137.283 -        performVariablesTest("package test; public class Test { public int test1() { int i = 3; return i; } }",
 137.284 -                             "{ $s1$; int $i = 3; $s2$; return $i; }",
 137.285 -                             new Pair[0],
 137.286 -                             new Pair[] {
 137.287 -                                  new Pair<String, int[]>("$s1$", new int[] {}),
 137.288 -                                  new Pair<String, int[]>("$s2$", new int[] {}),
 137.289 -                             },
 137.290 -                             new Pair[] {new Pair<String, String>("$i", "i")});
 137.291 -    }
 137.292 -
 137.293 -    public void testMultiStatementVariablesAndBlocks1() throws Exception {
 137.294 -        performVariablesTest("package test; public class Test { public void test1() { if (true) System.err.println(); } }",
 137.295 -                             "if ($c) {$s1$; System.err.println(); $s2$; }",
 137.296 -                             new Pair[] {new Pair<String, int[]>("$c", new int[] {60, 64})},
 137.297 -                             new Pair[] {
 137.298 -                                  new Pair<String, int[]>("$s1$", new int[] {}),
 137.299 -                                  new Pair<String, int[]>("$s2$", new int[] {}),
 137.300 -                             },
 137.301 -                             new Pair[0]);
 137.302 -    }
 137.303 -
 137.304 -    public void testMultiStatementVariablesAndBlocks2() throws Exception {
 137.305 -        performVariablesTest("package test; public class Test { public void test1() { if (true) System.err.println(); } }",
 137.306 -                             "if ($c) {$s1$; System.err.println(); }",
 137.307 -                             new Pair[] {new Pair<String, int[]>("$c", new int[] {60, 64})},
 137.308 -                             new Pair[] {
 137.309 -                                  new Pair<String, int[]>("$s1$", new int[] {}),
 137.310 -                             },
 137.311 -                             new Pair[0]);
 137.312 -    }
 137.313 -
 137.314 -    public void testMultiStatementVariablesAndBlocks3() throws Exception {
 137.315 -        performVariablesTest("package test; public class Test { public void test1() { if (true) System.err.println(); } }",
 137.316 -                             "if ($c) {System.err.println(); $s2$; }",
 137.317 -                             new Pair[] {new Pair<String, int[]>("$c", new int[] {60, 64})},
 137.318 -                             new Pair[] {
 137.319 -                                  new Pair<String, int[]>("$s2$", new int[] {}),
 137.320 -                             },
 137.321 -                             new Pair[0]);
 137.322 -    }
 137.323 -
 137.324 -    public void testMultiStatementVariablesAndBlocks4() throws Exception {
 137.325 -        performVariablesTest("package test; public class Test { public void test1() { if (true) System.err.println(); } }",
 137.326 -                             "if ($c) { $s$; }",
 137.327 -                             new Pair[] {new Pair<String, int[]>("$c", new int[] {60, 64})},
 137.328 -                             new Pair[] {
 137.329 -                                  new Pair<String, int[]>("$s$", new int[] {66, 87}),
 137.330 -                             },
 137.331 -                             new Pair[0]);
 137.332 -    }
 137.333 -
 137.334 -    public void testVariableVerification() throws Exception {
 137.335 -        performVariablesTest("package test; public class Test { public void test1(String[] a, String[] b) { for (int c = 0; c < a.length; c++) { String s = b[c]; System.err.println(s); } } }",
 137.336 -                             "for(int $i = 0; $i < $array.length; $i++) { $T $var = $array[$i]; $stmts$; }",
 137.337 -                             new Pair[0],
 137.338 -                             new Pair[0],
 137.339 -                             new Pair[0],
 137.340 -                             true);
 137.341 -    }
 137.342 -
 137.343 -    public void testFor() throws Exception {
 137.344 -        performVariablesTest("package test; public class Test { public void test1(String[] a) { for (int c = 0; c < a.length; c++) { String s = a[c]; System.err.println(s); } } }",
 137.345 -                             "for(int $i = 0; $i < $array.length; $i++) { $T $var = $array[$i]; $stmts$; }",
 137.346 -                             new Pair[] {
 137.347 -                                  new Pair<String, int[]>("$array", new int[] {117 - 31, 118 - 31}),
 137.348 -                                  new Pair<String, int[]>("$T", new int[] {134 - 31, 140 - 31}),
 137.349 -                             },
 137.350 -                             new Pair[] {
 137.351 -                                  new Pair<String, int[]>("$stmts$", new int[] {151 - 31, 173 - 31}),
 137.352 -                             },
 137.353 -                             new Pair[] {
 137.354 -                                  new Pair<String, String>("$i", "c"),
 137.355 -                                  new Pair<String, String>("$var", "s"),
 137.356 -                             });
 137.357 -    }
 137.358 -
 137.359 -    public void testEnhancedFor() throws Exception {
 137.360 -        performVariablesTest("package test; public class Test { public void test1(String[] a) { for (String s : a) { System.err.println(s); } } }",
 137.361 -                             "for($T $var : $array) { $stmts$; }",
 137.362 -                             new Pair[] {
 137.363 -                                  new Pair<String, int[]>("$array", new int[] {113 - 31, 114 - 31}),
 137.364 -                                  new Pair<String, int[]>("$T", new int[] {102 - 31, 108 - 31}),
 137.365 -                             },
 137.366 -                             new Pair[] {
 137.367 -                                  new Pair<String, int[]>("$stmts$", new int[] {118 - 31, 140 - 31}),
 137.368 -                             },
 137.369 -                             new Pair[] {
 137.370 -                                  new Pair<String, String>("$var", "s"),
 137.371 -                             });
 137.372 -    }
 137.373 -
 137.374 -    public void testWhile() throws Exception {
 137.375 -        performVariablesTest("package test; public class Test { public void test1(String[] a) { int c = 0; while  (c < a.length) { String s = a[c]; System.err.println(s); c++; } } }",
 137.376 -                             "while ($i < $array.length) { $T $var = $array[$i]; $stmts$; $i++; }",
 137.377 -                             new Pair[] {
 137.378 -                                  new Pair<String, int[]>("$array", new int[] {120 - 31, 121 - 31}),
 137.379 -                                  new Pair<String, int[]>("$T", new int[] {132 - 31, 138 - 31}),
 137.380 -                                  new Pair<String, int[]>("$i", new int[] {116 - 31, 117 - 31}),
 137.381 -                             },
 137.382 -                             new Pair[] {
 137.383 -                                  new Pair<String, int[]>("$stmts$", new int[] {149 - 31, 171 - 31}),
 137.384 -                             },
 137.385 -                             new Pair[] {
 137.386 -                                  new Pair<String, String>("$var", "s"),
 137.387 -                             });
 137.388 -    }
 137.389 -
 137.390 -    public void testDoWhile() throws Exception {
 137.391 -        performVariablesTest("package test; public class Test { public void test1(String[] a) { int c = 0; do { String s = a[c]; System.err.println(s); c++; } while  (c < a.length); } }",
 137.392 -                             "do { $T $var = $array[$i]; $stmts$; $i++; } while ($i < $array.length);",
 137.393 -                             new Pair[] {
 137.394 -                                  new Pair<String, int[]>("$array", new int[] {124 - 31, 125 - 31}),
 137.395 -                                  new Pair<String, int[]>("$T", new int[] {113 - 31, 119 - 31}),
 137.396 -                                  new Pair<String, int[]>("$i", new int[] {126 - 31, 127 - 31}),
 137.397 -                             },
 137.398 -                             new Pair[] {
 137.399 -                                  new Pair<String, int[]>("$stmts$", new int[] {130 - 31, 152 - 31}),
 137.400 -                             },
 137.401 -                             new Pair[] {
 137.402 -                                  new Pair<String, String>("$var", "s"),
 137.403 -                             });
 137.404 -    }
 137.405 -
 137.406 -    public void testArrayType() throws Exception {
 137.407 -        performVariablesTest("package test; public class Test { public void test1() { int[][] a; } }",
 137.408 -                             "$T[]",
 137.409 -                             new Pair[] {
 137.410 -                                  new Pair<String, int[]>("$T", new int[] {87 - 31, /*92*//*XXX:*/94 - 31}),
 137.411 -                             },
 137.412 -                             new Pair[0],
 137.413 -                             new Pair[0]);
 137.414 -    }
 137.415 -
 137.416 -    public void testSemiMatchPackage() throws Exception {
 137.417 -        performVariablesTest("package test; import javax.lang.model.type.TypeMirror; public class Test { }",
 137.418 -                             "$T{java.lang.Object}.type",
 137.419 -                             new Pair[0],
 137.420 -                             new Pair[0],
 137.421 -                             new Pair[0],
 137.422 -                             true);
 137.423 -    }
 137.424 -
 137.425 -    public void testNullType() throws Exception {
 137.426 -        performVariablesTest("package javax.lang.model.type; public class Test { }",
 137.427 -                             "$T{java.lang.Object}.type",
 137.428 -                             new Pair[0],
 137.429 -                             new Pair[0],
 137.430 -                             new Pair[0],
 137.431 -                             true);
 137.432 -    }
 137.433 -
 137.434 -    public void testTryCatch() throws Exception {
 137.435 -        performVariablesTest("package test; import java.io.*; public class Test { public void test() { InputStream ins = null; try { ins = new FileInputStream(\"\"); } catch (IOException e) { e.printStackTrace(); } finally {ins.close();} } }",
 137.436 -                             "try {$stmts$;} catch (java.io.IOException $e) {$e.printStackTrace();} finally {$finally$;}",
 137.437 -                             new Pair[] {
 137.438 -                                   new Pair<String, int[]>("$e", new int[] {176 - 31 - 2, 189 - 31 - 2}),
 137.439 -                             },
 137.440 -                             new Pair[] {
 137.441 -                                  new Pair<String, int[]>("$stmts$", new int[] {134 - 31, 166 - 31 - 2}),
 137.442 -                                  new Pair<String, int[]>("$finally$", new int[] {225 - 31 - 2, 237 - 31 - 2}),
 137.443 -                             },
 137.444 -                             new Pair[] {
 137.445 -                                  new Pair<String, String>("$e", "e"),
 137.446 -                             });
 137.447 -    }
 137.448 -
 137.449 -    public void testMultiParameters1() throws Exception {
 137.450 -        performVariablesTest("package test; public class Test { { java.util.Arrays.asList(\"a\", \"b\", \"c\"); }",
 137.451 -                             "java.util.Arrays.asList($1$)",
 137.452 -                             new Pair[] {
 137.453 -                             },
 137.454 -                             new Pair[] {
 137.455 -                                new Pair<String, int[]>("$1$", new int[] {60, 63, 65, 68, 70, 73}),
 137.456 -                             },
 137.457 -                             new Pair[] {
 137.458 -                             });
 137.459 -    }
 137.460 -
 137.461 -    public void testMultiParameters2() throws Exception {
 137.462 -        performVariablesTest("package test; public class Test { { java.util.Arrays.asList(new String(\"a\"), \"b\", \"c\"); }",
 137.463 -                             "java.util.Arrays.asList(new String(\"a\"), $1$)",
 137.464 -                             new Pair[] {
 137.465 -                             },
 137.466 -                             new Pair[] {
 137.467 -                                new Pair<String, int[]>("$1$", new int[] {77, 80, 82, 85}),
 137.468 -                             },
 137.469 -                             new Pair[] {
 137.470 -                             });
 137.471 -    }
 137.472 -
 137.473 -    public void testMultiParameters3() throws Exception {
 137.474 -        performVariablesTest("package test; public class Test { { java.util.Arrays.asList(); }",
 137.475 -                             "java.util.Arrays.asList($1$)",
 137.476 -                             new Pair[] {
 137.477 -                             },
 137.478 -                             new Pair[] {
 137.479 -                                new Pair<String, int[]>("$1$", new int[] {}),
 137.480 -                             },
 137.481 -                             new Pair[] {
 137.482 -                             });
 137.483 -    }
 137.484 -
 137.485 -    public void testTypeParameters() throws Exception {
 137.486 -        performVariablesTest("package test; public class Test { { java.util.Arrays.<String>asList(\"a\", \"b\"); }",
 137.487 -                             "java.util.Arrays.<$1>asList($1$)",
 137.488 -                             new Pair[] {
 137.489 -                                   new Pair<String, int[]>("$1", new int[] {85 - 31, 91 - 31}),
 137.490 -                             },
 137.491 -                             new Pair[] {
 137.492 -                             },
 137.493 -                             new Pair[] {
 137.494 -                             });
 137.495 -    }
 137.496 -
 137.497 -    public void testModifiers() throws Exception {
 137.498 -        performVariablesTest("package test; public class Test { private String s; }",
 137.499 -                             "$mods$ java.lang.String $name;",
 137.500 -                             new Pair[] {
 137.501 -                                 new Pair<String, int[]>("$name", new int[] {65 - 31, 82 - 31}),
 137.502 -                                 new Pair<String, int[]>("$mods$", new int[] {65 - 31, 72 - 31}), //XXX: shouldn't this be a multi-variable?
 137.503 -                             },
 137.504 -                             new Pair[] {
 137.505 -                             },
 137.506 -                             new Pair[] {
 137.507 -                                  new Pair<String, String>("$name", "s"),
 137.508 -                             });
 137.509 -    }
 137.510 -
 137.511 -    public void testVariableIsFullPattern1() throws Exception {
 137.512 -        performVariablesTest("package test; public class Test { private int a; {System.err.println(a);} }",
 137.513 -                             "$0{int}",
 137.514 -                             new Pair[] {
 137.515 -                                 new Pair<String, int[]>("$0", new int[] {100 - 31, 101 - 31}),
 137.516 -                             },
 137.517 -                             new Pair[] {
 137.518 -                             },
 137.519 -                             new Pair[] {
 137.520 -                             });
 137.521 -    }
 137.522 -
 137.523 -    public void testVariableIsFullPattern2() throws Exception {
 137.524 -        performVariablesTest("package test; public class Test { private int a; {System.err.println(a);} }",
 137.525 -                             "$0{int}",
 137.526 -                             new Pair[] {
 137.527 -                                 new Pair<String, int[]>("$0", new int[] {100 - 31, 101 - 31}),
 137.528 -                             },
 137.529 -                             new Pair[] {
 137.530 -                             },
 137.531 -                             new Pair[] {
 137.532 -                             },
 137.533 -                             false,
 137.534 -                             true);
 137.535 -    }
 137.536 -
 137.537 -    public void testNoCCEForVariableName() throws Exception {
 137.538 -        performVariablesTest("package test; public class Test { { int[] arr = null; int a; arr[a] = 0;} }",
 137.539 -                             "int $a; $a = 0;",
 137.540 -                             new Pair[] {
 137.541 -                             },
 137.542 -                             new Pair[] {
 137.543 -                             },
 137.544 -                             new Pair[] {
 137.545 -                             },
 137.546 -                             true,
 137.547 -                             true);
 137.548 -    }
 137.549 -
 137.550 -    public void testVerifySameTrees1() throws Exception {
 137.551 -        performVariablesTest("package test; public class Test { { if (true) { System.err.println(); } else { System.err.println(); System.err.println(); } } }",
 137.552 -                             "if ($c) $s; else $s;",
 137.553 -                             new Pair[] {
 137.554 -                             },
 137.555 -                             new Pair[] {
 137.556 -                             },
 137.557 -                             new Pair[] {
 137.558 -                             },
 137.559 -                             true,
 137.560 -                             true);
 137.561 -    }
 137.562 -
 137.563 -    public void testVerifySameTreesMultiVariables1() throws Exception {
 137.564 -        performVariablesTest("package test; public class Test { { if (true) { System.err.println(); System.err.println(); } else { System.err.println(); System.err.println(); System.err.println(); } } }",
 137.565 -                             "if ($c) { $s$;} else { $s$; }",
 137.566 -                             new Pair[] {
 137.567 -                             },
 137.568 -                             new Pair[] {
 137.569 -                             },
 137.570 -                             new Pair[] {
 137.571 -                             },
 137.572 -                             true,
 137.573 -                             true);
 137.574 -    }
 137.575 -
 137.576 -    public void testVerifySameTreesMultiVariables2() throws Exception {
 137.577 -        performVariablesTest("package test; public class Test { { if (true) { System.err.println(1); System.err.println(); } else System.err.println(1); } }",
 137.578 -                             "if ($c) { System.err.println(1); $s2$; } else { System.err.println(1); $s2$; }",
 137.579 -                             new Pair[] {
 137.580 -                             },
 137.581 -                             new Pair[] {
 137.582 -                             },
 137.583 -                             new Pair[] {
 137.584 -                             },
 137.585 -                             true,
 137.586 -                             true);
 137.587 -    }
 137.588 -
 137.589 -    public void testVerifySameTreesMultiVariables3() throws Exception {
 137.590 -        performVariablesTest("package test; public class Test { { if (true) { System.err.println(); System.err.println(1); } else System.err.println(1); } }",
 137.591 -                             "if ($c) { $s1$; System.err.println(1); } else { $s1$; System.err.println(1); }",
 137.592 -                             new Pair[] {
 137.593 -                             },
 137.594 -                             new Pair[] {
 137.595 -                             },
 137.596 -                             new Pair[] {
 137.597 -                             },
 137.598 -                             true,
 137.599 -                             true);
 137.600 -    }
 137.601 -
 137.602 -    public void XtestVerifySameTreesMultiVariables4() throws Exception {
 137.603 -        performVariablesTest("package test; public class Test { { if (true) { System.err.println(); System.err.println(1); System.err.println(); } else System.err.println(1); } }",
 137.604 -                             "if ($c) { $s1$; System.err.println(1); $s2$; } else { $s1$; System.err.println(1); $s2$; }",
 137.605 -                             new Pair[] {
 137.606 -                             },
 137.607 -                             new Pair[] {
 137.608 -                             },
 137.609 -                             new Pair[] {
 137.610 -                             },
 137.611 -                             true,
 137.612 -                             true);
 137.613 -    }
 137.614 -
 137.615 -    public void testVerifySameTreesMultiVariables5() throws Exception {
 137.616 -        performVariablesTest("package test; public class Test { { if (true) { System.err.println(1); } else System.err.println(2); } }",
 137.617 -                             "if ($c) { $s$; } else { $s$; }",
 137.618 -                             new Pair[] {
 137.619 -                             },
 137.620 -                             new Pair[] {
 137.621 -                             },
 137.622 -                             new Pair[] {
 137.623 -                             },
 137.624 -                             true,
 137.625 -                             true);
 137.626 -    }
 137.627 -
 137.628 -    public void testSimpleRemapping1() throws Exception {
 137.629 -        performRemappingTest("package test;\n" +
 137.630 -                             "public class Test {\n" +
 137.631 -                             "    void t1() {\n" +
 137.632 -                             "        int i = 0;\n" +
 137.633 -                             "        |System.err.println(i);|\n" +
 137.634 -                             "    }\n" +
 137.635 -                             "    void t2() {\n" +
 137.636 -                             "        int a = 0;\n" +
 137.637 -                             "        |System.err.println(a);|\n" +
 137.638 -                             "    }\n" +
 137.639 -                             "}\n",
 137.640 -                             "i",
 137.641 -                             Options.ALLOW_REMAP_VARIABLE_TO_EXPRESSION);
 137.642 -    }
 137.643 -
 137.644 -    public void testSimpleRemapping2() throws Exception {
 137.645 -        performRemappingTest("package test;\n" +
 137.646 -                             "public class Test {\n" +
 137.647 -                             "    void t1() {\n" +
 137.648 -                             "        int i = 0;\n" +
 137.649 -                             "        |System.err.println(i);\n" +
 137.650 -                             "         int i2 = 0;\n" +
 137.651 -                             "         System.err.println(i2);|\n" +
 137.652 -                             "    }\n" +
 137.653 -                             "    void t2() {\n" +
 137.654 -                             "        int a = 0;\n" +
 137.655 -                             "        |System.err.println(a);\n" +
 137.656 -                             "         int a2 = 0;\n" +
 137.657 -                             "         System.err.println(a2);|\n" +
 137.658 -                             "    }\n" +
 137.659 -                             "}\n",
 137.660 -                             "i",
 137.661 -                             Options.ALLOW_REMAP_VARIABLE_TO_EXPRESSION);
 137.662 -    }
 137.663 -
 137.664 -    public void testSimpleRemapping3() throws Exception {
 137.665 -        performRemappingTest("package test;\n" +
 137.666 -                             "public class Test {\n" +
 137.667 -                             "    void t1() {\n" +
 137.668 -                             "        |int i = 0;\n" +
 137.669 -                             "         System.err.println(i);\n" +
 137.670 -                             "         int i2 = 0;\n" +
 137.671 -                             "         System.err.println(i2);|\n" +
 137.672 -                             "    }\n" +
 137.673 -                             "    void t2() {\n" +
 137.674 -                             "        |int a = 0;\n" +
 137.675 -                             "         System.err.println(a);\n" +
 137.676 -                             "         int a2 = 0;\n" +
 137.677 -                             "         System.err.println(a2);|\n" +
 137.678 -                             "    }\n" +
 137.679 -                             "}\n",
 137.680 -                             "",
 137.681 -                             Options.ALLOW_REMAP_VARIABLE_TO_EXPRESSION);
 137.682 -    }
 137.683 -
 137.684 -    public void testSimpleRemapping4() throws Exception {
 137.685 -        performRemappingTest("package test;\n" +
 137.686 -                             "public class Test {\n" +
 137.687 -                             "    void t1() {\n" +
 137.688 -                             "        int i = 0;\n" +
 137.689 -                             "        |System.err.println(i);|\n" +
 137.690 -                             "    }\n" +
 137.691 -                             "    void t2() {\n" +
 137.692 -                             "        int[] a = {0};\n" +
 137.693 -                             "        |System.err.println(a[0]);|\n" +
 137.694 -                             "    }\n" +
 137.695 -                             "}\n",
 137.696 -                             "i",
 137.697 -                             Options.ALLOW_REMAP_VARIABLE_TO_EXPRESSION);
 137.698 -    }
 137.699 -
 137.700 -    public void testPreventRemapOnExpressions1() throws Exception {
 137.701 -        performRemappingTest("package test;\n" +
 137.702 -                             "public class Test {\n" +
 137.703 -                             "    void t1() {\n" +
 137.704 -                             "        Throwable t = null;\n" +
 137.705 -                             "        |System.err.println(t);|\n" +
 137.706 -                             "    }\n" +
 137.707 -                             "    void t2() {\n" +
 137.708 -                             "        Throwable t = null;\n" +
 137.709 -                             "        |System.err.println(t.getCause());|\n" +
 137.710 -                             "    }\n" +
 137.711 -                             "}\n",
 137.712 -                             "t",
 137.713 -                             Options.ALLOW_REMAP_VARIABLE_TO_EXPRESSION);
 137.714 -    }
 137.715 -
 137.716 -    public void testPreventRemapOnExpressions2() throws Exception {
 137.717 -        performRemappingTest("package test;\n" +
 137.718 -                             "public class Test {\n" +
 137.719 -                             "    void t1() {\n" +
 137.720 -                             "        Throwable t = null;\n" +
 137.721 -                             "        |System.err.println(t);|\n" +
 137.722 -                             "    }\n" +
 137.723 -                             "    void t2() {\n" +
 137.724 -                             "        Throwable t = null;\n" +
 137.725 -                             "        System.err.println(t.getCause());\n" +
 137.726 -                             "    }\n" +
 137.727 -                             "}\n",
 137.728 -                             "t");
 137.729 -    }
 137.730 -
 137.731 -    public void testVariableMemberSelect() throws Exception {
 137.732 -        performVariablesTest("package test; public class Test {public void test(String str) { str.length(); str.length(); } public void test1(String str) { str.length(); str.isEmpty(); } }",
 137.733 -                             "{ $str.$method(); $str.$method(); }",
 137.734 -                             new Pair[0],
 137.735 -                             new Pair[] {new Pair<String, String>("$method", "length")});
 137.736 -    }
 137.737 -
 137.738 -    public void testCorrectSite1() throws Exception {
 137.739 -        performVariablesTest("package test; public class Test { public void test(Object o) { o.wait(); } }",
 137.740 -                             "$s{java.util.concurrent.locks.Condition}.wait()",
 137.741 -                             new Pair[0],
 137.742 -                             new Pair[0],
 137.743 -                             new Pair[0],
 137.744 -                             true);
 137.745 -    }
 137.746 -
 137.747 -    public void testCorrectSite2() throws Exception {
 137.748 -        performVariablesTest("package test; public class Test { public void test(Object o) { wait(); } }",
 137.749 -                             "$s{java.util.concurrent.locks.Condition}.wait()",
 137.750 -                             new Pair[0],
 137.751 -                             new Pair[0],
 137.752 -                             new Pair[0],
 137.753 -                             true);
 137.754 -    }
 137.755 -
 137.756 -    public void testCorrectSite3() throws Exception {
 137.757 -        performVariablesTest("package test; public abstract class Test implements java.util.concurrent.locks.Condition { public void test() { new Runnable() { public void run() { wait(); } } } }",
 137.758 -                             "$0{java.util.concurrent.locks.Condition}.wait()",
 137.759 -                             new Pair[0],// {new Pair<String, int[]>("$s", new int[] {-1, -1})},
 137.760 -                             new Pair[0],
 137.761 -                             new Pair[0]);
 137.762 -    }
 137.763 -
 137.764 -    public void testCorrectSite4() throws Exception {
 137.765 -        performVariablesTest("package test; public class Test { public void test() { foo.stop(); } }",
 137.766 -                             "$0{java.lang.Thread}.stop()",
 137.767 -                             new Pair[0],
 137.768 -                             new Pair[0],
 137.769 -                             new Pair[0],
 137.770 -                             true);
 137.771 -    }
 137.772 -
 137.773 -    public void testDotClassForSameClass() throws Exception {
 137.774 -        performTest("package test; public class Test { {Class c = |Test.class|; c = |Test.class|; c = String.class; } }");
 137.775 -    }
 137.776 -
 137.777 -    public void testTryCatchVariable() throws Exception {
 137.778 -        performVariablesTest("package test; public class Test { { try { throw new java.io.IOException(); } catch (java.io.IOException ex) { } } }",
 137.779 -                             "try { $stmts$; } catch $catches$",
 137.780 -                             new Pair[] {
 137.781 -                             },
 137.782 -                             new Pair[] {
 137.783 -                                new Pair<String, int[]>("$stmts$", new int[] {42, 74}),
 137.784 -                                new Pair<String, int[]>("$catches$", new int[] {77, 111}),
 137.785 -                             },
 137.786 -                             new Pair[] {
 137.787 -                             },
 137.788 -                             false,
 137.789 -                             true);
 137.790 -    }
 137.791 -
 137.792 -    public void testMatchInterfaceNoFQN() throws Exception {
 137.793 -        performTest("package test; import java.util.*; public class Test { public void test() { |List| l1; |java.util.List| l2;} }");
 137.794 -    }
 137.795 -
 137.796 -    public void testUnresolvableNonMatchingConstraint() throws Exception {
 137.797 -        performVariablesTest("package test; public class Test { private Object a; {System.err.println(a);} }",
 137.798 -                             "System.err.println($v{does.not.Exist}",
 137.799 -                             new Pair[0],
 137.800 -                             new Pair[0],
 137.801 -                             new Pair[0],
 137.802 -                             true);
 137.803 -    }
 137.804 -
 137.805 -    public void testIndexOutOfBoundsInMultiList() throws Exception {
 137.806 -        performVariablesTest("package test;" +
 137.807 -                             "public class Test {" +
 137.808 -                             "    public void test() {" +
 137.809 -                             "        int i = 0;" +
 137.810 -                             "        int j = 0;" +
 137.811 -                             "        i++;" +
 137.812 -                             "        j++;" +
 137.813 -                             "    }" +
 137.814 -                             "}",
 137.815 -                             "{$type $i = $init; $stms$; $i++;}",
 137.816 -                             new Pair[0],
 137.817 -                             new Pair[0],
 137.818 -                             new Pair[0],
 137.819 -                             true,
 137.820 -                             false);
 137.821 -    }
 137.822 -
 137.823 -    public void testCorrectSite192812() throws Exception {
 137.824 -        performVariablesTest("package test; public class Test { private int i; public void test(Test t) { t.i = i - 10; } }",
 137.825 -                             "$t = $t - $v",
 137.826 -                             new Pair[0],
 137.827 -                             new Pair[0],
 137.828 -                             new Pair[0],
 137.829 -                             true,
 137.830 -                             true);
 137.831 -    }
 137.832 -
 137.833 -    public void testCorrectSite183367() throws Exception {
 137.834 -        performVariablesTest("package test; public class Test { public void test(java.util.List l) { l.subList(0, 0).remove(0); } }",
 137.835 -                             "$l{java.util.Collection}.remove($o{java.lang.Object})",
 137.836 -                             new Pair[0],
 137.837 -                             new Pair[0],
 137.838 -                             new Pair[0],
 137.839 -                             true,
 137.840 -                             true);
 137.841 -    }
 137.842 -
 137.843 -    public void testDisableVariablesWhenVerifyingDuplicates1() throws Exception {
 137.844 -        performVariablesTest("package test; public class Test { public void test() { int $i = 1, $j = 2; int k = $i + $i; } }",
 137.845 -                             "$i + $i",
 137.846 -                             new Pair[] {new Pair<String, int[]>("$i", new int[] {83, 85})},
 137.847 -                             new Pair[0],
 137.848 -                             new Pair[0],
 137.849 -                             false,
 137.850 -                             true);
 137.851 -    }
 137.852 -
 137.853 -    public void testDisableVariablesWhenVerifyingDuplicates2() throws Exception {
 137.854 -        performVariablesTest("package test; public class Test { public void test() { int $i = 1, $j = 2; int k = $i + $i; } }",
 137.855 -                             "$i + $i",
 137.856 -                             new Pair[] {new Pair<String, int[]>("$i", new int[] {83, 85})},
 137.857 -                             new Pair[0],
 137.858 -                             new Pair[0],
 137.859 -                             false,
 137.860 -                             false);
 137.861 -    }
 137.862 -
 137.863 -    public void testMethodMatchingMoreParams() throws Exception {
 137.864 -        performVariablesTest("package test; public class Test {public void test(String s1, String s2) { } }",
 137.865 -                             "public void test($params$) { }",
 137.866 -                             new Pair[0],
 137.867 -                             new Pair[] {new Pair<String, int[]>("$params$", new int[] {50, 59, 61, 70})},
 137.868 -                             new Pair[0],
 137.869 -                             false,
 137.870 -                             true);
 137.871 -    }
 137.872 -
 137.873 -    public void testLambdaInput1() throws Exception {
 137.874 -        performVariablesTest("package test; public class Test {public void test() { new java.io.FilenameFilter() { public boolean accept(File dir, String name) { } }; } }",
 137.875 -                             "new $type() {public $retType $name($params$) { $body$; } }",
 137.876 -                             new Pair[0],
 137.877 -                             new Pair[] {new Pair<String, int[]>("$params$", new int[] { 107, 115, 117, 128 })},
 137.878 -                             new Pair[] {new Pair<String, String>("$name", "accept")},
 137.879 -                             false,
 137.880 -                             false);
 137.881 -    }
 137.882 -
 137.883 -    public void testLambdaInput2() throws Exception {
 137.884 -        performVariablesTest("package test; public class Test {public void test() { new java.io.FilenameFilter() { public boolean accept(File dir, String name) { } }; } }",
 137.885 -                             "new $type() { $mods$ $retType $name($params$) { $body$; } }",
 137.886 -                             new Pair[0],
 137.887 -                             new Pair[] {new Pair<String, int[]>("$params$", new int[] { 107, 115, 117, 128 })},
 137.888 -                             new Pair[] {new Pair<String, String>("$name", "accept")},
 137.889 -                             false,
 137.890 -                             true);
 137.891 -    }
 137.892 -
 137.893 -    public void testSwitch1() throws Exception {
 137.894 -        performVariablesTest("package test;\n" +
 137.895 -                             "public class Test {\n" +
 137.896 -                             "     {\n" +
 137.897 -                             "         E e = null;\n" +
 137.898 -                             "         switch (e) {\n" +
 137.899 -                             "             case A: System.err.println(1); break;\n" +
 137.900 -                             "             case D: System.err.println(2); break;\n" +
 137.901 -                             "             case E: System.err.println(3); break;\n" +
 137.902 -                             "         }\n" +
 137.903 -                             "     }\n" +
 137.904 -                             "     public enum E {A, B, C, D, E, F;}\n" +
 137.905 -                             "}\n",
 137.906 -                             "switch ($0{test.Test.E}) { case $c1$ case D: $stmts$; case $c2$ }",
 137.907 -                             new Pair[] {new Pair<String, int[]>("$0", new int[] {79, 80})},
 137.908 -                             new Pair[] {
 137.909 -                                new Pair<String, int[]>("$stmts$", new int[] { 156, 178, 179, 185 }),
 137.910 -                                new Pair<String, int[]>("$c1$", new int[] { 97, 134 }),
 137.911 -                                new Pair<String, int[]>("$c2$", new int[] { 199, 236 }),
 137.912 -                             },
 137.913 -                             new Pair[0],
 137.914 -                             false,
 137.915 -                             false);
 137.916 -    }
 137.917 -
 137.918 -    public void testWildcard1() throws Exception {
 137.919 -        performTest("package test; import java.util.*; public class Test { public void test() { |List<?>| l1; |List<?>| l2;} }");
 137.920 -    }
 137.921 -
 137.922 -    public void testWildcard2() throws Exception {
 137.923 -        performTest("package test; import java.util.*; public class Test { public void test() { |List<? extends String>| l1; |List<? extends String>| l2;} }");
 137.924 -    }
 137.925 -
 137.926 -    public void testWildcard3() throws Exception {
 137.927 -        performTest("package test; import java.util.*; public class Test { public void test() { |List<? super String>| l1; |List<? super String>| l2;} }");
 137.928 -    }
 137.929 -
 137.930 -    public void testSingleVariableStrict() throws Exception {
 137.931 -        performVariablesTest("package test; public class Test { public void test() { if (true) System.err.println(1); } }",
 137.932 -                             "if ($c) $then; else $else;",
 137.933 -                             new Pair[0],
 137.934 -                             new Pair[0],
 137.935 -                             new Pair[0],
 137.936 -                             true,
 137.937 -                             true);
 137.938 -    }
 137.939 -
 137.940 -    public void testMultiVariableZeroOrOne1() throws Exception {
 137.941 -        performVariablesTest("package test; public class Test { public void test() { if (true) System.err.println(1); } }",
 137.942 -                             "if ($c) $then; else $else$;",
 137.943 -                             new Pair[] {new Pair<String, int[]>("$c", new int[] {59, 63}),
 137.944 -                                         new Pair<String, int[]>("$then", new int[] {65, 87})},
 137.945 -                             new Pair[0],
 137.946 -                             new Pair[0],
 137.947 -                             false,
 137.948 -                             true);
 137.949 -    }
 137.950 -
 137.951 -    public void testMultiVariableZeroOrOne2() throws Exception {
 137.952 -        performVariablesTest("package test; public class Test { public void test() { if (true) System.err.println(1); else System.err.println(2); } }",
 137.953 -                             "if ($c) $then; else $else$;",
 137.954 -                             new Pair[] {new Pair<String, int[]>("$c", new int[] {59, 63}),
 137.955 -                                         new Pair<String, int[]>("$then", new int[] {65, 87}),
 137.956 -                                         new Pair<String, int[]>("$else$", new int[] {93, 115})},
 137.957 -                             new Pair[0],
 137.958 -                             new Pair[0],
 137.959 -                             false,
 137.960 -                             true);
 137.961 -    }
 137.962 -
 137.963 -    public void testNonResolvableType() throws Exception {
 137.964 -        performVariablesTest("package test; public class Test { { java.io.File f = null; boolean b = f.isDirectory(); } }",
 137.965 -                             "$1{can.not.Resolve}.$m($args$)",
 137.966 -                             new Pair[0],
 137.967 -                             new Pair[0],
 137.968 -                             new Pair[0],
 137.969 -                             true,
 137.970 -                             true);
 137.971 -    }
 137.972 -
 137.973 -    public void testTryWithResources() throws Exception {
 137.974 -        performVariablesTest("package test; public class Test { { try (java.io.InputStream in = null) { System.err.println(1); } } }",
 137.975 -                             "try ($resources$) {$body$;}",
 137.976 -                             new Pair[] {
 137.977 -                             },
 137.978 -                             new Pair[] {
 137.979 -                                new Pair<String, int[]>("$resources$", new int[] {41, 70}),
 137.980 -                                new Pair<String, int[]>("$body$", new int[] {74, 96}),
 137.981 -                             },
 137.982 -                             new Pair[] {
 137.983 -                             },
 137.984 -                             false,
 137.985 -                             true);
 137.986 -    }
 137.987 -
 137.988 -    public void testIgnoreOtherKind() throws Exception {
 137.989 -        performVariablesTest("package test; public class Test { private java.util.Collection<String> x() { return java.util.Collections.emptySet(); } } }",
 137.990 -                             "$i{java.lang.Class}",
 137.991 -                             new Pair[] {
 137.992 -                             },
 137.993 -                             new Pair[] {
 137.994 -                             },
 137.995 -                             new Pair[] {
 137.996 -                             },
 137.997 -                             true,
 137.998 -                             true);
 137.999 -    }
137.1000 -
137.1001 -    public void testSearchPackageClause() throws Exception {
137.1002 -        performVariablesTest("package test.a; public class Test { }",
137.1003 -                             "test.$1",
137.1004 -                             new Pair[] {
137.1005 -                             },
137.1006 -                             new Pair[] {
137.1007 -                             },
137.1008 -                             new Pair[] {
137.1009 -                                 new Pair<String, String>("$1", "a"),
137.1010 -                             },
137.1011 -                             false,
137.1012 -                             true);
137.1013 -    }
137.1014 -
137.1015 -    public void testPackageImport() throws Exception {
137.1016 -        performVariablesTest("package test; import java.util.*; public class Test { }",
137.1017 -                             "java.$1",
137.1018 -                             new Pair[] {
137.1019 -                             },
137.1020 -                             new Pair[] {
137.1021 -                             },
137.1022 -                             new Pair[] {
137.1023 -                                 new Pair<String, String>("$1", "util"),
137.1024 -                             },
137.1025 -                             false,
137.1026 -                             true);
137.1027 -    }
137.1028 -    
137.1029 -    public void testSubclassMatching() throws Exception {
137.1030 -        performVariablesTest("package test; import java.util.*; public abstract class Test { Map.Entry e; }",
137.1031 -                             "java.util.Map.$1",
137.1032 -                             new Pair[] {
137.1033 -                             },
137.1034 -                             new Pair[] {
137.1035 -                             },
137.1036 -                             new Pair[] {
137.1037 -                                 new Pair<String, String>("$1", "Entry"),
137.1038 -                             },
137.1039 -                             false,
137.1040 -                             true);
137.1041 -    }
137.1042 -    
137.1043 -    public void testMethodTypeParameters1() throws Exception {
137.1044 -        performVariablesTest("package test; public class Test { private void t() { } }",
137.1045 -                             "$mods$ <$tp$> $ret $name($args$) { $body$; }",
137.1046 -                             new Pair[] {
137.1047 -                                new Pair<String, int[]>("$ret", new int[] {42, 46}),
137.1048 -                                new Pair<String, int[]>("$mods$", new int[] {34, 41}),
137.1049 -                             },
137.1050 -                             new Pair[] {
137.1051 -                                new Pair<String, int[]>("$tp$", new int[] {}),
137.1052 -                                new Pair<String, int[]>("$args$", new int[] {}),
137.1053 -                                new Pair<String, int[]>("$body$", new int[] {}),
137.1054 -                             },
137.1055 -                             new Pair[] {
137.1056 -                                 new Pair<String, String>("$name", "t")
137.1057 -                             },
137.1058 -                             false,
137.1059 -                             false);
137.1060 -    }
137.1061 -    
137.1062 -    public void testMethodTypeParameters2() throws Exception {
137.1063 -        performVariablesTest("package test; public class Test { private <A, B> String aa(int a, int b) { a = b; b = a;} }",
137.1064 -                             "$mods$ <$tp$> $ret $name($args$) { $body$; }",
137.1065 -                             new Pair[] {
137.1066 -                                new Pair<String, int[]>("$ret", new int[] {49, 55}),
137.1067 -                                new Pair<String, int[]>("$mods$", new int[] {34, 41}),
137.1068 -                             },
137.1069 -                             new Pair[] {
137.1070 -                                new Pair<String, int[]>("$tp$", new int[] {43, 44, 46, 47}),
137.1071 -                                new Pair<String, int[]>("$args$", new int[] {59, 64, 66, 71}),
137.1072 -                                new Pair<String, int[]>("$body$", new int[] {75, 81, 82, 88}),
137.1073 -                             },
137.1074 -                             new Pair[] {
137.1075 -                                 new Pair<String, String>("$name", "aa")
137.1076 -                             },
137.1077 -                             false,
137.1078 -                             true);
137.1079 -    }
137.1080 -    
137.1081 -    public void testMethodTypeParameters3() throws Exception {
137.1082 -        performVariablesTest("package test; public class Test { private <A> String aa(int a, int b) { a = b; b = a;} }",
137.1083 -                             "$mods$ <$tp> $ret $name($args$) { $body$; }",
137.1084 -                             new Pair[] {
137.1085 -                                new Pair<String, int[]>("$ret", new int[] {46, 52}),
137.1086 -                                new Pair<String, int[]>("$mods$", new int[] {34, 41}),
137.1087 -                                new Pair<String, int[]>("$tp", new int[] {43, 44}),
137.1088 -                             },
137.1089 -                             new Pair[] {
137.1090 -                                new Pair<String, int[]>("$args$", new int[] {56, 61, 63, 68}),
137.1091 -                                new Pair<String, int[]>("$body$", new int[] {72, 78, 79, 85}),
137.1092 -                             },
137.1093 -                             new Pair[] {
137.1094 -                                 new Pair<String, String>("$name", "aa")
137.1095 -                             },
137.1096 -                             false,
137.1097 -                             true);
137.1098 -    }
137.1099 -    
137.1100 -    public void testTypeParameters1() throws Exception {
137.1101 -        performVariablesTest("package test; public class Test { private <A extends String> void aa() { } }",
137.1102 -                             "$mods$ <$tp extends $bound&$obounds$> $ret $name($args$) { $body$; }",
137.1103 -                             new Pair[] {
137.1104 -                                new Pair<String, int[]>("$ret", new int[] {61, 65}),
137.1105 -                                new Pair<String, int[]>("$mods$", new int[] {34, 41}),
137.1106 -                                new Pair<String, int[]>("$tp", new int[] {43, 59}),
137.1107 -                                new Pair<String, int[]>("$bound", new int[] {53, 59}),
137.1108 -                             },
137.1109 -                             new Pair[] {
137.1110 -                                new Pair<String, int[]>("$obounds$", new int[] {}),
137.1111 -                             },
137.1112 -                             new Pair[] {
137.1113 -                                 new Pair<String, String>("$name", "aa"),
137.1114 -                                 new Pair<String, String>("$tp", "A")
137.1115 -                             },
137.1116 -                             false,
137.1117 -                             true);
137.1118 -    }
137.1119 -    
137.1120 -    public void testPartialModifiers1() throws Exception {
137.1121 -        performVariablesTest("package test; public class Test { @Deprecated @Override private void aa() { } }",
137.1122 -                             "$mods$ @Deprecated private $ret $name() { $body$; }",
137.1123 -                             new Pair[] {
137.1124 -                                new Pair<String, int[]>("$ret", new int[] {64, 68}),
137.1125 -                                new Pair<String, int[]>("$mods$", new int[] {34, 63}),
137.1126 -                             },
137.1127 -                             new Pair[] {
137.1128 -                             },
137.1129 -                             new Pair[] {
137.1130 -                                 new Pair<String, String>("$name", "aa"),
137.1131 -                             },
137.1132 -                             false,
137.1133 -                             true);
137.1134 -    }
137.1135 -    
137.1136 -    public void testPartialModifiers2() throws Exception {
137.1137 -        performVariablesTest("package test; public class Test { @Override private void aa() { } }",
137.1138 -                             "$mods$ @Deprecated private $ret $name() { $body$; }",
137.1139 -                             new Pair[0],
137.1140 -                             new Pair[0],
137.1141 -                             new Pair[0],
137.1142 -                             true,
137.1143 -                             true);
137.1144 -    }
137.1145 -    
137.1146 -    public void testNonStaticInnerClassesMatch() throws Exception {
137.1147 -        performVariablesTest("package test; import test.Test.Inner; public class Test { public class Inner { } } class Other { { Inner i = null; } }",
137.1148 -                             "test.Test.Inner $i = $init$;",
137.1149 -                             new Pair[] {
137.1150 -                                 new Pair<String, int[]>("$i", new int[] {99, 114}),
137.1151 -                                 new Pair<String, int[]>("$init$", new int[] {109, 113})
137.1152 -                             },
137.1153 -                             new Pair[0],
137.1154 -                             new Pair[] {
137.1155 -                                 new Pair<String, String>("$i", "i")
137.1156 -                             },
137.1157 -                             false,
137.1158 -                             true);
137.1159 -    }
137.1160 -    
137.1161 -    public void testNewClassTypeParams222066a() throws Exception {
137.1162 -        performVariablesTest("package test; public class Test { private Object aa() { return new java.util.ArrayList(1); } }",
137.1163 -                             "new java.util.ArrayList<$whatever$>($param)",
137.1164 -                             new Pair[] {
137.1165 -                                 new Pair<String, int[]>("$param", new int[] {87, 88})
137.1166 -                             },
137.1167 -                             new Pair[] {
137.1168 -                                 new Pair<String, int[]>("$whatever$", new int[0])
137.1169 -                             },
137.1170 -                             new Pair[0],
137.1171 -                             false,
137.1172 -                             false);
137.1173 -    }
137.1174 -    
137.1175 -    public void testNewClassTypeParams222066b() throws Exception {
137.1176 -        performVariablesTest("package test; import java.util.ArrayList; public class Test { private Object aa() { return new ArrayList(1); } }",
137.1177 -                             "new java.util.ArrayList<$whatever$>($param)",
137.1178 -                             new Pair[] {
137.1179 -                                 new Pair<String, int[]>("$param", new int[] {105, 106})
137.1180 -                             },
137.1181 -                             new Pair[] {
137.1182 -                                 new Pair<String, int[]>("$whatever$", new int[0])
137.1183 -                             },
137.1184 -                             new Pair[0],
137.1185 -                             false,
137.1186 -                             false);
137.1187 -    }
137.1188 -    
137.1189 -    public void testFindLambda() throws Exception {
137.1190 -        performVariablesTest("package test; import java.util.Comparator; public class Test { private void aa() { Comparator<String> c = (l, r) -> l.compareTo(r); } }",
137.1191 -                             "($args$) -> $expression",
137.1192 -                             new Pair[] {
137.1193 -                                 new Pair<String, int[]>("$expression", new int[] {116, 130})
137.1194 -                             },
137.1195 -                             new Pair[] {
137.1196 -                                 new Pair<String, int[]>("$args$", new int[] {107, 108, 110, 111})
137.1197 -                             },
137.1198 -                             new Pair[0],
137.1199 -                             false,
137.1200 -                             false);
137.1201 -    }
137.1202 -    
137.1203 -    public void testAnnotation1() throws Exception {
137.1204 -        performVariablesTest("package test; import test.Test.A; @A(i=1) public class Test { @interface A { public int i(); } }",
137.1205 -                             "@$annotation($args$)",
137.1206 -                             new Pair[] {
137.1207 -                                 new Pair<String, int[]>("$annotation", new int[] {35, 36})
137.1208 -                             },
137.1209 -                             new Pair[] {
137.1210 -                                 new Pair<String, int[]>("$args$", new int[] {37, 40})
137.1211 -                             },
137.1212 -                             new Pair[0],
137.1213 -                             false,
137.1214 -                             true);
137.1215 -    }
137.1216 -    
137.1217 -    public void testAnnotation2() throws Exception {
137.1218 -        performVariablesTest("package test; import test.Test.A; @A(i=1,b=true,l=2) public class Test { @interface A { public int i(); public boolean b(); public long l(); } }",
137.1219 -                             "@test.Test.A($prefix$, b=$value, $suffix$)",
137.1220 -                             new Pair[] {
137.1221 -                                 new Pair<String, int[]>("$value", new int[] {43, 47})
137.1222 -                             },
137.1223 -                             new Pair[] {
137.1224 -                                 new Pair<String, int[]>("$prefix$", new int[] {37, 40}),
137.1225 -                                 new Pair<String, int[]>("$suffix$", new int[] {48, 51})
137.1226 -                             },
137.1227 -                             new Pair[0],
137.1228 -                             false,
137.1229 -                             false);
137.1230 -    }
137.1231 -    
137.1232 -    protected void prepareTest(String code) throws Exception {
137.1233 -        prepareTest(code, -1);
137.1234 -    }
137.1235 -
137.1236 -    protected void prepareTest(String code, int testIndex) throws Exception {
137.1237 -        File workDirWithIndexFile = testIndex != (-1) ? new File(getWorkDir(), Integer.toString(testIndex)) : getWorkDir();
137.1238 -        FileObject workDirWithIndex = FileUtil.toFileObject(workDirWithIndexFile);
137.1239 -
137.1240 -        if (workDirWithIndex != null) {
137.1241 -            workDirWithIndex.delete();
137.1242 -        }
137.1243 -
137.1244 -        workDirWithIndex = FileUtil.createFolder(workDirWithIndexFile);
137.1245 -
137.1246 -        assertNotNull(workDirWithIndexFile);
137.1247 -
137.1248 -        FileObject sourceRoot = workDirWithIndex.createFolder("src");
137.1249 -        FileObject buildRoot  = workDirWithIndex.createFolder("build");
137.1250 -        FileObject cache = workDirWithIndex.createFolder("cache");
137.1251 -
137.1252 -        FileObject data = FileUtil.createData(sourceRoot, "test/Test.java");
137.1253 -
137.1254 -        TestUtilities.copyStringToFile(data, code);
137.1255 -
137.1256 -        data.refresh();
137.1257 -
137.1258 -        SourceUtilsTestUtil.prepareTest(sourceRoot, buildRoot, cache);
137.1259 -
137.1260 -        DataObject od = DataObject.find(data);
137.1261 -        EditorCookie ec = od.getLookup().lookup(EditorCookie.class);
137.1262 -
137.1263 -        assertNotNull(ec);
137.1264 -
137.1265 -        doc = ec.openDocument();
137.1266 -
137.1267 -        doc.putProperty(Language.class, JavaTokenId.language());
137.1268 -        doc.putProperty("mimeType", "text/x-java");
137.1269 -
137.1270 -        JavaSource js = JavaSource.forFileObject(data);
137.1271 -
137.1272 -        assertNotNull(js);
137.1273 -
137.1274 -        info = SourceUtilsTestUtil.getCompilationInfo(js, Phase.RESOLVED);
137.1275 -
137.1276 -        assertNotNull(info);
137.1277 -    }
137.1278 -
137.1279 -    private static String findRegions(String code, List<int[]> regions) {
137.1280 -        String[] split = code.split("\\|");
137.1281 -        StringBuilder filtered = new StringBuilder();
137.1282 -
137.1283 -        filtered.append(split[0]);
137.1284 -
137.1285 -        int offset = split[0].length();
137.1286 -
137.1287 -        for (int cntr = 1; cntr < split.length; cntr += 2) {
137.1288 -            int[] i = new int[] {
137.1289 -                offset,
137.1290 -                offset + split[cntr].length()
137.1291 -            };
137.1292 -
137.1293 -            regions.add(i);
137.1294 -
137.1295 -            filtered.append(split[cntr]);
137.1296 -            filtered.append(split[cntr + 1]);
137.1297 -
137.1298 -            offset += split[cntr].length();
137.1299 -            offset += split[cntr + 1].length();
137.1300 -        }
137.1301 -
137.1302 -        return filtered.toString();
137.1303 -    }
137.1304 -
137.1305 -    protected CompilationInfo info;
137.1306 -    private Document doc;
137.1307 -
137.1308 -    private void performTest(String code) throws Exception {
137.1309 -        performTest(code, true);
137.1310 -    }
137.1311 -
137.1312 -    private void performTest(String code, boolean verify) throws Exception {
137.1313 -        List<int[]> result = new LinkedList<int[]>();
137.1314 -
137.1315 -        code = findRegions(code, result);
137.1316 -
137.1317 -        int testIndex = 0;
137.1318 -
137.1319 -        for (int[] i : result) {
137.1320 -            int[] duplicates = new int[2 * (result.size() - 1)];
137.1321 -            int cntr = 0;
137.1322 -            List<int[]> l = new LinkedList<int[]>(result);
137.1323 -
137.1324 -            l.remove(i);
137.1325 -
137.1326 -            for (int[] span : l) {
137.1327 -                duplicates[cntr++] = span[0];
137.1328 -                duplicates[cntr++] = span[1];
137.1329 -            }
137.1330 -
137.1331 -            doPerformTest(code, i[0], i[1], testIndex++, verify, duplicates);
137.1332 -        }
137.1333 -    }
137.1334 -
137.1335 -    protected void performTest(String code, int start, int end, int... duplicates) throws Exception {
137.1336 -        doPerformTest(code, start, end, -1, true, duplicates);
137.1337 -    }
137.1338 -
137.1339 -    protected void doPerformTest(String code, int start, int end, int testIndex, int... duplicates) throws Exception {
137.1340 -        doPerformTest(code, start, end, testIndex, true, duplicates);
137.1341 -    }
137.1342 -
137.1343 -    protected void doPerformTest(String code, int start, int end, int testIndex, boolean verify, int... duplicates) throws Exception {
137.1344 -        prepareTest(code, testIndex);
137.1345 -
137.1346 -        TreePath path = info.getTreeUtilities().pathFor((start + end) / 2 + 1);
137.1347 -
137.1348 -        while (path != null) {
137.1349 -            Tree t = path.getLeaf();
137.1350 -            SourcePositions sp = info.getTrees().getSourcePositions();
137.1351 -
137.1352 -            if (   start == sp.getStartPosition(info.getCompilationUnit(), t)
137.1353 -                && end   == sp.getEndPosition(info.getCompilationUnit(), t)) {
137.1354 -                break;
137.1355 -            }
137.1356 -
137.1357 -            path = path.getParentPath();
137.1358 -        }
137.1359 -
137.1360 -        assertNotNull(path);
137.1361 -
137.1362 -        Collection<TreePath> result = computeDuplicates(path);
137.1363 -
137.1364 -        //        assertEquals(f.result.toString(), duplicates.length / 2, f.result.size());
137.1365 -
137.1366 -        if (verify) {
137.1367 -            int[] dupes = new int[result.size() * 2];
137.1368 -            int   index = 0;
137.1369 -
137.1370 -            for (TreePath tp : result) {
137.1371 -                dupes[index++] = (int) info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), tp.getLeaf());
137.1372 -                dupes[index++] = (int) info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), tp.getLeaf());
137.1373 -            }
137.1374 -
137.1375 -            assertTrue("Was: " + Arrays.toString(dupes) + " should have been: " + Arrays.toString(duplicates), Arrays.equals(duplicates, dupes));
137.1376 -        }
137.1377 -    }
137.1378 -
137.1379 -    protected void performVariablesTest(String code, String pattern, Pair<String, int[]>[] duplicatesPos, Pair<String, String>[] duplicatesNames) throws Exception {
137.1380 -        performVariablesTest(code, pattern, duplicatesPos, new Pair[0], duplicatesNames);
137.1381 -    }
137.1382 -
137.1383 -    protected void performVariablesTest(String code, String pattern, Pair<String, int[]>[] duplicatesPos, Pair<String, int[]>[] multiStatementPos, Pair<String, String>[] duplicatesNames) throws Exception {
137.1384 -        performVariablesTest(code, pattern, duplicatesPos, multiStatementPos, duplicatesNames, false);
137.1385 -    }
137.1386 -
137.1387 -    protected void performVariablesTest(String code, String pattern, Pair<String, int[]>[] duplicatesPos, Pair<String, int[]>[] multiStatementPos, Pair<String, String>[] duplicatesNames, boolean noOccurrences) throws Exception {
137.1388 -        performVariablesTest(code, pattern, duplicatesPos, multiStatementPos, duplicatesNames, noOccurrences, false);
137.1389 -    }
137.1390 -
137.1391 -    protected void performVariablesTest(String code, String pattern, Pair<String, int[]>[] duplicatesPos, Pair<String, int[]>[] multiStatementPos, Pair<String, String>[] duplicatesNames, boolean noOccurrences, boolean useBulkSearch) throws Exception {
137.1392 -        prepareTest(code, -1);
137.1393 -
137.1394 -        Map<String, TypeMirror> constraints = new HashMap<String, TypeMirror>();
137.1395 -        String patternCode = PatternCompilerUtilities.parseOutTypesFromPattern(info, pattern, constraints);
137.1396 -
137.1397 -        Pattern patternObj = PatternCompiler.compile(info, patternCode, constraints, Collections.<String>emptyList());
137.1398 -        TreePath patternPath = MatchingTestAccessor.getPattern(patternObj).iterator().next();
137.1399 -        Map<TreePath, VariableAssignments> result;
137.1400 -
137.1401 -        if (useBulkSearch) {
137.1402 -            result = new HashMap<TreePath, VariableAssignments>();
137.1403 -
137.1404 -            BulkPattern bulkPattern = BulkSearch.getDefault().create(info, new AtomicBoolean(), patternCode);
137.1405 -
137.1406 -            for (Entry<String, Collection<TreePath>> e : BulkSearch.getDefault().match(info, new AtomicBoolean(), new TreePath(info.getCompilationUnit()), bulkPattern).entrySet()) {
137.1407 -                for (TreePath tp : e.getValue()) {
137.1408 -                    VariableAssignments vars = computeVariables(info, patternPath, tp, new AtomicBoolean(), MatchingTestAccessor.getVariable2Type(patternObj));
137.1409 -
137.1410 -                    if (vars != null) {
137.1411 -                        result.put(tp, vars);
137.1412 -                    }
137.1413 -                }
137.1414 -            }
137.1415 -        } else {
137.1416 -            result = computeDuplicates(info, patternPath, new TreePath( info.getCompilationUnit()), new AtomicBoolean(), MatchingTestAccessor.getVariable2Type(patternObj));
137.1417 -        }
137.1418 -
137.1419 -        if (noOccurrences) {
137.1420 -            assertEquals(0, result.size());
137.1421 -            return ;
137.1422 -        }
137.1423 -
137.1424 -        assertSame(1, result.size());
137.1425 -
137.1426 -        Map<String, int[]> actual = new HashMap<String, int[]>();
137.1427 -
137.1428 -        for (Entry<String, TreePath> e : result.values().iterator().next().variables.entrySet()) {
137.1429 -            int[] span = new int[] {
137.1430 -                (int) info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), e.getValue().getLeaf()),
137.1431 -                (int) info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), e.getValue().getLeaf())
137.1432 -            };
137.1433 -
137.1434 -            actual.put(e.getKey(), span);
137.1435 -        }
137.1436 -
137.1437 -        for (Pair<String, int[]> dup : duplicatesPos) {
137.1438 -            int[] span = actual.remove(dup.getA());
137.1439 -
137.1440 -            if (span == null) {
137.1441 -                fail(dup.getA());
137.1442 -            }
137.1443 -            assertTrue(dup.getA() + ":" + Arrays.toString(span), Arrays.equals(span, dup.getB()));
137.1444 -        }
137.1445 -
137.1446 -        Map<String, int[]> actualMulti = new HashMap<String, int[]>();
137.1447 -
137.1448 -        for (Entry<String, Collection<? extends TreePath>> e : result.values().iterator().next().multiVariables.entrySet()) {
137.1449 -            int[] span = new int[2 * e.getValue().size()];
137.1450 -            int i = 0;
137.1451 -
137.1452 -            for (TreePath tp : e.getValue()) {
137.1453 -                span[i++] = (int) info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), tp.getLeaf());
137.1454 -                span[i++] = (int) info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), tp.getLeaf());
137.1455 -            }
137.1456 -
137.1457 -            actualMulti.put(e.getKey(), span);
137.1458 -        }
137.1459 -
137.1460 -        for (Pair<String, int[]> dup : multiStatementPos) {
137.1461 -            int[] span = actualMulti.remove(dup.getA());
137.1462 -
137.1463 -            if (span == null) {
137.1464 -                fail(dup.getA());
137.1465 -            }
137.1466 -            assertTrue(dup.getA() + ":" + Arrays.toString(span), Arrays.equals(span, dup.getB()));
137.1467 -        }
137.1468 -
137.1469 -        Map<String, String> golden = new HashMap<String, String>();
137.1470 -
137.1471 -        for ( Pair<String, String> e : duplicatesNames) {
137.1472 -            golden.put(e.getA(), e.getB());
137.1473 -        }
137.1474 -
137.1475 -        assertEquals(golden, result.values().iterator().next().variables2Names);
137.1476 -    }
137.1477 -
137.1478 -    protected VariableAssignments computeVariables(CompilationInfo info, TreePath searchingFor, TreePath scope, AtomicBoolean cancel, Map<String, TypeMirror> designedTypeHack) {
137.1479 -        Collection<VariableAssignments> values = CopyFinder.internalComputeDuplicates(info, Collections.singletonList(searchingFor), scope, null, null, new AtomicBooleanCancel(cancel), designedTypeHack, Options.ALLOW_VARIABLES_IN_PATTERN).values();
137.1480 -
137.1481 -        if (values.iterator().hasNext()) {
137.1482 -            return values.iterator().next();
137.1483 -        } else {
137.1484 -            return null;
137.1485 -        }
137.1486 -    }
137.1487 -
137.1488 -    protected Map<TreePath, VariableAssignments> computeDuplicates(CompilationInfo info, TreePath searchingFor, TreePath scope, AtomicBoolean cancel, Map<String, TypeMirror> designedTypeHack) {
137.1489 -        return CopyFinder.internalComputeDuplicates(info, Collections.singletonList(searchingFor), scope, null, null, new AtomicBooleanCancel(cancel), designedTypeHack, Options.ALLOW_VARIABLES_IN_PATTERN, Options.ALLOW_GO_DEEPER);
137.1490 -    }
137.1491 -
137.1492 -    private void performRemappingTest(String code, String remappableVariables, Options... options) throws Exception {
137.1493 -        List<int[]> regions = new LinkedList<int[]>();
137.1494 -
137.1495 -        code = findRegions(code, regions);
137.1496 -
137.1497 -        prepareTest(code, -1);
137.1498 -
137.1499 -        int[] statements = new int[2];
137.1500 -
137.1501 -        int[] currentRegion = regions.get(0);
137.1502 -        TreePathHandle tph = IntroduceMethodFix.validateSelectionForIntroduceMethod(info, currentRegion[0], currentRegion[1], statements);
137.1503 -
137.1504 -        assertNotNull(tph);
137.1505 -
137.1506 -        TreePath tp = tph.resolve(info);
137.1507 -
137.1508 -        assertNotNull(tp);
137.1509 -
137.1510 -        BlockTree bt = (BlockTree) tp.getParentPath().getLeaf();
137.1511 -        List<TreePath> searchFor = new LinkedList<TreePath>();
137.1512 -
137.1513 -        for (StatementTree t : bt.getStatements().subList(statements[0], statements[1] + 1)) {
137.1514 -            searchFor.add(new TreePath(tp, t));
137.1515 -        }
137.1516 -
137.1517 -        final Set<VariableElement> vars = new HashSet<VariableElement>();
137.1518 -
137.1519 -        for (final String name : remappableVariables.split(",")) {
137.1520 -            if (name.isEmpty()) continue;
137.1521 -            new TreePathScanner<Object, Object>() {
137.1522 -                @Override
137.1523 -                public Object visitVariable(VariableTree node, Object p) {
137.1524 -                    if (node.getName().contentEquals(name)) {
137.1525 -                        vars.add((VariableElement) info.getTrees().getElement(getCurrentPath()));
137.1526 -                    }
137.1527 -
137.1528 -                    return super.visitVariable(node, p);
137.1529 -                }
137.1530 -            }.scan(info.getCompilationUnit(), null);
137.1531 -        }
137.1532 -
137.1533 -        Set<Options> opts = EnumSet.of(Options.ALLOW_GO_DEEPER);
137.1534 -
137.1535 -        opts.addAll(Arrays.asList(options));
137.1536 -
137.1537 -        Map<TreePath, VariableAssignments> result = CopyFinder.internalComputeDuplicates(info, searchFor, new TreePath(info.getCompilationUnit()), null, vars, new AtomicBooleanCancel(), Collections.<String, TypeMirror>emptyMap(), opts.toArray(new Options[0]));
137.1538 -        Set<List<Integer>> realSpans = new HashSet<List<Integer>>();
137.1539 -
137.1540 -        for (Entry<TreePath, VariableAssignments> e : result.entrySet()) {
137.1541 -            List<? extends StatementTree> parentStatements = CopyFinder.getStatements(e.getKey());
137.1542 -            int dupeStart = parentStatements.indexOf(e.getKey().getLeaf());
137.1543 -            int startPos = (int) info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), parentStatements.get(dupeStart));
137.1544 -            int endPos = (int) info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), parentStatements.get(dupeStart + searchFor.size() - 1));
137.1545 -
137.1546 -            realSpans.add(Arrays.asList(startPos, endPos));
137.1547 -        }
137.1548 -
137.1549 -        Set<List<Integer>> goldenSpans = new HashSet<List<Integer>>();
137.1550 -
137.1551 -        for (int[] region : regions) {
137.1552 -            if (region == currentRegion) continue;
137.1553 -
137.1554 -            int[] stmts = new int[2];
137.1555 -            TreePathHandle gtph = IntroduceMethodFix.validateSelectionForIntroduceMethod(info, region[0], region[1], stmts);
137.1556 -
137.1557 -            assertNotNull(gtph);
137.1558 -
137.1559 -            TreePath gtp = gtph.resolve(info);
137.1560 -
137.1561 -            assertNotNull(gtp);
137.1562 -
137.1563 -            BlockTree b = (BlockTree) gtp.getParentPath().getLeaf();
137.1564 -
137.1565 -            int startPos = (int) info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), b.getStatements().get(stmts[0]));
137.1566 -            int endPos = (int) info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), b.getStatements().get(stmts[1]));
137.1567 -
137.1568 -            goldenSpans.add(Arrays.asList(startPos, endPos));
137.1569 -        }
137.1570 -
137.1571 -        assertEquals(goldenSpans, realSpans);
137.1572 -    }
137.1573 -
137.1574 -    protected Collection<TreePath> computeDuplicates(TreePath path) {
137.1575 -        return CopyFinder.internalComputeDuplicates(info, Collections.singletonList(path), new TreePath(info.getCompilationUnit()), null, null, new AtomicBooleanCancel(), null, Options.ALLOW_GO_DEEPER).keySet();
137.1576 -    }
137.1577 -
137.1578 -    public static final class Pair<A, B> {
137.1579 -        private final A a;
137.1580 -        private final B b;
137.1581 -
137.1582 -        public Pair(A a, B b) {
137.1583 -            this.a = a;
137.1584 -            this.b = b;
137.1585 -        }
137.1586 -
137.1587 -        public A getA() {
137.1588 -            return a;
137.1589 -        }
137.1590 -
137.1591 -        public B getB() {
137.1592 -            return b;
137.1593 -        }
137.1594 -
137.1595 -    }
137.1596 -
137.1597 -    private static final class AtomicBooleanCancel implements Cancel {
137.1598 -
137.1599 -        private final AtomicBoolean cancel;
137.1600 -
137.1601 -        public AtomicBooleanCancel() {
137.1602 -            this(new AtomicBoolean());
137.1603 -        }
137.1604 -
137.1605 -        public AtomicBooleanCancel(AtomicBoolean cancel) {
137.1606 -            this.cancel = cancel;
137.1607 -        }
137.1608 -
137.1609 -        @Override
137.1610 -        public boolean isCancelled() {
137.1611 -            return cancel.get();
137.1612 -        }
137.1613 -
137.1614 -    }
137.1615 -}
   138.1 --- a/java.hints/spi.java.hints/test/unit/src/org/netbeans/spi/java/hints/support/FixFactoryTest.java	Sun Oct 16 08:01:27 2016 +0200
   138.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   138.3 @@ -1,79 +0,0 @@
   138.4 -/*
   138.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   138.6 - *
   138.7 - * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
   138.8 - *
   138.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  138.10 - * Other names may be trademarks of their respective owners.
  138.11 - *
  138.12 - * The contents of this file are subject to the terms of either the GNU
  138.13 - * General Public License Version 2 only ("GPL") or the Common
  138.14 - * Development and Distribution License("CDDL") (collectively, the
  138.15 - * "License"). You may not use this file except in compliance with the
  138.16 - * License. You can obtain a copy of the License at
  138.17 - * http://www.netbeans.org/cddl-gplv2.html
  138.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  138.19 - * specific language governing permissions and limitations under the
  138.20 - * License.  When distributing the software, include this License Header
  138.21 - * Notice in each file and include the License file at
  138.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  138.23 - * particular file as subject to the "Classpath" exception as provided
  138.24 - * by Oracle in the GPL Version 2 section of the License file that
  138.25 - * accompanied this code. If applicable, add the following below the
  138.26 - * License Header, with the fields enclosed by brackets [] replaced by
  138.27 - * your own identifying information:
  138.28 - * "Portions Copyrighted [year] [name of copyright owner]"
  138.29 - *
  138.30 - * If you wish your version of this file to be governed by only the CDDL
  138.31 - * or only the GPL Version 2, indicate your decision by adding
  138.32 - * "[Contributor] elects to include this software in this distribution
  138.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
  138.34 - * single choice of license, a recipient has the option to distribute
  138.35 - * your version of this file under either the CDDL, the GPL Version 2 or
  138.36 - * to extend the choice of license to its licensees as provided above.
  138.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
  138.38 - * Version 2 license, then the option applies only if the new code is
  138.39 - * made subject to such option by the copyright holder.
  138.40 - *
  138.41 - * Contributor(s):
  138.42 - *
  138.43 - * Portions Copyrighted 2013 Sun Microsystems, Inc.
  138.44 - */
  138.45 -package org.netbeans.spi.java.hints.support;
  138.46 -
  138.47 -import com.sun.source.tree.ClassTree;
  138.48 -import com.sun.source.util.TreePath;
  138.49 -import java.util.EnumSet;
  138.50 -import javax.lang.model.element.Modifier;
  138.51 -import org.netbeans.api.java.source.SourceUtilsTestUtil;
  138.52 -import org.netbeans.modules.java.hints.spiimpl.TestBase;
  138.53 -import org.openide.LifecycleManager;
  138.54 -
  138.55 -/**
  138.56 - *
  138.57 - * @author lahvac
  138.58 - */
  138.59 -public class FixFactoryTest extends TestBase {
  138.60 -    
  138.61 -    public FixFactoryTest(String name) {
  138.62 -        super(name);
  138.63 -    }
  138.64 -
  138.65 -    @Override
  138.66 -    protected void setUp() throws Exception {
  138.67 -        super.setUp();
  138.68 -        SourceUtilsTestUtil.makeScratchDir(this);
  138.69 -    }
  138.70 -    
  138.71 -    public void testInterfaceModifiers() throws Exception {
  138.72 -        prepareTest("test/Test.java", "package test; public interface I { }");
  138.73 -        
  138.74 -        ClassTree i = (ClassTree) info.getCompilationUnit().getTypeDecls().get(0);
  138.75 -        
  138.76 -        FixFactory.removeModifiersFix(info, TreePath.getPath(info.getCompilationUnit(), i.getModifiers()), EnumSet.of(Modifier.PUBLIC), "").implement();
  138.77 -        
  138.78 -        LifecycleManager.getDefault().saveAll();
  138.79 -        
  138.80 -        assertEquals("package test; interface I { }", info.getFileObject().asText());
  138.81 -    }
  138.82 -}
  138.83 \ No newline at end of file
   139.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   139.2 +++ b/sandbox/java.hints/build.sh	Sun Oct 23 11:50:54 2016 +0200
   139.3 @@ -0,0 +1,3 @@
   139.4 +#!/bin/bash
   139.5 +ant "$@" clean && ant "$@" nbms && ant "$@" test || exit 1
   139.6 +
   140.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   140.2 +++ b/sandbox/java.hints/build.xml	Sun Oct 23 11:50:54 2016 +0200
   140.3 @@ -0,0 +1,8 @@
   140.4 +<?xml version="1.0" encoding="UTF-8"?>
   140.5 +<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
   140.6 +<!-- for some information on what you could do (e.g. targets to override). -->
   140.7 +<!-- If you delete this file and reopen the project it will be recreated. -->
   140.8 +<project name="java.hints" basedir=".">
   140.9 +    <description>Builds the module suite java.hints.</description>
  140.10 +    <import file="nbproject/build-impl.xml"/>
  140.11 +</project>
   141.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   141.2 +++ b/sandbox/java.hints/hintsimpl/build.xml	Sun Oct 23 11:50:54 2016 +0200
   141.3 @@ -0,0 +1,8 @@
   141.4 +<?xml version="1.0" encoding="UTF-8"?>
   141.5 +<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
   141.6 +<!-- for some information on what you could do (e.g. targets to override). -->
   141.7 +<!-- If you delete this file and reopen the project it will be recreated. -->
   141.8 +<project name="org.netbeans.modules.jackpot30.hintsimpl" default="netbeans" basedir=".">
   141.9 +    <description>Builds, tests, and runs the project org.netbeans.modules.jackpot30.hintsimpl.</description>
  141.10 +    <import file="nbproject/build-impl.xml"/>
  141.11 +</project>
   142.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   142.2 +++ b/sandbox/java.hints/hintsimpl/manifest.mf	Sun Oct 23 11:50:54 2016 +0200
   142.3 @@ -0,0 +1,5 @@
   142.4 +Manifest-Version: 1.0
   142.5 +OpenIDE-Module: org.netbeans.modules.jackpot30.hintsimpl
   142.6 +OpenIDE-Module-Implementation-Version: 1
   142.7 +OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/jackpot30/hintsimpl/Bundle.properties
   142.8 +
   143.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   143.2 +++ b/sandbox/java.hints/hintsimpl/nbproject/build-impl.xml	Sun Oct 23 11:50:54 2016 +0200
   143.3 @@ -0,0 +1,45 @@
   143.4 +<?xml version="1.0" encoding="UTF-8"?>
   143.5 +<!--
   143.6 +*** GENERATED FROM project.xml - DO NOT EDIT  ***
   143.7 +***         EDIT ../build.xml INSTEAD         ***
   143.8 +-->
   143.9 +<project name="org.netbeans.modules.jackpot30.hintsimpl-impl" basedir="..">
  143.10 +    <fail message="Please build using Ant 1.7.1 or higher.">
  143.11 +        <condition>
  143.12 +            <not>
  143.13 +                <antversion atleast="1.7.1"/>
  143.14 +            </not>
  143.15 +        </condition>
  143.16 +    </fail>
  143.17 +    <property file="nbproject/private/suite-private.properties"/>
  143.18 +    <property file="nbproject/suite.properties"/>
  143.19 +    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
  143.20 +    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
  143.21 +    <property file="${suite.dir}/nbproject/platform.properties"/>
  143.22 +    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
  143.23 +        <attribute name="name"/>
  143.24 +        <attribute name="value"/>
  143.25 +        <sequential>
  143.26 +            <property name="@{name}" value="${@{value}}"/>
  143.27 +        </sequential>
  143.28 +    </macrodef>
  143.29 +    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
  143.30 +        <attribute name="property"/>
  143.31 +        <attribute name="value"/>
  143.32 +        <sequential>
  143.33 +            <property name="@{property}" value="@{value}"/>
  143.34 +        </sequential>
  143.35 +    </macrodef>
  143.36 +    <property file="${user.properties.file}"/>
  143.37 +    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
  143.38 +    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
  143.39 +    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
  143.40 +    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
  143.41 +        <condition>
  143.42 +            <not>
  143.43 +                <contains string="${cluster.path.evaluated}" substring="platform"/>
  143.44 +            </not>
  143.45 +        </condition>
  143.46 +    </fail>
  143.47 +    <import file="${harness.dir}/build.xml"/>
  143.48 +</project>
   144.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   144.2 +++ b/sandbox/java.hints/hintsimpl/nbproject/genfiles.properties	Sun Oct 23 11:50:54 2016 +0200
   144.3 @@ -0,0 +1,8 @@
   144.4 +build.xml.data.CRC32=52580c5f
   144.5 +build.xml.script.CRC32=ef577a91
   144.6 +build.xml.stylesheet.CRC32=a56c6a5b@2.70
   144.7 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
   144.8 +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
   144.9 +nbproject/build-impl.xml.data.CRC32=52580c5f
  144.10 +nbproject/build-impl.xml.script.CRC32=9204f652
  144.11 +nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.70
   145.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   145.2 +++ b/sandbox/java.hints/hintsimpl/nbproject/project.properties	Sun Oct 23 11:50:54 2016 +0200
   145.3 @@ -0,0 +1,5 @@
   145.4 +javac.source=1.7
   145.5 +javac.compilerargs=-Xlint -Xlint:-serial
   145.6 +requires.nb.javac=true
   145.7 +spec.version.base=1.0
   145.8 +test.runner=junit
   146.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   146.2 +++ b/sandbox/java.hints/hintsimpl/nbproject/project.xml	Sun Oct 23 11:50:54 2016 +0200
   146.3 @@ -0,0 +1,232 @@
   146.4 +<?xml version="1.0" encoding="UTF-8"?>
   146.5 +<project xmlns="http://www.netbeans.org/ns/project/1">
   146.6 +    <type>org.netbeans.modules.apisupport.project</type>
   146.7 +    <configuration>
   146.8 +        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
   146.9 +            <code-name-base>org.netbeans.modules.jackpot30.hintsimpl</code-name-base>
  146.10 +            <suite-component/>
  146.11 +            <module-dependencies>
  146.12 +                <dependency>
  146.13 +                    <code-name-base>org.netbeans.api.annotations.common</code-name-base>
  146.14 +                    <build-prerequisite/>
  146.15 +                    <compile-dependency/>
  146.16 +                    <run-dependency>
  146.17 +                        <release-version>1</release-version>
  146.18 +                        <specification-version>1.20</specification-version>
  146.19 +                    </run-dependency>
  146.20 +                </dependency>
  146.21 +                <dependency>
  146.22 +                    <code-name-base>org.netbeans.api.java.classpath</code-name-base>
  146.23 +                    <build-prerequisite/>
  146.24 +                    <compile-dependency/>
  146.25 +                    <run-dependency>
  146.26 +                        <release-version>1</release-version>
  146.27 +                        <specification-version>1.39</specification-version>
  146.28 +                    </run-dependency>
  146.29 +                </dependency>
  146.30 +                <dependency>
  146.31 +                    <code-name-base>org.netbeans.libs.javacapi</code-name-base>
  146.32 +                    <build-prerequisite/>
  146.33 +                    <compile-dependency/>
  146.34 +                    <run-dependency>
  146.35 +                        <specification-version>8.4.0.3</specification-version>
  146.36 +                    </run-dependency>
  146.37 +                </dependency>
  146.38 +                <dependency>
  146.39 +                    <code-name-base>org.netbeans.modules.java.hints</code-name-base>
  146.40 +                    <build-prerequisite/>
  146.41 +                    <compile-dependency/>
  146.42 +                    <run-dependency>
  146.43 +                        <release-version>1</release-version>
  146.44 +                        <implementation-version/>
  146.45 +                    </run-dependency>
  146.46 +                </dependency>
  146.47 +                <dependency>
  146.48 +                    <code-name-base>org.netbeans.modules.java.source</code-name-base>
  146.49 +                    <build-prerequisite/>
  146.50 +                    <compile-dependency/>
  146.51 +                    <run-dependency>
  146.52 +                        <specification-version>0.124.0.24.1.23.6</specification-version>
  146.53 +                    </run-dependency>
  146.54 +                </dependency>
  146.55 +                <dependency>
  146.56 +                    <code-name-base>org.netbeans.modules.java.source.base</code-name-base>
  146.57 +                    <build-prerequisite/>
  146.58 +                    <compile-dependency/>
  146.59 +                    <run-dependency>
  146.60 +                        <specification-version>2.4.1.2.25.8.1</specification-version>
  146.61 +                    </run-dependency>
  146.62 +                </dependency>
  146.63 +                <dependency>
  146.64 +                    <code-name-base>org.netbeans.modules.java.sourceui</code-name-base>
  146.65 +                    <build-prerequisite/>
  146.66 +                    <compile-dependency/>
  146.67 +                    <run-dependency>
  146.68 +                        <release-version>1</release-version>
  146.69 +                        <specification-version>1.33.0.1.25</specification-version>
  146.70 +                    </run-dependency>
  146.71 +                </dependency>
  146.72 +                <dependency>
  146.73 +                    <code-name-base>org.netbeans.modules.queries</code-name-base>
  146.74 +                    <build-prerequisite/>
  146.75 +                    <compile-dependency/>
  146.76 +                    <run-dependency>
  146.77 +                        <release-version>1</release-version>
  146.78 +                        <specification-version>1.36</specification-version>
  146.79 +                    </run-dependency>
  146.80 +                </dependency>
  146.81 +                <dependency>
  146.82 +                    <code-name-base>org.netbeans.modules.refactoring.api</code-name-base>
  146.83 +                    <build-prerequisite/>
  146.84 +                    <compile-dependency/>
  146.85 +                    <run-dependency>
  146.86 +                        <specification-version>1.37.0.1</specification-version>
  146.87 +                    </run-dependency>
  146.88 +                </dependency>
  146.89 +                <dependency>
  146.90 +                    <code-name-base>org.netbeans.modules.refactoring.java</code-name-base>
  146.91 +                    <build-prerequisite/>
  146.92 +                    <compile-dependency/>
  146.93 +                    <run-dependency>
  146.94 +                        <release-version>1</release-version>
  146.95 +                        <implementation-version/>
  146.96 +                    </run-dependency>
  146.97 +                </dependency>
  146.98 +                <dependency>
  146.99 +                    <code-name-base>org.netbeans.spi.editor.hints</code-name-base>
 146.100 +                    <build-prerequisite/>
 146.101 +                    <compile-dependency/>
 146.102 +                    <run-dependency>
 146.103 +                        <release-version>0</release-version>
 146.104 +                        <specification-version>1.31.0.7.42</specification-version>
 146.105 +                    </run-dependency>
 146.106 +                </dependency>
 146.107 +                <dependency>
 146.108 +                    <code-name-base>org.netbeans.spi.java.hints</code-name-base>
 146.109 +                    <build-prerequisite/>
 146.110 +                    <compile-dependency/>
 146.111 +                    <run-dependency>
 146.112 +                        <specification-version>2.0</specification-version>
 146.113 +                    </run-dependency>
 146.114 +                </dependency>
 146.115 +                <dependency>
 146.116 +                    <code-name-base>org.openide.awt</code-name-base>
 146.117 +                    <build-prerequisite/>
 146.118 +                    <compile-dependency/>
 146.119 +                    <run-dependency>
 146.120 +                        <specification-version>7.59</specification-version>
 146.121 +                    </run-dependency>
 146.122 +                </dependency>
 146.123 +                <dependency>
 146.124 +                    <code-name-base>org.openide.filesystems</code-name-base>
 146.125 +                    <build-prerequisite/>
 146.126 +                    <compile-dependency/>
 146.127 +                    <run-dependency>
 146.128 +                        <specification-version>8.8</specification-version>
 146.129 +                    </run-dependency>
 146.130 +                </dependency>
 146.131 +                <dependency>
 146.132 +                    <code-name-base>org.openide.loaders</code-name-base>
 146.133 +                    <build-prerequisite/>
 146.134 +                    <compile-dependency/>
 146.135 +                    <run-dependency>
 146.136 +                        <specification-version>7.50</specification-version>
 146.137 +                    </run-dependency>
 146.138 +                </dependency>
 146.139 +                <dependency>
 146.140 +                    <code-name-base>org.openide.nodes</code-name-base>
 146.141 +                    <build-prerequisite/>
 146.142 +                    <compile-dependency/>
 146.143 +                    <run-dependency>
 146.144 +                        <specification-version>7.36</specification-version>
 146.145 +                    </run-dependency>
 146.146 +                </dependency>
 146.147 +                <dependency>
 146.148 +                    <code-name-base>org.openide.text</code-name-base>
 146.149 +                    <build-prerequisite/>
 146.150 +                    <compile-dependency/>
 146.151 +                    <run-dependency>
 146.152 +                        <specification-version>6.57</specification-version>
 146.153 +                    </run-dependency>
 146.154 +                </dependency>
 146.155 +                <dependency>
 146.156 +                    <code-name-base>org.openide.util</code-name-base>
 146.157 +                    <build-prerequisite/>
 146.158 +                    <compile-dependency/>
 146.159 +                    <run-dependency>
 146.160 +                        <specification-version>8.32</specification-version>
 146.161 +                    </run-dependency>
 146.162 +                </dependency>
 146.163 +                <dependency>
 146.164 +                    <code-name-base>org.openide.util.lookup</code-name-base>
 146.165 +                    <build-prerequisite/>
 146.166 +                    <compile-dependency/>
 146.167 +                    <run-dependency>
 146.168 +                        <specification-version>8.22</specification-version>
 146.169 +                    </run-dependency>
 146.170 +                </dependency>
 146.171 +                <dependency>
 146.172 +                    <code-name-base>org.openide.util.ui</code-name-base>
 146.173 +                    <build-prerequisite/>
 146.174 +                    <compile-dependency/>
 146.175 +                    <run-dependency>
 146.176 +                        <specification-version>9.3</specification-version>
 146.177 +                    </run-dependency>
 146.178 +                </dependency>
 146.179 +                <dependency>
 146.180 +                    <code-name-base>org.openide.windows</code-name-base>
 146.181 +                    <build-prerequisite/>
 146.182 +                    <compile-dependency/>
 146.183 +                    <run-dependency>
 146.184 +                        <specification-version>6.64</specification-version>
 146.185 +                    </run-dependency>
 146.186 +                </dependency>
 146.187 +            </module-dependencies>
 146.188 +            <test-dependencies>
 146.189 +                <test-type>
 146.190 +                    <name>unit</name>
 146.191 +                    <test-dependency>
 146.192 +                        <code-name-base>org.netbeans.libs.junit4</code-name-base>
 146.193 +                        <compile-dependency/>
 146.194 +                    </test-dependency>
 146.195 +                    <test-dependency>
 146.196 +                        <code-name-base>org.netbeans.libs.testng</code-name-base>
 146.197 +                        <compile-dependency/>
 146.198 +                    </test-dependency>
 146.199 +                    <test-dependency>
 146.200 +                        <code-name-base>org.netbeans.modules.editor.mimelookup.impl</code-name-base>
 146.201 +                        <compile-dependency/>
 146.202 +                    </test-dependency>
 146.203 +                    <test-dependency>
 146.204 +                        <code-name-base>org.netbeans.modules.jackpot30.test.borrowed</code-name-base>
 146.205 +                        <compile-dependency/>
 146.206 +                    </test-dependency>
 146.207 +                    <test-dependency>
 146.208 +                        <code-name-base>org.netbeans.modules.java.editor</code-name-base>
 146.209 +                        <recursive/>
 146.210 +                        <compile-dependency/>
 146.211 +                    </test-dependency>
 146.212 +                    <test-dependency>
 146.213 +                        <code-name-base>org.netbeans.modules.java.hints.test</code-name-base>
 146.214 +                        <recursive/>
 146.215 +                        <compile-dependency/>
 146.216 +                    </test-dependency>
 146.217 +                    <test-dependency>
 146.218 +                        <code-name-base>org.netbeans.modules.parsing.nb</code-name-base>
 146.219 +                        <compile-dependency/>
 146.220 +                    </test-dependency>
 146.221 +                    <test-dependency>
 146.222 +                        <code-name-base>org.netbeans.modules.projectapi.nb</code-name-base>
 146.223 +                        <compile-dependency/>
 146.224 +                    </test-dependency>
 146.225 +                    <test-dependency>
 146.226 +                        <code-name-base>org.netbeans.spi.java.hints</code-name-base>
 146.227 +                        <compile-dependency/>
 146.228 +                        <test/>
 146.229 +                    </test-dependency>
 146.230 +                </test-type>
 146.231 +            </test-dependencies>
 146.232 +            <public-packages/>
 146.233 +        </data>
 146.234 +    </configuration>
 146.235 +</project>
   147.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   147.2 +++ b/sandbox/java.hints/hintsimpl/nbproject/suite.properties	Sun Oct 23 11:50:54 2016 +0200
   147.3 @@ -0,0 +1,1 @@
   147.4 +suite.dir=${basedir}/..
   148.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   148.2 +++ b/sandbox/java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/Bundle.properties	Sun Oct 23 11:50:54 2016 +0200
   148.3 @@ -0,0 +1,1 @@
   148.4 +OpenIDE-Module-Name=Jackpot 3.0 Experimental Hints Impl
   149.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   149.2 +++ b/sandbox/java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/GlobalyUnused.java	Sun Oct 23 11:50:54 2016 +0200
   149.3 @@ -0,0 +1,120 @@
   149.4 +/*
   149.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   149.6 + *
   149.7 + * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
   149.8 + *
   149.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  149.10 + * Other names may be trademarks of their respective owners.
  149.11 + *
  149.12 + * The contents of this file are subject to the terms of either the GNU
  149.13 + * General Public License Version 2 only ("GPL") or the Common
  149.14 + * Development and Distribution License("CDDL") (collectively, the
  149.15 + * "License"). You may not use this file except in compliance with the
  149.16 + * License. You can obtain a copy of the License at
  149.17 + * http://www.netbeans.org/cddl-gplv2.html
  149.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  149.19 + * specific language governing permissions and limitations under the
  149.20 + * License.  When distributing the software, include this License Header
  149.21 + * Notice in each file and include the License file at
  149.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  149.23 + * particular file as subject to the "Classpath" exception as provided
  149.24 + * by Oracle in the GPL Version 2 section of the License file that
  149.25 + * accompanied this code. If applicable, add the following below the
  149.26 + * License Header, with the fields enclosed by brackets [] replaced by
  149.27 + * your own identifying information:
  149.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  149.29 + *
  149.30 + * If you wish your version of this file to be governed by only the CDDL
  149.31 + * or only the GPL Version 2, indicate your decision by adding
  149.32 + * "[Contributor] elects to include this software in this distribution
  149.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  149.34 + * single choice of license, a recipient has the option to distribute
  149.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  149.36 + * to extend the choice of license to its licensees as provided above.
  149.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  149.38 + * Version 2 license, then the option applies only if the new code is
  149.39 + * made subject to such option by the copyright holder.
  149.40 + *
  149.41 + * Contributor(s):
  149.42 + *
  149.43 + * Portions Copyrighted 2013 Sun Microsystems, Inc.
  149.44 + */
  149.45 +package org.netbeans.modules.jackpot30.hintsimpl;
  149.46 +
  149.47 +import com.sun.source.tree.Tree.Kind;
  149.48 +import javax.lang.model.element.Element;
  149.49 +import javax.lang.model.element.ElementKind;
  149.50 +import javax.lang.model.type.TypeKind;
  149.51 +import org.netbeans.api.java.source.TreePathHandle;
  149.52 +import org.netbeans.spi.editor.hints.ErrorDescription;
  149.53 +import org.netbeans.spi.java.hints.Decision;
  149.54 +import org.netbeans.spi.java.hints.Decision.Factory;
  149.55 +import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
  149.56 +import org.netbeans.spi.java.hints.Hint;
  149.57 +import org.netbeans.spi.java.hints.HintContext;
  149.58 +import org.netbeans.spi.java.hints.TriggerDecision;
  149.59 +import org.netbeans.spi.java.hints.TriggerTreeKind;
  149.60 +
  149.61 +/**
  149.62 + *
  149.63 + * @author lahvac
  149.64 + */
  149.65 +@Hint(displayName="Unused", description="Unused", category="general")
  149.66 +public class GlobalyUnused {
  149.67 +    
  149.68 +    @TriggerTreeKind({Kind.IDENTIFIER, Kind.MEMBER_SELECT})
  149.69 +    public static ErrorDescription usage(HintContext ctx) {
  149.70 +        DecisionImpl d = decisionOrNull(ctx);
  149.71 +        
  149.72 +        if (d != null) {
  149.73 +            System.err.println("recording usage");
  149.74 +            d.recordLocalFact(ctx.getInfo(), null);
  149.75 +        }
  149.76 +        
  149.77 +        return null;
  149.78 +    }
  149.79 +    
  149.80 +    @TriggerTreeKind({Kind.CLASS})
  149.81 +    public static ErrorDescription declaration(HintContext ctx) {
  149.82 +        decisionOrNull(ctx);
  149.83 +        return null;
  149.84 +    }
  149.85 +    
  149.86 +    @TriggerDecision(DecisionImpl.class)
  149.87 +    public static ErrorDescription produceWarning(HintContext ctx) {
  149.88 +        if (((DecisionImpl) ctx.decision).getCurrentResult() != Boolean.TRUE) {
  149.89 +            return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), "Unused");
  149.90 +        }
  149.91 +        
  149.92 +        return null;
  149.93 +    }
  149.94 +    
  149.95 +    private static DecisionImpl decisionOrNull(HintContext ctx) {
  149.96 +        Element el = ctx.getInfo().getTrees().getElement(ctx.getPath());
  149.97 +        
  149.98 +        if (el == null || (el.asType() != null && el.asType().getKind() == TypeKind.ERROR) || el.getKind() != ElementKind.CLASS) return null;
  149.99 +        
 149.100 +        TreePathHandle h = TreePathHandle.create(el, ctx.getInfo());
 149.101 +        
 149.102 +        System.err.println("decision for: " + el);
 149.103 +        return ctx.findDecision(h, new Factory<Void, Boolean, DecisionImpl>(DecisionImpl.class) {
 149.104 +            @Override
 149.105 +            public DecisionImpl create(TreePathHandle handle) {
 149.106 +                return new DecisionImpl(handle);
 149.107 +            }
 149.108 +        });
 149.109 +    }
 149.110 +    
 149.111 +    private static final class DecisionImpl extends Decision<Void, Boolean> {
 149.112 +
 149.113 +        public DecisionImpl(TreePathHandle root) {
 149.114 +            super(root);
 149.115 +        }
 149.116 +
 149.117 +        @Override
 149.118 +        protected Boolean makeDecision(Iterable<? extends Void> input) {
 149.119 +            return input.iterator().hasNext();
 149.120 +        }
 149.121 +        
 149.122 +    }
 149.123 +}
   150.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   150.2 +++ b/sandbox/java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/NonPrivateMakeFinal.java	Sun Oct 23 11:50:54 2016 +0200
   150.3 @@ -0,0 +1,152 @@
   150.4 +/*
   150.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   150.6 + *
   150.7 + * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
   150.8 + *
   150.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  150.10 + * Other names may be trademarks of their respective owners.
  150.11 + *
  150.12 + * The contents of this file are subject to the terms of either the GNU
  150.13 + * General Public License Version 2 only ("GPL") or the Common
  150.14 + * Development and Distribution License("CDDL") (collectively, the
  150.15 + * "License"). You may not use this file except in compliance with the
  150.16 + * License. You can obtain a copy of the License at
  150.17 + * http://www.netbeans.org/cddl-gplv2.html
  150.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  150.19 + * specific language governing permissions and limitations under the
  150.20 + * License.  When distributing the software, include this License Header
  150.21 + * Notice in each file and include the License file at
  150.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  150.23 + * particular file as subject to the "Classpath" exception as provided
  150.24 + * by Oracle in the GPL Version 2 section of the License file that
  150.25 + * accompanied this code. If applicable, add the following below the
  150.26 + * License Header, with the fields enclosed by brackets [] replaced by
  150.27 + * your own identifying information:
  150.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  150.29 + *
  150.30 + * If you wish your version of this file to be governed by only the CDDL
  150.31 + * or only the GPL Version 2, indicate your decision by adding
  150.32 + * "[Contributor] elects to include this software in this distribution
  150.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  150.34 + * single choice of license, a recipient has the option to distribute
  150.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  150.36 + * to extend the choice of license to its licensees as provided above.
  150.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  150.38 + * Version 2 license, then the option applies only if the new code is
  150.39 + * made subject to such option by the copyright holder.
  150.40 + *
  150.41 + * Contributor(s):
  150.42 + *
  150.43 + * Portions Copyrighted 2013 Sun Microsystems, Inc.
  150.44 + */
  150.45 +package org.netbeans.modules.jackpot30.hintsimpl;
  150.46 +
  150.47 +import com.sun.source.tree.Tree.Kind;
  150.48 +import com.sun.source.tree.VariableTree;
  150.49 +import com.sun.source.util.TreePath;
  150.50 +import java.util.EnumSet;
  150.51 +import javax.lang.model.element.Element;
  150.52 +import javax.lang.model.element.ElementKind;
  150.53 +import javax.lang.model.element.Modifier;
  150.54 +import javax.lang.model.element.VariableElement;
  150.55 +import org.netbeans.api.annotations.common.NonNull;
  150.56 +import org.netbeans.api.java.source.TreePathHandle;
  150.57 +import org.netbeans.modules.java.hints.introduce.Flow;
  150.58 +import org.netbeans.modules.java.hints.introduce.Flow.FlowResult;
  150.59 +import org.netbeans.spi.editor.hints.ErrorDescription;
  150.60 +import org.netbeans.spi.editor.hints.Fix;
  150.61 +import org.netbeans.spi.java.hints.Decision;
  150.62 +import org.netbeans.spi.java.hints.Decision.Factory;
  150.63 +import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
  150.64 +import org.netbeans.spi.java.hints.Hint;
  150.65 +import org.netbeans.spi.java.hints.HintContext;
  150.66 +import org.netbeans.spi.java.hints.TriggerDecision;
  150.67 +import org.netbeans.spi.java.hints.TriggerPattern;
  150.68 +import org.netbeans.spi.java.hints.TriggerTreeKind;
  150.69 +import org.netbeans.spi.java.hints.support.FixFactory;
  150.70 +import org.openide.util.NbBundle.Messages;
  150.71 +
  150.72 +/**
  150.73 + *
  150.74 + * @author lahvac
  150.75 + */
  150.76 +@Hint(displayName="Non Private Make Final", description="Non Private Make Final", category="general")
  150.77 +public class NonPrivateMakeFinal {
  150.78 +
  150.79 +    @TriggerPattern("$variable = $value")
  150.80 +    public static ErrorDescription write(HintContext ctx) {
  150.81 +        Element field = ctx.getInfo().getTrees().getElement(ctx.getVariables().get("$variable"));
  150.82 +
  150.83 +        if (field == null || field.getKind() != ElementKind.FIELD) {
  150.84 +            //unknown, or not a field, ignore.
  150.85 +            return null;
  150.86 +        }
  150.87 +
  150.88 +        if (ctx.getInfo().getTopLevelElements().contains(ctx.getInfo().getElementUtilities().outermostTypeElement(field))) {
  150.89 +            //field in current CU, ignore (will be handled by local flow)
  150.90 +            return null;
  150.91 +        }
  150.92 +
  150.93 +        decision(ctx, (VariableElement) field).recordLocalFact(ctx.getInfo(), false);
  150.94 +        
  150.95 +        return null;
  150.96 +    }
  150.97 +    
  150.98 +    @TriggerTreeKind({Kind.VARIABLE})
  150.99 +    public static ErrorDescription declaration(HintContext ctx) {
 150.100 +        Element ve = ctx.getInfo().getTrees().getElement(ctx.getPath());
 150.101 +
 150.102 +        if (ve == null || ve.getKind() != ElementKind.FIELD || ve.getModifiers().contains(Modifier.FINAL) || /*TODO: the point of volatile?*/ve.getModifiers().contains(Modifier.VOLATILE)) return null;
 150.103 +
 150.104 +        //handle all fields, even the private ones, which are handled by the standard hints.
 150.105 +        
 150.106 +        FlowResult flow = Flow.assignmentsForUse(ctx);
 150.107 +
 150.108 +        if (flow == null || ctx.isCanceled()) return null;
 150.109 +
 150.110 +        DecisionImpl decision = decision(ctx, (VariableElement) ve);
 150.111 +
 150.112 +        decision.recordLocalFact(ctx.getInfo(), flow.getFinalCandidates().contains((VariableElement) ve));
 150.113 +
 150.114 +        return null;
 150.115 +    }
 150.116 +    
 150.117 +    @TriggerDecision(DecisionImpl.class)
 150.118 +    @Messages("FIX_CanBeFinal={0} can be final")
 150.119 +    public static ErrorDescription produceWarning(HintContext ctx) {
 150.120 +        if (((DecisionImpl) ctx.decision).getCurrentResult() == Boolean.TRUE) {
 150.121 +            VariableTree vt = (VariableTree) ctx.getPath().getLeaf();
 150.122 +            Fix fix = FixFactory.addModifiersFix(ctx.getInfo(), new TreePath(ctx.getPath(), vt.getModifiers()), EnumSet.of(Modifier.FINAL), Bundle.FIX_CanBeFinal(vt.getName().toString()));
 150.123 +            return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), "Can be final", fix);
 150.124 +        }
 150.125 +        
 150.126 +        return null;
 150.127 +    }
 150.128 +    
 150.129 +    private static @NonNull DecisionImpl decision(HintContext ctx, @NonNull VariableElement field) {
 150.130 +        TreePathHandle h = TreePathHandle.create(field, ctx.getInfo());
 150.131 +        
 150.132 +        return ctx.findDecision(h, new Factory<Boolean, Boolean, DecisionImpl>(DecisionImpl.class) {
 150.133 +            @Override
 150.134 +            public DecisionImpl create(TreePathHandle handle) {
 150.135 +                return new DecisionImpl(handle);
 150.136 +            }
 150.137 +        });
 150.138 +    }
 150.139 +    
 150.140 +    private static final class DecisionImpl extends Decision<Boolean, Boolean> {
 150.141 +
 150.142 +        public DecisionImpl(TreePathHandle root) {
 150.143 +            super(root);
 150.144 +        }
 150.145 +
 150.146 +        @Override
 150.147 +        protected Boolean makeDecision(Iterable<? extends Boolean> input) {
 150.148 +            for (Boolean b : input) {
 150.149 +                if (b == null || !b) return false;
 150.150 +            }
 150.151 +            return true;
 150.152 +        }
 150.153 +        
 150.154 +    }
 150.155 +}
   151.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   151.2 +++ b/sandbox/java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/duplicates/DuplicateMethodRefactoring.java	Sun Oct 23 11:50:54 2016 +0200
   151.3 @@ -0,0 +1,58 @@
   151.4 +/*
   151.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   151.6 + *
   151.7 + * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
   151.8 + *
   151.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  151.10 + * Other names may be trademarks of their respective owners.
  151.11 + *
  151.12 + * The contents of this file are subject to the terms of either the GNU
  151.13 + * General Public License Version 2 only ("GPL") or the Common
  151.14 + * Development and Distribution License("CDDL") (collectively, the
  151.15 + * "License"). You may not use this file except in compliance with the
  151.16 + * License. You can obtain a copy of the License at
  151.17 + * http://www.netbeans.org/cddl-gplv2.html
  151.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  151.19 + * specific language governing permissions and limitations under the
  151.20 + * License.  When distributing the software, include this License Header
  151.21 + * Notice in each file and include the License file at
  151.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  151.23 + * particular file as subject to the "Classpath" exception as provided
  151.24 + * by Oracle in the GPL Version 2 section of the License file that
  151.25 + * accompanied this code. If applicable, add the following below the
  151.26 + * License Header, with the fields enclosed by brackets [] replaced by
  151.27 + * your own identifying information:
  151.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  151.29 + *
  151.30 + * If you wish your version of this file to be governed by only the CDDL
  151.31 + * or only the GPL Version 2, indicate your decision by adding
  151.32 + * "[Contributor] elects to include this software in this distribution
  151.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  151.34 + * single choice of license, a recipient has the option to distribute
  151.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  151.36 + * to extend the choice of license to its licensees as provided above.
  151.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  151.38 + * Version 2 license, then the option applies only if the new code is
  151.39 + * made subject to such option by the copyright holder.
  151.40 + *
  151.41 + * Contributor(s):
  151.42 + *
  151.43 + * Portions Copyrighted 2013 Sun Microsystems, Inc.
  151.44 + */
  151.45 +package org.netbeans.modules.jackpot30.hintsimpl.duplicates;
  151.46 +
  151.47 +import org.netbeans.api.java.source.TreePathHandle;
  151.48 +import org.netbeans.modules.refactoring.api.AbstractRefactoring;
  151.49 +import org.openide.util.lookup.Lookups;
  151.50 +
  151.51 +/**
  151.52 + *
  151.53 + * @author lahvac
  151.54 + */
  151.55 +public class DuplicateMethodRefactoring extends AbstractRefactoring {
  151.56 +
  151.57 +    public DuplicateMethodRefactoring(TreePathHandle source) {
  151.58 +        super(Lookups.singleton(source));
  151.59 +    }
  151.60 +
  151.61 +}
   152.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   152.2 +++ b/sandbox/java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/duplicates/DuplicateMethodRefactoringAction.java	Sun Oct 23 11:50:54 2016 +0200
   152.3 @@ -0,0 +1,84 @@
   152.4 +/*
   152.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   152.6 + *
   152.7 + * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
   152.8 + *
   152.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  152.10 + * Other names may be trademarks of their respective owners.
  152.11 + *
  152.12 + * The contents of this file are subject to the terms of either the GNU
  152.13 + * General Public License Version 2 only ("GPL") or the Common
  152.14 + * Development and Distribution License("CDDL") (collectively, the
  152.15 + * "License"). You may not use this file except in compliance with the
  152.16 + * License. You can obtain a copy of the License at
  152.17 + * http://www.netbeans.org/cddl-gplv2.html
  152.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  152.19 + * specific language governing permissions and limitations under the
  152.20 + * License.  When distributing the software, include this License Header
  152.21 + * Notice in each file and include the License file at
  152.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  152.23 + * particular file as subject to the "Classpath" exception as provided
  152.24 + * by Oracle in the GPL Version 2 section of the License file that
  152.25 + * accompanied this code. If applicable, add the following below the
  152.26 + * License Header, with the fields enclosed by brackets [] replaced by
  152.27 + * your own identifying information:
  152.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  152.29 + *
  152.30 + * If you wish your version of this file to be governed by only the CDDL
  152.31 + * or only the GPL Version 2, indicate your decision by adding
  152.32 + * "[Contributor] elects to include this software in this distribution
  152.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  152.34 + * single choice of license, a recipient has the option to distribute
  152.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  152.36 + * to extend the choice of license to its licensees as provided above.
  152.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  152.38 + * Version 2 license, then the option applies only if the new code is
  152.39 + * made subject to such option by the copyright holder.
  152.40 + *
  152.41 + * Contributor(s):
  152.42 + *
  152.43 + * Portions Copyrighted 2013 Sun Microsystems, Inc.
  152.44 + */
  152.45 +package org.netbeans.modules.jackpot30.hintsimpl.duplicates;
  152.46 +
  152.47 +import com.sun.source.tree.Tree.Kind;
  152.48 +import java.awt.event.ActionEvent;
  152.49 +import java.awt.event.ActionListener;
  152.50 +import org.netbeans.api.fileinfo.NonRecursiveFolder;
  152.51 +import org.netbeans.api.java.source.CompilationInfo;
  152.52 +import org.netbeans.api.java.source.TreePathHandle;
  152.53 +import org.netbeans.api.java.source.ui.ScanDialog;
  152.54 +import org.netbeans.modules.refactoring.java.ui.ContextAnalyzer;
  152.55 +import org.netbeans.modules.refactoring.java.ui.JavaRefactoringUIFactory;
  152.56 +import org.netbeans.modules.refactoring.spi.ui.RefactoringUI;
  152.57 +import org.openide.awt.ActionID;
  152.58 +import org.openide.awt.ActionReference;
  152.59 +import org.openide.awt.ActionRegistration;
  152.60 +import org.openide.filesystems.FileObject;
  152.61 +import org.openide.util.NbBundle.Messages;
  152.62 +import org.openide.util.Utilities;
  152.63 +
  152.64 +@ActionID(
  152.65 +        category = "Refactoring",
  152.66 +        id = "org.netbeans.modules.jackpot30.hintsimpl.duplicates.DuplicateMethodRefactoringAction")
  152.67 +@ActionRegistration(
  152.68 +        displayName = "#CTL_DuplicateMethodRefactoringAction")
  152.69 +@ActionReference(path = "Menu/Refactoring", position = 1120)
  152.70 +@Messages("CTL_DuplicateMethodRefactoringAction=Find and Replace Duplicates...")
  152.71 +public final class DuplicateMethodRefactoringAction implements ActionListener {
  152.72 +
  152.73 +    @Override
  152.74 +    public void actionPerformed(ActionEvent e) {
  152.75 +        Runnable task = ContextAnalyzer.createTask(Utilities.actionsGlobalContext()/*!!!*/, new JavaRefactoringUIFactory() {
  152.76 +            @Override public RefactoringUI create(CompilationInfo info, TreePathHandle[] handles, FileObject[] files, NonRecursiveFolder[] packages) {
  152.77 +                //todo: more precise verification of refactoring feasibility:
  152.78 +                return handles.length == 1 && handles[0].getKind() == Kind.METHOD ? new DuplicateMethodRefactoringUI(handles[0]) : null;
  152.79 +            }
  152.80 +        });
  152.81 +        ScanDialog.runWhenScanFinished(task, "Find&Replace Duplicates");
  152.82 +    }
  152.83 +
  152.84 +    public boolean isEnabled() {
  152.85 +        return ContextAnalyzer.canRefactorSingle(Utilities.actionsGlobalContext()/*!!!*/, true, true);
  152.86 +    }
  152.87 +}
   153.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   153.2 +++ b/sandbox/java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/duplicates/DuplicateMethodRefactoringPlugin.java	Sun Oct 23 11:50:54 2016 +0200
   153.3 @@ -0,0 +1,183 @@
   153.4 +/*
   153.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   153.6 + *
   153.7 + * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
   153.8 + *
   153.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  153.10 + * Other names may be trademarks of their respective owners.
  153.11 + *
  153.12 + * The contents of this file are subject to the terms of either the GNU
  153.13 + * General Public License Version 2 only ("GPL") or the Common
  153.14 + * Development and Distribution License("CDDL") (collectively, the
  153.15 + * "License"). You may not use this file except in compliance with the
  153.16 + * License. You can obtain a copy of the License at
  153.17 + * http://www.netbeans.org/cddl-gplv2.html
  153.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  153.19 + * specific language governing permissions and limitations under the
  153.20 + * License.  When distributing the software, include this License Header
  153.21 + * Notice in each file and include the License file at
  153.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  153.23 + * particular file as subject to the "Classpath" exception as provided
  153.24 + * by Oracle in the GPL Version 2 section of the License file that
  153.25 + * accompanied this code. If applicable, add the following below the
  153.26 + * License Header, with the fields enclosed by brackets [] replaced by
  153.27 + * your own identifying information:
  153.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  153.29 + *
  153.30 + * If you wish your version of this file to be governed by only the CDDL
  153.31 + * or only the GPL Version 2, indicate your decision by adding
  153.32 + * "[Contributor] elects to include this software in this distribution
  153.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  153.34 + * single choice of license, a recipient has the option to distribute
  153.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  153.36 + * to extend the choice of license to its licensees as provided above.
  153.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  153.38 + * Version 2 license, then the option applies only if the new code is
  153.39 + * made subject to such option by the copyright holder.
  153.40 + *
  153.41 + * Contributor(s):
  153.42 + *
  153.43 + * Portions Copyrighted 2013 Sun Microsystems, Inc.
  153.44 + */
  153.45 +package org.netbeans.modules.jackpot30.hintsimpl.duplicates;
  153.46 +
  153.47 +import com.sun.source.tree.BlockTree;
  153.48 +import com.sun.source.tree.ExpressionTree;
  153.49 +import com.sun.source.tree.MethodInvocationTree;
  153.50 +import com.sun.source.tree.MethodTree;
  153.51 +import com.sun.source.tree.StatementTree;
  153.52 +import com.sun.source.util.TreePath;
  153.53 +import java.net.URL;
  153.54 +import java.util.ArrayList;
  153.55 +import java.util.Collection;
  153.56 +import java.util.Collections;
  153.57 +import java.util.Enumeration;
  153.58 +import java.util.HashSet;
  153.59 +import java.util.List;
  153.60 +import java.util.Set;
  153.61 +import javax.lang.model.element.Element;
  153.62 +import javax.lang.model.element.ExecutableElement;
  153.63 +import javax.lang.model.element.VariableElement;
  153.64 +import org.netbeans.api.java.source.CancellableTask;
  153.65 +import org.netbeans.api.java.source.ClasspathInfo;
  153.66 +import org.netbeans.api.java.source.ClasspathInfo.PathKind;
  153.67 +import org.netbeans.api.java.source.JavaSource;
  153.68 +import org.netbeans.api.java.source.SourceUtils;
  153.69 +import org.netbeans.api.java.source.TreeMaker;
  153.70 +import org.netbeans.api.java.source.TreePathHandle;
  153.71 +import org.netbeans.api.java.source.WorkingCopy;
  153.72 +import org.netbeans.api.java.source.matching.Matcher;
  153.73 +import org.netbeans.api.java.source.matching.Occurrence;
  153.74 +import org.netbeans.api.java.source.matching.Pattern;
  153.75 +import org.netbeans.modules.refactoring.api.Problem;
  153.76 +import org.netbeans.modules.refactoring.java.spi.JavaRefactoringPlugin;
  153.77 +import org.netbeans.modules.refactoring.spi.RefactoringElementsBag;
  153.78 +import org.openide.filesystems.FileObject;
  153.79 +import org.openide.filesystems.FileUtil;
  153.80 +import org.openide.filesystems.URLMapper;
  153.81 +
  153.82 +/**
  153.83 + *
  153.84 + * @author lahvac
  153.85 + */
  153.86 +public class DuplicateMethodRefactoringPlugin extends JavaRefactoringPlugin {
  153.87 +    private final DuplicateMethodRefactoring refactoring;
  153.88 +
  153.89 +    DuplicateMethodRefactoringPlugin(DuplicateMethodRefactoring refactoring) {
  153.90 +        this.refactoring = refactoring;
  153.91 +    }
  153.92 +
  153.93 +    @Override
  153.94 +    public Problem preCheck() {
  153.95 +        return null;
  153.96 +    }
  153.97 +
  153.98 +    @Override
  153.99 +    public Problem checkParameters() {
 153.100 +        return null;
 153.101 +    }
 153.102 +
 153.103 +    @Override
 153.104 +    public Problem fastCheckParameters() {
 153.105 +        return null;
 153.106 +    }
 153.107 +
 153.108 +    @Override
 153.109 +    public void cancelRequest() {
 153.110 +    }
 153.111 +
 153.112 +    @Override
 153.113 +    public Problem prepare(RefactoringElementsBag refactoringElements) {
 153.114 +        final TreePathHandle source = refactoring.getRefactoringSource().lookup(TreePathHandle.class);
 153.115 +        Set<URL> dependent = new HashSet<>();
 153.116 +
 153.117 +        for (FileObject root : ClasspathInfo.create(source.getFileObject()).getClassPath(PathKind.SOURCE).getRoots()) {
 153.118 +            dependent.add(root.toURL());
 153.119 +            dependent.addAll(SourceUtils.getDependentRoots(root.toURL()));
 153.120 +        }
 153.121 +
 153.122 +        Set<FileObject> files = new HashSet<>();
 153.123 +
 153.124 +        for (URL root : dependent) {
 153.125 +            FileObject rootFO = URLMapper.findFileObject(root);
 153.126 +
 153.127 +            if (rootFO == null) continue;
 153.128 +
 153.129 +            for (Enumeration<? extends FileObject> en = rootFO.getChildren(true); en.hasMoreElements(); ){
 153.130 +                FileObject file = en.nextElement();
 153.131 +
 153.132 +                if (file.isData() && "text/x-java".equals(FileUtil.getMIMEType(file, "text/x-java"))) {
 153.133 +                    files.add(file);
 153.134 +                }
 153.135 +            }
 153.136 +        }
 153.137 +
 153.138 +        return createAndAddElements(files, new CancellableTask<WorkingCopy>() {
 153.139 +            @Override public void cancel() {
 153.140 +                //TODO - is used? if yes, implement.
 153.141 +            }
 153.142 +            @Override public void run(WorkingCopy parameter) throws Exception {
 153.143 +                if (parameter.toPhase(org.netbeans.api.java.source.JavaSource.Phase.RESOLVED).compareTo(org.netbeans.api.java.source.JavaSource.Phase.RESOLVED) < 0) {
 153.144 +                    return ;
 153.145 +                }
 153.146 +
 153.147 +                Element methodElement = source.getElementHandle().resolve(parameter);
 153.148 +                TreePath method = parameter.getTrees().getPath(methodElement);
 153.149 +
 153.150 +                if (method == null) {
 153.151 +                    //nothing to do
 153.152 +                    //TODO: create a problem
 153.153 +                    return ;
 153.154 +                }
 153.155 +
 153.156 +                BlockTree content = ((MethodTree) method.getLeaf()).getBody();
 153.157 +                TreePath bodyPath = new TreePath(method, content);
 153.158 +                List<TreePath> statements = new ArrayList<>();
 153.159 +
 153.160 +                for (StatementTree st : content.getStatements()) {
 153.161 +                    statements.add(new TreePath(bodyPath, st));
 153.162 +                }
 153.163 +
 153.164 +                List<? extends VariableElement> formalParameters = ((ExecutableElement) methodElement).getParameters();
 153.165 +                Pattern pattern = Pattern.createPatternWithRemappableVariables(statements, formalParameters, true);
 153.166 +                Collection<? extends Occurrence> found = Matcher.create(parameter).setCancel(cancelRequested).setSearchRoot(new TreePath(parameter.getCompilationUnit())).match(pattern);
 153.167 +                TreeMaker make = parameter.getTreeMaker();
 153.168 +
 153.169 +                for (Occurrence occ : found) {
 153.170 +                    List<ExpressionTree> newParams = new ArrayList<>();
 153.171 +                    for (VariableElement p : formalParameters) {
 153.172 +                        newParams.add((ExpressionTree) occ.getVariablesRemapToTrees().get(p).getLeaf());
 153.173 +                    }
 153.174 +                    MethodInvocationTree newCall = make.MethodInvocation(Collections.<ExpressionTree>emptyList(), make.QualIdent(methodElement), newParams);
 153.175 +                    parameter.rewrite(occ.getOccurrenceRoot().getLeaf(), make.ExpressionStatement(newCall));
 153.176 +                }
 153.177 +            }
 153.178 +        }, refactoringElements, refactoring);
 153.179 +    }
 153.180 +
 153.181 +    @Override
 153.182 +    protected JavaSource getJavaSource(Phase p) {
 153.183 +        return null;
 153.184 +    }
 153.185 +
 153.186 +}
   154.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   154.2 +++ b/sandbox/java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/duplicates/DuplicateMethodRefactoringUI.java	Sun Oct 23 11:50:54 2016 +0200
   154.3 @@ -0,0 +1,108 @@
   154.4 +/*
   154.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   154.6 + *
   154.7 + * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
   154.8 + *
   154.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  154.10 + * Other names may be trademarks of their respective owners.
  154.11 + *
  154.12 + * The contents of this file are subject to the terms of either the GNU
  154.13 + * General Public License Version 2 only ("GPL") or the Common
  154.14 + * Development and Distribution License("CDDL") (collectively, the
  154.15 + * "License"). You may not use this file except in compliance with the
  154.16 + * License. You can obtain a copy of the License at
  154.17 + * http://www.netbeans.org/cddl-gplv2.html
  154.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  154.19 + * specific language governing permissions and limitations under the
  154.20 + * License.  When distributing the software, include this License Header
  154.21 + * Notice in each file and include the License file at
  154.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  154.23 + * particular file as subject to the "Classpath" exception as provided
  154.24 + * by Oracle in the GPL Version 2 section of the License file that
  154.25 + * accompanied this code. If applicable, add the following below the
  154.26 + * License Header, with the fields enclosed by brackets [] replaced by
  154.27 + * your own identifying information:
  154.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  154.29 + *
  154.30 + * If you wish your version of this file to be governed by only the CDDL
  154.31 + * or only the GPL Version 2, indicate your decision by adding
  154.32 + * "[Contributor] elects to include this software in this distribution
  154.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  154.34 + * single choice of license, a recipient has the option to distribute
  154.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  154.36 + * to extend the choice of license to its licensees as provided above.
  154.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  154.38 + * Version 2 license, then the option applies only if the new code is
  154.39 + * made subject to such option by the copyright holder.
  154.40 + *
  154.41 + * Contributor(s):
  154.42 + *
  154.43 + * Portions Copyrighted 2013 Sun Microsystems, Inc.
  154.44 + */
  154.45 +package org.netbeans.modules.jackpot30.hintsimpl.duplicates;
  154.46 +
  154.47 +import javax.swing.event.ChangeListener;
  154.48 +import org.netbeans.api.java.source.TreePathHandle;
  154.49 +import org.netbeans.modules.refactoring.api.AbstractRefactoring;
  154.50 +import org.netbeans.modules.refactoring.api.Problem;
  154.51 +import org.netbeans.modules.refactoring.spi.ui.CustomRefactoringPanel;
  154.52 +import org.netbeans.modules.refactoring.spi.ui.RefactoringUI;
  154.53 +import org.openide.util.HelpCtx;
  154.54 +
  154.55 +/**
  154.56 + *
  154.57 + * @author lahvac
  154.58 + */
  154.59 +public class DuplicateMethodRefactoringUI implements RefactoringUI {
  154.60 +    private final TreePathHandle treePathHandle;
  154.61 +
  154.62 +    DuplicateMethodRefactoringUI(TreePathHandle treePathHandle) {
  154.63 +        this.treePathHandle = treePathHandle;
  154.64 +    }
  154.65 +
  154.66 +    @Override
  154.67 +    public String getName() {
  154.68 +        return "Duplicate Method Refactoring";
  154.69 +    }
  154.70 +
  154.71 +    @Override
  154.72 +    public String getDescription() {
  154.73 +        return "Duplicate Method Refactoring";
  154.74 +    }
  154.75 +
  154.76 +    @Override
  154.77 +    public boolean isQuery() {
  154.78 +        return false;
  154.79 +    }
  154.80 +
  154.81 +    @Override
  154.82 +    public CustomRefactoringPanel getPanel(ChangeListener parent) {
  154.83 +        return null;
  154.84 +    }
  154.85 +
  154.86 +    @Override
  154.87 +    public Problem setParameters() {
  154.88 +        return null;
  154.89 +    }
  154.90 +
  154.91 +    @Override
  154.92 +    public Problem checkParameters() {
  154.93 +        return null;
  154.94 +    }
  154.95 +
  154.96 +    @Override
  154.97 +    public boolean hasParameters() {
  154.98 +        return false;
  154.99 +    }
 154.100 +
 154.101 +    @Override
 154.102 +    public AbstractRefactoring getRefactoring() {
 154.103 +        return new DuplicateMethodRefactoring(treePathHandle);
 154.104 +    }
 154.105 +
 154.106 +    @Override
 154.107 +    public HelpCtx getHelpCtx() {
 154.108 +        return HelpCtx.DEFAULT_HELP;
 154.109 +    }
 154.110 +
 154.111 +}
   155.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   155.2 +++ b/sandbox/java.hints/hintsimpl/src/org/netbeans/modules/jackpot30/hintsimpl/duplicates/RefactoringPluginFactoryImpl.java	Sun Oct 23 11:50:54 2016 +0200
   155.3 @@ -0,0 +1,62 @@
   155.4 +/*
   155.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   155.6 + *
   155.7 + * Copyright 2008-2010 Sun Microsystems, Inc. All rights reserved.
   155.8 + *
   155.9 + * The contents of this file are subject to the terms of either the GNU
  155.10 + * General Public License Version 2 only ("GPL") or the Common
  155.11 + * Development and Distribution License("CDDL") (collectively, the
  155.12 + * "License"). You may not use this file except in compliance with the
  155.13 + * License. You can obtain a copy of the License at
  155.14 + * http://www.netbeans.org/cddl-gplv2.html
  155.15 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  155.16 + * specific language governing permissions and limitations under the
  155.17 + * License.  When distributing the software, include this License Header
  155.18 + * Notice in each file and include the License file at
  155.19 + * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
  155.20 + * particular file as subject to the "Classpath" exception as provided
  155.21 + * by Sun in the GPL Version 2 section of the License file that
  155.22 + * accompanied this code. If applicable, add the following below the
  155.23 + * License Header, with the fields enclosed by brackets [] replaced by
  155.24 + * your own identifying information:
  155.25 + * "Portions Copyrighted [year] [name of copyright owner]"
  155.26 + *
  155.27 + * If you wish your version of this file to be governed by only the CDDL
  155.28 + * or only the GPL Version 2, indicate your decision by adding
  155.29 + * "[Contributor] elects to include this software in this distribution
  155.30 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  155.31 + * single choice of license, a recipient has the option to distribute
  155.32 + * your version of this file under either the CDDL, the GPL Version 2 or
  155.33 + * to extend the choice of license to its licensees as provided above.
  155.34 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  155.35 + * Version 2 license, then the option applies only if the new code is
  155.36 + * made subject to such option by the copyright holder.
  155.37 + *
  155.38 + * Contributor(s):
  155.39 + *
  155.40 + * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
  155.41 + */
  155.42 +
  155.43 +package org.netbeans.modules.jackpot30.hintsimpl.duplicates;
  155.44 +
  155.45 +import org.netbeans.modules.refactoring.api.AbstractRefactoring;
  155.46 +import org.netbeans.modules.refactoring.spi.RefactoringPlugin;
  155.47 +import org.netbeans.modules.refactoring.spi.RefactoringPluginFactory;
  155.48 +import org.openide.util.lookup.ServiceProvider;
  155.49 +
  155.50 +/**
  155.51 + *
  155.52 + * @author Jan Lahoda
  155.53 + */
  155.54 +@ServiceProvider(service=RefactoringPluginFactory.class)
  155.55 +public class RefactoringPluginFactoryImpl implements RefactoringPluginFactory {
  155.56 +
  155.57 +    public RefactoringPlugin createInstance(AbstractRefactoring refactoring) {
  155.58 +        if (refactoring instanceof DuplicateMethodRefactoring) {
  155.59 +            return new DuplicateMethodRefactoringPlugin((DuplicateMethodRefactoring) refactoring);
  155.60 +        }
  155.61 +
  155.62 +        return null;
  155.63 +    }
  155.64 +
  155.65 +}
   156.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   156.2 +++ b/sandbox/java.hints/hintsimpl/test/unit/src/org/netbeans/modules/jackpot30/hintsimpl/GlobalyUnusedNGTest.java	Sun Oct 23 11:50:54 2016 +0200
   156.3 @@ -0,0 +1,84 @@
   156.4 +/*
   156.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   156.6 + *
   156.7 + * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
   156.8 + *
   156.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  156.10 + * Other names may be trademarks of their respective owners.
  156.11 + *
  156.12 + * The contents of this file are subject to the terms of either the GNU
  156.13 + * General Public License Version 2 only ("GPL") or the Common
  156.14 + * Development and Distribution License("CDDL") (collectively, the
  156.15 + * "License"). You may not use this file except in compliance with the
  156.16 + * License. You can obtain a copy of the License at
  156.17 + * http://www.netbeans.org/cddl-gplv2.html
  156.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  156.19 + * specific language governing permissions and limitations under the
  156.20 + * License.  When distributing the software, include this License Header
  156.21 + * Notice in each file and include the License file at
  156.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  156.23 + * particular file as subject to the "Classpath" exception as provided
  156.24 + * by Oracle in the GPL Version 2 section of the License file that
  156.25 + * accompanied this code. If applicable, add the following below the
  156.26 + * License Header, with the fields enclosed by brackets [] replaced by
  156.27 + * your own identifying information:
  156.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  156.29 + *
  156.30 + * If you wish your version of this file to be governed by only the CDDL
  156.31 + * or only the GPL Version 2, indicate your decision by adding
  156.32 + * "[Contributor] elects to include this software in this distribution
  156.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  156.34 + * single choice of license, a recipient has the option to distribute
  156.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  156.36 + * to extend the choice of license to its licensees as provided above.
  156.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  156.38 + * Version 2 license, then the option applies only if the new code is
  156.39 + * made subject to such option by the copyright holder.
  156.40 + *
  156.41 + * Contributor(s):
  156.42 + *
  156.43 + * Portions Copyrighted 2013 Sun Microsystems, Inc.
  156.44 + */
  156.45 +package org.netbeans.modules.jackpot30.hintsimpl;
  156.46 +
  156.47 +import org.junit.Test;
  156.48 +import org.netbeans.modules.java.hints.test.api.HintTest;
  156.49 +
  156.50 +/**
  156.51 + *
  156.52 + * @author lahvac
  156.53 + */
  156.54 +public class GlobalyUnusedNGTest {
  156.55 +
  156.56 +    @Test
  156.57 +    public void testUsed1() throws Exception {
  156.58 +        HintTest.create()
  156.59 +                .input("test/Test1.java",
  156.60 +                       "package test;\n" +
  156.61 +                       "public class Test1 {\n" +
  156.62 +                       "    private final Test2 test2 = null;\n" +
  156.63 +                       "}\n")
  156.64 +                .input("test/Test2.java",
  156.65 +                       "package test;\n" +
  156.66 +                       "public class Test2 {\n" +
  156.67 +                       "    private final Test1 test1 = null;\n" +
  156.68 +                       "}\n")
  156.69 +                .runGlobal(GlobalyUnused.class)
  156.70 +                .assertWarnings();
  156.71 +    }
  156.72 +    
  156.73 +    @Test
  156.74 +    public void testUnused() throws Exception {
  156.75 +        HintTest.create()
  156.76 +                .input("test/Test1.java",
  156.77 +                       "package test;\n" +
  156.78 +                       "public class Test1 { }\n")
  156.79 +                .input("test/Test2.java",
  156.80 +                       "package test;\n" +
  156.81 +                       "public class Test2 {\n" +
  156.82 +                       "}\n")
  156.83 +                .runGlobal(GlobalyUnused.class)
  156.84 +                .assertWarnings("1:13-1:18:verifier:Unused", "1:13-1:18:verifier:Unused");
  156.85 +    }
  156.86 +
  156.87 +}
   157.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   157.2 +++ b/sandbox/java.hints/hintsimpl/test/unit/src/org/netbeans/modules/jackpot30/hintsimpl/NonPrivateMakeFinalNGTest.java	Sun Oct 23 11:50:54 2016 +0200
   157.3 @@ -0,0 +1,90 @@
   157.4 +/*
   157.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   157.6 + *
   157.7 + * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
   157.8 + *
   157.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  157.10 + * Other names may be trademarks of their respective owners.
  157.11 + *
  157.12 + * The contents of this file are subject to the terms of either the GNU
  157.13 + * General Public License Version 2 only ("GPL") or the Common
  157.14 + * Development and Distribution License("CDDL") (collectively, the
  157.15 + * "License"). You may not use this file except in compliance with the
  157.16 + * License. You can obtain a copy of the License at
  157.17 + * http://www.netbeans.org/cddl-gplv2.html
  157.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  157.19 + * specific language governing permissions and limitations under the
  157.20 + * License.  When distributing the software, include this License Header
  157.21 + * Notice in each file and include the License file at
  157.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  157.23 + * particular file as subject to the "Classpath" exception as provided
  157.24 + * by Oracle in the GPL Version 2 section of the License file that
  157.25 + * accompanied this code. If applicable, add the following below the
  157.26 + * License Header, with the fields enclosed by brackets [] replaced by
  157.27 + * your own identifying information:
  157.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  157.29 + *
  157.30 + * If you wish your version of this file to be governed by only the CDDL
  157.31 + * or only the GPL Version 2, indicate your decision by adding
  157.32 + * "[Contributor] elects to include this software in this distribution
  157.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  157.34 + * single choice of license, a recipient has the option to distribute
  157.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  157.36 + * to extend the choice of license to its licensees as provided above.
  157.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  157.38 + * Version 2 license, then the option applies only if the new code is
  157.39 + * made subject to such option by the copyright holder.
  157.40 + *
  157.41 + * Contributor(s):
  157.42 + *
  157.43 + * Portions Copyrighted 2013 Sun Microsystems, Inc.
  157.44 + */
  157.45 +package org.netbeans.modules.jackpot30.hintsimpl;
  157.46 +
  157.47 +import org.junit.Test;
  157.48 +import org.netbeans.modules.java.hints.test.api.HintTest;
  157.49 +
  157.50 +/**
  157.51 + *
  157.52 + * @author lahvac
  157.53 + */
  157.54 +public class NonPrivateMakeFinalNGTest {
  157.55 +
  157.56 +    @Test
  157.57 +    public void testNotFinal() throws Exception {
  157.58 +        HintTest.create()
  157.59 +                .input("test/Test1.java",
  157.60 +                       "package test;\n" +
  157.61 +                       "public class Test1 {\n" +
  157.62 +                       "    public String str = \"\";\n" +
  157.63 +                       "}\n")
  157.64 +                .input("test/Test2.java",
  157.65 +                       "package test;\n" +
  157.66 +                       "public class Test2 {\n" +
  157.67 +                       "    {\n" +
  157.68 +                       "        new Test1().str = null;\n" +
  157.69 +                       "    }\n" +
  157.70 +                       "}\n")
  157.71 +                .runGlobal(NonPrivateMakeFinal.class)
  157.72 +                .assertWarnings();
  157.73 +    }
  157.74 +
  157.75 +    @Test
  157.76 +    public void testFinal() throws Exception {
  157.77 +        HintTest.create()
  157.78 +                .input("test/Test1.java",
  157.79 +                       "package test;\n" +
  157.80 +                       "public class Test1 {\n" +
  157.81 +                       "    public String str = \"\";\n" +
  157.82 +                       "}\n")
  157.83 +                .input("test/Test2.java",
  157.84 +                       "package test;\n" +
  157.85 +                       "public class Test2 {\n" +
  157.86 +                       "    {\n" +
  157.87 +                       "        System.err.println(new Test1().str);\n" +
  157.88 +                       "    }\n" +
  157.89 +                       "}\n")
  157.90 +                .runGlobal(NonPrivateMakeFinal.class)
  157.91 +                .assertWarnings("2:18-2:21:verifier:Can be final");
  157.92 +    }
  157.93 +}
   158.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   158.2 +++ b/sandbox/java.hints/hintsimpl/test/unit/src/org/netbeans/modules/jackpot30/hintsimpl/borrowed/RefactoringTestBase.java	Sun Oct 23 11:50:54 2016 +0200
   158.3 @@ -0,0 +1,387 @@
   158.4 +/*
   158.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   158.6 + *
   158.7 + * Copyright 2009-2010 Sun Microsystems, Inc. All rights reserved.
   158.8 + *
   158.9 + * The contents of this file are subject to the terms of either the GNU
  158.10 + * General Public License Version 2 only ("GPL") or the Common
  158.11 + * Development and Distribution License("CDDL") (collectively, the
  158.12 + * "License"). You may not use this file except in compliance with the
  158.13 + * License. You can obtain a copy of the License at
  158.14 + * http://www.netbeans.org/cddl-gplv2.html
  158.15 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  158.16 + * specific language governing permissions and limitations under the
  158.17 + * License.  When distributing the software, include this License Header
  158.18 + * Notice in each file and include the License file at
  158.19 + * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
  158.20 + * particular file as subject to the "Classpath" exception as provided
  158.21 + * by Sun in the GPL Version 2 section of the License file that
  158.22 + * accompanied this code. If applicable, add the following below the
  158.23 + * License Header, with the fields enclosed by brackets [] replaced by
  158.24 + * your own identifying information:
  158.25 + * "Portions Copyrighted [year] [name of copyright owner]"
  158.26 + *
  158.27 + * If you wish your version of this file to be governed by only the CDDL
  158.28 + * or only the GPL Version 2, indicate your decision by adding
  158.29 + * "[Contributor] elects to include this software in this distribution
  158.30 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  158.31 + * single choice of license, a recipient has the option to distribute
  158.32 + * your version of this file under either the CDDL, the GPL Version 2 or
  158.33 + * to extend the choice of license to its licensees as provided above.
  158.34 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  158.35 + * Version 2 license, then the option applies only if the new code is
  158.36 + * made subject to such option by the copyright holder.
  158.37 + *
  158.38 + * Contributor(s):
  158.39 + *
  158.40 + * Portions Copyrighted 2009-2010 Sun Microsystems, Inc.
  158.41 + */
  158.42 +package org.netbeans.modules.jackpot30.hintsimpl.borrowed;
  158.43 +
  158.44 +import java.io.EOFException;
  158.45 +import java.io.FileInputStream;
  158.46 +import java.io.IOException;
  158.47 +import java.nio.charset.Charset;
  158.48 +import java.util.Arrays;
  158.49 +import java.util.Collections;
  158.50 +import java.util.HashMap;
  158.51 +import java.util.HashSet;
  158.52 +import java.util.Iterator;
  158.53 +import java.util.LinkedList;
  158.54 +import java.util.List;
  158.55 +import java.util.Map;
  158.56 +import java.util.logging.Level;
  158.57 +import java.util.logging.Logger;
  158.58 +import javax.swing.event.ChangeListener;
  158.59 +import org.netbeans.api.editor.mimelookup.MimePath;
  158.60 +import org.netbeans.api.java.classpath.ClassPath;
  158.61 +import org.netbeans.api.java.classpath.GlobalPathRegistry;
  158.62 +import org.netbeans.api.java.source.SourceUtilsTestUtil;
  158.63 +import org.netbeans.api.java.source.TestUtilities;
  158.64 +import org.netbeans.api.java.source.TreeUtilities;
  158.65 +import org.netbeans.api.project.Project;
  158.66 +import org.netbeans.api.project.ProjectManager;
  158.67 +import org.netbeans.api.project.SourceGroup;
  158.68 +import org.netbeans.api.project.Sources;
  158.69 +import org.netbeans.core.startup.Main;
  158.70 +import org.netbeans.junit.NbTestCase;
  158.71 +import org.netbeans.modules.java.source.indexing.JavaCustomIndexer;
  158.72 +import org.netbeans.modules.parsing.api.indexing.IndexingManager;
  158.73 +import org.netbeans.modules.parsing.impl.indexing.CacheFolder;
  158.74 +import org.netbeans.modules.parsing.impl.indexing.MimeTypes;
  158.75 +import org.netbeans.modules.parsing.impl.indexing.RepositoryUpdater;
  158.76 +import org.netbeans.modules.refactoring.api.Problem;
  158.77 +import org.netbeans.spi.editor.mimelookup.MimeDataProvider;
  158.78 +import org.netbeans.spi.gototest.TestLocator;
  158.79 +import org.netbeans.spi.gototest.TestLocator.FileType;
  158.80 +import org.netbeans.spi.gototest.TestLocator.LocationListener;
  158.81 +import org.netbeans.spi.gototest.TestLocator.LocationResult;
  158.82 +import org.netbeans.spi.java.classpath.ClassPathProvider;
  158.83 +import org.netbeans.spi.java.classpath.support.ClassPathSupport;
  158.84 +import org.netbeans.spi.project.ProjectFactory;
  158.85 +import org.netbeans.spi.project.ProjectState;
  158.86 +import org.netbeans.spi.project.support.GenericSources;
  158.87 +import org.openide.filesystems.FileObject;
  158.88 +import org.openide.filesystems.FileUtil;
  158.89 +import org.openide.util.Lookup;
  158.90 +import org.openide.util.NbBundle;
  158.91 +import org.openide.util.lookup.Lookups;
  158.92 +import org.openide.util.lookup.ServiceProvider;
  158.93 +
  158.94 +public class RefactoringTestBase extends NbTestCase {
  158.95 +    // Turning off annoying info messages from treeutilities
  158.96 +    private static final Logger TREEUTILITIESLOGGER = Logger.getLogger(TreeUtilities.class.getName());
  158.97 +
  158.98 +    public RefactoringTestBase(String name) {
  158.99 +        super(name);
 158.100 +    }
 158.101 +
 158.102 +    protected static void writeFilesAndWaitForScan(FileObject sourceRoot, File... files) throws Exception {
 158.103 +        for (FileObject c : sourceRoot.getChildren()) {
 158.104 +            c.delete();
 158.105 +        }
 158.106 +
 158.107 +        for (File f : files) {
 158.108 +            FileObject fo = FileUtil.createData(sourceRoot, f.filename);
 158.109 +            TestUtilities.copyStringToFile(fo, f.content);
 158.110 +        }
 158.111 +
 158.112 +        IndexingManager.getDefault().refreshIndexAndWait(sourceRoot.toURL(), null, true);
 158.113 +    }
 158.114 +
 158.115 +    protected void verifyContent(FileObject sourceRoot, File... files) throws Exception {
 158.116 +        List<FileObject> todo = new LinkedList<FileObject>();
 158.117 +
 158.118 +        todo.add(sourceRoot);
 158.119 +
 158.120 +        Map<String, String> content = new HashMap<String, String>();
 158.121 +
 158.122 +        FileUtil.refreshFor(FileUtil.toFile(sourceRoot));
 158.123 +
 158.124 +        while (!todo.isEmpty()) {
 158.125 +            FileObject file = todo.remove(0);
 158.126 +
 158.127 +            if (file.isData()) {
 158.128 +                content.put(FileUtil.getRelativePath(sourceRoot, file), copyFileToString(FileUtil.toFile(file)));
 158.129 +            } else {
 158.130 +                todo.addAll(Arrays.asList(file.getChildren()));
 158.131 +            }
 158.132 +        }
 158.133 +
 158.134 +        for (File f : files) {
 158.135 +            String fileContent = content.remove(f.filename);
 158.136 +
 158.137 +            assertNotNull(f);
 158.138 +            assertNotNull(f.content);
 158.139 +            assertNotNull("Cannot find " + f.filename + " in map " + content, fileContent);
 158.140 +            assertEquals(getName() ,f.content.replaceAll("[ \t\r\n\n]+", " "), fileContent.replaceAll("[ \t\r\n\n]+", " "));
 158.141 +        }
 158.142 +
 158.143 +        assertTrue(content.toString(), content.isEmpty());
 158.144 +    }
 158.145 +    
 158.146 +    /**
 158.147 +     * Returns a string which contains the contents of a file.
 158.148 +     *
 158.149 +     * @param f the file to be read
 158.150 +     * @return the contents of the file(s).
 158.151 +     */
 158.152 +    private static String copyFileToString(java.io.File f) throws java.io.IOException {
 158.153 +        int s = (int) f.length();
 158.154 +        byte[] data = new byte[s];
 158.155 +        int len = new FileInputStream(f).read(data);
 158.156 +        if (len != s) {
 158.157 +            throw new EOFException("truncated file");
 158.158 +        }
 158.159 +        return new String(data, Charset.forName("UTF8"));
 158.160 +    }
 158.161 +
 158.162 +    protected static void addAllProblems(List<Problem> problems, Problem head) {
 158.163 +        while (head != null) {
 158.164 +            problems.add(head);
 158.165 +            head = head.getNext();
 158.166 +        }
 158.167 +    }
 158.168 +
 158.169 +    protected static void assertProblems(Iterable<? extends Problem> golden, Iterable<? extends Problem> real) {
 158.170 +        Iterator<? extends Problem> g = golden.iterator();
 158.171 +        Iterator<? extends Problem> r = real.iterator();
 158.172 +
 158.173 +        while (g.hasNext() && r.hasNext()) {
 158.174 +            Problem gp = g.next();
 158.175 +            Problem rp = r.next();
 158.176 +
 158.177 +            assertEquals(gp.isFatal(), rp.isFatal());
 158.178 +            assertEquals(gp.getMessage(), rp.getMessage());
 158.179 +        }
 158.180 +        boolean goldenHasNext = g.hasNext();
 158.181 +        boolean realHasNext = r.hasNext();
 158.182 +
 158.183 +        assertFalse(goldenHasNext?"Expected: " + g.next().getMessage():"", goldenHasNext);
 158.184 +        assertFalse(realHasNext?"Unexpected: " + r.next().getMessage():"", realHasNext);
 158.185 +    }
 158.186 +
 158.187 +    static {
 158.188 +        NbBundle.setBranding("test");
 158.189 +    }
 158.190 +
 158.191 +    protected static final class File {
 158.192 +        public final String filename;
 158.193 +        public final String content;
 158.194 +
 158.195 +        public File(String filename, String content) {
 158.196 +            this.filename = filename;
 158.197 +            this.content = content;
 158.198 +        }
 158.199 +    }
 158.200 +
 158.201 +    protected FileObject src;
 158.202 +    protected FileObject test;
 158.203 +    protected Project prj;
 158.204 +    private ClassPath sourcePath;
 158.205 +
 158.206 +    @Override
 158.207 +    protected void setUp() throws Exception {
 158.208 +        System.setProperty("org.netbeans.modules.java.source.usages.SourceAnalyser.fullIndex", "true");
 158.209 +        TREEUTILITIESLOGGER.setLevel(Level.SEVERE);
 158.210 +        MimeTypes.setAllMimeTypes(new HashSet<String>());
 158.211 +        SourceUtilsTestUtil.prepareTest(new String[] {"org/netbeans/modules/openide/loaders/layer.xml",
 158.212 +                    "org/netbeans/modules/java/source/resources/layer.xml",
 158.213 +                    "org/netbeans/modules/java/editor/resources/layer.xml",
 158.214 +            /*"org/netbeans/modules/refactoring/java/test/resources/layer.xml", */"META-INF/generated-layer.xml"}, new Object[] {
 158.215 +                    new ClassPathProvider() {
 158.216 +                        @Override
 158.217 +                        public ClassPath findClassPath(FileObject file, String type) {
 158.218 +                    if (sourcePath != null && sourcePath.contains(file)){
 158.219 +                                if (ClassPath.BOOT.equals(type)) {
 158.220 +                                    return ClassPathSupport.createClassPath(System.getProperty("sun.boot.class.path"));
 158.221 +                                }
 158.222 +                                if (ClassPath.COMPILE.equals(type)) {
 158.223 +                                    return ClassPathSupport.createClassPath(new FileObject[0]);
 158.224 +                                }
 158.225 +                                if (ClassPath.SOURCE.equals(type)) {
 158.226 +                                    return sourcePath;
 158.227 +                                }
 158.228 +                            }
 158.229 +
 158.230 +                            return null;
 158.231 +                        }
 158.232 +                    },
 158.233 +                    new ProjectFactory() {
 158.234 +                        @Override
 158.235 +                        public boolean isProject(FileObject projectDirectory) {
 158.236 +                            return src != null && src.getParent() == projectDirectory;
 158.237 +                        }
 158.238 +                        @Override
 158.239 +                        public Project loadProject(final FileObject projectDirectory, ProjectState state) throws IOException {
 158.240 +                if (!isProject(projectDirectory)) {
 158.241 +                    return null;
 158.242 +                }
 158.243 +                            return new Project() {
 158.244 +                                @Override
 158.245 +                                public FileObject getProjectDirectory() {
 158.246 +                                    return projectDirectory;
 158.247 +                                }
 158.248 +                                @Override
 158.249 +                                public Lookup getLookup() {
 158.250 +                                    final Project p = this;
 158.251 +                                    return Lookups.singleton(new Sources() {
 158.252 +
 158.253 +                                        @Override
 158.254 +                                        public SourceGroup[] getSourceGroups(String type) {
 158.255 +                                return new SourceGroup[] {GenericSources.group(p, src.getParent(), "source", "Java Sources", null, null),
 158.256 +                                                        GenericSources.group(p, test, "testsources", "Test Sources", null, null)};
 158.257 +                                        }
 158.258 +
 158.259 +                                        @Override
 158.260 +                                        public void addChangeListener(ChangeListener listener) {
 158.261 +                                        }
 158.262 +
 158.263 +                                        @Override
 158.264 +                                        public void removeChangeListener(ChangeListener listener) {
 158.265 +                                        }
 158.266 +                                    });
 158.267 +                                }
 158.268 +                            };
 158.269 +                        }
 158.270 +                        @Override
 158.271 +            public void saveProject(Project project) throws IOException, ClassCastException {}
 158.272 +                    },
 158.273 +                    new TestLocator() {
 158.274 +
 158.275 +                        @Override
 158.276 +                        public boolean appliesTo(FileObject fo) {
 158.277 +                            return true;
 158.278 +                        }
 158.279 +
 158.280 +                        @Override
 158.281 +                        public boolean asynchronous() {
 158.282 +                            return false;
 158.283 +                        }
 158.284 +
 158.285 +                        @Override
 158.286 +                        public LocationResult findOpposite(FileObject fo, int caretOffset) {
 158.287 +                            ClassPath srcCp;
 158.288 +
 158.289 +                            if ((srcCp = ClassPath.getClassPath(fo, ClassPath.SOURCE)) == null) {
 158.290 +                                return new LocationResult("File not found"); //NOI18N
 158.291 +                            }
 158.292 +
 158.293 +                            String baseResName = srcCp.getResourceName(fo, '/', false);
 158.294 +                            String testResName = getTestResName(baseResName, fo.getExt());
 158.295 +                            assert testResName != null;
 158.296 +                            FileObject fileObject = test.getFileObject(testResName);
 158.297 +                if(fileObject != null) {
 158.298 +                                return new LocationResult(fileObject, -1);
 158.299 +                            }
 158.300 +
 158.301 +                            return new LocationResult("File not found"); //NOI18N
 158.302 +                        }
 158.303 +
 158.304 +                        @Override
 158.305 +                        public void findOpposite(FileObject fo, int caretOffset, LocationListener callback) {
 158.306 +                            throw new UnsupportedOperationException("This should not be called on synchronous locators.");
 158.307 +                        }
 158.308 +
 158.309 +                        @Override
 158.310 +                        public FileType getFileType(FileObject fo) {
 158.311 +                if(FileUtil.isParentOf(test, fo)) {
 158.312 +                                return FileType.TEST;
 158.313 +                } else if(FileUtil.isParentOf(src, fo)) {
 158.314 +                                return FileType.TESTED;
 158.315 +                            }
 158.316 +                            return FileType.NEITHER;
 158.317 +                        }
 158.318 +
 158.319 +                        private String getTestResName(String baseResName, String ext) {
 158.320 +                StringBuilder buf
 158.321 +                        = new StringBuilder(baseResName.length() + ext.length() + 10);
 158.322 +                            buf.append(baseResName).append("Test");                         //NOI18N
 158.323 +                            if (ext.length() != 0) {
 158.324 +                                buf.append('.').append(ext);
 158.325 +                            }
 158.326 +                            return buf.toString();
 158.327 +                        }
 158.328 +                    }});
 158.329 +        Main.initializeURLFactory();
 158.330 +        org.netbeans.api.project.ui.OpenProjects.getDefault().getOpenProjects();
 158.331 +        prepareTest();
 158.332 +        org.netbeans.api.project.ui.OpenProjects.getDefault().open(new Project[] {prj = ProjectManager.getDefault().findProject(src.getParent())}, false);
 158.333 +        MimeTypes.setAllMimeTypes(Collections.singleton("text/x-java"));
 158.334 +        sourcePath = ClassPathSupport.createClassPath(src, test);
 158.335 +        GlobalPathRegistry.getDefault().register(ClassPath.SOURCE, new ClassPath[] {sourcePath});
 158.336 +        RepositoryUpdater.getDefault().start(true);
 158.337 +        super.setUp();
 158.338 +        FileUtil.createData(FileUtil.getConfigRoot(), "Templates/Classes/Empty.java");
 158.339 +        System.setProperty("org.netbeans.modules.parsing.impl.Source.excludedTasks", ".*");
 158.340 +    }
 158.341 +
 158.342 +    @Override
 158.343 +    protected void tearDown() throws Exception {
 158.344 +        super.tearDown();
 158.345 +        GlobalPathRegistry.getDefault().unregister(ClassPath.SOURCE, new ClassPath[] {sourcePath});
 158.346 +        org.netbeans.api.project.ui.OpenProjects.getDefault().close(new Project[] {prj});
 158.347 +        prj = null;
 158.348 +    }
 158.349 +
 158.350 +    private void prepareTest() throws Exception {
 158.351 +        FileObject workdir = SourceUtilsTestUtil.makeScratchDir(this);
 158.352 +
 158.353 +        FileObject projectFolder = FileUtil.createFolder(workdir, "testProject");
 158.354 +        src = FileUtil.createFolder(projectFolder, "src");
 158.355 +        test = FileUtil.createFolder(projectFolder, "test");
 158.356 +
 158.357 +        FileObject cache = FileUtil.createFolder(workdir, "cache");
 158.358 +
 158.359 +        CacheFolder.setCacheFolder(cache);
 158.360 +    }
 158.361 +
 158.362 +    @ServiceProvider(service=MimeDataProvider.class)
 158.363 +    public static final class MimeDataProviderImpl implements MimeDataProvider {
 158.364 +
 158.365 +        private static final Lookup L = Lookups.singleton(new JavaCustomIndexer.Factory());
 158.366 +
 158.367 +        @Override
 158.368 +        public Lookup getLookup(MimePath mimePath) {
 158.369 +            if ("text/x-java".equals(mimePath.getPath())) {
 158.370 +                return L;
 158.371 +            }
 158.372 +
 158.373 +            return null;
 158.374 +        }
 158.375 +        
 158.376 +    }
 158.377 +
 158.378 +    protected static boolean problemIsFatal(List<Problem> problems) {
 158.379 +        for (Problem problem : problems) {
 158.380 +            Problem next = problem;
 158.381 +            do {
 158.382 +                if (next.isFatal()) {
 158.383 +                    return true;
 158.384 +                }
 158.385 +                next = next.getNext();
 158.386 +            } while (next != null);
 158.387 +        }
 158.388 +        return false;
 158.389 +    }
 158.390 +}
 158.391 \ No newline at end of file
   159.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   159.2 +++ b/sandbox/java.hints/hintsimpl/test/unit/src/org/netbeans/modules/jackpot30/hintsimpl/duplicates/DuplicateMethodRefactoringPluginTest.java	Sun Oct 23 11:50:54 2016 +0200
   159.3 @@ -0,0 +1,165 @@
   159.4 +/*
   159.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   159.6 + *
   159.7 + * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
   159.8 + *
   159.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  159.10 + * Other names may be trademarks of their respective owners.
  159.11 + *
  159.12 + * The contents of this file are subject to the terms of either the GNU
  159.13 + * General Public License Version 2 only ("GPL") or the Common
  159.14 + * Development and Distribution License("CDDL") (collectively, the
  159.15 + * "License"). You may not use this file except in compliance with the
  159.16 + * License. You can obtain a copy of the License at
  159.17 + * http://www.netbeans.org/cddl-gplv2.html
  159.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  159.19 + * specific language governing permissions and limitations under the
  159.20 + * License.  When distributing the software, include this License Header
  159.21 + * Notice in each file and include the License file at
  159.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  159.23 + * particular file as subject to the "Classpath" exception as provided
  159.24 + * by Oracle in the GPL Version 2 section of the License file that
  159.25 + * accompanied this code. If applicable, add the following below the
  159.26 + * License Header, with the fields enclosed by brackets [] replaced by
  159.27 + * your own identifying information:
  159.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  159.29 + *
  159.30 + * If you wish your version of this file to be governed by only the CDDL
  159.31 + * or only the GPL Version 2, indicate your decision by adding
  159.32 + * "[Contributor] elects to include this software in this distribution
  159.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  159.34 + * single choice of license, a recipient has the option to distribute
  159.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  159.36 + * to extend the choice of license to its licensees as provided above.
  159.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  159.38 + * Version 2 license, then the option applies only if the new code is
  159.39 + * made subject to such option by the copyright holder.
  159.40 + *
  159.41 + * Contributor(s):
  159.42 + *
  159.43 + * Portions Copyrighted 2013 Sun Microsystems, Inc.
  159.44 + */
  159.45 +package org.netbeans.modules.jackpot30.hintsimpl.duplicates;
  159.46 +
  159.47 +import java.util.Arrays;
  159.48 +import java.util.LinkedList;
  159.49 +import java.util.List;
  159.50 +import javax.lang.model.element.ExecutableElement;
  159.51 +import javax.lang.model.util.ElementFilter;
  159.52 +import org.netbeans.api.java.source.CompilationController;
  159.53 +import org.netbeans.api.java.source.JavaSource;
  159.54 +import org.netbeans.api.java.source.Task;
  159.55 +import org.netbeans.api.java.source.TreePathHandle;
  159.56 +import org.netbeans.modules.jackpot30.hintsimpl.borrowed.RefactoringTestBase;
  159.57 +import org.netbeans.modules.refactoring.api.Problem;
  159.58 +import org.netbeans.modules.refactoring.api.RefactoringSession;
  159.59 +
  159.60 +/**
  159.61 + *
  159.62 + * @author lahvac
  159.63 + */
  159.64 +public class DuplicateMethodRefactoringPluginTest extends RefactoringTestBase {
  159.65 +
  159.66 +    public DuplicateMethodRefactoringPluginTest(String name) {
  159.67 +        super(name);
  159.68 +    }
  159.69 +
  159.70 +    public void testSimple() throws Exception {
  159.71 +        writeFilesAndWaitForScan(src,
  159.72 +                                 new File("test/Test.java",
  159.73 +                                          "package test;\n" +
  159.74 +                                          "public class Test {\n" +
  159.75 +                                          "    public static void toCall() {\n" +
  159.76 +                                          "        System.err.println(1);\n" +
  159.77 +                                          "    }\n" +
  159.78 +                                          "    public static void test1() {\n" +
  159.79 +                                          "        System.err.println(1);\n" +
  159.80 +                                          "    }\n" +
  159.81 +                                          "    public static void test2() {\n" +
  159.82 +                                          "        System.out.println(1);\n" +
  159.83 +                                          "    }\n" +
  159.84 +                                          "    public static void test3() {\n" +
  159.85 +                                          "        System.err.println(2);\n" +
  159.86 +                                          "    }\n" +
  159.87 +                                          "}\n"));
  159.88 +        performDuplicateMethod("toCall");
  159.89 +        verifyContent(src,
  159.90 +                      new File("test/Test.java",
  159.91 +                               "package test;\n" +
  159.92 +                               "public class Test {\n" +
  159.93 +                               "    public static void toCall() {\n" +
  159.94 +                               "        System.err.println(1);\n" +
  159.95 +                               "    }\n" +
  159.96 +                               "    public static void test1() {\n" +
  159.97 +                               "        toCall();\n" +
  159.98 +                               "    }\n" +
  159.99 +                               "    public static void test2() {\n" +
 159.100 +                               "        System.out.println(1);\n" +
 159.101 +                               "    }\n" +
 159.102 +                               "    public static void test3() {\n" +
 159.103 +                               "        System.err.println(2);\n" +
 159.104 +                               "    }\n" +
 159.105 +                               "}\n"));
 159.106 +    }
 159.107 +
 159.108 +    public void testParams() throws Exception {
 159.109 +        writeFilesAndWaitForScan(src,
 159.110 +                                 new File("test/Test.java",
 159.111 +                                          "package test;\n" +
 159.112 +                                          "public class Test {\n" +
 159.113 +                                          "    public static void toCall(int i) {\n" +
 159.114 +                                          "        System.err.println(i);\n" +
 159.115 +                                          "    }\n" +
 159.116 +                                          "    public static void test1(int j) {\n" +
 159.117 +                                          "        System.err.println(1 + j);\n" +
 159.118 +                                          "    }\n" +
 159.119 +                                          "    public static void test3() {\n" +
 159.120 +                                          "        System.err.println(2);\n" +
 159.121 +                                          "    }\n" +
 159.122 +                                          "}\n"));
 159.123 +        performDuplicateMethod("toCall");
 159.124 +        verifyContent(src,
 159.125 +                      new File("test/Test.java",
 159.126 +                               "package test;\n" +
 159.127 +                               "public class Test {\n" +
 159.128 +                               "    public static void toCall(int i) {\n" +
 159.129 +                               "        System.err.println(i);\n" +
 159.130 +                               "    }\n" +
 159.131 +                               "    public static void test1(int j) {\n" +
 159.132 +                               "        toCall(1 + j);\n" +
 159.133 +                               "    }\n" +
 159.134 +                               "    public static void test3() {\n" +
 159.135 +                               "        toCall(2);\n" +
 159.136 +                               "    }\n" +
 159.137 +                               "}\n"));
 159.138 +    }
 159.139 +
 159.140 +    private void performDuplicateMethod(final String methodName, Problem... expectedProblems) throws Exception {
 159.141 +        final DuplicateMethodRefactoring[] r = new DuplicateMethodRefactoring[1];
 159.142 +
 159.143 +        JavaSource.forFileObject(src.getFileObject("test/Test.java")).runUserActionTask(new Task<CompilationController>() {
 159.144 +            @Override public void run(CompilationController javac) throws Exception {
 159.145 +                javac.toPhase(JavaSource.Phase.RESOLVED);
 159.146 +
 159.147 +                for (ExecutableElement method : ElementFilter.methodsIn(javac.getTopLevelElements().get(0).getEnclosedElements())) {
 159.148 +                    if (method.getSimpleName().contentEquals(methodName)) {
 159.149 +                        r[0] = new DuplicateMethodRefactoring(TreePathHandle.create(javac.getTrees().getPath(method), javac));
 159.150 +                    }
 159.151 +                }
 159.152 +            }
 159.153 +        }, true);
 159.154 +
 159.155 +        RefactoringSession rs = RefactoringSession.create("Session");
 159.156 +        List<Problem> problems = new LinkedList<Problem>();
 159.157 +
 159.158 +        addAllProblems(problems, r[0].preCheck());
 159.159 +        if (!problemIsFatal(problems)) {
 159.160 +            addAllProblems(problems, r[0].prepare(rs));
 159.161 +        }
 159.162 +        if (!problemIsFatal(problems)) {
 159.163 +            addAllProblems(problems, rs.doRefactoring(true));
 159.164 +        }
 159.165 +
 159.166 +        assertProblems(Arrays.asList(expectedProblems), problems);
 159.167 +    }
 159.168 +}
   160.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   160.2 +++ b/sandbox/java.hints/java.hints.test/apichanges.xml	Sun Oct 23 11:50:54 2016 +0200
   160.3 @@ -0,0 +1,181 @@
   160.4 +<?xml version="1.0" encoding="UTF-8"?>
   160.5 +<!-- Search for CHANGEME in this document when copying and using it: -->
   160.6 +<!--
   160.7 +DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   160.8 +
   160.9 +Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
  160.10 +
  160.11 +Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  160.12 +Other names may be trademarks of their respective owners.
  160.13 +
  160.14 +The contents of this file are subject to the terms of either the GNU
  160.15 +General Public License Version 2 only ("GPL") or the Common
  160.16 +Development and Distribution License("CDDL") (collectively, the
  160.17 +"License"). You may not use this file except in compliance with the
  160.18 +License. You can obtain a copy of the License at
  160.19 +http://www.netbeans.org/cddl-gplv2.html
  160.20 +or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  160.21 +specific language governing permissions and limitations under the
  160.22 +License.  When distributing the software, include this License Header
  160.23 +Notice in each file and include the License file at
  160.24 +nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  160.25 +particular file as subject to the "Classpath" exception as provided
  160.26 +by Oracle in the GPL Version 2 section of the License file that
  160.27 +accompanied this code. If applicable, add the following below the
  160.28 +License Header, with the fields enclosed by brackets [] replaced by
  160.29 +your own identifying information:
  160.30 +"Portions Copyrighted [year] [name of copyright owner]"
  160.31 +
  160.32 +Contributor(s):
  160.33 +
  160.34 +The Original Software is NetBeans. The Initial Developer of the Original
  160.35 +Software is Sun Microsystems, Inc. Portions Copyright 1997-2010 Sun
  160.36 +Microsystems, Inc. All Rights Reserved.
  160.37 +
  160.38 +If you wish your version of this file to be governed by only the CDDL
  160.39 +or only the GPL Version 2, indicate your decision by adding
  160.40 +"[Contributor] elects to include this software in this distribution
  160.41 +under the [CDDL or GPL Version 2] license." If you do not indicate a
  160.42 +single choice of license, a recipient has the option to distribute
  160.43 +your version of this file under either the CDDL, the GPL Version 2 or
  160.44 +to extend the choice of license to its licensees as provided above.
  160.45 +However, if you add GPL Version 2 code and therefore, elected the GPL
  160.46 +Version 2 license, then the option applies only if the new code is
  160.47 +made subject to such option by the copyright holder.
  160.48 +-->
  160.49 +<?xml-stylesheet type="text/xml" href="../nbbuild/javadoctools/apichanges.xsl"?>
  160.50 +<!DOCTYPE apichanges PUBLIC "-//NetBeans//DTD API changes list 1.0//EN" "../nbbuild/javadoctools/apichanges.dtd">
  160.51 +
  160.52 +<!--
  160.53 +
  160.54 +INFO FOR PEOPLE ADDING CHANGES:
  160.55 +
  160.56 +Check the DTD (apichanges.dtd) for details on the syntax. You do not
  160.57 +need to regenerate the HTML, as this is part of Javadoc generation; just
  160.58 +change the XML. Rough syntax of a change (several parts optional):
  160.59 +
  160.60 +<change>
  160.61 +    <api name="compiler"/>
  160.62 +    <summary>Some brief description here, can use <b>XHTML</b></summary>
  160.63 +    <version major="1" minor="99"/>
  160.64 +    <date day="13" month="6" year="2001"/>
  160.65 +    <author login="jrhacker"/>
  160.66 +    <compatibility addition="yes"/>
  160.67 +    <description>
  160.68 +        The main description of the change here.
  160.69 +        Again can use full <b>XHTML</b> as needed.
  160.70 +    </description>
  160.71 +    <class package="org.openide.compiler" name="DoWhatIWantCompiler"/>
  160.72 +    <issue number="14309"/>
  160.73 +</change>
  160.74 +
  160.75 +Also permitted elements: <package>, <branch>. <version> is API spec
  160.76 +version, recommended for all new changes. <compatibility> should say
  160.77 +if things were added/modified/deprecated/etc. and give all information
  160.78 +related to upgrading old code. List affected top-level classes and
  160.79 +link to issue numbers if applicable. See the DTD for more details.
  160.80 +
  160.81 +Changes need not be in any particular order, they are sorted in various
  160.82 +ways by the stylesheet anyway.
  160.83 +
  160.84 +Dates are assumed to mean "on the trunk". If you *also* make the same
  160.85 +change on a stabilization branch, use the <branch> tag to indicate this
  160.86 +and explain why the change was made on a branch in the <description>.
  160.87 +
  160.88 +Please only change this file on the trunk! Rather: you can change it
  160.89 +on branches if you want, but these changes will be ignored; only the
  160.90 +trunk version of this file is important.
  160.91 +
  160.92 +Deprecations do not count as incompatible, assuming that code using the
  160.93 +deprecated calls continues to see their documented behavior. But do
  160.94 +specify deprecation="yes" in <compatibility>.
  160.95 +
  160.96 +This file is not a replacement for Javadoc: it is intended to list changes,
  160.97 +not describe the complete current behavior, for which ordinary documentation
  160.98 +is the proper place.
  160.99 +
 160.100 +-->
 160.101 +
 160.102 +<apichanges>
 160.103 +
 160.104 +    <!-- First, a list of API names you may use: -->
 160.105 +    <apidefs>
 160.106 +        <apidef name="JavaHintsTest">Java Hints Test API</apidef>
 160.107 +    </apidefs>
 160.108 +
 160.109 +    <!-- ACTUAL CHANGES BEGIN HERE: -->
 160.110 +
 160.111 +    <changes>
 160.112 +        <change id="HintTest-singleHint">
 160.113 +            <api name="JavaHintsTest"/>
 160.114 +            <summary>Allowed to check a single hint</summary>
 160.115 +            <version major="1" minor="9"/>
 160.116 +            <date day="3" month="4" year="2013"/>
 160.117 +            <author login="sdedic"/>
 160.118 +            <compatibility addition="yes" binary="compatible" deletion="no" deprecation="no" modification="no" semantic="compatible" source="compatible"/>
 160.119 +            <description>
 160.120 +                New method <code>run(Class, String)</code> was added so that hint with a specific ID can be run, if the
 160.121 +                class contains multiple hint implementations.
 160.122 +            </description>
 160.123 +            <class name="HintTest" package="org.netbeans.modules.java.hints.test.api"/>
 160.124 +            <issue number="227962"/>
 160.125 +        </change>
 160.126 +        <change id="HintTest-ensureJavaFixes">
 160.127 +             <api name="JavaHintsTest"/>
 160.128 +             <summary>Added assertFixes method to HintWarning</summary>
 160.129 +             <version major="1" minor="8"/>
 160.130 +             <date day="22" month="3" year="2013"/>
 160.131 +             <author login="jlahoda"/>
 160.132 +             <compatibility addition="no" binary="compatible" deletion="no" deprecation="no" modification="no" semantic="incompatible" source="compatible"/>
 160.133 +             <description>
 160.134 +                 <code>HintTest.HintWarning.applyFix</code> now enforces constraints for Inspect&amp;Transform. Unless a hint
 160.135 +                 is marked as <code>Options.QUERY</code>, <code>Options.NO_BULK</code> or <code>Kind.ACTION</code>,
 160.136 +                 the <code>Fix</code> that is being applied is tested to be <code>JavaFix</code> and repeatable,
 160.137 +                 which are the requirements of Inspect&amp;Transform.
 160.138 +             </description>
 160.139 +             <class name="HintTest" package="org.netbeans.modules.java.hints.test.api"/>
 160.140 +             <issue number="227271"/>
 160.141 +        </change>
 160.142 +        
 160.143 +        <change id="HintWarning-assertFixes">
 160.144 +             <api name="JavaHintsTest"/>
 160.145 +             <summary>Added assertFixes method to HintWarning</summary>
 160.146 +             <version major="1" minor="1"/>
 160.147 +             <date day="30" month="3" year="2012"/>
 160.148 +             <author login="jlahoda"/>
 160.149 +             <compatibility addition="yes" binary="compatible" deletion="no" deprecation="no" modification="no" semantic="compatible" source="compatible"/>
 160.150 +             <description>
 160.151 +                 Added assertFixes method to HintWarning
 160.152 +             </description>
 160.153 +             <class name="HintTest" package="org.netbeans.modules.java.hints.test.api"/>
 160.154 +             <issue number="209828"/>
 160.155 +        </change>
 160.156 +
 160.157 +    </changes>
 160.158 +
 160.159 +    <!-- Now the surrounding HTML text and document structure: -->
 160.160 +
 160.161 +    <htmlcontents>
 160.162 +<!-- Generated from apichanges.xml -->
 160.163 +    <head>
 160.164 +      <title>Change History for the Editor Hints SPI</title>
 160.165 +      <link rel="stylesheet" href="prose.css" type="text/css"/>
 160.166 +    </head>
 160.167 +    <body>
 160.168 +
 160.169 +<p class="overviewlink"><a href="@TOP@/overview-summary.html">Overview</a></p>
 160.170 +
 160.171 +<h1>Introduction</h1>
 160.172 +
 160.173 +<p>This document lists changes made to the <a href="@TOP@/overview-summary.html">Editor Hints SPI</a>.</p>
 160.174 +
 160.175 +<!-- The actual lists of changes, as summaries and details: -->
 160.176 +      <hr/>
 160.177 +      <standard-changelists module-code-name="org.netbeans.spi.editor.hints/0"/>
 160.178 +
 160.179 +      <hr/><p>@FOOTER@</p>
 160.180 +
 160.181 +    </body>
 160.182 +  </htmlcontents>
 160.183 +
 160.184 +</apichanges>
   161.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   161.2 +++ b/sandbox/java.hints/java.hints.test/arch.xml	Sun Oct 23 11:50:54 2016 +0200
   161.3 @@ -0,0 +1,1078 @@
   161.4 +<?xml version="1.0" encoding="UTF-8"?>
   161.5 +<!DOCTYPE api-answers PUBLIC "-//NetBeans//DTD Arch Answers//EN" "../nbbuild/antsrc/org/netbeans/nbbuild/Arch.dtd" [
   161.6 +  <!ENTITY api-questions SYSTEM "../nbbuild/antsrc/org/netbeans/nbbuild/Arch-api-questions.xml">
   161.7 +]>
   161.8 +
   161.9 +<api-answers
  161.10 +  question-version="1.29"
  161.11 +  author="yourname@netbeans.org"
  161.12 +>
  161.13 +
  161.14 +  &api-questions;
  161.15 +
  161.16 +
  161.17 +<!--
  161.18 +        <question id="arch-overall" when="init">
  161.19 +            Describe the overall architecture. 
  161.20 +            <hint>
  161.21 +            What will be API for 
  161.22 +            <a href="http://wiki.netbeans.org/API_Design#Separate_API_for_clients_from_support_API">
  161.23 +                clients and what support API</a>? 
  161.24 +            What parts will be pluggable?
  161.25 +            How will plug-ins be registered? Please use <code>&lt;api type="export"/&gt;</code>
  161.26 +            to describe your general APIs and specify their
  161.27 +            <a href="http://wiki.netbeans.org/API_Stability#Private">
  161.28 +            stability categories</a>.
  161.29 +            If possible please provide simple diagrams.
  161.30 +            </hint>
  161.31 +        </question>
  161.32 +-->
  161.33 + <answer id="arch-overall">
  161.34 +  <p>
  161.35 +   <api type="export" category="devel" group="java" name="java.hints.test">
  161.36 +       API to create tests for the custom Java hints.
  161.37 +   </api>
  161.38 +  </p>
  161.39 + </answer>
  161.40 +
  161.41 +
  161.42 +
  161.43 +<!--
  161.44 +        <question id="arch-quality" when="init">
  161.45 +            How will the <a href="http://www.netbeans.org/community/guidelines/q-evangelism.html">quality</a>
  161.46 +            of your code be tested and 
  161.47 +            how are future regressions going to be prevented?
  161.48 +            <hint>
  161.49 +            What kind of testing do
  161.50 +            you want to use? How much functionality, in which areas,
  161.51 +            should be covered by the tests? How you find out that your
  161.52 +            project was successful?
  161.53 +            </hint>
  161.54 +        </question>
  161.55 +-->
  161.56 + <answer id="arch-quality">
  161.57 +  <p>
  161.58 +   XXX no answer for arch-quality
  161.59 +  </p>
  161.60 + </answer>
  161.61 +
  161.62 +
  161.63 +
  161.64 +<!--
  161.65 +        <question id="arch-time" when="init">
  161.66 +            What are the time estimates of the work?
  161.67 +            <hint>
  161.68 +            Please express your estimates of how long the design, implementation,
  161.69 +            stabilization are likely to last. How many people will be needed to
  161.70 +            implement this and what is the expected milestone by which the work should be 
  161.71 +            ready?
  161.72 +            </hint>
  161.73 +        </question>
  161.74 +-->
  161.75 + <answer id="arch-time">
  161.76 +  <p>
  161.77 +   XXX no answer for arch-time
  161.78 +  </p>
  161.79 + </answer>
  161.80 +
  161.81 +
  161.82 +
  161.83 +<!--
  161.84 +        <question id="arch-usecases" when="init">
  161.85 +            <hint>
  161.86 +                Content of this answer will be displayed as part of page at
  161.87 +                http://www.netbeans.org/download/dev/javadoc/usecases.html 
  161.88 +                You can use tags &lt;usecase name="name&gt; regular html description &lt;/usecase&gt;
  161.89 +                and if you want to use an URL you can prefix if with @TOP@ to begin
  161.90 +                at the root of your javadoc
  161.91 +            </hint>
  161.92 +        
  161.93 +            Describe the main <a href="http://wiki.netbeans.org/API_Design#The_Importance_of_Being_Use_Case_Oriented">
  161.94 +            use cases</a> of the new API. Who will use it under
  161.95 +            what circumstances? What kind of code would typically need to be written
  161.96 +            to use the module?
  161.97 +        </question>
  161.98 +-->
  161.99 + <answer id="arch-usecases">
 161.100 +  <p>
 161.101 +   XXX no answer for arch-usecases
 161.102 +  </p>
 161.103 + </answer>
 161.104 +
 161.105 +
 161.106 +
 161.107 +<!--
 161.108 +        <question id="arch-what" when="init">
 161.109 +            What is this project good for?
 161.110 +            <hint>
 161.111 +            Please provide here a few lines describing the project, 
 161.112 +            what problem it should solve, provide links to documentation, 
 161.113 +            specifications, etc.
 161.114 +            </hint>
 161.115 +        </question>
 161.116 +-->
 161.117 + <answer id="arch-what">
 161.118 +  <p>
 161.119 +   XXX no answer for arch-what
 161.120 +  </p>
 161.121 + </answer>
 161.122 +
 161.123 +
 161.124 +
 161.125 +<!--
 161.126 +        <question id="arch-where" when="impl">
 161.127 +            Where one can find sources for your module?
 161.128 +            <hint>
 161.129 +                Please provide link to the Hg web client at
 161.130 +                http://hg.netbeans.org/
 161.131 +                or just use tag defaultanswer generate='here'
 161.132 +            </hint>
 161.133 +        </question>
 161.134 +-->
 161.135 + <answer id="arch-where">
 161.136 +  <defaultanswer generate='here' />
 161.137 + </answer>
 161.138 +
 161.139 +
 161.140 +
 161.141 +<!--
 161.142 +        <question id="compat-deprecation" when="init">
 161.143 +            How the introduction of your project influences functionality
 161.144 +            provided by previous version of the product?
 161.145 +            <hint>
 161.146 +            If you are planning to deprecate/remove/change any existing APIs,
 161.147 +            list them here accompanied with the reason explaining why you
 161.148 +            are doing so.
 161.149 +            </hint>
 161.150 +        </question>
 161.151 +-->
 161.152 + <answer id="compat-deprecation">
 161.153 +  <p>
 161.154 +   XXX no answer for compat-deprecation
 161.155 +  </p>
 161.156 + </answer>
 161.157 +
 161.158 +
 161.159 +
 161.160 +<!--
 161.161 +        <question id="compat-i18n" when="impl">
 161.162 +            Is your module correctly internationalized?
 161.163 +            <hint>
 161.164 +            Correct internationalization means that it obeys instructions 
 161.165 +            at <a href="http://www.netbeans.org/download/dev/javadoc/org-openide-modules/org/openide/modules/doc-files/i18n-branding.html">
 161.166 +            NetBeans I18N pages</a>.
 161.167 +            </hint>
 161.168 +        </question>
 161.169 +-->
 161.170 + <answer id="compat-i18n">
 161.171 +  <p>
 161.172 +   XXX no answer for compat-i18n
 161.173 +  </p>
 161.174 + </answer>
 161.175 +
 161.176 +
 161.177 +
 161.178 +<!--
 161.179 +        <question id="compat-standards" when="init">
 161.180 +            Does the module implement or define any standards? Is the 
 161.181 +            implementation exact or does it deviate somehow?
 161.182 +        </question>
 161.183 +-->
 161.184 + <answer id="compat-standards">
 161.185 +  <p>
 161.186 +   XXX no answer for compat-standards
 161.187 +  </p>
 161.188 + </answer>
 161.189 +
 161.190 +
 161.191 +
 161.192 +<!--
 161.193 +        <question id="compat-version" when="impl">
 161.194 +            Can your module coexist with earlier and future
 161.195 +            versions of itself? Can you correctly read all old settings? Will future
 161.196 +            versions be able to read your current settings? Can you read
 161.197 +            or politely ignore settings stored by a future version?
 161.198 +            
 161.199 +            <hint>
 161.200 +            Very helpful for reading settings is to store version number
 161.201 +            there, so future versions can decide whether how to read/convert
 161.202 +            the settings and older versions can ignore the new ones.
 161.203 +            </hint>
 161.204 +        </question>
 161.205 +-->
 161.206 + <answer id="compat-version">
 161.207 +  <p>
 161.208 +   XXX no answer for compat-version
 161.209 +  </p>
 161.210 + </answer>
 161.211 +
 161.212 +
 161.213 +
 161.214 +<!--
 161.215 +        <question id="dep-jre" when="final">
 161.216 +            Which version of JRE do you need (1.2, 1.3, 1.4, etc.)?
 161.217 +            <hint>
 161.218 +            It is expected that if your module runs on 1.x that it will run 
 161.219 +            on 1.x+1 if no, state that please. Also describe here cases where
 161.220 +            you run different code on different versions of JRE and why.
 161.221 +            </hint>
 161.222 +        </question>
 161.223 +-->
 161.224 + <answer id="dep-jre">
 161.225 +  <p>
 161.226 +   XXX no answer for dep-jre
 161.227 +  </p>
 161.228 + </answer>
 161.229 +
 161.230 +
 161.231 +
 161.232 +<!--
 161.233 +        <question id="dep-jrejdk" when="final">
 161.234 +            Do you require the JDK or is the JRE enough?
 161.235 +        </question>
 161.236 +-->
 161.237 + <answer id="dep-jrejdk">
 161.238 +  <p>
 161.239 +   XXX no answer for dep-jrejdk
 161.240 +  </p>
 161.241 + </answer>
 161.242 +
 161.243 +
 161.244 +
 161.245 +<!--
 161.246 +        <question id="dep-nb" when="init">
 161.247 +            What other NetBeans projects and modules does this one depend on?
 161.248 +            <hint>
 161.249 +            Depending on other NetBeans projects influnces the ability of
 161.250 +            users of your work to customize their own branded version of
 161.251 +            NetBeans by enabling and disabling some modules. Too
 161.252 +            much dependencies restrict this kind of customization. If that
 161.253 +            is your case, then you may want to split your functionality into
 161.254 +            pieces of autoload, eager and regular modules which can be
 161.255 +            enabled independently. Usually the answer to this question
 161.256 +            is generated from your <code>project.xml</code> file, but
 161.257 +            if it is not guessed correctly, you can suppress it by
 161.258 +            specifying &lt;defaultanswer generate="none"/&gt; and
 161.259 +            write here your own. Please describe such projects as imported APIs using
 161.260 +            the <code>&lt;api name="identification" type="import or export" category="stable" url="where is the description" /&gt;</code>.
 161.261 +            By doing this information gets listed in the summary page of your
 161.262 +            javadoc.
 161.263 +            </hint>
 161.264 +        </question>
 161.265 +-->
 161.266 + <answer id="dep-nb">
 161.267 +  <defaultanswer generate='here' />
 161.268 + </answer>
 161.269 +
 161.270 +
 161.271 +
 161.272 +<!--
 161.273 +        <question id="dep-non-nb" when="init">
 161.274 +            What other projects outside NetBeans does this one depend on?
 161.275 +            
 161.276 +            <hint>
 161.277 +            Depending on 3rd party libraries is always problematic,
 161.278 +            especially if they are not open source, as that complicates
 161.279 +            the licensing scheme of NetBeans. Please enumerate your
 161.280 +            external dependencies here, so it is correctly understood since
 161.281 +            the begining what are the legal implications of your project.
 161.282 +            Also please note that
 161.283 +            some non-NetBeans projects are packaged as NetBeans modules
 161.284 +            (see <a href="http://libs.netbeans.org/">libraries</a>) and
 161.285 +            it is preferred to use this approach when more modules may
 161.286 +            depend and share such third-party libraries.
 161.287 +            </hint>
 161.288 +        </question>
 161.289 +-->
 161.290 + <answer id="dep-non-nb">
 161.291 +  <p>
 161.292 +   XXX no answer for dep-non-nb
 161.293 +  </p>
 161.294 + </answer>
 161.295 +
 161.296 +
 161.297 +
 161.298 +<!--
 161.299 +        <question id="dep-platform" when="init">
 161.300 +            On which platforms does your module run? Does it run in the same
 161.301 +            way on each?
 161.302 +            <hint>
 161.303 +            If you plan any dependency on OS or any usage of native code,
 161.304 +            please describe why you are doing so and describe how you envision
 161.305 +            to enforce the portability of your code.
 161.306 +            Please note that there is a support for <a href="http://www.netbeans.org/download/dev/javadoc/org-openide-modules/org/openide/modules/doc-files/api.html#how-os-specific">OS conditionally
 161.307 +            enabled modules</a> which together with autoload/eager modules
 161.308 +            can allow you to enable to provide the best OS aware support
 161.309 +            on certain OSes while providing compatibility bridge on the not
 161.310 +            supported ones.
 161.311 +            Also please list the supported
 161.312 +            OSes/HW platforms and mentioned the lovest version of JDK required
 161.313 +            for your project to run on. Also state whether JRE is enough or
 161.314 +            you really need JDK.
 161.315 +            </hint>
 161.316 +        </question>
 161.317 +-->
 161.318 + <answer id="dep-platform">
 161.319 +  <p>
 161.320 +   XXX no answer for dep-platform
 161.321 +  </p>
 161.322 + </answer>
 161.323 +
 161.324 +
 161.325 +
 161.326 +<!--
 161.327 +        <question id="deploy-dependencies" when="final">
 161.328 +            What do other modules need to do to declare a dependency on this one,
 161.329 +            in addition to or instead of the normal module dependency declaration
 161.330 +            (e.g. tokens to require)?
 161.331 +            <hint>
 161.332 +                Provide a sample of the actual lines you would add to a module manifest
 161.333 +                to declare a dependency, for example OpenIDE-Module-Requires: some.token.
 161.334 +                If other modules should not depend on this module, or should just use a
 161.335 +                simple regular module dependency, you can just answer "nothing". If you
 161.336 +                intentionally expose a semistable API to clients using implementation
 161.337 +                dependencies, you should mention that here (but there is no need to give
 161.338 +                an example of usage).
 161.339 +            </hint>
 161.340 +        </question>
 161.341 +-->
 161.342 + <answer id="deploy-dependencies">
 161.343 +  <p>
 161.344 +   XXX no answer for deploy-dependencies
 161.345 +  </p>
 161.346 + </answer>
 161.347 +
 161.348 +
 161.349 +
 161.350 +<!--
 161.351 +        <question id="deploy-jar" when="impl">
 161.352 +            Do you deploy just module JAR file(s) or other files as well?
 161.353 +            <hint>
 161.354 +            Usually a module consist of one JAR file (perhaps with Class-Path
 161.355 +            extensions) and also a configuration file that enables it. If you
 161.356 +            have any other files, use
 161.357 +            &lt;api group="java.io.File" name="yourname" type="export" category="friend"&gt;...&lt;/api&gt;
 161.358 +            to define the location, name and stability of your files (of course
 161.359 +            changing "yourname" and "friend" to suit your needs).
 161.360 +            
 161.361 +            If it uses more than one JAR, describe where they are located, how
 161.362 +            they refer to each other. 
 161.363 +            If it consist of module JAR(s) and other files, please describe
 161.364 +            what is their purpose, why other files are necessary. Please 
 161.365 +            make sure that installation/uninstallation leaves the system 
 161.366 +            in state as it was before installation.
 161.367 +            </hint>
 161.368 +        </question>
 161.369 +-->
 161.370 + <answer id="deploy-jar">
 161.371 +  <p>
 161.372 +   XXX no answer for deploy-jar
 161.373 +  </p>
 161.374 + </answer>
 161.375 +
 161.376 +
 161.377 +
 161.378 +<!--
 161.379 +        <question id="deploy-nbm" when="impl">
 161.380 +            Can you deploy an NBM via the Update Center?
 161.381 +            <hint>
 161.382 +            If not why?
 161.383 +            </hint>
 161.384 +        </question>
 161.385 +-->
 161.386 + <answer id="deploy-nbm">
 161.387 +  <p>
 161.388 +   XXX no answer for deploy-nbm
 161.389 +  </p>
 161.390 + </answer>
 161.391 +
 161.392 +
 161.393 +
 161.394 +<!--
 161.395 +        <question id="deploy-packages" when="init">
 161.396 +            Are packages of your module made inaccessible by not declaring them
 161.397 +            public?
 161.398 +            
 161.399 +            <hint>
 161.400 +            By default NetBeans build harness treats all packages are private.
 161.401 +            If you export some of them - either as public or friend packages,
 161.402 +            you should have a reason. If the reason is described elsewhere
 161.403 +            in this document, you can ignore this question.
 161.404 +            </hint>
 161.405 +        </question>
 161.406 +-->
 161.407 + <answer id="deploy-packages">
 161.408 +  <p>
 161.409 +   XXX no answer for deploy-packages
 161.410 +  </p>
 161.411 + </answer>
 161.412 +
 161.413 +
 161.414 +
 161.415 +<!--
 161.416 +        <question id="deploy-shared" when="final">
 161.417 +            Do you need to be installed in the shared location only, or in the user directory only,
 161.418 +            or can your module be installed anywhere?
 161.419 +            <hint>
 161.420 +            Installation location shall not matter, if it does explain why.
 161.421 +            Consider also whether <code>InstalledFileLocator</code> can help.
 161.422 +            </hint>
 161.423 +        </question>
 161.424 +-->
 161.425 + <answer id="deploy-shared">
 161.426 +  <p>
 161.427 +   XXX no answer for deploy-shared
 161.428 +  </p>
 161.429 + </answer>
 161.430 +
 161.431 +
 161.432 +
 161.433 +<!--
 161.434 +        <question id="exec-ant-tasks" when="impl">
 161.435 +            Do you define or register any ant tasks that other can use?
 161.436 +            
 161.437 +            <hint>
 161.438 +            If you provide an ant task that users can use, you need to be very
 161.439 +            careful about its syntax and behaviour, as it most likely forms an
 161.440 +	          API for end users and as there is a lot of end users, their reaction
 161.441 +            when such API gets broken can be pretty strong.
 161.442 +            </hint>
 161.443 +        </question>
 161.444 +-->
 161.445 + <answer id="exec-ant-tasks">
 161.446 +  <p>
 161.447 +   XXX no answer for exec-ant-tasks
 161.448 +  </p>
 161.449 + </answer>
 161.450 +
 161.451 +
 161.452 +
 161.453 +<!--
 161.454 +        <question id="exec-classloader" when="impl">
 161.455 +            Does your code create its own class loader(s)?
 161.456 +            <hint>
 161.457 +            A bit unusual. Please explain why and what for.
 161.458 +            </hint>
 161.459 +        </question>
 161.460 +-->
 161.461 + <answer id="exec-classloader">
 161.462 +  <p>
 161.463 +   XXX no answer for exec-classloader
 161.464 +  </p>
 161.465 + </answer>
 161.466 +
 161.467 +
 161.468 +
 161.469 +<!--
 161.470 +        <question id="exec-component" when="impl">
 161.471 +            Is execution of your code influenced by any (string) property
 161.472 +            of any of your components?
 161.473 +            
 161.474 +            <hint>
 161.475 +            Often <code>JComponent.getClientProperty</code>, <code>Action.getValue</code>
 161.476 +            or <code>PropertyDescriptor.getValue</code>, etc. are used to influence
 161.477 +            a behavior of some code. This of course forms an interface that should
 161.478 +            be documented. Also if one depends on some interface that an object
 161.479 +            implements (<code>component instanceof Runnable</code>) that forms an
 161.480 +            API as well.
 161.481 +            </hint>
 161.482 +        </question>
 161.483 +-->
 161.484 + <answer id="exec-component">
 161.485 +  <p>
 161.486 +   XXX no answer for exec-component
 161.487 +  </p>
 161.488 + </answer>
 161.489 +
 161.490 +
 161.491 +
 161.492 +<!--
 161.493 +        <question id="exec-introspection" when="impl">
 161.494 +            Does your module use any kind of runtime type information (<code>instanceof</code>,
 161.495 +            work with <code>java.lang.Class</code>, etc.)?
 161.496 +            <hint>
 161.497 +            Check for cases when you have an object of type A and you also
 161.498 +            expect it to (possibly) be of type B and do some special action. That
 161.499 +            should be documented. The same applies on operations in meta-level
 161.500 +            (Class.isInstance(...), Class.isAssignableFrom(...), etc.).
 161.501 +            </hint>
 161.502 +        </question>
 161.503 +-->
 161.504 + <answer id="exec-introspection">
 161.505 +  <p>
 161.506 +   XXX no answer for exec-introspection
 161.507 +  </p>
 161.508 + </answer>
 161.509 +
 161.510 +
 161.511 +
 161.512 +<!--
 161.513 +        <question id="exec-privateaccess" when="final">
 161.514 +            Are you aware of any other parts of the system calling some of 
 161.515 +            your methods by reflection?
 161.516 +            <hint>
 161.517 +            If so, describe the "contract" as an API. Likely private or friend one, but
 161.518 +            still API and consider rewrite of it.
 161.519 +            </hint>
 161.520 +        </question>
 161.521 +-->
 161.522 + <answer id="exec-privateaccess">
 161.523 +  <p>
 161.524 +   XXX no answer for exec-privateaccess
 161.525 +  </p>
 161.526 + </answer>
 161.527 +
 161.528 +
 161.529 +
 161.530 +<!--
 161.531 +        <question id="exec-process" when="impl">
 161.532 +            Do you execute an external process from your module? How do you ensure
 161.533 +            that the result is the same on different platforms? Do you parse output?
 161.534 +            Do you depend on result code?
 161.535 +            <hint>
 161.536 +            If you feed an input, parse the output please declare that as an API.
 161.537 +            </hint>
 161.538 +        </question>
 161.539 +-->
 161.540 + <answer id="exec-process">
 161.541 +  <p>
 161.542 +   XXX no answer for exec-process
 161.543 +  </p>
 161.544 + </answer>
 161.545 +
 161.546 +
 161.547 +
 161.548 +<!--
 161.549 +        <question id="exec-property" when="impl">
 161.550 +            Is execution of your code influenced by any environment or
 161.551 +            Java system (<code>System.getProperty</code>) property?
 161.552 +            On a similar note, is there something interesting that you
 161.553 +            pass to <code>java.util.logging.Logger</code>? Or do you observe
 161.554 +            what others log?
 161.555 +            <hint>
 161.556 +            If there is a property that can change the behavior of your 
 161.557 +            code, somebody will likely use it. You should describe what it does 
 161.558 +            and the <a href="http://wiki.netbeans.org/API_Stability">stability category</a>
 161.559 +            of this API. You may use
 161.560 +            <pre>
 161.561 +                &lt;api type="export" group="property" name="id" category="private" url="http://..."&gt;
 161.562 +                    description of the property, where it is used, what it influence, etc.
 161.563 +                &lt;/api&gt;            
 161.564 +            </pre>
 161.565 +            </hint>
 161.566 +        </question>
 161.567 +-->
 161.568 + <answer id="exec-property">
 161.569 +  <p>
 161.570 +   XXX no answer for exec-property
 161.571 +  </p>
 161.572 + </answer>
 161.573 +
 161.574 +
 161.575 +
 161.576 +<!--
 161.577 +        <question id="exec-reflection" when="impl">
 161.578 +            Does your code use Java Reflection to execute other code?
 161.579 +            <hint>
 161.580 +            This usually indicates a missing or insufficient API in the other
 161.581 +            part of the system. If the other side is not aware of your dependency
 161.582 +            this contract can be easily broken.
 161.583 +            </hint>
 161.584 +        </question>
 161.585 +-->
 161.586 + <answer id="exec-reflection">
 161.587 +  <p>
 161.588 +   XXX no answer for exec-reflection
 161.589 +  </p>
 161.590 + </answer>
 161.591 +
 161.592 +
 161.593 +
 161.594 +<!--
 161.595 +        <question id="exec-threading" when="init">
 161.596 +            What threading models, if any, does your module adhere to? How the
 161.597 +            project behaves with respect to threading?
 161.598 +            <hint>
 161.599 +                Is your API threadsafe? Can it be accessed from any threads or
 161.600 +                just from some dedicated ones? Any special relation to AWT and
 161.601 +                its Event Dispatch thread? Also
 161.602 +                if your module calls foreign APIs which have a specific threading model,
 161.603 +                indicate how you comply with the requirements for multithreaded access
 161.604 +                (synchronization, mutexes, etc.) applicable to those APIs.
 161.605 +                If your module defines any APIs, or has complex internal structures
 161.606 +                that might be used from multiple threads, declare how you protect
 161.607 +                data against concurrent access, race conditions, deadlocks, etc.,
 161.608 +                and whether such rules are enforced by runtime warnings, errors, assertions, etc.
 161.609 +                Examples: a class might be non-thread-safe (like Java Collections); might
 161.610 +                be fully thread-safe (internal locking); might require access through a mutex
 161.611 +                (and may or may not automatically acquire that mutex on behalf of a client method);
 161.612 +                might be able to run only in the event queue; etc.
 161.613 +                Also describe when any events are fired: synchronously, asynchronously, etc.
 161.614 +                Ideas: <a href="http://core.netbeans.org/proposals/threading/index.html#recommendations">Threading Recommendations</a> (in progress)
 161.615 +            </hint>
 161.616 +        </question>
 161.617 +-->
 161.618 + <answer id="exec-threading">
 161.619 +  <p>
 161.620 +   XXX no answer for exec-threading
 161.621 +  </p>
 161.622 + </answer>
 161.623 +
 161.624 +
 161.625 +
 161.626 +<!--
 161.627 +        <question id="format-clipboard" when="impl">
 161.628 +            Which data flavors (if any) does your code read from or insert to
 161.629 +            the clipboard (by access to clipboard on means calling methods on <code>java.awt.datatransfer.Transferable</code>?
 161.630 +            
 161.631 +            <hint>
 161.632 +            Often Node's deal with clipboard by usage of <code>Node.clipboardCopy, Node.clipboardCut and Node.pasteTypes</code>.
 161.633 +            Check your code for overriding these methods.
 161.634 +            </hint>
 161.635 +        </question>
 161.636 +-->
 161.637 + <answer id="format-clipboard">
 161.638 +  <p>
 161.639 +   XXX no answer for format-clipboard
 161.640 +  </p>
 161.641 + </answer>
 161.642 +
 161.643 +
 161.644 +
 161.645 +<!--
 161.646 +        <question id="format-dnd" when="impl">
 161.647 +            Which protocols (if any) does your code understand during Drag &amp; Drop?
 161.648 +            <hint>
 161.649 +            Often Node's deal with clipboard by usage of <code>Node.drag, Node.getDropType</code>. 
 161.650 +            Check your code for overriding these methods. Btw. if they are not overridden, they
 161.651 +            by default delegate to <code>Node.clipboardCopy, Node.clipboardCut and Node.pasteTypes</code>.
 161.652 +            </hint>
 161.653 +        </question>
 161.654 +-->
 161.655 + <answer id="format-dnd">
 161.656 +  <p>
 161.657 +   XXX no answer for format-dnd
 161.658 +  </p>
 161.659 + </answer>
 161.660 +
 161.661 +
 161.662 +
 161.663 +<!--
 161.664 +        <question id="format-types" when="impl">
 161.665 +            Which protocols and file formats (if any) does your module read or write on disk,
 161.666 +            or transmit or receive over the network? Do you generate an ant build script?
 161.667 +            Can it be edited and modified? 
 161.668 +            
 161.669 +            <hint>
 161.670 +            <p>
 161.671 +            Files can be read and written by other programs, modules and users. If they influence
 161.672 +            your behaviour, make sure you either document the format or claim that it is a private
 161.673 +            api (using the &lt;api&gt; tag). 
 161.674 +            </p>
 161.675 +            
 161.676 +            <p>
 161.677 +            If you generate an ant build file, this is very likely going to be seen by end users and
 161.678 +            they will be attempted to edit it. You should be ready for that and provide here a link
 161.679 +            to documentation that you have for such purposes and also describe how you are going to
 161.680 +            understand such files during next release, when you (very likely) slightly change the 
 161.681 +            format.
 161.682 +            </p>
 161.683 +            </hint>
 161.684 +        </question>
 161.685 +-->
 161.686 + <answer id="format-types">
 161.687 +  <p>
 161.688 +   XXX no answer for format-types
 161.689 +  </p>
 161.690 + </answer>
 161.691 +
 161.692 +
 161.693 +
 161.694 +<!--
 161.695 +        <question id="lookup-lookup" when="init">
 161.696 +            Does your module use <code>org.openide.util.Lookup</code>
 161.697 +            or any similar technology to find any components to communicate with? Which ones?
 161.698 +            
 161.699 +            <hint>
 161.700 +            NetBeans is build around a generic registry of services called
 161.701 +            lookup. It is preferable to use it for registration and discovery
 161.702 +            if possible. See
 161.703 +            <a href="http://www.netbeans.org/download/dev/javadoc/org-openide-util/org/openide/util/lookup/doc-files/index.html">
 161.704 +            The Solution to Comunication Between Components
 161.705 +            </a>. If you do not plan to use lookup and insist usage
 161.706 +            of other solution, then please describe why it is not working for
 161.707 +            you.
 161.708 +            <br/>
 161.709 +            When filling the final version of your arch document, please
 161.710 +            describe the interfaces you are searching for, where 
 161.711 +            are defined, whether you are searching for just one or more of them,
 161.712 +            if the order is important, etc. Also classify the stability of such
 161.713 +            API contract. Use &lt;api group=&amp;lookup&amp; /&gt; tag, so
 161.714 +            your information gets listed in the summary page of your javadoc.
 161.715 +            </hint>
 161.716 +        </question>
 161.717 +-->
 161.718 + <answer id="lookup-lookup">
 161.719 +  <p>
 161.720 +   XXX no answer for lookup-lookup
 161.721 +  </p>
 161.722 + </answer>
 161.723 +
 161.724 +
 161.725 +
 161.726 +<!--
 161.727 +        <question id="lookup-register" when="final">
 161.728 +            Do you register anything into lookup for other code to find?
 161.729 +            <hint>
 161.730 +            Do you register using layer file or using a declarative annotation such as <code>@ServiceProvider</code>?
 161.731 +            Who is supposed to find your component?
 161.732 +            </hint>
 161.733 +        </question>
 161.734 +-->
 161.735 + <answer id="lookup-register">
 161.736 +  <p>
 161.737 +   XXX no answer for lookup-register
 161.738 +  </p>
 161.739 + </answer>
 161.740 +
 161.741 +
 161.742 +
 161.743 +<!--
 161.744 +        <question id="lookup-remove" when="final">
 161.745 +            Do you remove entries of other modules from lookup?
 161.746 +            <hint>
 161.747 +            Why? Of course, that is possible, but it can be dangerous. Is the module
 161.748 +            your are masking resource from aware of what you are doing?
 161.749 +            </hint>
 161.750 +        </question>
 161.751 +-->
 161.752 + <answer id="lookup-remove">
 161.753 +  <p>
 161.754 +   XXX no answer for lookup-remove
 161.755 +  </p>
 161.756 + </answer>
 161.757 +
 161.758 +
 161.759 +
 161.760 +<!--
 161.761 +        <question id="perf-exit" when="final">
 161.762 +            Does your module run any code on exit?
 161.763 +        </question>
 161.764 +-->
 161.765 + <answer id="perf-exit">
 161.766 +  <p>
 161.767 +   XXX no answer for perf-exit
 161.768 +  </p>
 161.769 + </answer>
 161.770 +
 161.771 +
 161.772 +
 161.773 +<!--
 161.774 +        <question id="perf-huge_dialogs" when="final">
 161.775 +            Does your module contain any dialogs or wizards with a large number of
 161.776 +            GUI controls such as combo boxes, lists, trees, or text areas?
 161.777 +        </question>
 161.778 +-->
 161.779 + <answer id="perf-huge_dialogs">
 161.780 +  <p>
 161.781 +   XXX no answer for perf-huge_dialogs
 161.782 +  </p>
 161.783 + </answer>
 161.784 +
 161.785 +
 161.786 +
 161.787 +<!--
 161.788 +        <question id="perf-limit" when="init">
 161.789 +            Are there any hard-coded or practical limits in the number or size of
 161.790 +            elements your code can handle?
 161.791 +            <hint>
 161.792 +                Most of algorithms have increasing memory and speed complexity
 161.793 +                with respect to size of data they operate on. What is the critical
 161.794 +                part of your project that can be seen as a bottleneck with
 161.795 +                respect to speed or required memory? What are the practical
 161.796 +                sizes of data you tested your project with? What is your estimate
 161.797 +                of potential size of data that would cause visible performance
 161.798 +                problems? Is there some kind of check to detect such situation
 161.799 +                and prevent "hard" crashes - for example the CloneableEditorSupport
 161.800 +                checks for size of a file to be opened in editor
 161.801 +                and if it is larger than 1Mb it shows a dialog giving the
 161.802 +                user the right to decide - e.g. to cancel or commit suicide.
 161.803 +            </hint>
 161.804 +        </question>
 161.805 +-->
 161.806 + <answer id="perf-limit">
 161.807 +  <p>
 161.808 +   XXX no answer for perf-limit
 161.809 +  </p>
 161.810 + </answer>
 161.811 +
 161.812 +
 161.813 +
 161.814 +<!--
 161.815 +        <question id="perf-mem" when="final">
 161.816 +            How much memory does your component consume? Estimate
 161.817 +            with a relation to the number of windows, etc.
 161.818 +        </question>
 161.819 +-->
 161.820 + <answer id="perf-mem">
 161.821 +  <p>
 161.822 +   XXX no answer for perf-mem
 161.823 +  </p>
 161.824 + </answer>
 161.825 +
 161.826 +
 161.827 +
 161.828 +<!--
 161.829 +        <question id="perf-menus" when="final">
 161.830 +            Does your module use dynamically updated context menus, or
 161.831 +            context-sensitive actions with complicated and slow enablement logic?
 161.832 +            <hint>
 161.833 +                If you do a lot of tricks when adding actions to regular or context menus, you can significantly
 161.834 +                slow down display of the menu, even when the user is not using your action. Pay attention to
 161.835 +                actions you add to the main menu bar, and to context menus of foreign nodes or components. If
 161.836 +                the action is conditionally enabled, or changes its display dynamically, you need to check the
 161.837 +                impact on performance. In some cases it may be more appropriate to make a simple action that is
 161.838 +                always enabled but does more detailed checks in a dialog if it is actually run.
 161.839 +            </hint>
 161.840 +        </question>
 161.841 +-->
 161.842 + <answer id="perf-menus">
 161.843 +  <p>
 161.844 +   XXX no answer for perf-menus
 161.845 +  </p>
 161.846 + </answer>
 161.847 +
 161.848 +
 161.849 +
 161.850 +<!--
 161.851 +        <question id="perf-progress" when="final">
 161.852 +            Does your module execute any long-running tasks?
 161.853 +            
 161.854 +            <hint>Long running tasks should never block 
 161.855 +            AWT thread as it badly hurts the UI
 161.856 +            <a href="http://performance.netbeans.org/responsiveness/issues.html">
 161.857 +            responsiveness</a>.
 161.858 +            Tasks like connecting over
 161.859 +            network, computing huge amount of data, compilation
 161.860 +            be done asynchronously (for example
 161.861 +            using <code>RequestProcessor</code>), definitively it should 
 161.862 +            not block AWT thread.
 161.863 +            </hint>
 161.864 +        </question>
 161.865 +-->
 161.866 + <answer id="perf-progress">
 161.867 +  <p>
 161.868 +   XXX no answer for perf-progress
 161.869 +  </p>
 161.870 + </answer>
 161.871 +
 161.872 +
 161.873 +
 161.874 +<!--
 161.875 +        <question id="perf-scale" when="init">
 161.876 +            Which external criteria influence the performance of your
 161.877 +            program (size of file in editor, number of files in menu, 
 161.878 +            in source directory, etc.) and how well your code scales?
 161.879 +            <hint>
 161.880 +            Please include some estimates, there are other more detailed 
 161.881 +            questions to answer in later phases of implementation. 
 161.882 +            </hint>
 161.883 +        </question>
 161.884 +-->
 161.885 + <answer id="perf-scale">
 161.886 +  <p>
 161.887 +   XXX no answer for perf-scale
 161.888 +  </p>
 161.889 + </answer>
 161.890 +
 161.891 +
 161.892 +
 161.893 +<!--
 161.894 +        <question id="perf-spi" when="init">
 161.895 +            How the performance of the plugged in code will be enforced?
 161.896 +            <hint>
 161.897 +            If you allow foreign code to be plugged into your own module, how
 161.898 +            do you enforce that it will behave correctly and quickly and will not
 161.899 +            negatively influence the performance of your own module?
 161.900 +            </hint>
 161.901 +        </question>
 161.902 +-->
 161.903 + <answer id="perf-spi">
 161.904 +  <p>
 161.905 +   XXX no answer for perf-spi
 161.906 +  </p>
 161.907 + </answer>
 161.908 +
 161.909 +
 161.910 +
 161.911 +<!--
 161.912 +        <question id="perf-startup" when="final">
 161.913 +            Does your module run any code on startup?
 161.914 +        </question>
 161.915 +-->
 161.916 + <answer id="perf-startup">
 161.917 +  <p>
 161.918 +   XXX no answer for perf-startup
 161.919 +  </p>
 161.920 + </answer>
 161.921 +
 161.922 +
 161.923 +
 161.924 +<!--
 161.925 +        <question id="perf-wakeup" when="final">
 161.926 +            Does any piece of your code wake up periodically and do something
 161.927 +            even when the system is otherwise idle (no user interaction)?
 161.928 +        </question>
 161.929 +-->
 161.930 + <answer id="perf-wakeup">
 161.931 +  <p>
 161.932 +   XXX no answer for perf-wakeup
 161.933 +  </p>
 161.934 + </answer>
 161.935 +
 161.936 +
 161.937 +
 161.938 +<!--
 161.939 +        <question id="resources-file" when="final">
 161.940 +            Does your module use <code>java.io.File</code> directly?
 161.941 +            
 161.942 +            <hint>
 161.943 +            NetBeans provide a logical wrapper over plain files called 
 161.944 +            <code>org.openide.filesystems.FileObject</code> that
 161.945 +            provides uniform access to such resources and is the preferred
 161.946 +            way that should be used. But of course there can be situations when
 161.947 +            this is not suitable.
 161.948 +            </hint>
 161.949 +        </question>
 161.950 +-->
 161.951 + <answer id="resources-file">
 161.952 +  <p>
 161.953 +   XXX no answer for resources-file
 161.954 +  </p>
 161.955 + </answer>
 161.956 +
 161.957 +
 161.958 +
 161.959 +<!--
 161.960 +        <question id="resources-layer" when="final">
 161.961 +            Does your module provide own layer? Does it create any files or
 161.962 +            folders in it? What it is trying to communicate by that and with which 
 161.963 +            components?
 161.964 +            
 161.965 +            <hint>
 161.966 +            NetBeans allows automatic and declarative installation of resources 
 161.967 +            by module layers. Module register files into appropriate places
 161.968 +            and other components use that information to perform their task
 161.969 +            (build menu, toolbar, window layout, list of templates, set of
 161.970 +            options, etc.). 
 161.971 +            </hint>
 161.972 +        </question>
 161.973 +-->
 161.974 + <answer id="resources-layer">
 161.975 +  <p>
 161.976 +   XXX no answer for resources-layer
 161.977 +  </p>
 161.978 + </answer>
 161.979 +
 161.980 +
 161.981 +
 161.982 +<!--
 161.983 +        <question id="resources-mask" when="final">
 161.984 +            Does your module mask/hide/override any resources provided by other modules in
 161.985 +            their layers?
 161.986 +            
 161.987 +            <hint>
 161.988 +            If you mask a file provided by another module, you probably depend
 161.989 +            on that and do not want the other module to (for example) change
 161.990 +            the file's name. That module shall thus make that file available as an API
 161.991 +            of some stability category.
 161.992 +            </hint>
 161.993 +        </question>
 161.994 +-->
 161.995 + <answer id="resources-mask">
 161.996 +  <p>
 161.997 +   XXX no answer for resources-mask
 161.998 +  </p>
 161.999 + </answer>
161.1000 +
161.1001 +
161.1002 +
161.1003 +<!--
161.1004 +        <question id="resources-preferences" when="final">
161.1005 +            Does your module uses preferences via Preferences API? Does your module use NbPreferences or
161.1006 +            or regular JDK Preferences ? Does it read, write or both ? 
161.1007 +            Does it share preferences with other modules ? If so, then why ?
161.1008 +            <hint>
161.1009 +                You may use
161.1010 +                    &lt;api type="export" group="preferences"
161.1011 +                    name="preference node name" category="private"&gt;
161.1012 +                    description of individual keys, where it is used, what it
161.1013 +                    influences, whether the module reads/write it, etc.
161.1014 +                    &lt;/api&gt;
161.1015 +                Due to XML ID restrictions, rather than /org/netbeans/modules/foo give the "name" as org.netbeans.modules.foo.
161.1016 +                Note that if you use NbPreferences this name will then be the same as the code name base of the module.
161.1017 +            </hint>
161.1018 +        </question>
161.1019 +-->
161.1020 + <answer id="resources-preferences">
161.1021 +  <p>
161.1022 +   XXX no answer for resources-preferences
161.1023 +  </p>
161.1024 + </answer>
161.1025 +
161.1026 +
161.1027 +
161.1028 +<!--
161.1029 +        <question id="resources-read" when="final">
161.1030 +            Does your module read any resources from layers? For what purpose?
161.1031 +            
161.1032 +            <hint>
161.1033 +            As this is some kind of intermodule dependency, it is a kind of API.
161.1034 +            Please describe it and classify according to 
161.1035 +            <a href="http://wiki.netbeans.org/API_Design#What_is_an_API.3F">
161.1036 +            common stability categories</a>.
161.1037 +            </hint>
161.1038 +        </question>
161.1039 +-->
161.1040 + <answer id="resources-read">
161.1041 +  <p>
161.1042 +   XXX no answer for resources-read
161.1043 +  </p>
161.1044 + </answer>
161.1045 +
161.1046 +
161.1047 +
161.1048 +<!--
161.1049 +        <question id="security-grant" when="final">
161.1050 +            Does your code grant additional rights to some other code?
161.1051 +            <hint>Avoid using a class loader that adds extra
161.1052 +            permissions to loaded code unless really necessary.
161.1053 +            Also note that your API implementation
161.1054 +            can also expose unneeded permissions to enemy code by
161.1055 +            calling AccessController.doPrivileged().</hint>
161.1056 +        </question>
161.1057 +-->
161.1058 + <answer id="security-grant">
161.1059 +  <p>
161.1060 +   XXX no answer for security-grant
161.1061 +  </p>
161.1062 + </answer>
161.1063 +
161.1064 +
161.1065 +
161.1066 +<!--
161.1067 +        <question id="security-policy" when="final">
161.1068 +            Does your functionality require modifications to the standard policy file?
161.1069 +            <hint>Your code might pass control to third-party code not
161.1070 +            coming from trusted domains. This could be code downloaded over the
161.1071 +            network or code coming from libraries that are not bundled
161.1072 +            with NetBeans. Which permissions need to be granted to which domains?</hint>
161.1073 +        </question>
161.1074 +-->
161.1075 + <answer id="security-policy">
161.1076 +  <p>
161.1077 +   XXX no answer for security-policy
161.1078 +  </p>
161.1079 + </answer>
161.1080 +
161.1081 +</api-answers>
   162.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   162.2 +++ b/sandbox/java.hints/java.hints.test/build.xml	Sun Oct 23 11:50:54 2016 +0200
   162.3 @@ -0,0 +1,8 @@
   162.4 +<?xml version="1.0" encoding="UTF-8"?>
   162.5 +<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
   162.6 +<!-- for some information on what you could do (e.g. targets to override). -->
   162.7 +<!-- If you delete this file and reopen the project it will be recreated. -->
   162.8 +<project name="org.netbeans.modules.java.hints.test" default="netbeans" basedir=".">
   162.9 +    <description>Builds, tests, and runs the project org.netbeans.modules.java.hints.test.</description>
  162.10 +    <import file="nbproject/build-impl.xml"/>
  162.11 +</project>
   163.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   163.2 +++ b/sandbox/java.hints/java.hints.test/manifest.mf	Sun Oct 23 11:50:54 2016 +0200
   163.3 @@ -0,0 +1,5 @@
   163.4 +Manifest-Version: 1.0
   163.5 +OpenIDE-Module: org.netbeans.modules.java.hints.test/1
   163.6 +OpenIDE-Module-Implementation-Version: 1
   163.7 +OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/java/hints/test/Bundle.properties
   163.8 +
   164.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   164.2 +++ b/sandbox/java.hints/java.hints.test/nbproject/build-impl.xml	Sun Oct 23 11:50:54 2016 +0200
   164.3 @@ -0,0 +1,45 @@
   164.4 +<?xml version="1.0" encoding="UTF-8"?>
   164.5 +<!--
   164.6 +*** GENERATED FROM project.xml - DO NOT EDIT  ***
   164.7 +***         EDIT ../build.xml INSTEAD         ***
   164.8 +-->
   164.9 +<project name="org.netbeans.modules.java.hints.test-impl" basedir="..">
  164.10 +    <fail message="Please build using Ant 1.7.1 or higher.">
  164.11 +        <condition>
  164.12 +            <not>
  164.13 +                <antversion atleast="1.7.1"/>
  164.14 +            </not>
  164.15 +        </condition>
  164.16 +    </fail>
  164.17 +    <property file="nbproject/private/suite-private.properties"/>
  164.18 +    <property file="nbproject/suite.properties"/>
  164.19 +    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
  164.20 +    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
  164.21 +    <property file="${suite.dir}/nbproject/platform.properties"/>
  164.22 +    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
  164.23 +        <attribute name="name"/>
  164.24 +        <attribute name="value"/>
  164.25 +        <sequential>
  164.26 +            <property name="@{name}" value="${@{value}}"/>
  164.27 +        </sequential>
  164.28 +    </macrodef>
  164.29 +    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
  164.30 +        <attribute name="property"/>
  164.31 +        <attribute name="value"/>
  164.32 +        <sequential>
  164.33 +            <property name="@{property}" value="@{value}"/>
  164.34 +        </sequential>
  164.35 +    </macrodef>
  164.36 +    <property file="${user.properties.file}"/>
  164.37 +    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
  164.38 +    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
  164.39 +    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
  164.40 +    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
  164.41 +        <condition>
  164.42 +            <not>
  164.43 +                <contains string="${cluster.path.evaluated}" substring="platform"/>
  164.44 +            </not>
  164.45 +        </condition>
  164.46 +    </fail>
  164.47 +    <import file="${harness.dir}/build.xml"/>
  164.48 +</project>
   165.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   165.2 +++ b/sandbox/java.hints/java.hints.test/nbproject/genfiles.properties	Sun Oct 23 11:50:54 2016 +0200
   165.3 @@ -0,0 +1,8 @@
   165.4 +build.xml.data.CRC32=bdfc486d
   165.5 +build.xml.script.CRC32=fb578ef0
   165.6 +build.xml.stylesheet.CRC32=a56c6a5b@2.70
   165.7 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
   165.8 +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
   165.9 +nbproject/build-impl.xml.data.CRC32=bdfc486d
  165.10 +nbproject/build-impl.xml.script.CRC32=c676886e
  165.11 +nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.70
   166.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   166.2 +++ b/sandbox/java.hints/java.hints.test/nbproject/org-netbeans-modules-java-hints-test.sig	Sun Oct 23 11:50:54 2016 +0200
   166.3 @@ -0,0 +1,67 @@
   166.4 +#Signature file v4.1
   166.5 +#Version 1.6.1
   166.6 +
   166.7 +CLSS public java.lang.Object
   166.8 +cons public init()
   166.9 +meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
  166.10 +meth protected void finalize() throws java.lang.Throwable
  166.11 +meth public boolean equals(java.lang.Object)
  166.12 +meth public final java.lang.Class<?> getClass()
  166.13 +meth public final void notify()
  166.14 +meth public final void notifyAll()
  166.15 +meth public final void wait() throws java.lang.InterruptedException
  166.16 +meth public final void wait(long) throws java.lang.InterruptedException
  166.17 +meth public final void wait(long,int) throws java.lang.InterruptedException
  166.18 +meth public int hashCode()
  166.19 +meth public java.lang.String toString()
  166.20 +
  166.21 +CLSS public org.netbeans.modules.java.hints.test.api.HintTest
  166.22 +innr public final AppliedFix
  166.23 +innr public final HintOutput
  166.24 +innr public final HintWarning
  166.25 +meth public !varargs org.netbeans.modules.java.hints.test.api.HintTest classpath(java.net.URL[])
  166.26 +meth public org.netbeans.modules.java.hints.test.api.HintTest input(java.lang.String) throws java.lang.Exception
  166.27 +meth public org.netbeans.modules.java.hints.test.api.HintTest input(java.lang.String,boolean) throws java.lang.Exception
  166.28 +meth public org.netbeans.modules.java.hints.test.api.HintTest input(java.lang.String,java.lang.String) throws java.lang.Exception
  166.29 +meth public org.netbeans.modules.java.hints.test.api.HintTest input(java.lang.String,java.lang.String,boolean) throws java.lang.Exception
  166.30 +meth public org.netbeans.modules.java.hints.test.api.HintTest preference(java.lang.String,boolean)
  166.31 +meth public org.netbeans.modules.java.hints.test.api.HintTest preference(java.lang.String,int)
  166.32 +meth public org.netbeans.modules.java.hints.test.api.HintTest preference(java.lang.String,java.lang.String)
  166.33 +meth public org.netbeans.modules.java.hints.test.api.HintTest setCaretMarker(char)
  166.34 +meth public org.netbeans.modules.java.hints.test.api.HintTest sourceLevel(java.lang.String)
  166.35 +meth public org.netbeans.modules.java.hints.test.api.HintTest$HintOutput run(java.lang.Class<?>) throws java.lang.Exception
  166.36 +meth public static org.netbeans.modules.java.hints.test.api.HintTest create() throws java.lang.Exception
  166.37 +supr java.lang.Object
  166.38 +hfds DEBUGGING_HELPER,ERRORS_COMPARATOR,INDEXING_LOGGER,JUNIT_PROPERTIES_FILENAME,JUNIT_PROPERTIES_LOCATION_PROPERTY,NBJUNIT_WORKDIR,bootClassPath,buildRoot,cache,caret,caretMarker,checkCompilable,compileClassPath,log,sourceLevel,sourcePath,sourceRoot,testFile,testPreferences,usedPaths,workDir
  166.39 +hcls DeadlockTask,TempPreferences,TestProxyClassPathProvider,TestSourceForBinaryQuery,TestSourceLevelQueryImplementation
  166.40 +
  166.41 +CLSS public final org.netbeans.modules.java.hints.test.api.HintTest$AppliedFix
  166.42 + outer org.netbeans.modules.java.hints.test.api.HintTest
  166.43 +cons public init(org.netbeans.modules.java.hints.test.api.HintTest)
  166.44 +meth public java.lang.String getOutput() throws java.lang.Exception
  166.45 +meth public java.lang.String getOutput(java.lang.String) throws java.lang.Exception
  166.46 +meth public org.netbeans.modules.java.hints.test.api.HintTest$AppliedFix assertCompilable() throws java.lang.Exception
  166.47 +meth public org.netbeans.modules.java.hints.test.api.HintTest$AppliedFix assertCompilable(java.lang.String) throws java.lang.Exception
  166.48 +meth public org.netbeans.modules.java.hints.test.api.HintTest$AppliedFix assertOutput(java.lang.String) throws java.lang.Exception
  166.49 +meth public org.netbeans.modules.java.hints.test.api.HintTest$AppliedFix assertOutput(java.lang.String,java.lang.String) throws java.lang.Exception
  166.50 +meth public org.netbeans.modules.java.hints.test.api.HintTest$AppliedFix assertVerbatimOutput(java.lang.String) throws java.lang.Exception
  166.51 +meth public org.netbeans.modules.java.hints.test.api.HintTest$AppliedFix assertVerbatimOutput(java.lang.String,java.lang.String) throws java.lang.Exception
  166.52 +supr java.lang.Object
  166.53 +
  166.54 +CLSS public final org.netbeans.modules.java.hints.test.api.HintTest$HintOutput
  166.55 + outer org.netbeans.modules.java.hints.test.api.HintTest
  166.56 +meth public !varargs org.netbeans.modules.java.hints.test.api.HintTest$HintOutput assertContainsWarnings(java.lang.String[])
  166.57 +meth public !varargs org.netbeans.modules.java.hints.test.api.HintTest$HintOutput assertNotContainsWarnings(java.lang.String[])
  166.58 +meth public !varargs org.netbeans.modules.java.hints.test.api.HintTest$HintOutput assertWarnings(java.lang.String[])
  166.59 +meth public org.netbeans.modules.java.hints.test.api.HintTest$HintWarning findWarning(java.lang.String)
  166.60 +supr java.lang.Object
  166.61 +hfds errors
  166.62 +
  166.63 +CLSS public final org.netbeans.modules.java.hints.test.api.HintTest$HintWarning
  166.64 + outer org.netbeans.modules.java.hints.test.api.HintTest
  166.65 +meth public !varargs org.netbeans.modules.java.hints.test.api.HintTest$HintWarning assertFixes(java.lang.String[]) throws java.lang.Exception
  166.66 +meth public org.netbeans.modules.java.hints.test.api.HintTest$AppliedFix applyFix() throws java.lang.Exception
  166.67 +meth public org.netbeans.modules.java.hints.test.api.HintTest$AppliedFix applyFix(java.lang.String) throws java.lang.Exception
  166.68 +supr java.lang.Object
  166.69 +hfds warning
  166.70 +
   167.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   167.2 +++ b/sandbox/java.hints/java.hints.test/nbproject/project.properties	Sun Oct 23 11:50:54 2016 +0200
   167.3 @@ -0,0 +1,8 @@
   167.4 +is.autoload=true
   167.5 +javac.source=1.7
   167.6 +javac.compilerargs=-Xlint -Xlint:-serial
   167.7 +spec.version.base=2.0.0
   167.8 +javadoc.arch=${basedir}/arch.xml
   167.9 +javadoc.apichanges=${basedir}/apichanges.xml
  167.10 +requires.nb.javac=true
  167.11 +spec.version.base.fatal.warning=false
   168.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   168.2 +++ b/sandbox/java.hints/java.hints.test/nbproject/project.xml	Sun Oct 23 11:50:54 2016 +0200
   168.3 @@ -0,0 +1,276 @@
   168.4 +<?xml version="1.0" encoding="UTF-8"?>
   168.5 +<project xmlns="http://www.netbeans.org/ns/project/1">
   168.6 +    <type>org.netbeans.modules.apisupport.project</type>
   168.7 +    <configuration>
   168.8 +        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
   168.9 +            <code-name-base>org.netbeans.modules.java.hints.test</code-name-base>
  168.10 +            <suite-component/>
  168.11 +            <module-dependencies>
  168.12 +                <dependency>
  168.13 +                    <code-name-base>org.netbeans.api.annotations.common</code-name-base>
  168.14 +                    <build-prerequisite/>
  168.15 +                    <compile-dependency/>
  168.16 +                    <run-dependency>
  168.17 +                        <release-version>1</release-version>
  168.18 +                        <specification-version>1.13</specification-version>
  168.19 +                    </run-dependency>
  168.20 +                </dependency>
  168.21 +                <dependency>
  168.22 +                    <code-name-base>org.netbeans.api.java</code-name-base>
  168.23 +                    <build-prerequisite/>
  168.24 +                    <compile-dependency/>
  168.25 +                    <run-dependency>
  168.26 +                        <release-version>1</release-version>
  168.27 +                        <specification-version>1.37</specification-version>
  168.28 +                    </run-dependency>
  168.29 +                </dependency>
  168.30 +                <dependency>
  168.31 +                    <code-name-base>org.netbeans.api.java.classpath</code-name-base>
  168.32 +                    <build-prerequisite/>
  168.33 +                    <compile-dependency/>
  168.34 +                    <run-dependency>
  168.35 +                        <release-version>1</release-version>
  168.36 +                        <specification-version>1.32</specification-version>
  168.37 +                    </run-dependency>
  168.38 +                </dependency>
  168.39 +                <dependency>
  168.40 +                    <code-name-base>org.netbeans.api.progress</code-name-base>
  168.41 +                    <build-prerequisite/>
  168.42 +                    <compile-dependency/>
  168.43 +                    <run-dependency>
  168.44 +                        <release-version>1</release-version>
  168.45 +                        <specification-version>1.33</specification-version>
  168.46 +                    </run-dependency>
  168.47 +                </dependency>
  168.48 +                <dependency>
  168.49 +                    <code-name-base>org.netbeans.core.startup</code-name-base>
  168.50 +                    <build-prerequisite/>
  168.51 +                    <compile-dependency/>
  168.52 +                    <run-dependency>
  168.53 +                        <release-version>1</release-version>
  168.54 +                        <specification-version>1.41</specification-version>
  168.55 +                    </run-dependency>
  168.56 +                </dependency>
  168.57 +                <dependency>
  168.58 +                    <code-name-base>org.netbeans.libs.javacapi</code-name-base>
  168.59 +                    <build-prerequisite/>
  168.60 +                    <compile-dependency/>
  168.61 +                    <run-dependency>
  168.62 +                        <specification-version>7.9</specification-version>
  168.63 +                    </run-dependency>
  168.64 +                </dependency>
  168.65 +                <dependency>
  168.66 +                    <code-name-base>org.netbeans.libs.junit4</code-name-base>
  168.67 +                    <build-prerequisite/>
  168.68 +                    <compile-dependency/>
  168.69 +                    <run-dependency>
  168.70 +                        <specification-version>1.13</specification-version>
  168.71 +                    </run-dependency>
  168.72 +                </dependency>
  168.73 +                <dependency>
  168.74 +                    <code-name-base>org.netbeans.modules.code.analysis</code-name-base>
  168.75 +                    <build-prerequisite/>
  168.76 +                    <compile-dependency/>
  168.77 +                    <run-dependency>
  168.78 +                        <release-version>0</release-version>
  168.79 +                        <implementation-version/>
  168.80 +                    </run-dependency>
  168.81 +                </dependency>
  168.82 +                <dependency>
  168.83 +                    <code-name-base>org.netbeans.modules.editor.mimelookup</code-name-base>
  168.84 +                    <build-prerequisite/>
  168.85 +                    <compile-dependency/>
  168.86 +                    <run-dependency>
  168.87 +                        <release-version>1</release-version>
  168.88 +                        <specification-version>1.25</specification-version>
  168.89 +                    </run-dependency>
  168.90 +                </dependency>
  168.91 +                <dependency>
  168.92 +                    <code-name-base>org.netbeans.modules.java.lexer</code-name-base>
  168.93 +                    <build-prerequisite/>
  168.94 +                    <compile-dependency/>
  168.95 +                    <run-dependency>
  168.96 +                        <release-version>1</release-version>
  168.97 +                        <specification-version>1.17</specification-version>
  168.98 +                    </run-dependency>
  168.99 +                </dependency>
 168.100 +                <dependency>
 168.101 +                    <code-name-base>org.netbeans.modules.java.source</code-name-base>
 168.102 +                    <build-prerequisite/>
 168.103 +                    <compile-dependency/>
 168.104 +                    <run-dependency>
 168.105 +                        <implementation-version/>
 168.106 +                    </run-dependency>
 168.107 +                </dependency>
 168.108 +                <dependency>
 168.109 +                    <code-name-base>org.netbeans.modules.java.source.base</code-name-base>
 168.110 +                    <build-prerequisite/>
 168.111 +                    <compile-dependency/>
 168.112 +                    <run-dependency>
 168.113 +                        <implementation-version/>
 168.114 +                    </run-dependency>
 168.115 +                </dependency>
 168.116 +                <dependency>
 168.117 +                    <code-name-base>org.netbeans.modules.lexer</code-name-base>
 168.118 +                    <build-prerequisite/>
 168.119 +                    <compile-dependency/>
 168.120 +                    <run-dependency>
 168.121 +                        <release-version>2</release-version>
 168.122 +                        <specification-version>1.43</specification-version>
 168.123 +                    </run-dependency>
 168.124 +                </dependency>
 168.125 +                <dependency>
 168.126 +                    <code-name-base>org.netbeans.modules.nbjunit</code-name-base>
 168.127 +                    <build-prerequisite/>
 168.128 +                    <compile-dependency/>
 168.129 +                    <run-dependency>
 168.130 +                        <release-version>1</release-version>
 168.131 +                        <specification-version>1.74</specification-version>
 168.132 +                    </run-dependency>
 168.133 +                </dependency>
 168.134 +                <dependency>
 168.135 +                    <code-name-base>org.netbeans.modules.parsing.api</code-name-base>
 168.136 +                    <build-prerequisite/>
 168.137 +                    <compile-dependency/>
 168.138 +                    <run-dependency>
 168.139 +                        <release-version>1</release-version>
 168.140 +                        <implementation-version/>
 168.141 +                    </run-dependency>
 168.142 +                </dependency>
 168.143 +                <dependency>
 168.144 +                    <code-name-base>org.netbeans.modules.parsing.indexing</code-name-base>
 168.145 +                    <build-prerequisite/>
 168.146 +                    <compile-dependency/>
 168.147 +                    <run-dependency>
 168.148 +                        <implementation-version/>
 168.149 +                    </run-dependency>
 168.150 +                </dependency>
 168.151 +                <dependency>
 168.152 +                    <code-name-base>org.netbeans.modules.projectapi</code-name-base>
 168.153 +                    <build-prerequisite/>
 168.154 +                    <compile-dependency/>
 168.155 +                    <run-dependency>
 168.156 +                        <release-version>1</release-version>
 168.157 +                        <specification-version>1.41</specification-version>
 168.158 +                    </run-dependency>
 168.159 +                </dependency>
 168.160 +                <dependency>
 168.161 +                    <code-name-base>org.netbeans.modules.projectuiapi</code-name-base>
 168.162 +                    <build-prerequisite/>
 168.163 +                    <compile-dependency/>
 168.164 +                    <run-dependency>
 168.165 +                        <release-version>1</release-version>
 168.166 +                        <specification-version>1.54</specification-version>
 168.167 +                    </run-dependency>
 168.168 +                </dependency>
 168.169 +                <dependency>
 168.170 +                    <code-name-base>org.netbeans.modules.projectuiapi.base</code-name-base>
 168.171 +                    <build-prerequisite/>
 168.172 +                    <compile-dependency/>
 168.173 +                    <run-dependency>
 168.174 +                        <release-version>1</release-version>
 168.175 +                        <specification-version>1.79.0.9</specification-version>
 168.176 +                    </run-dependency>
 168.177 +                </dependency>
 168.178 +                <dependency>
 168.179 +                    <code-name-base>org.netbeans.modules.refactoring.api</code-name-base>
 168.180 +                    <build-prerequisite/>
 168.181 +                    <compile-dependency/>
 168.182 +                    <run-dependency>
 168.183 +                        <specification-version>1.34</specification-version>
 168.184 +                    </run-dependency>
 168.185 +                </dependency>
 168.186 +                <dependency>
 168.187 +                    <code-name-base>org.netbeans.spi.editor.hints</code-name-base>
 168.188 +                    <build-prerequisite/>
 168.189 +                    <compile-dependency/>
 168.190 +                    <run-dependency>
 168.191 +                        <release-version>0-1</release-version>
 168.192 +                        <specification-version>1.22</specification-version>
 168.193 +                    </run-dependency>
 168.194 +                </dependency>
 168.195 +                <dependency>
 168.196 +                    <code-name-base>org.netbeans.spi.java.hints</code-name-base>
 168.197 +                    <build-prerequisite/>
 168.198 +                    <compile-dependency/>
 168.199 +                    <run-dependency>
 168.200 +                        <implementation-version/>
 168.201 +                    </run-dependency>
 168.202 +                </dependency>
 168.203 +                <dependency>
 168.204 +                    <code-name-base>org.openide.filesystems</code-name-base>
 168.205 +                    <build-prerequisite/>
 168.206 +                    <compile-dependency/>
 168.207 +                    <run-dependency>
 168.208 +                        <specification-version>7.55</specification-version>
 168.209 +                    </run-dependency>
 168.210 +                </dependency>
 168.211 +                <dependency>
 168.212 +                    <code-name-base>org.openide.loaders</code-name-base>
 168.213 +                    <build-prerequisite/>
 168.214 +                    <compile-dependency/>
 168.215 +                    <run-dependency>
 168.216 +                        <specification-version>7.33</specification-version>
 168.217 +                    </run-dependency>
 168.218 +                </dependency>
 168.219 +                <dependency>
 168.220 +                    <code-name-base>org.openide.nodes</code-name-base>
 168.221 +                    <build-prerequisite/>
 168.222 +                    <compile-dependency/>
 168.223 +                    <run-dependency>
 168.224 +                        <specification-version>7.26</specification-version>
 168.225 +                    </run-dependency>
 168.226 +                </dependency>
 168.227 +                <dependency>
 168.228 +                    <code-name-base>org.openide.text</code-name-base>
 168.229 +                    <build-prerequisite/>
 168.230 +                    <compile-dependency/>
 168.231 +                    <run-dependency>
 168.232 +                        <specification-version>6.44</specification-version>
 168.233 +                    </run-dependency>
 168.234 +                </dependency>
 168.235 +                <dependency>
 168.236 +                    <code-name-base>org.openide.util</code-name-base>
 168.237 +                    <build-prerequisite/>
 168.238 +                    <compile-dependency/>
 168.239 +                    <run-dependency>
 168.240 +                        <specification-version>8.20</specification-version>
 168.241 +                    </run-dependency>
 168.242 +                </dependency>
 168.243 +                <dependency>
 168.244 +                    <code-name-base>org.openide.util.lookup</code-name-base>
 168.245 +                    <build-prerequisite/>
 168.246 +                    <compile-dependency/>
 168.247 +                    <run-dependency>
 168.248 +                        <specification-version>8.12</specification-version>
 168.249 +                    </run-dependency>
 168.250 +                </dependency>
 168.251 +                <dependency>
 168.252 +                    <code-name-base>org.openide.util.ui</code-name-base>
 168.253 +                    <build-prerequisite/>
 168.254 +                    <compile-dependency/>
 168.255 +                    <run-dependency>
 168.256 +                        <specification-version>9.3</specification-version>
 168.257 +                    </run-dependency>
 168.258 +                </dependency>
 168.259 +            </module-dependencies>
 168.260 +            <test-dependencies>
 168.261 +                <test-type>
 168.262 +                    <name>unit</name>
 168.263 +                    <test-dependency>
 168.264 +                        <code-name-base>org.netbeans.modules.parsing.nb</code-name-base>
 168.265 +                        <recursive/>
 168.266 +                        <compile-dependency/>
 168.267 +                    </test-dependency>
 168.268 +                    <test-dependency>
 168.269 +                        <code-name-base>org.netbeans.modules.projectapi.nb</code-name-base>
 168.270 +                        <compile-dependency/>
 168.271 +                    </test-dependency>
 168.272 +                </test-type>
 168.273 +            </test-dependencies>
 168.274 +            <public-packages>
 168.275 +                <package>org.netbeans.modules.java.hints.test.api</package>
 168.276 +            </public-packages>
 168.277 +        </data>
 168.278 +    </configuration>
 168.279 +</project>
   169.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   169.2 +++ b/sandbox/java.hints/java.hints.test/nbproject/suite.properties	Sun Oct 23 11:50:54 2016 +0200
   169.3 @@ -0,0 +1,1 @@
   169.4 +suite.dir=${basedir}/..
   170.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   170.2 +++ b/sandbox/java.hints/java.hints.test/src/org/netbeans/modules/java/hints/test/Bundle.properties	Sun Oct 23 11:50:54 2016 +0200
   170.3 @@ -0,0 +1,1 @@
   170.4 +OpenIDE-Module-Name=Java Hints Test API
   171.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   171.2 +++ b/sandbox/java.hints/java.hints.test/src/org/netbeans/modules/java/hints/test/Utilities.java	Sun Oct 23 11:50:54 2016 +0200
   171.3 @@ -0,0 +1,104 @@
   171.4 +/*
   171.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   171.6 + *
   171.7 + * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
   171.8 + *
   171.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  171.10 + * Other names may be trademarks of their respective owners.
  171.11 + *
  171.12 + * The contents of this file are subject to the terms of either the GNU
  171.13 + * General Public License Version 2 only ("GPL") or the Common
  171.14 + * Development and Distribution License("CDDL") (collectively, the
  171.15 + * "License"). You may not use this file except in compliance with the
  171.16 + * License. You can obtain a copy of the License at
  171.17 + * http://www.netbeans.org/cddl-gplv2.html
  171.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  171.19 + * specific language governing permissions and limitations under the
  171.20 + * License.  When distributing the software, include this License Header
  171.21 + * Notice in each file and include the License file at
  171.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  171.23 + * particular file as subject to the "Classpath" exception as provided
  171.24 + * by Oracle in the GPL Version 2 section of the License file that
  171.25 + * accompanied this code. If applicable, add the following below the
  171.26 + * License Header, with the fields enclosed by brackets [] replaced by
  171.27 + * your own identifying information:
  171.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  171.29 + *
  171.30 + * If you wish your version of this file to be governed by only the CDDL
  171.31 + * or only the GPL Version 2, indicate your decision by adding
  171.32 + * "[Contributor] elects to include this software in this distribution
  171.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  171.34 + * single choice of license, a recipient has the option to distribute
  171.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  171.36 + * to extend the choice of license to its licensees as provided above.
  171.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  171.38 + * Version 2 license, then the option applies only if the new code is
  171.39 + * made subject to such option by the copyright holder.
  171.40 + *
  171.41 + * Contributor(s):
  171.42 + *
  171.43 + * Portions Copyrighted 2012 Sun Microsystems, Inc.
  171.44 + */
  171.45 +package org.netbeans.modules.java.hints.test;
  171.46 +
  171.47 +import org.netbeans.api.editor.mimelookup.MimePath;
  171.48 +import org.netbeans.modules.java.source.indexing.JavaCustomIndexer;
  171.49 +import org.netbeans.modules.java.source.parsing.JavacParser;
  171.50 +import org.netbeans.modules.java.source.parsing.JavacParserFactory;
  171.51 +import org.netbeans.spi.editor.mimelookup.MimeDataProvider;
  171.52 +import org.openide.filesystems.FileObject;
  171.53 +import org.openide.filesystems.MIMEResolver;
  171.54 +import org.openide.util.Lookup;
  171.55 +import org.openide.util.lookup.Lookups;
  171.56 +import org.openide.util.lookup.ProxyLookup;
  171.57 +import org.openide.util.lookup.ServiceProvider;
  171.58 +
  171.59 +/**
  171.60 + *
  171.61 + * @author lahvac
  171.62 + */
  171.63 +public class Utilities {
  171.64 +
  171.65 +    @ServiceProvider(service = Lookup.class)
  171.66 +    public static final class TestLookup extends ProxyLookup {
  171.67 +
  171.68 +        public void setLookupsImpl(Lookup... lookups) {
  171.69 +            setLookups(lookups);
  171.70 +        }
  171.71 +
  171.72 +    }
  171.73 +
  171.74 +    @ServiceProvider(service=MimeDataProvider.class)
  171.75 +    public static final class JavacParserProvider implements MimeDataProvider {
  171.76 +
  171.77 +        private Lookup javaLookup = Lookups.fixed(new JavacParserFactory(), new JavaCustomIndexer.Factory());
  171.78 +
  171.79 +        public Lookup getLookup(MimePath mimePath) {
  171.80 +            if (mimePath.getPath().endsWith(JavacParser.MIME_TYPE)) {
  171.81 +                return javaLookup;
  171.82 +            }
  171.83 +
  171.84 +            return Lookup.EMPTY;
  171.85 +        }
  171.86 +
  171.87 +    }
  171.88 +
  171.89 +    @ServiceProvider(service=MIMEResolver.class)
  171.90 +    public static final class JavaMimeResolver extends MIMEResolver {
  171.91 +
  171.92 +        public JavaMimeResolver() {
  171.93 +            super(JavacParser.MIME_TYPE);
  171.94 +        }
  171.95 +
  171.96 +        @Override
  171.97 +        public String findMIMEType(FileObject fo) {
  171.98 +            if ("java".equals(fo.getExt())) {
  171.99 +                return JavacParser.MIME_TYPE;
 171.100 +            }
 171.101 +
 171.102 +            return null;
 171.103 +        }
 171.104 +
 171.105 +    }
 171.106 +
 171.107 +}
   172.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   172.2 +++ b/sandbox/java.hints/java.hints.test/src/org/netbeans/modules/java/hints/test/api/HintTest.java	Sun Oct 23 11:50:54 2016 +0200
   172.3 @@ -0,0 +1,1427 @@
   172.4 +/*
   172.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   172.6 + *
   172.7 + * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
   172.8 + *
   172.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  172.10 + * Other names may be trademarks of their respective owners.
  172.11 + *
  172.12 + * The contents of this file are subject to the terms of either the GNU
  172.13 + * General Public License Version 2 only ("GPL") or the Common
  172.14 + * Development and Distribution License("CDDL") (collectively, the
  172.15 + * "License"). You may not use this file except in compliance with the
  172.16 + * License. You can obtain a copy of the License at
  172.17 + * http://www.netbeans.org/cddl-gplv2.html
  172.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  172.19 + * specific language governing permissions and limitations under the
  172.20 + * License.  When distributing the software, include this License Header
  172.21 + * Notice in each file and include the License file at
  172.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  172.23 + * particular file as subject to the "Classpath" exception as provided
  172.24 + * by Oracle in the GPL Version 2 section of the License file that
  172.25 + * accompanied this code. If applicable, add the following below the
  172.26 + * License Header, with the fields enclosed by brackets [] replaced by
  172.27 + * your own identifying information:
  172.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  172.29 + *
  172.30 + * If you wish your version of this file to be governed by only the CDDL
  172.31 + * or only the GPL Version 2, indicate your decision by adding
  172.32 + * "[Contributor] elects to include this software in this distribution
  172.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  172.34 + * single choice of license, a recipient has the option to distribute
  172.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  172.36 + * to extend the choice of license to its licensees as provided above.
  172.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  172.38 + * Version 2 license, then the option applies only if the new code is
  172.39 + * made subject to such option by the copyright holder.
  172.40 + *
  172.41 + * Contributor(s):
  172.42 + *
  172.43 + * Portions Copyrighted 2012 Sun Microsystems, Inc.
  172.44 + */
  172.45 +package org.netbeans.modules.java.hints.test.api;
  172.46 +
  172.47 +import com.sun.source.tree.CompilationUnitTree;
  172.48 +import com.sun.source.util.TreePath;
  172.49 +import java.io.File;
  172.50 +import java.io.FileInputStream;
  172.51 +import java.io.IOException;
  172.52 +import java.io.OutputStream;
  172.53 +import java.lang.ref.Reference;
  172.54 +import java.lang.ref.WeakReference;
  172.55 +import java.net.URL;
  172.56 +import java.util.ArrayList;
  172.57 +import java.util.Arrays;
  172.58 +import java.util.Collection;
  172.59 +import java.util.Collections;
  172.60 +import java.util.Comparator;
  172.61 +import java.util.Enumeration;
  172.62 +import java.util.HashMap;
  172.63 +import java.util.HashSet;
  172.64 +import java.util.IdentityHashMap;
  172.65 +import java.util.LinkedList;
  172.66 +import java.util.List;
  172.67 +import java.util.Map;
  172.68 +import java.util.Map.Entry;
  172.69 +import java.util.Properties;
  172.70 +import java.util.Set;
  172.71 +import java.util.concurrent.atomic.AtomicBoolean;
  172.72 +import java.util.logging.Handler;
  172.73 +import java.util.logging.Level;
  172.74 +import java.util.logging.LogRecord;
  172.75 +import java.util.logging.Logger;
  172.76 +import java.util.prefs.AbstractPreferences;
  172.77 +import java.util.prefs.BackingStoreException;
  172.78 +import java.util.prefs.Preferences;
  172.79 +import java.util.regex.Pattern;
  172.80 +import javax.swing.event.ChangeListener;
  172.81 +import javax.swing.text.Document;
  172.82 +import javax.tools.Diagnostic;
  172.83 +import junit.framework.Assert;
  172.84 +import static junit.framework.Assert.assertEquals;
  172.85 +import static junit.framework.Assert.assertFalse;
  172.86 +import static junit.framework.Assert.assertNotNull;
  172.87 +import static junit.framework.Assert.assertNotSame;
  172.88 +import static junit.framework.Assert.assertTrue;
  172.89 +
  172.90 +import org.netbeans.api.editor.mimelookup.MimeLookup;
  172.91 +import org.netbeans.api.java.classpath.ClassPath;
  172.92 +import org.netbeans.api.java.lexer.JavaTokenId;
  172.93 +import org.netbeans.api.java.queries.SourceForBinaryQuery;
  172.94 +import org.netbeans.api.java.source.ClasspathInfo;
  172.95 +import org.netbeans.api.java.source.CompilationController;
  172.96 +import org.netbeans.api.java.source.CompilationInfo;
  172.97 +import org.netbeans.api.java.source.JavaSource;
  172.98 +import org.netbeans.api.java.source.JavaSource.Phase;
  172.99 +import org.netbeans.api.java.source.ModificationResult;
 172.100 +import org.netbeans.api.java.source.ModificationResult.Difference;
 172.101 +import org.netbeans.api.java.source.Task;
 172.102 +import org.netbeans.api.java.source.WorkingCopy;
 172.103 +import org.netbeans.api.lexer.Language;
 172.104 +import org.netbeans.api.project.ui.*;
 172.105 +import org.netbeans.core.startup.Main;
 172.106 +import org.netbeans.junit.NbTestCase;
 172.107 +import org.netbeans.modules.java.JavaDataLoader;
 172.108 +import org.netbeans.modules.java.hints.providers.code.CodeHintProviderImpl;
 172.109 +import org.netbeans.modules.java.hints.providers.code.FSWrapper;
 172.110 +import org.netbeans.modules.java.hints.providers.code.FSWrapper.ClassWrapper;
 172.111 +import org.netbeans.modules.java.hints.providers.spi.HintDescription;
 172.112 +import org.netbeans.modules.java.hints.providers.spi.HintDescription.Worker;
 172.113 +import org.netbeans.modules.java.hints.providers.spi.HintDescriptionFactory;
 172.114 +import org.netbeans.modules.java.hints.providers.spi.HintMetadata;
 172.115 +import org.netbeans.modules.java.hints.providers.spi.HintMetadata.Options;
 172.116 +import org.netbeans.modules.java.hints.spiimpl.JavaFixImpl;
 172.117 +import org.netbeans.modules.java.hints.spiimpl.JavaFixImpl.Accessor;
 172.118 +import org.netbeans.modules.java.hints.spiimpl.MessageImpl;
 172.119 +import org.netbeans.modules.java.hints.spiimpl.SyntheticFix;
 172.120 +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch;
 172.121 +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.BatchResult;
 172.122 +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.Folder;
 172.123 +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.Resource;
 172.124 +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.Scope;
 172.125 +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.VerifiedSpansCallBack;
 172.126 +import org.netbeans.modules.java.hints.spiimpl.batch.BatchUtilities;
 172.127 +import org.netbeans.modules.java.hints.spiimpl.batch.ProgressHandleWrapper;
 172.128 +import org.netbeans.modules.java.hints.spiimpl.batch.Scopes;
 172.129 +import org.netbeans.modules.java.hints.spiimpl.hints.HintsInvoker;
 172.130 +import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings;
 172.131 +import org.netbeans.modules.java.hints.test.Utilities.TestLookup;
 172.132 +import org.netbeans.modules.java.source.JavaSourceAccessor;
 172.133 +import org.netbeans.modules.java.source.TreeLoader;
 172.134 +import org.netbeans.modules.parsing.api.indexing.IndexingManager;
 172.135 +import org.netbeans.modules.parsing.impl.indexing.CacheFolder;
 172.136 +import org.netbeans.modules.parsing.impl.indexing.MimeTypes;
 172.137 +import org.netbeans.modules.refactoring.spi.RefactoringElementImplementation;
 172.138 +import org.netbeans.spi.editor.hints.ErrorDescription;
 172.139 +import org.netbeans.spi.editor.hints.Fix;
 172.140 +import org.netbeans.spi.editor.hints.Severity;
 172.141 +import org.netbeans.spi.java.classpath.ClassPathProvider;
 172.142 +import org.netbeans.spi.java.classpath.support.ClassPathSupport;
 172.143 +import org.netbeans.spi.java.hints.Hint.Kind;
 172.144 +import org.netbeans.spi.java.hints.HintContext;
 172.145 +import org.netbeans.spi.java.hints.JavaFix;
 172.146 +import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation;
 172.147 +import org.netbeans.spi.java.queries.SourceLevelQueryImplementation;
 172.148 +import org.openide.LifecycleManager;
 172.149 +import org.openide.cookies.EditorCookie;
 172.150 +import org.openide.filesystems.FileObject;
 172.151 +import org.openide.filesystems.FileStateInvalidException;
 172.152 +import org.openide.filesystems.FileSystem;
 172.153 +import org.openide.filesystems.FileUtil;
 172.154 +import org.openide.filesystems.MultiFileSystem;
 172.155 +import org.openide.filesystems.Repository;
 172.156 +import org.openide.filesystems.URLMapper;
 172.157 +import org.openide.filesystems.XMLFileSystem;
 172.158 +import org.openide.loaders.DataObject;
 172.159 +import org.openide.loaders.DataObjectNotFoundException;
 172.160 +import org.openide.util.Exceptions;
 172.161 +import org.openide.util.Lookup;
 172.162 +import org.openide.util.NbBundle;
 172.163 +import org.openide.util.lookup.Lookups;
 172.164 +
 172.165 +/**A support class for writing a test for a Java Hint. A test verifying that correct
 172.166 + * warnings are produced should look like:
 172.167 + * <pre>
 172.168 + * HintTest.create()
 172.169 + *         .input("&lt;input Java source code>")
 172.170 + *         .run(&lt;class containg the hint>)
 172.171 + *         .assertWarnings("&lt;required warning(s)>");
 172.172 + * </pre>
 172.173 + *
 172.174 + * Note: when verifying that no warnings are produced in a particular situation,
 172.175 + * do not pass any warnings to the {@code assertWarnings} method.
 172.176 + *
 172.177 + * A test verifying that a hint's transformation is correct:
 172.178 + * <pre>
 172.179 + * HintTest.create()
 172.180 + *         .input("&lt;input Java source code>")
 172.181 + *         .run(&lt;class containg the hint>)
 172.182 + *         .findWarning("&lt;a warning produce by the hint>")
 172.183 + *         .applyFix() //fill apply the only fix in the given ErrorDescription
 172.184 + *         .assertCompilable()
 172.185 + *         .assertOutput("&lt;output Java source code>");
 172.186 + * </pre>
 172.187 + *
 172.188 + * All the tests run under the {@code test} branding, which allows to specify test values
 172.189 + * for bundle keys for warning and fix in {@code Bundle_test.properties}, to isolate the
 172.190 + * test from changes in the production {@code Bundle.properties}.
 172.191 + *
 172.192 + * @author lahvac
 172.193 + */
 172.194 +public class HintTest {
 172.195 +
 172.196 +    private static final Logger INDEXING_LOGGER = /* RepositoryUpdater.UI_LOGGER */ Logger.getLogger("org.netbeans.ui.indexing");
 172.197 +    static {
 172.198 +        INDEXING_LOGGER.setLevel(Level.WARNING);
 172.199 +    }
 172.200 +
 172.201 +    private final File workDir;
 172.202 +    private final FileObject sourceRoot;
 172.203 +    private final FileObject buildRoot;
 172.204 +    private final FileObject cache;
 172.205 +    private final Preferences testPreferences;
 172.206 +    private final HintsSettings hintSettings;
 172.207 +    private final List<FileObject> checkCompilable = new ArrayList<FileObject>();
 172.208 +    private final List<FileObject> testFiles = new ArrayList<FileObject>();
 172.209 +    private String sourceLevel = "1.5";
 172.210 +    private Character caretMarker;
 172.211 +    private FileObject testFile;
 172.212 +    private int caret = -1;
 172.213 +    private ClassPath sourcePath;
 172.214 +    private ClassPath compileClassPath = ClassPathSupport.createClassPath(new URL[0]);
 172.215 +
 172.216 +    private HintTest() throws Exception {
 172.217 +        List<URL> layers = new LinkedList<URL>();
 172.218 +
 172.219 +        for (String layer : new String[] {"META-INF/generated-layer.xml"}) {
 172.220 +            boolean found = false;
 172.221 +
 172.222 +            for (Enumeration<URL> en = Thread.currentThread().getContextClassLoader().getResources(layer); en.hasMoreElements(); ) {
 172.223 +                found = true;
 172.224 +                layers.add(en.nextElement());
 172.225 +            }
 172.226 +
 172.227 +            Assert.assertTrue(layer, found);
 172.228 +        }
 172.229 +
 172.230 +        XMLFileSystem xmlFS = new XMLFileSystem();
 172.231 +        xmlFS.setXmlUrls(layers.toArray(new URL[0]));
 172.232 +
 172.233 +        FileSystem system = new MultiFileSystem(new FileSystem[] {FileUtil.createMemoryFileSystem(), xmlFS});
 172.234 +
 172.235 +        Repository repository = new Repository(system);
 172.236 +
 172.237 +        assertEquals(Lookup.getDefault().getClass().getCanonicalName(), TestLookup.class, Lookup.getDefault().getClass());
 172.238 +
 172.239 +        ((TestLookup) Lookup.getDefault()).setLookupsImpl(
 172.240 +            Lookups.fixed(repository,
 172.241 +                          new TestProxyClassPathProvider(),
 172.242 +                          new TestSourceForBinaryQuery(),
 172.243 +                          new TestSourceLevelQueryImplementation(),
 172.244 +                          JavaDataLoader.findObject(JavaDataLoader.class, true)),
 172.245 +            Lookups.metaInfServices(HintTest.class.getClassLoader()),
 172.246 +            Lookups.singleton(HintTest.class.getClassLoader())
 172.247 +        );
 172.248 +
 172.249 +        Set<String> amt = MimeTypes.getAllMimeTypes();
 172.250 +        if (amt == null) {
 172.251 +            amt = new HashSet<String>();
 172.252 +        } else {
 172.253 +            amt = new HashSet<String>(amt);
 172.254 +        }
 172.255 +        amt.add("text/x-java");
 172.256 +        MimeTypes.setAllMimeTypes(amt);
 172.257 +        org.netbeans.api.project.ui.OpenProjects.getDefault().getOpenProjects();
 172.258 +
 172.259 +        TreeLoader.DISABLE_CONFINEMENT_TEST = true;
 172.260 +        testPreferences = new TempPreferences();
 172.261 +        hintSettings = new HintsSettings() {
 172.262 +            @Override public boolean isEnabled(HintMetadata hint) {
 172.263 +                return true;
 172.264 +            }
 172.265 +            @Override public void setEnabled(HintMetadata hint, boolean value) {
 172.266 +                throw new UnsupportedOperationException("Not supported.");
 172.267 +            }
 172.268 +            @Override public Preferences getHintPreferences(HintMetadata hint) {
 172.269 +                return testPreferences;
 172.270 +            }
 172.271 +            @Override public Severity getSeverity(HintMetadata hint) {
 172.272 +                return hint.severity;
 172.273 +            }
 172.274 +            @Override public void setSeverity(HintMetadata hint, Severity severity) {
 172.275 +                throw new UnsupportedOperationException("Not supported.");
 172.276 +            }
 172.277 +        };
 172.278 +
 172.279 +        workDir = getWorkDir();
 172.280 +        deleteSubFiles(workDir);
 172.281 +        FileUtil.refreshFor(workDir);
 172.282 +
 172.283 +        FileObject wd = FileUtil.toFileObject(workDir);
 172.284 +        
 172.285 +        assertNotNull(wd);
 172.286 +
 172.287 +        sourceRoot = FileUtil.createFolder(wd, "src");
 172.288 +        buildRoot = FileUtil.createFolder(wd, "build");
 172.289 +        cache = FileUtil.createFolder(wd, "cache");
 172.290 +
 172.291 +        CacheFolder.setCacheFolder(cache);
 172.292 +
 172.293 +        NbBundle.setBranding("test");
 172.294 +
 172.295 +        sourcePath = ClassPathSupport.createClassPath(sourceRoot);
 172.296 +        
 172.297 +        Main.initializeURLFactory();
 172.298 +    }
 172.299 +
 172.300 +    /**Bootstraps the test framework.
 172.301 +     *
 172.302 +     * @return the test framework - call more methods on it to set-up a test, then call {@code run} method and assert results.
 172.303 +     */
 172.304 +    public static HintTest create() throws Exception {
 172.305 +        return new HintTest();
 172.306 +    }
 172.307 +
 172.308 +    /**A character to use as a marker of a caret in the input code. The caret position
 172.309 +     * during the run method will be set to the position of this character in the first input file.
 172.310 +     *
 172.311 +     * @param c a caret marker
 172.312 +     * @return itself
 172.313 +     */
 172.314 +    public HintTest setCaretMarker(char c) {
 172.315 +        this.caretMarker = c;
 172.316 +        return this;
 172.317 +    }
 172.318 +
 172.319 +    /**Use the specified {@link java.net.URL}s as compile classpath while parsing
 172.320 +     * the Java input. The {@link java.net.URL}s need to be "folder" {@link java.net.URL}s,
 172.321 +     * ready to be passed to {@link ClassPathSupport#createClassPath(java.net.URL[]) }.
 172.322 +     *
 172.323 +     * @param entries that should become roots of the compile classpath
 172.324 +     * @return itself
 172.325 +     * @see FileUtil#urlForArchiveOrDir(java.io.File)
 172.326 +     * @see FileUtil#getArchiveRoot(java.net.URL)
 172.327 +     */
 172.328 +    public HintTest classpath(URL... entries) {
 172.329 +        compileClassPath = ClassPathSupport.createClassPath(entries);
 172.330 +        return this;
 172.331 +    }
 172.332 +
 172.333 +    /**Create a test file. Equivalent to calling {@code input("test/Test.java", code, true)}.
 172.334 +     *
 172.335 +     * @param code the content of the newly created test file
 172.336 +     * @return itself
 172.337 +     */
 172.338 +    public HintTest input(String code) throws Exception {
 172.339 +        return input("test/Test.java", code, true);
 172.340 +    }
 172.341 +
 172.342 +    /**Create a test file. Equivalent to calling {@code input("test/Test.java", code, compilable)}.
 172.343 +     *
 172.344 +     * @param code the content of the newly created test file
 172.345 +     * @param compilable if true, it will be verified that the file does not contain
 172.346 +     *                   compilation errors before the hint is run on it
 172.347 +     * @return itself
 172.348 +     */
 172.349 +    public HintTest input(String code, boolean compilable) throws Exception {
 172.350 +        return input("test/Test.java", code, compilable);
 172.351 +    }
 172.352 +
 172.353 +    /**Create a test file. Equivalent to calling {@code input(fileName, code, true)}.
 172.354 +     *
 172.355 +     * @param fileName a relative file name of the newly created file from a (automatically created) source root
 172.356 +     * @param code the content of the newly created test file
 172.357 +     * @return itself
 172.358 +     */
 172.359 +    public HintTest input(String fileName, String code) throws Exception {
 172.360 +        return input(fileName, code, true);
 172.361 +    }
 172.362 +    
 172.363 +    /**Create a test file. Any number of files can be created for one test, but the hint
 172.364 +     * will be run only on the first one.
 172.365 +     *
 172.366 +     * @param fileName a relative file name of the newly created file from a (automatically created) source root
 172.367 +     * @param code the content of the newly created test file
 172.368 +     * @param compilable if true, it will be verified that the file does not contain
 172.369 +     *                   compilation errors before the hint is run on it
 172.370 +     * @return itself
 172.371 +     */
 172.372 +    public HintTest input(String fileName, String code, boolean compilable) throws Exception {
 172.373 +        int caret = -1;
 172.374 +
 172.375 +        if (caretMarker != null && testFile == null) {
 172.376 +            caret = code.indexOf(caretMarker);
 172.377 +
 172.378 +            assertNotSame("A caret location must be specified", -1, caret);
 172.379 +
 172.380 +            code = code.substring(0, caret) + code.substring(caret + 1);
 172.381 +        }
 172.382 +
 172.383 +        FileObject file = FileUtil.createData(sourceRoot, fileName);
 172.384 +
 172.385 +        copyStringToFile(file, code);
 172.386 +
 172.387 +        if (compilable) {
 172.388 +            checkCompilable.add(file);
 172.389 +        }
 172.390 +
 172.391 +        if (testFile == null) {
 172.392 +            testFile = file;
 172.393 +            this.caret = caret;
 172.394 +        }
 172.395 +        
 172.396 +        testFiles.add(file);
 172.397 +        
 172.398 +        return this;
 172.399 +    }
 172.400 +
 172.401 +    private void ensureCompilable(FileObject file) throws IOException, AssertionError, IllegalArgumentException {
 172.402 +        CompilationInfo info = parse(file);
 172.403 +
 172.404 +        assertNotNull(info);
 172.405 +
 172.406 +        for (Diagnostic d : info.getDiagnostics()) {
 172.407 +            if (d.getKind() == Diagnostic.Kind.ERROR)
 172.408 +                throw new AssertionError(d.getLineNumber() + ":" + d.getColumnNumber() + " " + d.getMessage(null));
 172.409 +        }
 172.410 +    }
 172.411 +
 172.412 +    /**Sets a source level for all Java files used in this test.
 172.413 +     *
 172.414 +     * @param sourceLevel the source level to use while parsing Java files
 172.415 +     * @return itself
 172.416 +     */
 172.417 +    public HintTest sourceLevel(String sourceLevel) {
 172.418 +        this.sourceLevel = sourceLevel;
 172.419 +        return this;
 172.420 +    }
 172.421 +
 172.422 +    /**Sets a preference that will be visible to the hint.
 172.423 +     *
 172.424 +     * @param preferencesKey a key for the preferences
 172.425 +     * @param value the value to set
 172.426 +     * @return itself
 172.427 +     */
 172.428 +    public HintTest preference(String preferencesKey, String value) {
 172.429 +        this.testPreferences.put(preferencesKey, value);
 172.430 +        return this;
 172.431 +    }
 172.432 +
 172.433 +    /**Sets a preference that will be visible to the hint.
 172.434 +     *
 172.435 +     * @param preferencesKey a key for the preferences
 172.436 +     * @param value the value to set
 172.437 +     * @return itself
 172.438 +     */
 172.439 +    public HintTest preference(String preferencesKey, int value) {
 172.440 +        this.testPreferences.putInt(preferencesKey, value);
 172.441 +        return this;
 172.442 +    }
 172.443 +
 172.444 +    /**Sets a preference that will be visible to the hint.
 172.445 +     *
 172.446 +     * @param preferencesKey a key for the preferences
 172.447 +     * @param value the value to set
 172.448 +     * @return itself
 172.449 +     */
 172.450 +    public HintTest preference(String preferencesKey, boolean value) {
 172.451 +        this.testPreferences.putBoolean(preferencesKey, value);
 172.452 +        return this;
 172.453 +    }
 172.454 +    
 172.455 +    /**Runs the given hint(s) on the first file written by a {@code input} method.
 172.456 +     *
 172.457 +     * @param hint all hints in this class will be run on the file
 172.458 +     * @return a wrapper over the hint output that allows verifying results of the hint
 172.459 +     */
 172.460 +    public HintOutput run(Class<?> hint) throws Exception {
 172.461 +        return run(hint, null);
 172.462 +    }
 172.463 +
 172.464 +    /**Runs the given hint(s) on the first file written by a {@code input} method.
 172.465 +     * Runs only hints with the specified {@code hintCode}. Null hintCode includes
 172.466 +     * all hints from the class
 172.467 +     *
 172.468 +     * @param hint all hints in this class will be run on the file
 172.469 +     * @param hintCode if not {@code null}, only hints with the same id will be run
 172.470 +     * @return a wrapper over the hint output that allows verifying results of the hint
 172.471 +     */
 172.472 +    public HintOutput run(Class<?> hint, String hintCode) throws Exception {
 172.473 +        return runImpl(hint, hintCode, new HintComputer() {
 172.474 +            @Override public Collection<ErrorDescription> computeHints(List<HintDescription> total) throws Exception {
 172.475 +                CompilationInfo info = parse(testFile);
 172.476 +
 172.477 +                assertNotNull(info);
 172.478 +
 172.479 +                List<ErrorDescription> result = new ArrayList<ErrorDescription>();
 172.480 +
 172.481 +                Map<HintDescription, List<ErrorDescription>> errors = computeErrors(info, total, new AtomicBoolean());
 172.482 +
 172.483 +                for (Entry<HintDescription, List<ErrorDescription>> e : errors.entrySet()) {
 172.484 +                    result.addAll(e.getValue());
 172.485 +                }
 172.486 +
 172.487 +                Reference<CompilationInfo> infoRef = new WeakReference<CompilationInfo>(info);
 172.488 +                Reference<CompilationUnitTree> cut = new WeakReference<CompilationUnitTree>(info.getCompilationUnit());
 172.489 +
 172.490 +                info = null;
 172.491 +
 172.492 +                DEBUGGING_HELPER.add(result);
 172.493 +                NbTestCase.assertGC("noone holds CompilationInfo", infoRef);
 172.494 +                NbTestCase.assertGC("noone holds javac", cut);
 172.495 +                DEBUGGING_HELPER.remove(result);
 172.496 +
 172.497 +                return result;
 172.498 +            }
 172.499 +        });
 172.500 +    }
 172.501 +
 172.502 +    private HintOutput runImpl(Class<?> hint, String hintCode, HintComputer doComputeErrors) throws Exception {
 172.503 +        IndexingManager.getDefault().refreshIndexAndWait(sourceRoot.toURL(), null);
 172.504 +        
 172.505 +        for (FileObject file : checkCompilable) {
 172.506 +            ensureCompilable(file);
 172.507 +        }
 172.508 +        
 172.509 +        Map<HintMetadata, Collection<HintDescription>> hints = new HashMap<HintMetadata, Collection<HintDescription>>();
 172.510 +        List<ClassWrapper> found = new ArrayList<ClassWrapper>();
 172.511 +
 172.512 +        for (ClassWrapper w : FSWrapper.listClasses()) {
 172.513 +            if (hint.getCanonicalName().equals(w.getName().replace('$', '.'))) {
 172.514 +                found.add(w);
 172.515 +            }
 172.516 +        }
 172.517 +
 172.518 +        assertFalse(found.isEmpty());
 172.519 +
 172.520 +        for (ClassWrapper w : found) {
 172.521 +            CodeHintProviderImpl.processClass(w, hints);
 172.522 +        }
 172.523 +
 172.524 +        List<HintDescription> total = new LinkedList<HintDescription>();
 172.525 +        final Set<ErrorDescription> requiresJavaFix = Collections.newSetFromMap(new IdentityHashMap<ErrorDescription, Boolean>());
 172.526 +
 172.527 +        for (final Entry<HintMetadata, Collection<HintDescription>> e : hints.entrySet()) {
 172.528 +            if (null != hintCode && !e.getKey().id.equals(hintCode)) {
 172.529 +                continue;
 172.530 +            }
 172.531 +            if (   e.getKey().options.contains(Options.NO_BATCH)
 172.532 +                || e.getKey().options.contains(Options.QUERY)
 172.533 +                || e.getKey().kind == Kind.ACTION) {
 172.534 +                total.addAll(e.getValue());
 172.535 +                continue;
 172.536 +            }
 172.537 +            for (final HintDescription hd : e.getValue()) {
 172.538 +                total.add(HintDescriptionFactory.create()
 172.539 +                                               .setTrigger(hd.getTrigger())
 172.540 +                                               .setMetadata(e.getKey())
 172.541 +                                               .setAdditionalConstraints(hd.getAdditionalConstraints())
 172.542 +                                               .addOptions(hd.getOptions().toArray(new Options[0]))
 172.543 +                                               .setWorker(new Worker() {
 172.544 +                                                    @Override public Collection<? extends ErrorDescription> createErrors(HintContext ctx) {
 172.545 +                                                        Collection<? extends ErrorDescription> errors = hd.getWorker().createErrors(ctx);
 172.546 + 
 172.547 +                                                        if (errors != null) {
 172.548 +                                                            for (ErrorDescription ed : errors) {
 172.549 +                                                                requiresJavaFix.add(ed);
 172.550 +                                                            }
 172.551 +                                                        }
 172.552 +                                                        
 172.553 +                                                        return errors;
 172.554 +                                                     }
 172.555 +                                                })
 172.556 +                                              .produce());
 172.557 +            }
 172.558 +        }
 172.559 +        
 172.560 +        Handler h = new Handler() {
 172.561 +            @Override public void publish(LogRecord record) {
 172.562 +                if (   record.getLevel().intValue() >= Level.WARNING.intValue()
 172.563 +                    && record.getThrown() != null) {
 172.564 +                    throw new IllegalStateException(record.getThrown());
 172.565 +                }
 172.566 +            }
 172.567 +            @Override public void flush() { }
 172.568 +            @Override public void close() throws SecurityException { }
 172.569 +        };
 172.570 +
 172.571 +        Logger log = Logger.getLogger(Exceptions.class.getName());
 172.572 +        log.addHandler(h);
 172.573 +        List<ErrorDescription> result = new ArrayList<ErrorDescription>(doComputeErrors.computeHints(total));
 172.574 +        log.removeHandler(h);
 172.575 +
 172.576 +        Collections.sort(result, ERRORS_COMPARATOR);
 172.577 +        
 172.578 +        return new HintOutput(result, requiresJavaFix);
 172.579 +    }
 172.580 +
 172.581 +    private interface HintComputer {
 172.582 +        public Collection<ErrorDescription> computeHints(List<HintDescription> total) throws Exception;
 172.583 +    }
 172.584 +    
 172.585 +    public HintOutput runGlobal(Class<?> hint) throws Exception {
 172.586 +        return runImpl(hint, null, new HintComputer() {
 172.587 +            @Override public Collection<ErrorDescription> computeHints(List<HintDescription> total) throws Exception {
 172.588 +                final List<ErrorDescription> result = new ArrayList<ErrorDescription>();
 172.589 +                Scope s = Scopes.specifiedFoldersScope(Folder.convert(sourceRoot));
 172.590 +                BatchResult batchResult = BatchSearch.findOccurrences(total, s);
 172.591 +                BatchSearch.getVerifiedSpans(batchResult, new ProgressHandleWrapper(1, 1), new VerifiedSpansCallBack() {
 172.592 +                    @Override public void groupStarted() { }
 172.593 +                    @Override public boolean spansVerified(CompilationController wc, Resource r, Collection<? extends ErrorDescription> hints) throws Exception {
 172.594 +                        result.addAll(hints);
 172.595 +                        return true;
 172.596 +                    }
 172.597 +                    @Override public void groupFinished() { }
 172.598 +                    @Override public void cannotVerifySpan(Resource r) { }
 172.599 +                }, false, new ArrayList<MessageImpl>(), new AtomicBoolean());
 172.600 +
 172.601 +                return result;
 172.602 +            }
 172.603 +        });
 172.604 +    }
 172.605 +    
 172.606 +    //must keep the error descriptions (and their Fixes through them) in a field
 172.607 +    //so that assertGC is able to provide a useful trace of references:
 172.608 +    private static Set<List<ErrorDescription>> DEBUGGING_HELPER = Collections.newSetFromMap(new IdentityHashMap<List<ErrorDescription>, Boolean>());
 172.609 +
 172.610 +    private CompilationInfo parse(FileObject file) throws DataObjectNotFoundException, IllegalArgumentException, IOException {
 172.611 +        DataObject od = DataObject.find(file);
 172.612 +        EditorCookie ec = od.getLookup().lookup(EditorCookie.class);
 172.613 +
 172.614 +        assertNotNull(ec);
 172.615 +
 172.616 +        Document doc = ec.openDocument();
 172.617 +
 172.618 +        doc.putProperty(Language.class, JavaTokenId.language());
 172.619 +        doc.putProperty("mimeType", "text/x-java");
 172.620 +
 172.621 +        JavaSource js = JavaSource.create(ClasspathInfo.create(file), file);
 172.622 +
 172.623 +        assertNotNull("found JavaSource for " + file, js);
 172.624 +
 172.625 +        final DeadlockTask bt = new DeadlockTask(Phase.RESOLVED);
 172.626 +
 172.627 +        js.runUserActionTask(bt, true);
 172.628 +        
 172.629 +        return bt.info;
 172.630 +    }
 172.631 +
 172.632 +    private Map<HintDescription, List<ErrorDescription>> computeErrors(CompilationInfo info, Iterable<? extends HintDescription> hints, AtomicBoolean cancel) {
 172.633 +        return new HintsInvoker(hintSettings, caret, cancel).computeHints(info, new TreePath(info.getCompilationUnit()), hints, new LinkedList<MessageImpl>());
 172.634 +    }
 172.635 +
 172.636 +    FileObject getSourceRoot() {
 172.637 +        return sourceRoot;
 172.638 +    }
 172.639 +
 172.640 +    private static class TempPreferences extends AbstractPreferences {
 172.641 +
 172.642 +        /*private*/Properties properties;
 172.643 +
 172.644 +        private TempPreferences() {
 172.645 +            super(null, "");
 172.646 +        }
 172.647 +
 172.648 +        private  TempPreferences(TempPreferences parent, String name)  {
 172.649 +            super(parent, name);
 172.650 +            newNode = true;
 172.651 +        }
 172.652 +
 172.653 +        protected final String getSpi(String key) {
 172.654 +            return properties().getProperty(key);
 172.655 +        }
 172.656 +
 172.657 +        protected final String[] childrenNamesSpi() throws BackingStoreException {
 172.658 +            return new String[0];
 172.659 +        }
 172.660 +
 172.661 +        protected final String[] keysSpi() throws BackingStoreException {
 172.662 +            return properties().keySet().toArray(new String[0]);
 172.663 +        }
 172.664 +
 172.665 +        protected final void putSpi(String key, String value) {
 172.666 +            properties().put(key,value);
 172.667 +        }
 172.668 +
 172.669 +        protected final void removeSpi(String key) {
 172.670 +            properties().remove(key);
 172.671 +        }
 172.672 +
 172.673 +        protected final void removeNodeSpi() throws BackingStoreException {}
 172.674 +        protected  void flushSpi() throws BackingStoreException {}
 172.675 +        protected void syncSpi() throws BackingStoreException {
 172.676 +            properties().clear();
 172.677 +        }
 172.678 +
 172.679 +        @Override
 172.680 +        public void put(String key, String value) {
 172.681 +            try {
 172.682 +                super.put(key, value);
 172.683 +            } catch (IllegalArgumentException iae) {
 172.684 +                if (iae.getMessage().contains("too long")) {
 172.685 +                    // Not for us!
 172.686 +                    putSpi(key, value);
 172.687 +                } else {
 172.688 +                    throw iae;
 172.689 +                }
 172.690 +            }
 172.691 +        }
 172.692 +
 172.693 +        Properties properties()  {
 172.694 +            if (properties == null) {
 172.695 +                properties = new Properties();
 172.696 +            }
 172.697 +            return properties;
 172.698 +        }
 172.699 +
 172.700 +        protected AbstractPreferences childSpi(String name) {
 172.701 +            return new TempPreferences(this, name);
 172.702 +        }
 172.703 +    }
 172.704 +
 172.705 +    private class TestSourceForBinaryQuery implements SourceForBinaryQueryImplementation {
 172.706 +
 172.707 +        public SourceForBinaryQuery.Result findSourceRoots(URL binaryRoot) {
 172.708 +            FileObject f = URLMapper.findFileObject(binaryRoot);
 172.709 +
 172.710 +            if (buildRoot.equals(f)) {
 172.711 +                return new SourceForBinaryQuery.Result() {
 172.712 +                    public FileObject[] getRoots() {
 172.713 +                        return new FileObject[] {
 172.714 +                            sourceRoot,
 172.715 +                        };
 172.716 +                    }
 172.717 +
 172.718 +                    public void addChangeListener(ChangeListener l) {
 172.719 +                    }
 172.720 +
 172.721 +                    public void removeChangeListener(ChangeListener l) {
 172.722 +                    }
 172.723 +                };
 172.724 +            }
 172.725 +
 172.726 +            return null;
 172.727 +        }
 172.728 +
 172.729 +    }
 172.730 +
 172.731 +    private static List<URL> bootClassPath;
 172.732 +
 172.733 +    private static Logger log = Logger.getLogger(HintTest.class.getName());
 172.734 +
 172.735 +    private static synchronized List<URL> getBootClassPath() {
 172.736 +        if (bootClassPath == null) {
 172.737 +            try {
 172.738 +                String cp = System.getProperty("sun.boot.class.path");
 172.739 +                List<URL> urls = new ArrayList<URL>();
 172.740 +                String[] paths = cp.split(Pattern.quote(System.getProperty("path.separator")));
 172.741 +
 172.742 +                for (String path : paths) {
 172.743 +                    File f = new File(path);
 172.744 +
 172.745 +                    if (!f.canRead())
 172.746 +                        continue;
 172.747 +
 172.748 +                    FileObject fo = FileUtil.toFileObject(f);
 172.749 +
 172.750 +                    if (FileUtil.isArchiveFile(fo)) {
 172.751 +                        fo = FileUtil.getArchiveRoot(fo);
 172.752 +                    }
 172.753 +
 172.754 +                    if (fo != null) {
 172.755 +                        urls.add(fo.getURL());
 172.756 +                    }
 172.757 +                }
 172.758 +
 172.759 +                bootClassPath = urls;
 172.760 +            } catch (FileStateInvalidException e) {
 172.761 +                if (log.isLoggable(Level.SEVERE))
 172.762 +                    log.log(Level.SEVERE, e.getMessage(), e);
 172.763 +            }
 172.764 +        }
 172.765 +
 172.766 +        return bootClassPath;
 172.767 +    }
 172.768 +    
 172.769 +    private class TestProxyClassPathProvider implements ClassPathProvider {
 172.770 +
 172.771 +        public ClassPath findClassPath(FileObject file, String type) {
 172.772 +            try {
 172.773 +            if (ClassPath.BOOT == type) {
 172.774 +                // XXX simpler to use JavaPlatformManager.getDefault().getDefaultPlatform().getBootstrapLibraries()
 172.775 +                return ClassPathSupport.createClassPath(getBootClassPath().toArray(new URL[0]));
 172.776 +            }
 172.777 +
 172.778 +            if (ClassPath.SOURCE == type) {
 172.779 +                return sourcePath;
 172.780 +            }
 172.781 +
 172.782 +            if (ClassPath.COMPILE == type) {
 172.783 +                return compileClassPath;
 172.784 +            }
 172.785 +
 172.786 +            if (ClassPath.EXECUTE == type) {
 172.787 +                return ClassPathSupport.createClassPath(new FileObject[] {
 172.788 +                    buildRoot
 172.789 +                });
 172.790 +            }
 172.791 +            } catch (Exception e) {
 172.792 +                e.printStackTrace();
 172.793 +            }
 172.794 +            return null;
 172.795 +        }
 172.796 +
 172.797 +    }
 172.798 +
 172.799 +    private class TestSourceLevelQueryImplementation implements SourceLevelQueryImplementation {
 172.800 +
 172.801 +        public String getSourceLevel(FileObject javaFile) {
 172.802 +            return sourceLevel;
 172.803 +        }
 172.804 +
 172.805 +    }
 172.806 +
 172.807 +
 172.808 +    private static class DeadlockTask implements Task<CompilationController> {
 172.809 +
 172.810 +        private final Phase phase;
 172.811 +        private CompilationInfo info;
 172.812 +
 172.813 +        public DeadlockTask(Phase phase) {
 172.814 +            assert phase != null;
 172.815 +            this.phase = phase;
 172.816 +        }
 172.817 +
 172.818 +        public void run( CompilationController info ) {
 172.819 +            try {
 172.820 +                info.toPhase(this.phase);
 172.821 +                this.info = info;
 172.822 +            } catch (IOException ioe) {
 172.823 +                if (log.isLoggable(Level.SEVERE))
 172.824 +                    log.log(Level.SEVERE, ioe.getMessage(), ioe);
 172.825 +            }
 172.826 +        }
 172.827 +
 172.828 +    }
 172.829 +
 172.830 +    /**Encapsulated the output of the hint.
 172.831 +     */
 172.832 +    public final class HintOutput {
 172.833 +        
 172.834 +        private final List<ErrorDescription> errors;
 172.835 +        private final Set<ErrorDescription> requiresJavaFix;
 172.836 +
 172.837 +        private HintOutput(List<ErrorDescription> errors, Set<ErrorDescription> requiresJavaFix) {
 172.838 +            this.errors = errors;
 172.839 +            this.requiresJavaFix = requiresJavaFix;
 172.840 +
 172.841 +        }
 172.842 +
 172.843 +        /**Assert that the hint(s) produced the given warnings. The provided strings
 172.844 +         * should match {@code toString()} results of {@link ErrorDescription}s produced
 172.845 +         * by the hint(s).
 172.846 +         *
 172.847 +         * @param warnings expected {@code toString()} results of {@link ErrorDescription}s produced
 172.848 +         *                 by the hint
 172.849 +         * @return itself
 172.850 +         * @throws AssertionError if the given warnings do not match the actual warnings
 172.851 +         */
 172.852 +        public HintOutput assertWarnings(String... warnings) {
 172.853 +            assertEquals("The warnings provided by the hint do not match expected warnings.", Arrays.toString(warnings), errors.toString());
 172.854 +
 172.855 +            return this;
 172.856 +        }
 172.857 +
 172.858 +        /**Assert that the hint(s) produced warnings include the given warnings. The provided strings
 172.859 +         * should match {@code toString()} results of {@link ErrorDescription}s produced
 172.860 +         * by the hint(s).
 172.861 +         *
 172.862 +         * @param warnings expected {@code toString()} results of {@link ErrorDescription}s produced
 172.863 +         *                 by the hint
 172.864 +         * @return itself
 172.865 +         * @throws AssertionError if the given warnings do not match the actual warnings
 172.866 +         */
 172.867 +        public HintOutput assertContainsWarnings(String... warnings) {
 172.868 +            Set<String> goldenSet = new HashSet<String>(Arrays.asList(warnings));
 172.869 +            List<String> errorsNames = new LinkedList<String>();
 172.870 +
 172.871 +            for (ErrorDescription d : errors) {
 172.872 +                goldenSet.remove(d.toString());
 172.873 +                errorsNames.add(d.toString());
 172.874 +            }
 172.875 +            
 172.876 +            assertTrue("The warnings provided by the hint do not contain expected warnings. Provided warnings: " + errorsNames.toString(), goldenSet.isEmpty());
 172.877 +
 172.878 +            return this;
 172.879 +        }
 172.880 +
 172.881 +        /**Assert that the hint(s) produced warnings do not include the given warnings. The provided strings
 172.882 +         * should match {@code toString()} results of {@link ErrorDescription}s produced
 172.883 +         * by the hint(s).
 172.884 +         *
 172.885 +         * @param warnings expected {@code toString()} results of {@link ErrorDescription}s produced
 172.886 +         *                 by the hint
 172.887 +         * @return itself
 172.888 +         * @throws AssertionError if the given warnings do not match the actual warnings
 172.889 +         */
 172.890 +        public HintOutput assertNotContainsWarnings(String... warnings) {
 172.891 +            Set<String> goldenSet = new HashSet<String>(Arrays.asList(warnings));
 172.892 +            List<String> errorsNames = new LinkedList<String>();
 172.893 +
 172.894 +            boolean fail = false;
 172.895 +            for (ErrorDescription d : errors) {
 172.896 +                if (goldenSet.remove(d.getDescription()))
 172.897 +                    fail = true;
 172.898 +                errorsNames.add(d.toString());
 172.899 +            }
 172.900 +            
 172.901 +            assertFalse("The warnings provided by the hint do not exclude expected warnings. Provided warnings: " + errorsNames.toString(), fail);
 172.902 +
 172.903 +            return this;
 172.904 +        }
 172.905 +        
 172.906 +        /**Find a specific warning.
 172.907 +         *
 172.908 +         * @param warning the warning to find - must be equivalent to {@code toString()}
 172.909 +         *                results of the {@link ErrorDescription}.
 172.910 +         * @return a wrapper about the given specific warnings
 172.911 +         * @throws AssertionError if the given warning cannot be found
 172.912 +         */
 172.913 +        public HintWarning findWarning(String warning) {
 172.914 +            ErrorDescription toFix = null;
 172.915 +
 172.916 +            for (ErrorDescription d : errors) {
 172.917 +                if (warning.equals(d.toString())) {
 172.918 +                    toFix = d;
 172.919 +                    break;
 172.920 +                }
 172.921 +            }
 172.922 +
 172.923 +            assertNotNull("Warning: \"" + warning + "\" not found. All ErrorDescriptions: " + errors.toString(), toFix);
 172.924 +
 172.925 +            return new HintWarning(toFix, requiresJavaFix.contains(toFix));
 172.926 +        }
 172.927 +    }
 172.928 +
 172.929 +    /**A wrapper over a single warning.
 172.930 +     */
 172.931 +    public final class HintWarning {
 172.932 +        private final ErrorDescription warning;
 172.933 +        private final boolean requiresJavaFix;
 172.934 +        HintWarning(ErrorDescription warning, boolean requiresJavaFix) {
 172.935 +            this.warning = warning;
 172.936 +            this.requiresJavaFix = requiresJavaFix;
 172.937 +        }
 172.938 +        /**Applies the only fix of the current warning. Fails if the given warning
 172.939 +         * does not have exactly one fix.
 172.940 +         *
 172.941 +         * Note this is a destructive operation - the {@link #run(java.lang.Class)} or {@link #applyFix}
 172.942 +         * cannot be run in the future on any object that follows the chain from the same invocation of {@link #create()}.
 172.943 +         *
 172.944 +         * @return a wrapper over resulting source code
 172.945 +         * @throws AssertionError if there is not one fix for the given {@link ErrorDescription}
 172.946 +         */
 172.947 +        public AppliedFix applyFix() throws Exception {
 172.948 +            return applyFix(true);
 172.949 +        }
 172.950 +
 172.951 +        AppliedFix applyFix(boolean saveAll) throws Exception {
 172.952 +            assertTrue("Must be computed", warning.getFixes().isComputed());
 172.953 +
 172.954 +            List<Fix> fixes = warning.getFixes().getFixes();
 172.955 +
 172.956 +            assertEquals(1, fixes.size());
 172.957 +
 172.958 +            doApplyFix(fixes.get(0));
 172.959 +
 172.960 +            if (saveAll)
 172.961 +                LifecycleManager.getDefault().saveAll();
 172.962 +            
 172.963 +            return new AppliedFix();
 172.964 +        }
 172.965 +        /**Applies the specified fix of the current warning.
 172.966 +         *
 172.967 +         * Note this is a destructive operation - the {@link #run(java.lang.Class)} or {@link #applyFix}
 172.968 +         * cannot be run in the future on any object that follows the chain from the same invocation of {@link #create()}.
 172.969 +         *
 172.970 +         * @param fix {@link Fix#getText() } result of the required fix
 172.971 +         * @return a wrapper over resulting source code
 172.972 +         * @throws AssertionError if the fix cannot be found
 172.973 +         */
 172.974 +        public AppliedFix applyFix(String fix) throws Exception {
 172.975 +            assertTrue("Must be computed", warning.getFixes().isComputed());
 172.976 +
 172.977 +            List<Fix> fixes = warning.getFixes().getFixes();
 172.978 +            List<String> fixNames = new LinkedList<String>();
 172.979 +            Fix toApply = null;
 172.980 +
 172.981 +            for (Fix f : fixes) {
 172.982 +                if (fix.equals(f.getText())) {
 172.983 +                    toApply = f;
 172.984 +                }
 172.985 +
 172.986 +                fixNames.add(f.getText());
 172.987 +            }
 172.988 +
 172.989 +            assertNotNull("Cannot find fix to invoke: " + fixNames.toString(), toApply);
 172.990 +
 172.991 +            doApplyFix(toApply);
 172.992 +            
 172.993 +            LifecycleManager.getDefault().saveAll();
 172.994 +
 172.995 +            return new AppliedFix();
 172.996 +        }
 172.997 +        private void doApplyFix(Fix f) throws Exception {
 172.998 +            Preferences preferences = MimeLookup.getLookup(JavaTokenId.language().mimeType()).lookup(Preferences.class);
 172.999 +            preferences.putBoolean("importInnerClasses", true);
172.1000 +            try {
172.1001 +                if (requiresJavaFix) {
172.1002 +                    assertTrue("The fix must be a JavaFix", f instanceof JavaFixImpl);
172.1003 +                    
172.1004 +                    ModificationResult result1 = runJavaFix(((JavaFixImpl) f).jf);
172.1005 +                    ModificationResult result2 = runJavaFix(((JavaFixImpl) f).jf);
172.1006 +                    
172.1007 +                    //ensure the results are the same:
172.1008 +                    assertEquals("The fix must be repeatable", result1.getModifiedFileObjects(), result2.getModifiedFileObjects());
172.1009 +                    
172.1010 +                    for (FileObject file : result1.getModifiedFileObjects()) {
172.1011 +                        assertEquals("The fix must be repeatable", result1.getResultingSource(file), result2.getResultingSource(file));
172.1012 +                    }
172.1013 +                    
172.1014 +                    result1.commit();
172.1015 +                } else {
172.1016 +                    f.implement();
172.1017 +                }
172.1018 +            } finally {
172.1019 +                preferences.remove("importInnerClasses");
172.1020 +            }
172.1021 +        }
172.1022 +        private ModificationResult runJavaFix(final JavaFix jf) throws IOException {
172.1023 +            FileObject file = Accessor.INSTANCE.getFile(jf);
172.1024 +            JavaSource js = JavaSource.forFileObject(file);
172.1025 +            final Map<FileObject, List<Difference>> changes = new HashMap<FileObject, List<Difference>>();
172.1026 +
172.1027 +            ModificationResult mr = js.runModificationTask(new Task<WorkingCopy>() {
172.1028 +                public void run(WorkingCopy wc) throws Exception {
172.1029 +                    if (wc.toPhase(Phase.RESOLVED).compareTo(Phase.RESOLVED) < 0) {
172.1030 +                        return;
172.1031 +                    }
172.1032 +
172.1033 +                    Map<FileObject, byte[]> resourceContentChanges = new HashMap<FileObject, byte[]>();
172.1034 +                    Accessor.INSTANCE.process(jf, wc, true, resourceContentChanges, /*Ignored for now:*/new ArrayList<RefactoringElementImplementation>());
172.1035 +                    BatchUtilities.addResourceContentChanges(resourceContentChanges, changes);
172.1036 +                    
172.1037 +                }
172.1038 +            });
172.1039 +            
172.1040 +            changes.putAll(JavaSourceAccessor.getINSTANCE().getDiffsFromModificationResult(mr));
172.1041 +            
172.1042 +            return JavaSourceAccessor.getINSTANCE().createModificationResult(changes, Collections.<Object, int[]>emptyMap());
172.1043 +        }
172.1044 +        /**Verifies that the current warning provides the given fixes.
172.1045 +         *
172.1046 +         * @param fixes the {@link Fix#getText() } of the expected fixes
172.1047 +         * @return itself
172.1048 +         * @throws AssertionError if the expected fixes do not match the provided fixes
172.1049 +         * @since 1.1
172.1050 +         */
172.1051 +        public HintWarning assertFixes(String... expectedFixes) throws Exception {
172.1052 +            assertTrue("Must be computed", warning.getFixes().isComputed());
172.1053 +
172.1054 +            List<String> fixNames = new LinkedList<String>();
172.1055 +
172.1056 +            for (Fix f : warning.getFixes().getFixes()) {
172.1057 +                if (f instanceof SyntheticFix) continue;
172.1058 +                fixNames.add(f.getText());
172.1059 +            }
172.1060 +
172.1061 +            assertEquals("Fixes for the current warning do not match the expected fixes. All fixes: " + fixNames.toString(), Arrays.asList(expectedFixes), fixNames);
172.1062 +
172.1063 +            return this;
172.1064 +        }
172.1065 +    }
172.1066 +
172.1067 +    /**A wrapper over result after applying a fix.
172.1068 +     */
172.1069 +    public final class AppliedFix {
172.1070 +        /**Require that the result is compilable. Equivalent to {@code assertCompilable("test/Test.java")}
172.1071 +         *
172.1072 +         * @return the wrapper itself
172.1073 +         * @throws AssertionError if the result is not compilable
172.1074 +         */
172.1075 +        public AppliedFix assertCompilable() throws Exception {
172.1076 +            return assertCompilable("test/Test.java");
172.1077 +        }
172.1078 +        /**Require that the given resulting file is compilable.
172.1079 +         *
172.1080 +         * @param fileName the name of the file that should be verified
172.1081 +         * @return the wrapper itself
172.1082 +         * @throws AssertionError if the result is not compilable
172.1083 +         */
172.1084 +        public AppliedFix assertCompilable(String fileName) throws Exception {
172.1085 +            FileObject toCheck = sourceRoot.getFileObject(fileName);
172.1086 +
172.1087 +            assertNotNull(toCheck);
172.1088 +
172.1089 +            ensureCompilable(toCheck);
172.1090 +            return this;
172.1091 +        }
172.1092 +        /**Verify the content of the resulting file. Equivalent to {@code assertOutput("test/Test.java")}.
172.1093 +         *
172.1094 +         * This method will "normalize" whitespaces in the file: generally, all
172.1095 +         * whitespaces are reduced to a single space both in the given code and
172.1096 +         * the code read from the file, before the comparison.
172.1097 +         *
172.1098 +         * @param code expected content of the resulting file.
172.1099 +         * @return the wrapper itself
172.1100 +         * @throws AssertionError if the file does not have the correct content
172.1101 +         */
172.1102 +        public AppliedFix assertOutput(String code) throws Exception {
172.1103 +            return assertOutput("test/Test.java", code);
172.1104 +        }
172.1105 +        /**Verify the content of the given resulting file.
172.1106 +         *
172.1107 +         * This method will "normalize" whitespaces in the file: generally, all
172.1108 +         * whitespaces are reduced to a single space both in the given code and
172.1109 +         * the code read from the file, before the comparison.
172.1110 +         *
172.1111 +         * @param fileName the name of the file that should be verified
172.1112 +         * @param code expected content of the resulting file.
172.1113 +         * @return the wrapper itself
172.1114 +         * @throws AssertionError if the file does not have the correct content
172.1115 +         */
172.1116 +        public AppliedFix assertOutput(String fileName, String code) throws Exception {
172.1117 +            FileObject toCheck = sourceRoot.getFileObject(fileName);
172.1118 +
172.1119 +            assertNotNull("Required file: " + fileName + " not found", toCheck);
172.1120 +
172.1121 +            DataObject toCheckDO = DataObject.find(toCheck);
172.1122 +            EditorCookie ec = toCheckDO.getLookup().lookup(EditorCookie.class);
172.1123 +            Document toCheckDocument = ec.openDocument();
172.1124 +
172.1125 +            String realCode = toCheckDocument.getText(0, toCheckDocument.getLength());
172.1126 +
172.1127 +            //ignore whitespaces:
172.1128 +            realCode = reduceWhitespaces(realCode);
172.1129 +
172.1130 +            assertEquals("The output code does not match the expected code.", reduceWhitespaces(code), realCode);
172.1131 +
172.1132 +            return this;
172.1133 +        }
172.1134 +        
172.1135 +        private String reduceWhitespaces(String str) {
172.1136 +            StringBuilder result = new StringBuilder();
172.1137 +            int i = 0;
172.1138 +            boolean wasWhitespace = false;
172.1139 +            
172.1140 +            while (i < str.length()) {
172.1141 +                int codePoint = str.codePointAt(i);
172.1142 +                
172.1143 +                if (Character.isWhitespace(codePoint)) {
172.1144 +                    if (!wasWhitespace) {
172.1145 +                        result.append(" ");
172.1146 +                        wasWhitespace = true;
172.1147 +                    }
172.1148 +                } else {
172.1149 +                    result.appendCodePoint(codePoint);
172.1150 +                    wasWhitespace = false;
172.1151 +                }
172.1152 +                i += Character.charCount(codePoint);
172.1153 +            }
172.1154 +            
172.1155 +            return result.toString();
172.1156 +        }
172.1157 +        
172.1158 +        /**Verify the content of the resulting file. Equivalent to {@code assertVerbatimOutput("test/Test.java")}.
172.1159 +         *
172.1160 +         * This method will compare the content of the file exactly with the provided
172.1161 +         * code.
172.1162 +         *
172.1163 +         * @param fileName the name of the file that should be verified
172.1164 +         * @param code expected content of the resulting file.
172.1165 +         * @return the wrapper itself
172.1166 +         * @throws AssertionError if the result is not compilable
172.1167 +         */
172.1168 +        public AppliedFix assertVerbatimOutput(String code) throws Exception {
172.1169 +            return assertVerbatimOutput("test/Test.java", code);
172.1170 +        }
172.1171 +        /**Verify the content of the given resulting file.
172.1172 +         *
172.1173 +         * This method will compare the content of the file exactly with the provided
172.1174 +         * code.
172.1175 +         *
172.1176 +         * @param fileName the name of the file that should be verified
172.1177 +         * @param code expected content of the resulting file.
172.1178 +         * @return the wrapper itself
172.1179 +         * @throws AssertionError if the result is not compilable
172.1180 +         */
172.1181 +        public AppliedFix assertVerbatimOutput(String fileName, String code) throws Exception {
172.1182 +            FileObject toCheck = sourceRoot.getFileObject(fileName);
172.1183 +
172.1184 +            assertNotNull(toCheck);
172.1185 +
172.1186 +            DataObject toCheckDO = DataObject.find(toCheck);
172.1187 +            EditorCookie ec = toCheckDO.getLookup().lookup(EditorCookie.class);
172.1188 +            Document toCheckDocument = ec.openDocument();
172.1189 +
172.1190 +            String realCode = toCheckDocument.getText(0, toCheckDocument.getLength());
172.1191 +
172.1192 +            assertEquals("The output code does not match the expected code.", code, realCode);
172.1193 +
172.1194 +            return this;
172.1195 +        }
172.1196 +
172.1197 +        /**Return code after the fix has been applied.
172.1198 +         *
172.1199 +         * @return the code after the fix has been applied
172.1200 +         */
172.1201 +        public String getOutput() throws Exception {
172.1202 +            return getOutput("test/Test.java");
172.1203 +        }
172.1204 +
172.1205 +        /**Return code after the fix has been applied.
172.1206 +         *
172.1207 +         * @param fileName file for which the code should be returned
172.1208 +         * @return the code after the fix has been applied
172.1209 +         */
172.1210 +        public String getOutput(String fileName) throws Exception {
172.1211 +            FileObject toCheck = sourceRoot.getFileObject(fileName);
172.1212 +
172.1213 +            assertNotNull(toCheck);
172.1214 +
172.1215 +            DataObject toCheckDO = DataObject.find(toCheck);
172.1216 +            EditorCookie ec = toCheckDO.getLookup().lookup(EditorCookie.class);
172.1217 +            Document toCheckDocument = ec.openDocument();
172.1218 +
172.1219 +            return toCheckDocument.getText(0, toCheckDocument.getLength());
172.1220 +        }
172.1221 +    }
172.1222 +
172.1223 +    private static final Comparator<ErrorDescription> ERRORS_COMPARATOR = new Comparator<ErrorDescription> () {
172.1224 +
172.1225 +        public int compare (ErrorDescription e1, ErrorDescription e2) {
172.1226 +            return e1.getRange ().getBegin ().getOffset () - e2.getRange ().getBegin ().getOffset ();
172.1227 +        }
172.1228 +    };
172.1229 +
172.1230 +    static {
172.1231 +        System.setProperty("org.openide.util.Lookup", TestLookup.class.getName());
172.1232 +        Assert.assertEquals(TestLookup.class, Lookup.getDefault().getClass());
172.1233 +    }
172.1234 +
172.1235 +    //workdir computation (copied from NbTestCase):
172.1236 +    private static File getWorkDir() throws IOException {
172.1237 +        // now we have path, so if not available, create workdir
172.1238 +        File workdir = FileUtil.normalizeFile(new File(getWorkDirPath()));
172.1239 +        if (workdir.exists()) {
172.1240 +            if (!workdir.isDirectory()) {
172.1241 +                // work dir exists, but is not directory - this should not happen
172.1242 +                // trow exception
172.1243 +                throw new IOException("workdir exists, but is not a directory, workdir = " + workdir);
172.1244 +            } else {
172.1245 +                // everything looks correctly, return the path
172.1246 +                return workdir;
172.1247 +            }
172.1248 +        } else {
172.1249 +            // we need to create it
172.1250 +            boolean result = workdir.mkdirs();
172.1251 +            if (result == false) {
172.1252 +                // mkdirs() failed - throw an exception
172.1253 +                throw new IOException("workdir creation failed: " + workdir);
172.1254 +            } else {
172.1255 +                // everything looks ok - return path
172.1256 +                return workdir;
172.1257 +            }
172.1258 +        }
172.1259 +    }
172.1260 +
172.1261 +    private static String getWorkDirPath() {
172.1262 +        StackTraceElement caller = null;
172.1263 +        boolean seenItself = false;
172.1264 +        
172.1265 +        for (StackTraceElement e : new Exception().getStackTrace()) {
172.1266 +            if (HintTest.class.getName().equals(e.getClassName())) seenItself = true;
172.1267 +            if (seenItself && !HintTest.class.getName().equals(e.getClassName())) {
172.1268 +                caller = e;
172.1269 +                break;
172.1270 +            }
172.1271 +        }
172.1272 +        
172.1273 +        String name = caller != null ? caller.getMethodName() : "unknownTest";
172.1274 +        // start - PerformanceTestCase overrides getName() method and then
172.1275 +        // name can contain illegal characters
172.1276 +        String osName = System.getProperty("os.name");
172.1277 +        if (osName != null && osName.startsWith("Windows")) {
172.1278 +            char ntfsIllegal[] ={'"','/','\\','?','<','>','|',':'};
172.1279 +            for (int i=0; i<ntfsIllegal.length; i++) {
172.1280 +                name = name.replace(ntfsIllegal[i], '~');
172.1281 +            }
172.1282 +        }
172.1283 +        // end
172.1284 +        
172.1285 +        final String workDirPath = getWorkDirPathFromManager();
172.1286 +        
172.1287 +        // #94319 - shorten workdir path if the following is too long
172.1288 +        // "Manager.getWorkDirPath()+File.separator+getClass().getName()+File.separator+name"
172.1289 +        int len1 = workDirPath.length();
172.1290 +        String clazz = caller != null ? caller.getClassName() : "unknown.Class";
172.1291 +        int len2 = clazz.length();
172.1292 +        int len3 = name.length();
172.1293 +        
172.1294 +        int tooLong = Integer.getInteger("nbjunit.too.long", 100);
172.1295 +        if (len1 + len2 + len3 > tooLong) {
172.1296 +            clazz = abbrevDots(clazz);
172.1297 +            len2 = clazz.length();
172.1298 +        }
172.1299 +
172.1300 +        if (len1 + len2 + len3 > tooLong) {
172.1301 +            name = abbrevCapitals(name);
172.1302 +        }
172.1303 +        
172.1304 +        String p = workDirPath + File.separator + clazz + File.separator + name;
172.1305 +        String realP;
172.1306 +        
172.1307 +        for (int i = 0; ; i++) {
172.1308 +            realP = i == 0 ? p : p + "-" + i;
172.1309 +            if (usedPaths.add(realP)) {
172.1310 +                break;
172.1311 +            }
172.1312 +        }
172.1313 +        
172.1314 +        return realP;
172.1315 +    }
172.1316 +
172.1317 +    private static Set<String> usedPaths = new HashSet<String>();
172.1318 +    
172.1319 +    private static String abbrevDots(String dotted) {
172.1320 +        StringBuilder sb = new StringBuilder();
172.1321 +        String sep = "";
172.1322 +        for (String item : dotted.split("\\.")) {
172.1323 +            sb.append(sep);
172.1324 +            sb.append(item.charAt(0));
172.1325 +            sep = ".";
172.1326 +        }
172.1327 +        return sb.toString();
172.1328 +    }
172.1329 +
172.1330 +    private static String abbrevCapitals(String name) {
172.1331 +        if (name.startsWith("test")) {
172.1332 +            name = name.substring(4);
172.1333 +        }
172.1334 +        StringBuilder sb = new StringBuilder();
172.1335 +        for (int i = 0; i < name.length(); i++) {
172.1336 +            if (Character.isUpperCase(name.charAt(i))) {
172.1337 +                sb.append(Character.toLowerCase(name.charAt(i)));
172.1338 +            }
172.1339 +        }
172.1340 +        return sb.toString();
172.1341 +    }
172.1342 +
172.1343 +    private static final String JUNIT_PROPERTIES_FILENAME = "junit.properties";
172.1344 +    private static final String JUNIT_PROPERTIES_LOCATION_PROPERTY = "junit.properties.file";
172.1345 +    private static final String NBJUNIT_WORKDIR = "nbjunit.workdir";
172.1346 +    
172.1347 +    private static String getWorkDirPathFromManager() {
172.1348 +        String path = System.getProperty(NBJUNIT_WORKDIR);
172.1349 +                
172.1350 +        if (path == null) {            
172.1351 +            // try to get property from user's settings
172.1352 +            path = readProperties().getProperty(NBJUNIT_WORKDIR);
172.1353 +        }
172.1354 +        if (path != null) {
172.1355 +            path = path.replace('/', File.separatorChar);
172.1356 +        } else {
172.1357 +            // Fallback value, guaranteed to be defined.
172.1358 +            path = System.getProperty("java.io.tmpdir") + File.separatorChar + "tests-" + System.getProperty("user.name");
172.1359 +        }
172.1360 +        return path;
172.1361 +    }
172.1362 +
172.1363 +    private static Properties readProperties() {
172.1364 +        Properties result = new Properties();
172.1365 +        try {
172.1366 +            File propFile = getPreferencesFile();
172.1367 +            FileInputStream is = new FileInputStream(propFile);
172.1368 +            try {
172.1369 +                result.load(is);
172.1370 +            } finally {
172.1371 +                is.close();
172.1372 +            }
172.1373 +        }  catch (IOException e) {
172.1374 +        }
172.1375 +        
172.1376 +        return result;
172.1377 +    }
172.1378 +
172.1379 +    private static File getPreferencesFile() {
172.1380 +        String junitPropertiesLocation = System.getProperty(JUNIT_PROPERTIES_LOCATION_PROPERTY);
172.1381 +        if (junitPropertiesLocation != null) {
172.1382 +            File propertyFile = new File(junitPropertiesLocation);
172.1383 +            if (propertyFile.exists()) {
172.1384 +                return propertyFile;
172.1385 +            }
172.1386 +        }
172.1387 +        // property file was not found - lets fall back to defaults
172.1388 +        String home= System.getProperty("user.home");
172.1389 +        return new File(home, JUNIT_PROPERTIES_FILENAME);
172.1390 +    }
172.1391 +
172.1392 +    // private method for deleting a file/directory (and all its subdirectories/files)
172.1393 +    private static void deleteFile(File file) throws IOException {
172.1394 +        if (file.isDirectory() && file.equals(file.getCanonicalFile())) {
172.1395 +            // file is a directory - delete sub files first
172.1396 +            File files[] = file.listFiles();
172.1397 +            for (int i = 0; i < files.length; i++) {
172.1398 +                deleteFile(files[i]);
172.1399 +            }
172.1400 +            
172.1401 +        }
172.1402 +        // file is a File :-)
172.1403 +        boolean result = file.delete();
172.1404 +        if (result == false ) {
172.1405 +            // a problem has appeared
172.1406 +            throw new IOException("Cannot delete file, file = "+file.getPath());
172.1407 +        }
172.1408 +    }
172.1409 +    
172.1410 +    // private method for deleting every subfiles/subdirectories of a file object
172.1411 +    private static void deleteSubFiles(File file) throws IOException {
172.1412 +        File files[] = file.getCanonicalFile().listFiles();
172.1413 +        if (files != null) {
172.1414 +            for (File f : files) {
172.1415 +                deleteFile(f);
172.1416 +            }
172.1417 +        } else {
172.1418 +            // probably do nothing - file is not a directory
172.1419 +        }
172.1420 +    }
172.1421 +
172.1422 +    private static FileObject copyStringToFile (FileObject f, String content) throws Exception {
172.1423 +        OutputStream os = f.getOutputStream();
172.1424 +        os.write(content.getBytes("UTF-8"));
172.1425 +        os.close ();
172.1426 +
172.1427 +        return f;
172.1428 +    }
172.1429 +
172.1430 +}
   173.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   173.2 +++ b/sandbox/java.hints/java.hints.test/src/org/netbeans/modules/parsing/impl/indexing/MimeTypes.java	Sun Oct 23 11:50:54 2016 +0200
   173.3 @@ -0,0 +1,66 @@
   173.4 +/*
   173.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   173.6 + *
   173.7 + * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
   173.8 + *
   173.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  173.10 + * Other names may be trademarks of their respective owners.
  173.11 + *
  173.12 + * The contents of this file are subject to the terms of either the GNU
  173.13 + * General Public License Version 2 only ("GPL") or the Common
  173.14 + * Development and Distribution License("CDDL") (collectively, the
  173.15 + * "License"). You may not use this file except in compliance with the
  173.16 + * License. You can obtain a copy of the License at
  173.17 + * http://www.netbeans.org/cddl-gplv2.html
  173.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  173.19 + * specific language governing permissions and limitations under the
  173.20 + * License.  When distributing the software, include this License Header
  173.21 + * Notice in each file and include the License file at
  173.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  173.23 + * particular file as subject to the "Classpath" exception as provided
  173.24 + * by Oracle in the GPL Version 2 section of the License file that
  173.25 + * accompanied this code. If applicable, add the following below the
  173.26 + * License Header, with the fields enclosed by brackets [] replaced by
  173.27 + * your own identifying information:
  173.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  173.29 + *
  173.30 + * If you wish your version of this file to be governed by only the CDDL
  173.31 + * or only the GPL Version 2, indicate your decision by adding
  173.32 + * "[Contributor] elects to include this software in this distribution
  173.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  173.34 + * single choice of license, a recipient has the option to distribute
  173.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  173.36 + * to extend the choice of license to its licensees as provided above.
  173.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  173.38 + * Version 2 license, then the option applies only if the new code is
  173.39 + * made subject to such option by the copyright holder.
  173.40 + *
  173.41 + * Contributor(s):
  173.42 + *
  173.43 + * Portions Copyrighted 2011 Sun Microsystems, Inc.
  173.44 + */
  173.45 +package org.netbeans.modules.parsing.impl.indexing;
  173.46 +
  173.47 +import java.util.Set;
  173.48 +import org.netbeans.api.annotations.common.CheckForNull;
  173.49 +import org.netbeans.api.annotations.common.NonNull;
  173.50 +import org.openide.util.Parameters;
  173.51 +
  173.52 +/**Not an API!
  173.53 + *
  173.54 + * @author Tomas Zezula
  173.55 + */
  173.56 +public class MimeTypes {
  173.57 +
  173.58 +    private MimeTypes() {}
  173.59 +
  173.60 +    public static void setAllMimeTypes(@NonNull final Set<String> allMimeTypes) {
  173.61 +        Parameters.notNull("allMimeTypes", allMimeTypes);   //NOI18N
  173.62 +        Util.allMimeTypes = allMimeTypes;
  173.63 +    }
  173.64 +
  173.65 +    @CheckForNull
  173.66 +    public static Set<String> getAllMimeTypes() {
  173.67 +        return Util.allMimeTypes;
  173.68 +    }
  173.69 +}
   174.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   174.2 +++ b/sandbox/java.hints/java.hints.test/test/unit/src/org/netbeans/modules/java/hints/test/api/HintTestTest.java	Sun Oct 23 11:50:54 2016 +0200
   174.3 @@ -0,0 +1,336 @@
   174.4 +/*
   174.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   174.6 + *
   174.7 + * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
   174.8 + *
   174.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  174.10 + * Other names may be trademarks of their respective owners.
  174.11 + *
  174.12 + * The contents of this file are subject to the terms of either the GNU
  174.13 + * General Public License Version 2 only ("GPL") or the Common
  174.14 + * Development and Distribution License("CDDL") (collectively, the
  174.15 + * "License"). You may not use this file except in compliance with the
  174.16 + * License. You can obtain a copy of the License at
  174.17 + * http://www.netbeans.org/cddl-gplv2.html
  174.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  174.19 + * specific language governing permissions and limitations under the
  174.20 + * License.  When distributing the software, include this License Header
  174.21 + * Notice in each file and include the License file at
  174.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  174.23 + * particular file as subject to the "Classpath" exception as provided
  174.24 + * by Oracle in the GPL Version 2 section of the License file that
  174.25 + * accompanied this code. If applicable, add the following below the
  174.26 + * License Header, with the fields enclosed by brackets [] replaced by
  174.27 + * your own identifying information:
  174.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  174.29 + *
  174.30 + * If you wish your version of this file to be governed by only the CDDL
  174.31 + * or only the GPL Version 2, indicate your decision by adding
  174.32 + * "[Contributor] elects to include this software in this distribution
  174.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  174.34 + * single choice of license, a recipient has the option to distribute
  174.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  174.36 + * to extend the choice of license to its licensees as provided above.
  174.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  174.38 + * Version 2 license, then the option applies only if the new code is
  174.39 + * made subject to such option by the copyright holder.
  174.40 + *
  174.41 + * Contributor(s):
  174.42 + *
  174.43 + * Portions Copyrighted 2012 Sun Microsystems, Inc.
  174.44 + */
  174.45 +package org.netbeans.modules.java.hints.test.api;
  174.46 +
  174.47 +import com.sun.source.tree.Tree.Kind;
  174.48 +import com.sun.source.util.TreePath;
  174.49 +import java.io.ByteArrayOutputStream;
  174.50 +import java.io.InputStreamReader;
  174.51 +import java.io.OutputStream;
  174.52 +import java.io.OutputStreamWriter;
  174.53 +import java.io.Reader;
  174.54 +import java.io.Writer;
  174.55 +import javax.swing.text.Document;
  174.56 +import org.junit.Assert;
  174.57 +import org.junit.Test;
  174.58 +import org.netbeans.api.java.source.ClasspathInfo.PathKind;
  174.59 +import org.netbeans.api.java.source.CompilationInfo;
  174.60 +import org.netbeans.api.java.source.JavaSource;
  174.61 +import org.netbeans.spi.editor.hints.ChangeInfo;
  174.62 +import org.netbeans.spi.editor.hints.ErrorDescription;
  174.63 +import org.netbeans.spi.editor.hints.Fix;
  174.64 +import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
  174.65 +import org.netbeans.spi.java.hints.Hint;
  174.66 +import org.netbeans.spi.java.hints.HintContext;
  174.67 +import org.netbeans.spi.java.hints.JavaFix;
  174.68 +import org.netbeans.spi.java.hints.JavaFix.TransformationContext;
  174.69 +import org.netbeans.spi.java.hints.TriggerTreeKind;
  174.70 +import org.openide.LifecycleManager;
  174.71 +import org.openide.cookies.EditorCookie;
  174.72 +import org.openide.filesystems.FileObject;
  174.73 +import org.openide.filesystems.FileUtil;
  174.74 +import org.openide.loaders.DataObject;
  174.75 +
  174.76 +/**
  174.77 + *
  174.78 + * @author lahvac
  174.79 + */
  174.80 +public class HintTestTest {
  174.81 +
  174.82 +    public HintTestTest() {
  174.83 +    }
  174.84 +
  174.85 +    @Test
  174.86 +    public void testNonJavaChanges() throws Exception {
  174.87 +        HintTest.create()
  174.88 +                .input("package test;\n" +
  174.89 +                       "public class Test { }\n")
  174.90 +                .input("test/test.txt", "1\n2\n", false)
  174.91 +                .run(NonJavaChanges.class)
  174.92 +                .findWarning("1:13-1:17:verifier:Test")
  174.93 +                .applyFix()
  174.94 +                .assertVerbatimOutput("test/test.txt", "2\n3\n");
  174.95 +    }
  174.96 +
  174.97 +    @Test
  174.98 +    public void test220070() throws Exception {
  174.99 +        HintTest.create()
 174.100 +                .input("package test;\n" +
 174.101 +                       "public class Test { }\n")
 174.102 +                .input("test/test.txt", "1\n2\n", false)
 174.103 +                .run(NonJavaChanges.class)
 174.104 +                .findWarning("1:13-1:17:verifier:Test")
 174.105 +                .applyFix()
 174.106 +                .assertOutput("test/test.txt", "2\r3\r");
 174.107 +    }
 174.108 +    
 174.109 +    @Test
 174.110 +    public void testNonJavaChangesOpenedInEditor() throws Exception {
 174.111 +        try {
 174.112 +            HintTest ht = HintTest.create()
 174.113 +                                  .input("package test;\n" +
 174.114 +                                         "public class Test { }\n")
 174.115 +                                  .input("test/test.txt", "1\n2\n", false);
 174.116 +            FileObject resource = ht.getSourceRoot().getFileObject("test/test.txt");
 174.117 +            DataObject od = DataObject.find(resource);
 174.118 +            EditorCookie ec = od.getLookup().lookup(EditorCookie.class);
 174.119 +            Document doc = ec.openDocument();
 174.120 +            doc.remove(0, doc.getLength());
 174.121 +            doc.insertString(0, "5\n6\n", null);
 174.122 +            ht.run(NonJavaChanges.class)
 174.123 +              .findWarning("1:13-1:17:verifier:Test")
 174.124 +              .applyFix(false)
 174.125 +              .assertVerbatimOutput("test/test.txt", "6\n7\n");
 174.126 +            Assert.assertEquals("1\n2\n", resource.asText("UTF-8"));
 174.127 +            Assert.assertEquals("6\n7\n", doc.getText(0, doc.getLength()));
 174.128 +        } finally {
 174.129 +            LifecycleManager.getDefault().saveAll();
 174.130 +        }
 174.131 +    }
 174.132 +
 174.133 +    @Hint(displayName="testingNonJavaChanges", description="testingNonJavaChanges", category="test")
 174.134 +    public static final class NonJavaChanges {
 174.135 +        @TriggerTreeKind(Kind.CLASS)
 174.136 +        public static ErrorDescription hint(HintContext ctx) {
 174.137 +            return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), "Test", new TestingNonJavaChangesFix(ctx.getInfo(), ctx.getPath()).toEditorFix());
 174.138 +        }
 174.139 +    }
 174.140 +
 174.141 +    private static final class TestingNonJavaChangesFix extends JavaFix {
 174.142 +
 174.143 +        public TestingNonJavaChangesFix(CompilationInfo info, TreePath tp) {
 174.144 +            super(info, tp);
 174.145 +        }
 174.146 +
 174.147 +        @Override protected String getText() {
 174.148 +            return "Test";
 174.149 +        }
 174.150 +
 174.151 +        @Override protected void performRewrite(TransformationContext ctx) {
 174.152 +            try {
 174.153 +                FileObject resource = ctx.getWorkingCopy().getFileObject().getParent().getFileObject("test.txt");
 174.154 +                Assert.assertNotNull(resource);
 174.155 +                Reader r = new InputStreamReader(ctx.getResourceContent(resource), "UTF-8");
 174.156 +                ByteArrayOutputStream outData = new ByteArrayOutputStream();
 174.157 +                Writer w = new OutputStreamWriter(outData, "UTF-8");
 174.158 +                int read;
 174.159 +
 174.160 +                while ((read = r.read()) != -1) {
 174.161 +                    if (read != '\n') read++;
 174.162 +                    w.write(read);
 174.163 +                }
 174.164 +
 174.165 +                r.close();
 174.166 +                w.close();
 174.167 +
 174.168 +                OutputStream out = ctx.getResourceOutput(resource);
 174.169 +
 174.170 +                out.write(outData.toByteArray());
 174.171 +
 174.172 +                out.close();
 174.173 +            } catch (Exception ex) {
 174.174 +                throw new IllegalStateException(ex);
 174.175 +            }
 174.176 +        }
 174.177 +
 174.178 +    }
 174.179 +
 174.180 +    @Test
 174.181 +    public void testMeaningfullSourcePath() throws Exception {
 174.182 +        HintTest.create()
 174.183 +                .input("package test;\n" +
 174.184 +                       "public class Test { }\n")
 174.185 +                .run(MeaningfullSourcePath.class)
 174.186 +                .assertWarnings();
 174.187 +    }
 174.188 +
 174.189 +    @Hint(displayName="meaningfullSourcePath", description="meaningfullSourcePath", category="test")
 174.190 +    public static final class MeaningfullSourcePath {
 174.191 +        @TriggerTreeKind(Kind.CLASS)
 174.192 +        public static ErrorDescription hint(HintContext ctx) {
 174.193 +            if (ctx.getInfo().getClasspathInfo().getClassPath(PathKind.SOURCE).findOwnerRoot(ctx.getInfo().getFileObject()) == null) {
 174.194 +                return ErrorDescriptionFactory.forTree(ctx, ctx.getPath(), "Broken Source Path");
 174.195 +            }
 174.196 +
 174.197 +            return null;
 174.198 +        }
 174.199 +    }
 174.200 +
 174.201 +    @Test
 174.202 +    public void testCompilationClassPath() throws Exception {
 174.203 +        HintTest.create()
 174.204 +                .input("package test;\n" +
 174.205 +                       "public class Test { }\n")
 174.206 +                .classpath(FileUtil.getArchiveRoot(JavaSource.class.getProtectionDomain().getCodeSource().getLocation()))
 174.207 +                .run(CompilationClassPath.class)
 174.208 +                .assertWarnings();
 174.209 +    }
 174.210 +
 174.211 +    @Hint(displayName="compilationClassPath", description="compilationClassPath", category="test")
 174.212 +    public static final class CompilationClassPath {
 174.213 +        @TriggerTreeKind(Kind.CLASS)
 174.214 +        public static ErrorDescription hint(HintContext ctx) {
 174.215 +            FileObject clazz = ctx.getInfo().getClasspathInfo().getClassPath(PathKind.COMPILE).findResource("org/netbeans/api/java/source/JavaSource.class");
 174.216 +
 174.217 +            if (clazz == null) {
 174.218 +                return ErrorDescriptionFactory.forTree(ctx, ctx.getPath(), "Broken Compilation ClassPath");
 174.219 +            }
 174.220 +
 174.221 +            return null;
 174.222 +        }
 174.223 +    }
 174.224 +
 174.225 +    @Test
 174.226 +    public void testHintThrowsException() throws Exception {
 174.227 +        HintTest ht = HintTest.create()
 174.228 +                              .input("package test;\n" +
 174.229 +                                     "public class Test { }\n");
 174.230 +        try {
 174.231 +            ht.run(HintThrowsException.class);
 174.232 +            Assert.fail("No exception thrown");
 174.233 +        } catch (Exception ex) {
 174.234 +            //ok
 174.235 +            Assert.assertEquals(IllegalStateException.class, ex.getClass());
 174.236 +            Assert.assertNotNull(ex.getCause());
 174.237 +            Assert.assertEquals(NullPointerException.class, ex.getCause().getClass());
 174.238 +            Assert.assertEquals("a", ex.getCause().getMessage());
 174.239 +        }
 174.240 +    }
 174.241 +    
 174.242 +    @Hint(displayName="hintThrowsException", description="hintThrowsException", category="test")
 174.243 +    public static final class HintThrowsException {
 174.244 +        @TriggerTreeKind(Kind.CLASS)
 174.245 +        public static ErrorDescription hint(HintContext ctx) {
 174.246 +            throw new NullPointerException("a");
 174.247 +        }
 174.248 +    }
 174.249 +
 174.250 +    @Test
 174.251 +    public void testNonJavaFix() throws Exception {
 174.252 +        HintTest ht = HintTest.create()
 174.253 +                              .input("package test;\n" +
 174.254 +                                     "public class Test { }\n");
 174.255 +        try {
 174.256 +            ht.run(NonJavaFix.class)
 174.257 +              .findWarning("1:0-1:21:verifier:Test")
 174.258 +              .applyFix();
 174.259 +            Assert.fail("No exception thrown");
 174.260 +        } catch (AssertionError ae) {
 174.261 +            //ok
 174.262 +            Assert.assertEquals("The fix must be a JavaFix", ae.getMessage());
 174.263 +        }
 174.264 +    }
 174.265 +    
 174.266 +    @Hint(displayName="nonJavaFix", description="nonJavaFix", category="test")
 174.267 +    public static final class NonJavaFix {
 174.268 +        @TriggerTreeKind(Kind.CLASS)
 174.269 +        public static ErrorDescription hint(HintContext ctx) {
 174.270 +            return ErrorDescriptionFactory.forTree(ctx, ctx.getPath(), "Test", new Fix() {
 174.271 +                @Override public String getText() {
 174.272 +                    return "Fix";
 174.273 +                }
 174.274 +                @Override public ChangeInfo implement() throws Exception {
 174.275 +                    return null;
 174.276 +                }
 174.277 +            });
 174.278 +        }
 174.279 +    }
 174.280 +    
 174.281 +    @Test
 174.282 +    public void testNotRepeatableJavaFix() throws Exception {
 174.283 +        HintTest ht = HintTest.create()
 174.284 +                              .input("package test;\n" +
 174.285 +                                     "public class Test { }\n");
 174.286 +        try {
 174.287 +            ht.run(NotRepeatableJavaFix.class)
 174.288 +              .findWarning("1:0-1:21:verifier:Test")
 174.289 +              .applyFix();
 174.290 +            Assert.fail("No exception thrown");
 174.291 +        } catch (AssertionError ae) {
 174.292 +            //ok
 174.293 +            Assert.assertTrue(ae.getMessage().startsWith("The fix must be repeatable"));
 174.294 +        }
 174.295 +    }
 174.296 +    
 174.297 +    @Hint(displayName="notRepeatableJavaFix", description="notRepeatableJavaFix", category="test")
 174.298 +    public static final class NotRepeatableJavaFix {
 174.299 +        @TriggerTreeKind(Kind.CLASS)
 174.300 +        public static ErrorDescription hint(HintContext ctx) {
 174.301 +            Fix f = new JavaFix(ctx.getInfo(), ctx.getPath()) {
 174.302 +                private boolean wasRun;
 174.303 +                @Override protected String getText() {
 174.304 +                    return "Fix";
 174.305 +                }
 174.306 +                @Override protected void performRewrite(TransformationContext ctx) throws Exception {
 174.307 +                    if (wasRun) return ;
 174.308 +                    ctx.getWorkingCopy().rewrite(ctx.getPath().getLeaf(), ctx.getWorkingCopy().getTreeMaker().setLabel(ctx.getPath().getLeaf(), "Nue"));
 174.309 +                    wasRun = true;
 174.310 +                }
 174.311 +            }.toEditorFix();
 174.312 +            return ErrorDescriptionFactory.forTree(ctx, ctx.getPath(), "Test", f);
 174.313 +        }
 174.314 +    }
 174.315 +
 174.316 +    public void testSourcePathReady() throws Exception {
 174.317 +        HintTest.create()
 174.318 +                .input("test/Test1.java",
 174.319 +                       "package test;\n" +
 174.320 +                       "public class Test1 {\n" +
 174.321 +                       "    private final Test2 test2 = null;\n" +
 174.322 +                       "}\n")
 174.323 +                .input("test/Test2.java",
 174.324 +                       "package test;\n" +
 174.325 +                       "public class Test2 {\n" +
 174.326 +                       "    private final Test1 test1 = null;\n" +
 174.327 +                       "}\n")
 174.328 +                .runGlobal(NoOp.class)
 174.329 +                .assertWarnings();
 174.330 +    }
 174.331 +
 174.332 +    @Hint(displayName="noOp", description="noOp", category="test")
 174.333 +    public static final class NoOp {
 174.334 +        @TriggerTreeKind(Kind.CLASS)
 174.335 +        public static ErrorDescription hint(HintContext ctx) {
 174.336 +            return null;
 174.337 +        }
 174.338 +    }
 174.339 +}
   175.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   175.2 +++ b/sandbox/java.hints/nbproject/build-impl.xml	Sun Oct 23 11:50:54 2016 +0200
   175.3 @@ -0,0 +1,50 @@
   175.4 +<?xml version="1.0" encoding="UTF-8"?>
   175.5 +<!--
   175.6 +*** GENERATED FROM project.xml - DO NOT EDIT  ***
   175.7 +***         EDIT ../build.xml INSTEAD         ***
   175.8 +-->
   175.9 +<project name="java.hints-impl" basedir=".." xmlns:sproject="http://www.netbeans.org/ns/nb-module-suite-project/1">
  175.10 +    <fail message="Please build using Ant 1.7.1 or higher.">
  175.11 +        <condition>
  175.12 +            <not>
  175.13 +                <antversion atleast="1.7.1"/>
  175.14 +            </not>
  175.15 +        </condition>
  175.16 +    </fail>
  175.17 +    <property file="nbproject/private/platform-private.properties"/>
  175.18 +    <property file="nbproject/platform.properties"/>
  175.19 +    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-suite-project/1">
  175.20 +        <attribute name="name"/>
  175.21 +        <attribute name="value"/>
  175.22 +        <sequential>
  175.23 +            <property name="@{name}" value="${@{value}}"/>
  175.24 +        </sequential>
  175.25 +    </macrodef>
  175.26 +    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-suite-project/1">
  175.27 +        <attribute name="property"/>
  175.28 +        <attribute name="value"/>
  175.29 +        <sequential>
  175.30 +            <property name="@{property}" value="@{value}"/>
  175.31 +        </sequential>
  175.32 +    </macrodef>
  175.33 +    <property file="${user.properties.file}"/>
  175.34 +    <sproject:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir"/>
  175.35 +    <sproject:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir"/>
  175.36 +    <sproject:evalprops property="cluster.path.evaluated" value="${cluster.path}"/>
  175.37 +    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
  175.38 +        <condition>
  175.39 +            <not>
  175.40 +                <contains string="${cluster.path.evaluated}" substring="platform"/>
  175.41 +            </not>
  175.42 +        </condition>
  175.43 +    </fail>
  175.44 +    <ant antfile="nbproject/platform.xml"/>
  175.45 +    <fail message="Cannot find NetBeans build harness. ${line.separator}Check that nbplatform.${nbplatform.active}.netbeans.dest.dir and nbplatform.${nbplatform.active}.harness.dir are defined. ${line.separator}On a developer machine these are normally defined in ${user.properties.file}=${netbeans.user}/build.properties ${line.separator}but for automated builds you should pass these properties to Ant explicitly. ${line.separator}You may instead download the harness and platform: -Dbootstrap.url=.../tasks.jar -Dautoupdate.catalog.url=.../updates.xml">
  175.46 +        <condition>
  175.47 +            <not>
  175.48 +                <available file="${harness.dir}/suite.xml"/>
  175.49 +            </not>
  175.50 +        </condition>
  175.51 +    </fail>
  175.52 +    <import file="${harness.dir}/suite.xml"/>
  175.53 +</project>
   176.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   176.2 +++ b/sandbox/java.hints/nbproject/genfiles.properties	Sun Oct 23 11:50:54 2016 +0200
   176.3 @@ -0,0 +1,11 @@
   176.4 +build.xml.data.CRC32=85cca5f7
   176.5 +build.xml.script.CRC32=25a1521a
   176.6 +build.xml.stylesheet.CRC32=eaf9f76a@2.58
   176.7 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
   176.8 +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
   176.9 +nbproject/build-impl.xml.data.CRC32=85cca5f7
  176.10 +nbproject/build-impl.xml.script.CRC32=82e0fe0b
  176.11 +nbproject/build-impl.xml.stylesheet.CRC32=0f381476@2.58
  176.12 +nbproject/platform.xml.data.CRC32=85cca5f7
  176.13 +nbproject/platform.xml.script.CRC32=6dcbd131
  176.14 +nbproject/platform.xml.stylesheet.CRC32=4e1f53d4@2.70
   177.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   177.2 +++ b/sandbox/java.hints/nbproject/platform.properties	Sun Oct 23 11:50:54 2016 +0200
   177.3 @@ -0,0 +1,19 @@
   177.4 +cluster.path=\
   177.5 +    ${nbplatform.active.dir}/apisupport:\
   177.6 +    ${nbplatform.active.dir}/cnd:\
   177.7 +    ${nbplatform.active.dir}/dlight:\
   177.8 +    ${nbplatform.active.dir}/enterprise:\
   177.9 +    ${nbplatform.active.dir}/extide:\
  177.10 +    ${nbplatform.active.dir}/extra:\
  177.11 +    ${nbplatform.active.dir}/harness:\
  177.12 +    ${nbplatform.active.dir}/ide:\
  177.13 +    ${nbplatform.active.dir}/java:\
  177.14 +    ${nbplatform.active.dir}/nb:\
  177.15 +    ${nbplatform.active.dir}/platform:\
  177.16 +    ${nbplatform.active.dir}/profiler:\
  177.17 +    ${nbplatform.active.dir}/webcommon:\
  177.18 +    ${nbplatform.active.dir}/websvccommon:\
  177.19 +    ../remoting/common/build/cluster
  177.20 +extcluster.../remoting/common/build/cluster.javadoc=
  177.21 +extcluster.../remoting/common/build/cluster.sources=
  177.22 +nbplatform.active=default
   178.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   178.2 +++ b/sandbox/java.hints/nbproject/platform.xml	Sun Oct 23 11:50:54 2016 +0200
   178.3 @@ -0,0 +1,34 @@
   178.4 +<?xml version="1.0" encoding="UTF-8"?>
   178.5 +<project name="platform" default="download" basedir="..">
   178.6 +    <condition property="download.required">
   178.7 +        <and>
   178.8 +            <not>
   178.9 +                <available file="${harness.dir}/suite.xml"/>
  178.10 +            </not>
  178.11 +            <isset property="bootstrap.url"/>
  178.12 +            <isset property="autoupdate.catalog.url"/>
  178.13 +        </and>
  178.14 +    </condition>
  178.15 +    <target name="download" if="download.required">
  178.16 +        <mkdir dir="${harness.dir}"/>
  178.17 +        <pathconvert pathsep="|" property="download.clusters">
  178.18 +            <mapper type="flatten"/>
  178.19 +            <path path="${cluster.path}"/>
  178.20 +        </pathconvert>
  178.21 +        <property name="disabled.modules" value=""/>
  178.22 +        <pathconvert property="module.includes" pathsep="">
  178.23 +            <mapper type="glob" from="${basedir}${file.separator}*" to="(?!^\Q*\E$)"/>
  178.24 +            <path>
  178.25 +                <filelist files="${disabled.modules}" dir="."/>
  178.26 +            </path>
  178.27 +        </pathconvert>
  178.28 +        <echo message="Downloading clusters ${download.clusters}"/>
  178.29 +        <property name="tasks.jar" location="${java.io.tmpdir}/tasks.jar"/>
  178.30 +        <get src="${bootstrap.url}" dest="${tasks.jar}" usetimestamp="true" verbose="true"/>
  178.31 +        <taskdef name="autoupdate" classname="org.netbeans.nbbuild.AutoUpdate" classpath="${tasks.jar}"/>
  178.32 +        <autoupdate installdir="${nbplatform.active.dir}" updatecenter="${autoupdate.catalog.url}">
  178.33 +            <modules includes="${module.includes}.*" clusters="${download.clusters}"/>
  178.34 +            <modules includes="org[.]netbeans[.]modules[.]apisupport[.]harness" clusters="harness"/>
  178.35 +        </autoupdate>
  178.36 +    </target>
  178.37 +</project>
   179.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   179.2 +++ b/sandbox/java.hints/nbproject/project.properties	Sun Oct 23 11:50:54 2016 +0200
   179.3 @@ -0,0 +1,7 @@
   179.4 +modules=\
   179.5 +    ${project.org.netbeans.spi.java.hints}:\
   179.6 +    ${project.org.netbeans.modules.java.hints.test}:\
   179.7 +    ${project.org.netbeans.modules.jackpot30.hintsimpl}
   179.8 +project.org.netbeans.modules.jackpot30.hintsimpl=hintsimpl
   179.9 +project.org.netbeans.modules.java.hints.test=java.hints.test
  179.10 +project.org.netbeans.spi.java.hints=spi.java.hints
   180.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   180.2 +++ b/sandbox/java.hints/nbproject/project.xml	Sun Oct 23 11:50:54 2016 +0200
   180.3 @@ -0,0 +1,9 @@
   180.4 +<?xml version="1.0" encoding="UTF-8"?>
   180.5 +<project xmlns="http://www.netbeans.org/ns/project/1">
   180.6 +    <type>org.netbeans.modules.apisupport.project.suite</type>
   180.7 +    <configuration>
   180.8 +        <data xmlns="http://www.netbeans.org/ns/nb-module-suite-project/1">
   180.9 +            <name>java.hints</name>
  180.10 +        </data>
  180.11 +    </configuration>
  180.12 +</project>
   181.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   181.2 +++ b/sandbox/java.hints/spi.java.hints/apichanges.xml	Sun Oct 23 11:50:54 2016 +0200
   181.3 @@ -0,0 +1,139 @@
   181.4 +<?xml version="1.0" encoding="UTF-8"?>
   181.5 +<!--
   181.6 +DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   181.7 +
   181.8 +Copyright 2012 Oracle and/or its affiliates. All rights reserved.
   181.9 +
  181.10 +Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  181.11 +Other names may be trademarks of their respective owners.
  181.12 +
  181.13 +The contents of this file are subject to the terms of either the GNU
  181.14 +General Public License Version 2 only ("GPL") or the Common
  181.15 +Development and Distribution License("CDDL") (collectively, the
  181.16 +"License"). You may not use this file except in compliance with the
  181.17 +License. You can obtain a copy of the License at
  181.18 +http://www.netbeans.org/cddl-gplv2.html
  181.19 +or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  181.20 +specific language governing permissions and limitations under the
  181.21 +License.  When distributing the software, include this License Header
  181.22 +Notice in each file and include the License file at
  181.23 +nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  181.24 +particular file as subject to the "Classpath" exception as provided
  181.25 +by Oracle in the GPL Version 2 section of the License file that
  181.26 +accompanied this code. If applicable, add the following below the
  181.27 +License Header, with the fields enclosed by brackets [] replaced by
  181.28 +your own identifying information:
  181.29 +"Portions Copyrighted [year] [name of copyright owner]"
  181.30 +
  181.31 +If you wish your version of this file to be governed by only the CDDL
  181.32 +or only the GPL Version 2, indicate your decision by adding
  181.33 +"[Contributor] elects to include this software in this distribution
  181.34 +under the [CDDL or GPL Version 2] license." If you do not indicate a
  181.35 +single choice of license, a recipient has the option to distribute
  181.36 +your version of this file under either the CDDL, the GPL Version 2 or
  181.37 +to extend the choice of license to its licensees as provided above.
  181.38 +However, if you add GPL Version 2 code and therefore, elected the GPL
  181.39 +Version 2 license, then the option applies only if the new code is
  181.40 +made subject to such option by the copyright holder.
  181.41 +
  181.42 +Contributor(s):
  181.43 +
  181.44 +Portions Copyrighted 2012 Sun Microsystems, Inc.
  181.45 +-->
  181.46 +<!DOCTYPE apichanges PUBLIC "-//NetBeans//DTD API changes list 1.0//EN" "../nbbuild/javadoctools/apichanges.dtd">
  181.47 +<apichanges>
  181.48 +    <apidefs>
  181.49 +        <apidef name="JavaHintsSPI">Java Hints SPI</apidef>
  181.50 +    </apidefs>
  181.51 +    <changes>
  181.52 +        <change id="ProjectHintsJava">
  181.53 +            <api name="JavaHintsSPI"/>
  181.54 +            <summary>Defining system filesystem folder for per-project Java hints customizers</summary>
  181.55 +            <version major="1" minor="16"/>
  181.56 +            <date day="24" month="4" year="2013"/>
  181.57 +            <author login="jlahoda"/>
  181.58 +            <compatibility addition="yes"/>
  181.59 +            <description>
  181.60 +                <p>
  181.61 +                    Defining <code>Project/hints/java-based</code> folder, where provider for
  181.62 +                    hints customizers for Java-based projects should be stored.
  181.63 +                </p>    
  181.64 +            </description>
  181.65 +<!--            <issue number="227959"/>-->
  181.66 +        </change>
  181.67 +        <change id="IntegerOption">
  181.68 +            <api name="JavaHintsSPI"/>
  181.69 +            <summary>Added support for integer options. Hints can be declared to appear only in inspect &amp; transform</summary>
  181.70 +            <version major="1" minor="14"/>
  181.71 +            <date day="3" month="4" year="2013"/>
  181.72 +            <author login="sdedic"/>
  181.73 +            <compatibility addition="yes"/>
  181.74 +            <description>
  181.75 +                <p>
  181.76 +                    Added declarative support for integer options. <code>@IntegerOption</code> can
  181.77 +                    be used with option name field, similar to <code>@BooleanOption</code>.
  181.78 +                </p>    
  181.79 +                <p>
  181.80 +                    An option was added to <code>Hint.Options</code>, so that hint can declare
  181.81 +                    to be only shown in Inspect &amp; transform dialog. Useful for computation-intensive
  181.82 +                    hints, which should only run on demand.
  181.83 +                </p>    
  181.84 +            </description>
  181.85 +            <class package="org.netbeans.spi.java.hints" name="IntegerOption"/>
  181.86 +            <class package="org.netbeans.spi.java.hints" name="Hint"/>
  181.87 +            <issue number="227822"/>
  181.88 +            <issue number="227959"/>
  181.89 +        </change>
  181.90 +        <change id="ErrorDescriptionFactory.forSpan">
  181.91 +            <api name="JavaHintsSPI"/>
  181.92 +            <summary>Introducing ErrorDescriptionFactory.forSpan.</summary>
  181.93 +            <version major="1" minor="9"/>
  181.94 +            <date day="19" month="12" year="2012"/>
  181.95 +            <author login="jlahoda"/>
  181.96 +            <compatibility addition="yes"/>
  181.97 +            <description>
  181.98 +                <p>
  181.99 +                    Added ErrorDescriptionFactory.forSpan to create the correct
 181.100 +                    Java-enhanced ErrorDescription from a span.
 181.101 +                </p>    
 181.102 +            </description>
 181.103 +            <class package="org.netbeans.spi.java.hints" name="ErrorDescriptionFactory"/>
 181.104 +            <issue number="223723"/>
 181.105 +        </change>
 181.106 +        <change id="TransformationSupport">
 181.107 +            <api name="JavaHintsSPI"/>
 181.108 +            <summary>Added support for using jackpot patterns from other modules (e.g. refactoring).</summary>
 181.109 +            <version major="1" minor="1"/>
 181.110 +            <date day="29" month="3" year="2012"/>
 181.111 +            <author login="jbecicka"/>
 181.112 +            <compatibility addition="yes"/>
 181.113 +            <description>
 181.114 +                <p>
 181.115 +                    Added support for using jackpot patterns from other modules (e.g. refactoring).
 181.116 +                </p>    
 181.117 +            </description>
 181.118 +            <class package="org.netbeans.spi.java.hints.support" name="TransformationSupport"/>
 181.119 +            <issue number="210262"/>
 181.120 +        </change>
 181.121 +    </changes>
 181.122 +    <htmlcontents>
 181.123 +        <head>
 181.124 +            <title>Change History for the Java Hints SPI</title>
 181.125 +            <link rel="stylesheet" href="prose.css" type="text/css"/>
 181.126 +        </head>
 181.127 +        <body>
 181.128 +            <p class="overviewlink">
 181.129 +                <a href="overview-summary.html">Overview</a>
 181.130 +            </p>
 181.131 +            <h1>Introduction</h1>
 181.132 +            <p>This document lists changes made to the Java Hints SPI.</p>
 181.133 +            
 181.134 +            <!-- The actual lists of changes, as summaries and details: -->
 181.135 +            <hr/>
 181.136 +            <standard-changelists module-code-name="$codebase"/>
 181.137 +            
 181.138 +            <hr/>
 181.139 +            <p>@FOOTER@</p>
 181.140 +        </body>
 181.141 +    </htmlcontents>
 181.142 +</apichanges>
   182.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   182.2 +++ b/sandbox/java.hints/spi.java.hints/arch.xml	Sun Oct 23 11:50:54 2016 +0200
   182.3 @@ -0,0 +1,1115 @@
   182.4 +<?xml version="1.0" encoding="UTF-8"?>
   182.5 +<!DOCTYPE api-answers PUBLIC "-//NetBeans//DTD Arch Answers//EN" "../nbbuild/antsrc/org/netbeans/nbbuild/Arch.dtd" [
   182.6 +  <!ENTITY api-questions SYSTEM "../nbbuild/antsrc/org/netbeans/nbbuild/Arch-api-questions.xml">
   182.7 +]>
   182.8 +
   182.9 +<api-answers
  182.10 +  question-version="1.29"
  182.11 +  author="jlahoda@netbeans.org"
  182.12 +>
  182.13 +
  182.14 +  &api-questions;
  182.15 +
  182.16 +
  182.17 +<!--
  182.18 +        <question id="arch-overall" when="init">
  182.19 +            Describe the overall architecture. 
  182.20 +            <hint>
  182.21 +            What will be API for 
  182.22 +            <a href="http://openide.netbeans.org/tutorial/api-design.html#design.apiandspi">
  182.23 +                clients and what support API</a>? 
  182.24 +            What parts will be pluggable?
  182.25 +            How will plug-ins be registered? Please use <code>&lt;api type="export"/&gt;</code>
  182.26 +            to describe your general APIs and specify their
  182.27 +            <a href="http://openide.netbeans.org/tutorial/api-design.html#category-private">
  182.28 +            stability categories</a>.
  182.29 +            If possible please provide simple diagrams.
  182.30 +            </hint>
  182.31 +        </question>
  182.32 +-->
  182.33 + <answer id="arch-overall">
  182.34 +  <p>
  182.35 +   <api type="export" category="devel" group="java" name="spi.java.hints">
  182.36 +       SPI to create custom Java hints, including code smell warnings, productivity tips, etc.
  182.37 +       Please see the Use Cases section for a guide on how to use this SPI.
  182.38 +   </api>
  182.39 +  </p>
  182.40 + </answer>
  182.41 +
  182.42 +
  182.43 +
  182.44 +<!--
  182.45 +        <question id="arch-quality" when="init">
  182.46 +            How will the <a href="http://www.netbeans.org/community/guidelines/q-evangelism.html">quality</a>
  182.47 +            of your code be tested and 
  182.48 +            how are future regressions going to be prevented?
  182.49 +            <hint>
  182.50 +            What kind of testing do
  182.51 +            you want to use? How much functionality, in which areas,
  182.52 +            should be covered by the tests? How you find out that your
  182.53 +            project was successful?
  182.54 +            </hint>
  182.55 +        </question>
  182.56 +-->
  182.57 + <answer id="arch-quality">
  182.58 +  <p>
  182.59 +   XXX no answer for arch-quality
  182.60 +  </p>
  182.61 + </answer>
  182.62 +
  182.63 +
  182.64 +
  182.65 +<!--
  182.66 +        <question id="arch-time" when="init">
  182.67 +            What are the time estimates of the work?
  182.68 +            <hint>
  182.69 +            Please express your estimates of how long the design, implementation,
  182.70 +            stabilization are likely to last. How many people will be needed to
  182.71 +            implement this and what is the expected milestone by which the work should be 
  182.72 +            ready?
  182.73 +            </hint>
  182.74 +        </question>
  182.75 +-->
  182.76 + <answer id="arch-time">
  182.77 +  <p>
  182.78 +   XXX no answer for arch-time
  182.79 +  </p>
  182.80 + </answer>
  182.81 +
  182.82 +
  182.83 +
  182.84 +<!--
  182.85 +        <question id="arch-usecases" when="init">
  182.86 +            <hint>
  182.87 +                Content of this answer will be displayed as part of page at
  182.88 +                http://www.netbeans.org/download/dev/javadoc/usecases.html 
  182.89 +                You can use tags &lt;usecase name="name&gt; regular html description &lt;/usecase&gt;
  182.90 +                and if you want to use an URL you can prefix if with @TOP@ to begin
  182.91 +                at the root of your javadoc
  182.92 +            </hint>
  182.93 +        
  182.94 +            Describe the main <a href="http://openide.netbeans.org/tutorial/api-design.html#usecase">
  182.95 +            use cases</a> of the new API. Who will use it under
  182.96 +            what circumstances? What kind of code would typically need to be written
  182.97 +            to use the module?
  182.98 +        </question>
  182.99 +-->
 182.100 + <answer id="arch-usecases">
 182.101 +  <p>
 182.102 +   <usecase id="creating" name="Creating a new Java Hint">
 182.103 +       Simple way to create a new Java hint is as follows:
 182.104 +       <ul>
 182.105 +           <li>Create a new class, annotate it with the <a href="@TOP@/org/netbeans/spi/java/hints/Hint.html">@Hint</a>
 182.106 +           annotation to it.</li>
 182.107 +           <li>Create a <code>public static ErrorDescription hint(HintContext ctx) {}</code> method in the
 182.108 +           class. Annotate the method either with the <a href="@TOP@/org/netbeans/spi/java/hints/TriggerPattern.html">@TriggerPattern</a>
 182.109 +           annotation (strongly recommended), or with the <a href="@TOP@/org/netbeans/spi/java/hints/TriggerTreeKind.html">@TriggerTreeKind</a>.
 182.110 +           This method will be called when for parts of the code that match the given pattern, of for trees of the specified kinds.</li>
 182.111 +           <li>Perform whatever checks necessary to find out whether a warning should be produced at the given place, and produce the ErrorDescription if needed.</li>
 182.112 +       </ul>
 182.113 +       <br/>
 182.114 +       Tips:
 182.115 +       <ul>
 182.116 +           <li>Always use the java.hints' <a href="@TOP@/org/netbeans/spi/java/hints/ErrorDescriptionFactory.html">ErrorDescriptionFactory</a> to produce the resulting ErrorDescription.</li>
 182.117 +           <li>Never try to produce a custom suppress warnings "fix". Specify suppress warnings keys in the @Hint annotation.</li>
 182.118 +           <li>If an automated transformation is to be prodived from your hint, subclass <a href="@TOP@/org/netbeans/spi/java/hints/JavaFix.html">JavaFix</a> and
 182.119 +               use its <code>toEditorFix()</code> method to get the <code>Fix</code>, if the transformation is going to be used inside Inspect&amp;Transform.
 182.120 +           </li>
 182.121 +           <li>The name of the method is arbitrary, one hint can consist of more that one "triggered" method.</li>
 182.122 +       </ul>
 182.123 +   </usecase>
 182.124 +   <usecase id="no-class" name="Creating a new Java Hint Without a Class">
 182.125 +       For simple hints, it is possible to annotate the hint method with the <a href="@TOP@/org/netbeans/spi/java/hints/Hint.html">@Hint</a> annotation.
 182.126 +       The hint then consists of this sole method. Any number of such hints may be created in a single class.
 182.127 +   </usecase>
 182.128 +   <usecase id="testing" name="Creating a Tests for the Newly Created Java Hint">
 182.129 +       Creating automated tests for the hints is simple: create a test class, and use
 182.130 +       <a href="@TOP@/../org-netbeans-modules-java-hints-test/org/netbeans/modules/java/hints/test/api/HintTest.html">HintTest</a>
 182.131 +       to setup the test, run the hint and verify that its outcomes are correct.
 182.132 +       The tests automatically run with <code>test</code> branding, so create <code>Bundle_test.properties</code>, and add
 182.133 +       bundle keys into it for ErrorDescription and Fix display names, to isolate the test from changes in the production
 182.134 +       <code>Bundle.properties</code>.
 182.135 +   </usecase>
 182.136 +   <usecase id="adding-options" name="Adding options to a Java Hint">
 182.137 +       To add a simple boolean option to your hint, use <a href="@TOP@/org/netbeans/spi/java/hints/BooleanOption.html">@BooleanOption</a>.
 182.138 +   </usecase>
 182.139 +  </p>
 182.140 + </answer>
 182.141 +
 182.142 +
 182.143 +
 182.144 +<!--
 182.145 +        <question id="arch-what" when="init">
 182.146 +            What is this project good for?
 182.147 +            <hint>
 182.148 +            Please provide here a few lines describing the project, 
 182.149 +            what problem it should solve, provide links to documentation, 
 182.150 +            specifications, etc.
 182.151 +            </hint>
 182.152 +        </question>
 182.153 +-->
 182.154 + <answer id="arch-what">
 182.155 +  <p>
 182.156 +   XXX no answer for arch-what
 182.157 +  </p>
 182.158 + </answer>
 182.159 +
 182.160 +
 182.161 +
 182.162 +<!--
 182.163 +        <question id="arch-where" when="impl">
 182.164 +            Where one can find sources for your module?
 182.165 +            <hint>
 182.166 +                Please provide link to the Hg web client at
 182.167 +                http://hg.netbeans.org/
 182.168 +                or just use tag defaultanswer generate='here'
 182.169 +            </hint>
 182.170 +        </question>
 182.171 +-->
 182.172 + <answer id="arch-where">
 182.173 +  <defaultanswer generate='here' />
 182.174 + </answer>
 182.175 +
 182.176 +
 182.177 +
 182.178 +<!--
 182.179 +        <question id="compat-deprecation" when="init">
 182.180 +            How the introduction of your project influences functionality
 182.181 +            provided by previous version of the product?
 182.182 +            <hint>
 182.183 +            If you are planning to deprecate/remove/change any existing APIs,
 182.184 +            list them here accompanied with the reason explaining why you
 182.185 +            are doing so.
 182.186 +            </hint>
 182.187 +        </question>
 182.188 +-->
 182.189 + <answer id="compat-deprecation">
 182.190 +  <p>
 182.191 +   XXX no answer for compat-deprecation
 182.192 +  </p>
 182.193 + </answer>
 182.194 +
 182.195 +
 182.196 +
 182.197 +<!--
 182.198 +        <question id="compat-i18n" when="impl">
 182.199 +            Is your module correctly internationalized?
 182.200 +            <hint>
 182.201 +            Correct internationalization means that it obeys instructions 
 182.202 +            at <a href="http://www.netbeans.org/download/dev/javadoc/org-openide-modules/org/openide/modules/doc-files/i18n-branding.html">
 182.203 +            NetBeans I18N pages</a>.
 182.204 +            </hint>
 182.205 +        </question>
 182.206 +-->
 182.207 + <answer id="compat-i18n">
 182.208 +  <p>
 182.209 +   XXX no answer for compat-i18n
 182.210 +  </p>
 182.211 + </answer>
 182.212 +
 182.213 +
 182.214 +
 182.215 +<!--
 182.216 +        <question id="compat-standards" when="init">
 182.217 +            Does the module implement or define any standards? Is the 
 182.218 +            implementation exact or does it deviate somehow?
 182.219 +        </question>
 182.220 +-->
 182.221 + <answer id="compat-standards">
 182.222 +  <p>
 182.223 +   XXX no answer for compat-standards
 182.224 +  </p>
 182.225 + </answer>
 182.226 +
 182.227 +
 182.228 +
 182.229 +<!--
 182.230 +        <question id="compat-version" when="impl">
 182.231 +            Can your module coexist with earlier and future
 182.232 +            versions of itself? Can you correctly read all old settings? Will future
 182.233 +            versions be able to read your current settings? Can you read
 182.234 +            or politely ignore settings stored by a future version?
 182.235 +            
 182.236 +            <hint>
 182.237 +            Very helpful for reading settings is to store version number
 182.238 +            there, so future versions can decide whether how to read/convert
 182.239 +            the settings and older versions can ignore the new ones.
 182.240 +            </hint>
 182.241 +        </question>
 182.242 +-->
 182.243 + <answer id="compat-version">
 182.244 +  <p>
 182.245 +   XXX no answer for compat-version
 182.246 +  </p>
 182.247 + </answer>
 182.248 +
 182.249 +
 182.250 +
 182.251 +<!--
 182.252 +        <question id="dep-jre" when="final">
 182.253 +            Which version of JRE do you need (1.2, 1.3, 1.4, etc.)?
 182.254 +            <hint>
 182.255 +            It is expected that if your module runs on 1.x that it will run 
 182.256 +            on 1.x+1 if no, state that please. Also describe here cases where
 182.257 +            you run different code on different versions of JRE and why.
 182.258 +            </hint>
 182.259 +        </question>
 182.260 +-->
 182.261 + <answer id="dep-jre">
 182.262 +  <p>
 182.263 +   XXX no answer for dep-jre
 182.264 +  </p>
 182.265 + </answer>
 182.266 +
 182.267 +
 182.268 +
 182.269 +<!--
 182.270 +        <question id="dep-jrejdk" when="final">
 182.271 +            Do you require the JDK or is the JRE enough?
 182.272 +        </question>
 182.273 +-->
 182.274 + <answer id="dep-jrejdk">
 182.275 +  <p>
 182.276 +   XXX no answer for dep-jrejdk
 182.277 +  </p>
 182.278 + </answer>
 182.279 +
 182.280 +
 182.281 +
 182.282 +<!--
 182.283 +        <question id="dep-nb" when="init">
 182.284 +            What other NetBeans projects and modules does this one depend on?
 182.285 +            <hint>
 182.286 +            Depending on other NetBeans projects influnces the ability of
 182.287 +            users of your work to customize their own branded version of
 182.288 +            NetBeans by enabling and disabling some modules. Too
 182.289 +            much dependencies restrict this kind of customization. If that
 182.290 +            is your case, then you may want to split your functionality into
 182.291 +            pieces of autoload, eager and regular modules which can be
 182.292 +            enabled independently. Usually the answer to this question
 182.293 +            is generated from your <code>project.xml</code> file, but
 182.294 +            if it is not guessed correctly, you can suppress it by
 182.295 +            specifying &lt;defaultanswer generate="none"/&gt; and
 182.296 +            write here your own. Please describe such projects as imported APIs using
 182.297 +            the <code>&lt;api name="identification" type="import or export" category="stable" url="where is the description" /&gt;</code>.
 182.298 +            By doing this information gets listed in the summary page of your
 182.299 +            javadoc.
 182.300 +            </hint>
 182.301 +        </question>
 182.302 +-->
 182.303 + <answer id="dep-nb">
 182.304 +  <defaultanswer generate='here' />
 182.305 + </answer>
 182.306 +
 182.307 +
 182.308 +
 182.309 +<!--
 182.310 +        <question id="dep-non-nb" when="init">
 182.311 +            What other projects outside NetBeans does this one depend on?
 182.312 +            
 182.313 +            <hint>
 182.314 +            Depending on 3rd party libraries is always problematic,
 182.315 +            especially if they are not open source, as that complicates
 182.316 +            the licensing scheme of NetBeans. Please enumerate your
 182.317 +            external dependencies here, so it is correctly understood since
 182.318 +            the begining what are the legal implications of your project.
 182.319 +            Also please note that
 182.320 +            some non-NetBeans projects are packaged as NetBeans modules
 182.321 +            (see <a href="http://libs.netbeans.org/">libraries</a>) and
 182.322 +            it is preferred to use this approach when more modules may
 182.323 +            depend and share such third-party libraries.
 182.324 +            </hint>
 182.325 +        </question>
 182.326 +-->
 182.327 + <answer id="dep-non-nb">
 182.328 +  <p>
 182.329 +   XXX no answer for dep-non-nb
 182.330 +  </p>
 182.331 + </answer>
 182.332 +
 182.333 +
 182.334 +
 182.335 +<!--
 182.336 +        <question id="dep-platform" when="init">
 182.337 +            On which platforms does your module run? Does it run in the same
 182.338 +            way on each?
 182.339 +            <hint>
 182.340 +            If you plan any dependency on OS or any usage of native code,
 182.341 +            please describe why you are doing so and describe how you envision
 182.342 +            to enforce the portability of your code.
 182.343 +            Please note that there is a support for <a href="http://www.netbeans.org/download/dev/javadoc/org-openide-modules/org/openide/modules/doc-files/api.html#how-os-specific">OS conditionally
 182.344 +            enabled modules</a> which together with autoload/eager modules
 182.345 +            can allow you to enable to provide the best OS aware support
 182.346 +            on certain OSes while providing compatibility bridge on the not
 182.347 +            supported ones.
 182.348 +            Also please list the supported
 182.349 +            OSes/HW platforms and mentioned the lovest version of JDK required
 182.350 +            for your project to run on. Also state whether JRE is enough or
 182.351 +            you really need JDK.
 182.352 +            </hint>
 182.353 +        </question>
 182.354 +-->
 182.355 + <answer id="dep-platform">
 182.356 +  <p>
 182.357 +   XXX no answer for dep-platform
 182.358 +  </p>
 182.359 + </answer>
 182.360 +
 182.361 +
 182.362 +
 182.363 +<!--
 182.364 +        <question id="deploy-dependencies" when="final">
 182.365 +            What do other modules need to do to declare a dependency on this one,
 182.366 +            in addition to or instead of the normal module dependency declaration
 182.367 +            (e.g. tokens to require)?
 182.368 +            <hint>
 182.369 +                Provide a sample of the actual lines you would add to a module manifest
 182.370 +                to declare a dependency, for example OpenIDE-Module-Requires: some.token.
 182.371 +                If other modules should not depend on this module, or should just use a
 182.372 +                simple regular module dependency, you can just answer "nothing". If you
 182.373 +                intentionally expose a semistable API to clients using implementation
 182.374 +                dependencies, you should mention that here (but there is no need to give
 182.375 +                an example of usage).
 182.376 +            </hint>
 182.377 +        </question>
 182.378 +-->
 182.379 + <answer id="deploy-dependencies">
 182.380 +  <p>
 182.381 +   XXX no answer for deploy-dependencies
 182.382 +  </p>
 182.383 + </answer>
 182.384 +
 182.385 +
 182.386 +
 182.387 +<!--
 182.388 +        <question id="deploy-jar" when="impl">
 182.389 +            Do you deploy just module JAR file(s) or other files as well?
 182.390 +            <hint>
 182.391 +            Usually a module consist of one JAR file (perhaps with Class-Path
 182.392 +            extensions) and also a configuration file that enables it. If you
 182.393 +            have any other files, use
 182.394 +            &lt;api group="java.io.File" name="yourname" type="export" category="friend"&gt;...&lt;/api&gt;
 182.395 +            to define the location, name and stability of your files (of course
 182.396 +            changing "yourname" and "friend" to suit your needs).
 182.397 +            
 182.398 +            If it uses more than one JAR, describe where they are located, how
 182.399 +            they refer to each other. 
 182.400 +            If it consist of module JAR(s) and other files, please describe
 182.401 +            what is their purpose, why other files are necessary. Please 
 182.402 +            make sure that installation/uninstallation leaves the system 
 182.403 +            in state as it was before installation.
 182.404 +            </hint>
 182.405 +        </question>
 182.406 +-->
 182.407 + <answer id="deploy-jar">
 182.408 +  <p>
 182.409 +   XXX no answer for deploy-jar
 182.410 +  </p>
 182.411 + </answer>
 182.412 +
 182.413 +
 182.414 +
 182.415 +<!--
 182.416 +        <question id="deploy-nbm" when="impl">
 182.417 +            Can you deploy an NBM via the Update Center?
 182.418 +            <hint>
 182.419 +            If not why?
 182.420 +            </hint>
 182.421 +        </question>
 182.422 +-->
 182.423 + <answer id="deploy-nbm">
 182.424 +  <p>
 182.425 +   XXX no answer for deploy-nbm
 182.426 +  </p>
 182.427 + </answer>
 182.428 +
 182.429 +
 182.430 +
 182.431 +<!--
 182.432 +        <question id="deploy-packages" when="init">
 182.433 +            Are packages of your module made inaccessible by not declaring them
 182.434 +            public?
 182.435 +            
 182.436 +            <hint>
 182.437 +            By default NetBeans build harness treats all packages are private.
 182.438 +            If you export some of them - either as public or friend packages,
 182.439 +            you should have a reason. If the reason is described elsewhere
 182.440 +            in this document, you can ignore this question.
 182.441 +            </hint>
 182.442 +        </question>
 182.443 +-->
 182.444 + <answer id="deploy-packages">
 182.445 +  <p>
 182.446 +   XXX no answer for deploy-packages
 182.447 +  </p>
 182.448 + </answer>
 182.449 +
 182.450 +
 182.451 +
 182.452 +<!--
 182.453 +        <question id="deploy-shared" when="final">
 182.454 +            Do you need to be installed in the shared location only, or in the user directory only,
 182.455 +            or can your module be installed anywhere?
 182.456 +            <hint>
 182.457 +            Installation location shall not matter, if it does explain why.
 182.458 +            Consider also whether <code>InstalledFileLocator</code> can help.
 182.459 +            </hint>
 182.460 +        </question>
 182.461 +-->
 182.462 + <answer id="deploy-shared">
 182.463 +  <p>
 182.464 +   XXX no answer for deploy-shared
 182.465 +  </p>
 182.466 + </answer>
 182.467 +
 182.468 +
 182.469 +
 182.470 +<!--
 182.471 +        <question id="exec-ant-tasks" when="impl">
 182.472 +            Do you define or register any ant tasks that other can use?
 182.473 +            
 182.474 +            <hint>
 182.475 +            If you provide an ant task that users can use, you need to be very
 182.476 +            careful about its syntax and behaviour, as it most likely forms an
 182.477 +	          API for end users and as there is a lot of end users, their reaction
 182.478 +            when such API gets broken can be pretty strong.
 182.479 +            </hint>
 182.480 +        </question>
 182.481 +-->
 182.482 + <answer id="exec-ant-tasks">
 182.483 +  <p>
 182.484 +   XXX no answer for exec-ant-tasks
 182.485 +  </p>
 182.486 + </answer>
 182.487 +
 182.488 +
 182.489 +
 182.490 +<!--
 182.491 +        <question id="exec-classloader" when="impl">
 182.492 +            Does your code create its own class loader(s)?
 182.493 +            <hint>
 182.494 +            A bit unusual. Please explain why and what for.
 182.495 +            </hint>
 182.496 +        </question>
 182.497 +-->
 182.498 + <answer id="exec-classloader">
 182.499 +  <p>
 182.500 +   XXX no answer for exec-classloader
 182.501 +  </p>
 182.502 + </answer>
 182.503 +
 182.504 +
 182.505 +
 182.506 +<!--
 182.507 +        <question id="exec-component" when="impl">
 182.508 +            Is execution of your code influenced by any (string) property
 182.509 +            of any of your components?
 182.510 +            
 182.511 +            <hint>
 182.512 +            Often <code>JComponent.getClientProperty</code>, <code>Action.getValue</code>
 182.513 +            or <code>PropertyDescriptor.getValue</code>, etc. are used to influence
 182.514 +            a behavior of some code. This of course forms an interface that should
 182.515 +            be documented. Also if one depends on some interface that an object
 182.516 +            implements (<code>component instanceof Runnable</code>) that forms an
 182.517 +            API as well.
 182.518 +            </hint>
 182.519 +        </question>
 182.520 +-->
 182.521 + <answer id="exec-component">
 182.522 +  <p>
 182.523 +   XXX no answer for exec-component
 182.524 +  </p>
 182.525 + </answer>
 182.526 +
 182.527 +
 182.528 +
 182.529 +<!--
 182.530 +        <question id="exec-introspection" when="impl">
 182.531 +            Does your module use any kind of runtime type information (<code>instanceof</code>,
 182.532 +            work with <code>java.lang.Class</code>, etc.)?
 182.533 +            <hint>
 182.534 +            Check for cases when you have an object of type A and you also
 182.535 +            expect it to (possibly) be of type B and do some special action. That
 182.536 +            should be documented. The same applies on operations in meta-level
 182.537 +            (Class.isInstance(...), Class.isAssignableFrom(...), etc.).
 182.538 +            </hint>
 182.539 +        </question>
 182.540 +-->
 182.541 + <answer id="exec-introspection">
 182.542 +  <p>
 182.543 +   XXX no answer for exec-introspection
 182.544 +  </p>
 182.545 + </answer>
 182.546 +
 182.547 +
 182.548 +
 182.549 +<!--
 182.550 +        <question id="exec-privateaccess" when="final">
 182.551 +            Are you aware of any other parts of the system calling some of 
 182.552 +            your methods by reflection?
 182.553 +            <hint>
 182.554 +            If so, describe the "contract" as an API. Likely private or friend one, but
 182.555 +            still API and consider rewrite of it.
 182.556 +            </hint>
 182.557 +        </question>
 182.558 +-->
 182.559 + <answer id="exec-privateaccess">
 182.560 +  <p>
 182.561 +   XXX no answer for exec-privateaccess
 182.562 +  </p>
 182.563 + </answer>
 182.564 +
 182.565 +
 182.566 +
 182.567 +<!--
 182.568 +        <question id="exec-process" when="impl">
 182.569 +            Do you execute an external process from your module? How do you ensure
 182.570 +            that the result is the same on different platforms? Do you parse output?
 182.571 +            Do you depend on result code?
 182.572 +            <hint>
 182.573 +            If you feed an input, parse the output please declare that as an API.
 182.574 +            </hint>
 182.575 +        </question>
 182.576 +-->
 182.577 + <answer id="exec-process">
 182.578 +  <p>
 182.579 +   XXX no answer for exec-process
 182.580 +  </p>
 182.581 + </answer>
 182.582 +
 182.583 +
 182.584 +
 182.585 +<!--
 182.586 +        <question id="exec-property" when="impl">
 182.587 +            Is execution of your code influenced by any environment or
 182.588 +            Java system (<code>System.getProperty</code>) property?
 182.589 +            On a similar note, is there something interesting that you
 182.590 +            pass to <code>java.util.logging.Logger</code>? Or do you observe
 182.591 +            what others log?
 182.592 +            <hint>
 182.593 +            If there is a property that can change the behavior of your 
 182.594 +            code, somebody will likely use it. You should describe what it does 
 182.595 +            and the <a href="http://openide.netbeans.org/tutorial/api-design.html#life">stability category</a>
 182.596 +            of this API. You may use
 182.597 +            <pre>
 182.598 +                &lt;api type="export" group="property" name="id" category="private" url="http://..."&gt;
 182.599 +                    description of the property, where it is used, what it influence, etc.
 182.600 +                &lt;/api&gt;            
 182.601 +            </pre>
 182.602 +            </hint>
 182.603 +        </question>
 182.604 +-->
 182.605 + <answer id="exec-property">
 182.606 +  <p>
 182.607 +   XXX no answer for exec-property
 182.608 +  </p>
 182.609 + </answer>
 182.610 +
 182.611 +
 182.612 +
 182.613 +<!--
 182.614 +        <question id="exec-reflection" when="impl">
 182.615 +            Does your code use Java Reflection to execute other code?
 182.616 +            <hint>
 182.617 +            This usually indicates a missing or insufficient API in the other
 182.618 +            part of the system. If the other side is not aware of your dependency
 182.619 +            this contract can be easily broken.
 182.620 +            </hint>
 182.621 +        </question>
 182.622 +-->
 182.623 + <answer id="exec-reflection">
 182.624 +  <p>
 182.625 +   XXX no answer for exec-reflection
 182.626 +  </p>
 182.627 + </answer>
 182.628 +
 182.629 +
 182.630 +
 182.631 +<!--
 182.632 +        <question id="exec-threading" when="init">
 182.633 +            What threading models, if any, does your module adhere to? How the
 182.634 +            project behaves with respect to threading?
 182.635 +            <hint>
 182.636 +                Is your API threadsafe? Can it be accessed from any threads or
 182.637 +                just from some dedicated ones? Any special relation to AWT and
 182.638 +                its Event Dispatch thread? Also
 182.639 +                if your module calls foreign APIs which have a specific threading model,
 182.640 +                indicate how you comply with the requirements for multithreaded access
 182.641 +                (synchronization, mutexes, etc.) applicable to those APIs.
 182.642 +                If your module defines any APIs, or has complex internal structures
 182.643 +                that might be used from multiple threads, declare how you protect
 182.644 +                data against concurrent access, race conditions, deadlocks, etc.,
 182.645 +                and whether such rules are enforced by runtime warnings, errors, assertions, etc.
 182.646 +                Examples: a class might be non-thread-safe (like Java Collections); might
 182.647 +                be fully thread-safe (internal locking); might require access through a mutex
 182.648 +                (and may or may not automatically acquire that mutex on behalf of a client method);
 182.649 +                might be able to run only in the event queue; etc.
 182.650 +                Also describe when any events are fired: synchronously, asynchronously, etc.
 182.651 +                Ideas: <a href="http://core.netbeans.org/proposals/threading/index.html#recommendations">Threading Recommendations</a> (in progress)
 182.652 +            </hint>
 182.653 +        </question>
 182.654 +-->
 182.655 + <answer id="exec-threading">
 182.656 +  <p>
 182.657 +   XXX no answer for exec-threading
 182.658 +  </p>
 182.659 + </answer>
 182.660 +
 182.661 +
 182.662 +
 182.663 +<!--
 182.664 +        <question id="format-clipboard" when="impl">
 182.665 +            Which data flavors (if any) does your code read from or insert to
 182.666 +            the clipboard (by access to clipboard on means calling methods on <code>java.awt.datatransfer.Transferable</code>?
 182.667 +            
 182.668 +            <hint>
 182.669 +            Often Node's deal with clipboard by usage of <code>Node.clipboardCopy, Node.clipboardCut and Node.pasteTypes</code>.
 182.670 +            Check your code for overriding these methods.
 182.671 +            </hint>
 182.672 +        </question>
 182.673 +-->
 182.674 + <answer id="format-clipboard">
 182.675 +  <p>
 182.676 +   XXX no answer for format-clipboard
 182.677 +  </p>
 182.678 + </answer>
 182.679 +
 182.680 +
 182.681 +
 182.682 +<!--
 182.683 +        <question id="format-dnd" when="impl">
 182.684 +            Which protocols (if any) does your code understand during Drag &amp; Drop?
 182.685 +            <hint>
 182.686 +            Often Node's deal with clipboard by usage of <code>Node.drag, Node.getDropType</code>. 
 182.687 +            Check your code for overriding these methods. Btw. if they are not overridden, they
 182.688 +            by default delegate to <code>Node.clipboardCopy, Node.clipboardCut and Node.pasteTypes</code>.
 182.689 +            </hint>
 182.690 +        </question>
 182.691 +-->
 182.692 + <answer id="format-dnd">
 182.693 +  <p>
 182.694 +   XXX no answer for format-dnd
 182.695 +  </p>
 182.696 + </answer>
 182.697 +
 182.698 +
 182.699 +
 182.700 +<!--
 182.701 +        <question id="format-types" when="impl">
 182.702 +            Which protocols and file formats (if any) does your module read or write on disk,
 182.703 +            or transmit or receive over the network? Do you generate an ant build script?
 182.704 +            Can it be edited and modified? 
 182.705 +            
 182.706 +            <hint>
 182.707 +            <p>
 182.708 +            Files can be read and written by other programs, modules and users. If they influence
 182.709 +            your behaviour, make sure you either document the format or claim that it is a private
 182.710 +            api (using the &lt;api&gt; tag). 
 182.711 +            </p>
 182.712 +            
 182.713 +            <p>
 182.714 +            If you generate an ant build file, this is very likely going to be seen by end users and
 182.715 +            they will be attempted to edit it. You should be ready for that and provide here a link
 182.716 +            to documentation that you have for such purposes and also describe how you are going to
 182.717 +            understand such files during next release, when you (very likely) slightly change the 
 182.718 +            format.
 182.719 +            </p>
 182.720 +            </hint>
 182.721 +        </question>
 182.722 +-->
 182.723 + <answer id="format-types">
 182.724 +  <p>
 182.725 +   XXX no answer for format-types
 182.726 +  </p>
 182.727 + </answer>
 182.728 +
 182.729 +
 182.730 +
 182.731 +<!--
 182.732 +        <question id="lookup-lookup" when="init">
 182.733 +            Does your module use <code>org.openide.util.Lookup</code>
 182.734 +            or any similar technology to find any components to communicate with? Which ones?
 182.735 +            
 182.736 +            <hint>
 182.737 +            NetBeans is build around a generic registry of services called
 182.738 +            lookup. It is preferable to use it for registration and discovery
 182.739 +            if possible. See
 182.740 +            <a href="http://www.netbeans.org/download/dev/javadoc/org-openide-util/org/openide/util/lookup/doc-files/index.html">
 182.741 +            The Solution to Comunication Between Components
 182.742 +            </a>. If you do not plan to use lookup and insist usage
 182.743 +            of other solution, then please describe why it is not working for
 182.744 +            you.
 182.745 +            <br/>
 182.746 +            When filling the final version of your arch document, please
 182.747 +            describe the interfaces you are searching for, where 
 182.748 +            are defined, whether you are searching for just one or more of them,
 182.749 +            if the order is important, etc. Also classify the stability of such
 182.750 +            API contract. Use &lt;api group=&amp;lookup&amp; /&gt; tag, so
 182.751 +            your information gets listed in the summary page of your javadoc.
 182.752 +            </hint>
 182.753 +        </question>
 182.754 +-->
 182.755 + <answer id="lookup-lookup">
 182.756 +  <p>
 182.757 +   XXX no answer for lookup-lookup
 182.758 +  </p>
 182.759 + </answer>
 182.760 +
 182.761 +
 182.762 +
 182.763 +<!--
 182.764 +        <question id="lookup-register" when="final">
 182.765 +            Do you register anything into lookup for other code to find?
 182.766 +            <hint>
 182.767 +            Do you register using layer file or using a declarative annotation such as <code>@ServiceProvider</code>?
 182.768 +            Who is supposed to find your component?
 182.769 +            </hint>
 182.770 +        </question>
 182.771 +-->
 182.772 + <answer id="lookup-register">
 182.773 +  <p>
 182.774 +   XXX no answer for lookup-register
 182.775 +  </p>
 182.776 + </answer>
 182.777 +
 182.778 +
 182.779 +
 182.780 +<!--
 182.781 +        <question id="lookup-remove" when="final">
 182.782 +            Do you remove entries of other modules from lookup?
 182.783 +            <hint>
 182.784 +            Why? Of course, that is possible, but it can be dangerous. Is the module
 182.785 +            your are masking resource from aware of what you are doing?
 182.786 +            </hint>
 182.787 +        </question>
 182.788 +-->
 182.789 + <answer id="lookup-remove">
 182.790 +  <p>
 182.791 +   XXX no answer for lookup-remove
 182.792 +  </p>
 182.793 + </answer>
 182.794 +
 182.795 +
 182.796 +
 182.797 +<!--
 182.798 +        <question id="perf-exit" when="final">
 182.799 +            Does your module run any code on exit?
 182.800 +        </question>
 182.801 +-->
 182.802 + <answer id="perf-exit">
 182.803 +  <p>
 182.804 +   XXX no answer for perf-exit
 182.805 +  </p>
 182.806 + </answer>
 182.807 +
 182.808 +
 182.809 +
 182.810 +<!--
 182.811 +        <question id="perf-huge_dialogs" when="final">
 182.812 +            Does your module contain any dialogs or wizards with a large number of
 182.813 +            GUI controls such as combo boxes, lists, trees, or text areas?
 182.814 +        </question>
 182.815 +-->
 182.816 + <answer id="perf-huge_dialogs">
 182.817 +  <p>
 182.818 +   XXX no answer for perf-huge_dialogs
 182.819 +  </p>
 182.820 + </answer>
 182.821 +
 182.822 +
 182.823 +
 182.824 +<!--
 182.825 +        <question id="perf-limit" when="init">
 182.826 +            Are there any hard-coded or practical limits in the number or size of
 182.827 +            elements your code can handle?
 182.828 +            <hint>
 182.829 +                Most of algorithms have increasing memory and speed complexity
 182.830 +                with respect to size of data they operate on. What is the critical
 182.831 +                part of your project that can be seen as a bottleneck with
 182.832 +                respect to speed or required memory? What are the practical
 182.833 +                sizes of data you tested your project with? What is your estimate
 182.834 +                of potential size of data that would cause visible performance
 182.835 +                problems? Is there some kind of check to detect such situation
 182.836 +                and prevent "hard" crashes - for example the CloneableEditorSupport
 182.837 +                checks for size of a file to be opened in editor
 182.838 +                and if it is larger than 1Mb it shows a dialog giving the
 182.839 +                user the right to decide - e.g. to cancel or commit suicide.
 182.840 +            </hint>
 182.841 +        </question>
 182.842 +-->
 182.843 + <answer id="perf-limit">
 182.844 +  <p>
 182.845 +   XXX no answer for perf-limit
 182.846 +  </p>
 182.847 + </answer>
 182.848 +
 182.849 +
 182.850 +
 182.851 +<!--
 182.852 +        <question id="perf-mem" when="final">
 182.853 +            How much memory does your component consume? Estimate
 182.854 +            with a relation to the number of windows, etc.
 182.855 +        </question>
 182.856 +-->
 182.857 + <answer id="perf-mem">
 182.858 +  <p>
 182.859 +   XXX no answer for perf-mem
 182.860 +  </p>
 182.861 + </answer>
 182.862 +
 182.863 +
 182.864 +
 182.865 +<!--
 182.866 +        <question id="perf-menus" when="final">
 182.867 +            Does your module use dynamically updated context menus, or
 182.868 +            context-sensitive actions with complicated and slow enablement logic?
 182.869 +            <hint>
 182.870 +                If you do a lot of tricks when adding actions to regular or context menus, you can significantly
 182.871 +                slow down display of the menu, even when the user is not using your action. Pay attention to
 182.872 +                actions you add to the main menu bar, and to context menus of foreign nodes or components. If
 182.873 +                the action is conditionally enabled, or changes its display dynamically, you need to check the
 182.874 +                impact on performance. In some cases it may be more appropriate to make a simple action that is
 182.875 +                always enabled but does more detailed checks in a dialog if it is actually run.
 182.876 +            </hint>
 182.877 +        </question>
 182.878 +-->
 182.879 + <answer id="perf-menus">
 182.880 +  <p>
 182.881 +   XXX no answer for perf-menus
 182.882 +  </p>
 182.883 + </answer>
 182.884 +
 182.885 +
 182.886 +
 182.887 +<!--
 182.888 +        <question id="perf-progress" when="final">
 182.889 +            Does your module execute any long-running tasks?
 182.890 +            
 182.891 +            <hint>Long running tasks should never block 
 182.892 +            AWT thread as it badly hurts the UI
 182.893 +            <a href="http://performance.netbeans.org/responsiveness/issues.html">
 182.894 +            responsiveness</a>.
 182.895 +            Tasks like connecting over
 182.896 +            network, computing huge amount of data, compilation
 182.897 +            be done asynchronously (for example
 182.898 +            using <code>RequestProcessor</code>), definitively it should 
 182.899 +            not block AWT thread.
 182.900 +            </hint>
 182.901 +        </question>
 182.902 +-->
 182.903 + <answer id="perf-progress">
 182.904 +  <p>
 182.905 +   XXX no answer for perf-progress
 182.906 +  </p>
 182.907 + </answer>
 182.908 +
 182.909 +
 182.910 +
 182.911 +<!--
 182.912 +        <question id="perf-scale" when="init">
 182.913 +            Which external criteria influence the performance of your
 182.914 +            program (size of file in editor, number of files in menu, 
 182.915 +            in source directory, etc.) and how well your code scales?
 182.916 +            <hint>
 182.917 +            Please include some estimates, there are other more detailed 
 182.918 +            questions to answer in later phases of implementation. 
 182.919 +            </hint>
 182.920 +        </question>
 182.921 +-->
 182.922 + <answer id="perf-scale">
 182.923 +  <p>
 182.924 +   XXX no answer for perf-scale
 182.925 +  </p>
 182.926 + </answer>
 182.927 +
 182.928 +
 182.929 +
 182.930 +<!--
 182.931 +        <question id="perf-spi" when="init">
 182.932 +            How the performance of the plugged in code will be enforced?
 182.933 +            <hint>
 182.934 +            If you allow foreign code to be plugged into your own module, how
 182.935 +            do you enforce that it will behave correctly and quickly and will not
 182.936 +            negatively influence the performance of your own module?
 182.937 +            </hint>
 182.938 +        </question>
 182.939 +-->
 182.940 + <answer id="perf-spi">
 182.941 +  <p>
 182.942 +   XXX no answer for perf-spi
 182.943 +  </p>
 182.944 + </answer>
 182.945 +
 182.946 +
 182.947 +
 182.948 +<!--
 182.949 +        <question id="perf-startup" when="final">
 182.950 +            Does your module run any code on startup?
 182.951 +        </question>
 182.952 +-->
 182.953 + <answer id="perf-startup">
 182.954 +  <p>
 182.955 +   XXX no answer for perf-startup
 182.956 +  </p>
 182.957 + </answer>
 182.958 +
 182.959 +
 182.960 +
 182.961 +<!--
 182.962 +        <question id="perf-wakeup" when="final">
 182.963 +            Does any piece of your code wake up periodically and do something
 182.964 +            even when the system is otherwise idle (no user interaction)?
 182.965 +        </question>
 182.966 +-->
 182.967 + <answer id="perf-wakeup">
 182.968 +  <p>
 182.969 +   XXX no answer for perf-wakeup
 182.970 +  </p>
 182.971 + </answer>
 182.972 +
 182.973 +
 182.974 +
 182.975 +<!--
 182.976 +        <question id="resources-file" when="final">
 182.977 +            Does your module use <code>java.io.File</code> directly?
 182.978 +            
 182.979 +            <hint>
 182.980 +            NetBeans provide a logical wrapper over plain files called 
 182.981 +            <code>org.openide.filesystems.FileObject</code> that
 182.982 +            provides uniform access to such resources and is the preferred
 182.983 +            way that should be used. But of course there can be situations when
 182.984 +            this is not suitable.
 182.985 +            </hint>
 182.986 +        </question>
 182.987 +-->
 182.988 + <answer id="resources-file">
 182.989 +  <p>
 182.990 +   XXX no answer for resources-file
 182.991 +  </p>
 182.992 + </answer>
 182.993 +
 182.994 +
 182.995 +
 182.996 +<!--
 182.997 +        <question id="resources-layer" when="final">
 182.998 +            Does your module provide own layer? Does it create any files or
 182.999 +            folders in it? What it is trying to communicate by that and with which 
182.1000 +            components?
182.1001 +            
182.1002 +            <hint>
182.1003 +            NetBeans allows automatic and declarative installation of resources 
182.1004 +            by module layers. Module register files into appropriate places
182.1005 +            and other components use that information to perform their task
182.1006 +            (build menu, toolbar, window layout, list of templates, set of
182.1007 +            options, etc.). 
182.1008 +            </hint>
182.1009 +        </question>
182.1010 +-->
182.1011 + <answer id="resources-layer">
182.1012 +  <p>
182.1013 +   XXX no answer for resources-layer
182.1014 +  </p>
182.1015 + </answer>
182.1016 +
182.1017 +
182.1018 +
182.1019 +<!--
182.1020 +        <question id="resources-mask" when="final">
182.1021 +            Does your module mask/hide/override any resources provided by other modules in
182.1022 +            their layers?
182.1023 +            
182.1024 +            <hint>
182.1025 +            If you mask a file provided by another module, you probably depend
182.1026 +            on that and do not want the other module to (for example) change
182.1027 +            the file's name. That module shall thus make that file available as an API
182.1028 +            of some stability category.
182.1029 +            </hint>
182.1030 +        </question>
182.1031 +-->
182.1032 + <answer id="resources-mask">
182.1033 +  <p>
182.1034 +   XXX no answer for resources-mask
182.1035 +  </p>
182.1036 + </answer>
182.1037 +
182.1038 +
182.1039 +
182.1040 +<!--
182.1041 +        <question id="resources-preferences" when="final">
182.1042 +            Does your module uses preferences via Preferences API? Does your module use NbPreferences or
182.1043 +            or regular JDK Preferences ? Does it read, write or both ? 
182.1044 +            Does it share preferences with other modules ? If so, then why ?
182.1045 +            <hint>
182.1046 +                You may use
182.1047 +                    &lt;api type="export" group="preferences"
182.1048 +                    name="preference node name" category="private"&gt;
182.1049 +                    description of individual keys, where it is used, what it
182.1050 +                    influences, whether the module reads/write it, etc.
182.1051 +                    &lt;/api&gt;
182.1052 +                Due to XML ID restrictions, rather than /org/netbeans/modules/foo give the "name" as org.netbeans.modules.foo.
182.1053 +                Note that if you use NbPreferences this name will then be the same as the code name base of the module.
182.1054 +            </hint>
182.1055 +        </question>
182.1056 +-->
182.1057 + <answer id="resources-preferences">
182.1058 +  <p>
182.1059 +   XXX no answer for resources-preferences
182.1060 +  </p>
182.1061 + </answer>
182.1062 +
182.1063 +
182.1064 +
182.1065 +<!--
182.1066 +        <question id="resources-read" when="final">
182.1067 +            Does your module read any resources from layers? For what purpose?
182.1068 +            
182.1069 +            <hint>
182.1070 +            As this is some kind of intermodule dependency, it is a kind of API.
182.1071 +            Please describe it and classify according to 
182.1072 +            <a href="http://openide.netbeans.org/tutorial/api-design.html#categories">
182.1073 +            common stability categories</a>.
182.1074 +            </hint>
182.1075 +        </question>
182.1076 +-->
182.1077 + <answer id="resources-read">
182.1078 +  <p>
182.1079 +   XXX no answer for resources-read
182.1080 +  </p>
182.1081 + </answer>
182.1082 +
182.1083 +
182.1084 +
182.1085 +<!--
182.1086 +        <question id="security-grant" when="final">
182.1087 +            Does your code grant additional rights to some other code?
182.1088 +            <hint>Avoid using a class loader that adds extra
182.1089 +            permissions to loaded code unless really necessary.
182.1090 +            Also note that your API implementation
182.1091 +            can also expose unneeded permissions to enemy code by
182.1092 +            calling AccessController.doPrivileged().</hint>
182.1093 +        </question>
182.1094 +-->
182.1095 + <answer id="security-grant">
182.1096 +  <p>
182.1097 +   XXX no answer for security-grant
182.1098 +  </p>
182.1099 + </answer>
182.1100 +
182.1101 +
182.1102 +
182.1103 +<!--
182.1104 +        <question id="security-policy" when="final">
182.1105 +            Does your functionality require modifications to the standard policy file?
182.1106 +            <hint>Your code might pass control to third-party code not
182.1107 +            coming from trusted domains. This could be code downloaded over the
182.1108 +            network or code coming from libraries that are not bundled
182.1109 +            with NetBeans. Which permissions need to be granted to which domains?</hint>
182.1110 +        </question>
182.1111 +-->
182.1112 + <answer id="security-policy">
182.1113 +  <p>
182.1114 +   XXX no answer for security-policy
182.1115 +  </p>
182.1116 + </answer>
182.1117 +
182.1118 +</api-answers>
   183.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   183.2 +++ b/sandbox/java.hints/spi.java.hints/build.xml	Sun Oct 23 11:50:54 2016 +0200
   183.3 @@ -0,0 +1,8 @@
   183.4 +<?xml version="1.0" encoding="UTF-8"?>
   183.5 +<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
   183.6 +<!-- for some information on what you could do (e.g. targets to override). -->
   183.7 +<!-- If you delete this file and reopen the project it will be recreated. -->
   183.8 +<project name="org.netbeans.spi.java.hints" default="netbeans" basedir=".">
   183.9 +    <description>Builds, tests, and runs the project org.netbeans.spi.java.hints.</description>
  183.10 +    <import file="nbproject/build-impl.xml"/>
  183.11 +</project>
   184.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   184.2 +++ b/sandbox/java.hints/spi.java.hints/manifest.mf	Sun Oct 23 11:50:54 2016 +0200
   184.3 @@ -0,0 +1,5 @@
   184.4 +Manifest-Version: 1.0
   184.5 +OpenIDE-Module: org.netbeans.spi.java.hints
   184.6 +OpenIDE-Module-Implementation-Version: 11
   184.7 +OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/java/hints/spiimpl/Bundle.properties
   184.8 +
   185.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   185.2 +++ b/sandbox/java.hints/spi.java.hints/nbproject/build-impl.xml	Sun Oct 23 11:50:54 2016 +0200
   185.3 @@ -0,0 +1,45 @@
   185.4 +<?xml version="1.0" encoding="UTF-8"?>
   185.5 +<!--
   185.6 +*** GENERATED FROM project.xml - DO NOT EDIT  ***
   185.7 +***         EDIT ../build.xml INSTEAD         ***
   185.8 +-->
   185.9 +<project name="org.netbeans.spi.java.hints-impl" basedir="..">
  185.10 +    <fail message="Please build using Ant 1.7.1 or higher.">
  185.11 +        <condition>
  185.12 +            <not>
  185.13 +                <antversion atleast="1.7.1"/>
  185.14 +            </not>
  185.15 +        </condition>
  185.16 +    </fail>
  185.17 +    <property file="nbproject/private/suite-private.properties"/>
  185.18 +    <property file="nbproject/suite.properties"/>
  185.19 +    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
  185.20 +    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
  185.21 +    <property file="${suite.dir}/nbproject/platform.properties"/>
  185.22 +    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
  185.23 +        <attribute name="name"/>
  185.24 +        <attribute name="value"/>
  185.25 +        <sequential>
  185.26 +            <property name="@{name}" value="${@{value}}"/>
  185.27 +        </sequential>
  185.28 +    </macrodef>
  185.29 +    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
  185.30 +        <attribute name="property"/>
  185.31 +        <attribute name="value"/>
  185.32 +        <sequential>
  185.33 +            <property name="@{property}" value="@{value}"/>
  185.34 +        </sequential>
  185.35 +    </macrodef>
  185.36 +    <property file="${user.properties.file}"/>
  185.37 +    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
  185.38 +    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
  185.39 +    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
  185.40 +    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
  185.41 +        <condition>
  185.42 +            <not>
  185.43 +                <contains string="${cluster.path.evaluated}" substring="platform"/>
  185.44 +            </not>
  185.45 +        </condition>
  185.46 +    </fail>
  185.47 +    <import file="${harness.dir}/build.xml"/>
  185.48 +</project>
   186.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   186.2 +++ b/sandbox/java.hints/spi.java.hints/nbproject/genfiles.properties	Sun Oct 23 11:50:54 2016 +0200
   186.3 @@ -0,0 +1,8 @@
   186.4 +build.xml.data.CRC32=1b4fb019
   186.5 +build.xml.script.CRC32=caab83d9
   186.6 +build.xml.stylesheet.CRC32=a56c6a5b@2.70
   186.7 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
   186.8 +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
   186.9 +nbproject/build-impl.xml.data.CRC32=1b4fb019
  186.10 +nbproject/build-impl.xml.script.CRC32=7438bc77
  186.11 +nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.70
   187.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   187.2 +++ b/sandbox/java.hints/spi.java.hints/nbproject/org-netbeans-spi-java-hints.sig	Sun Oct 23 11:50:54 2016 +0200
   187.3 @@ -0,0 +1,276 @@
   187.4 +#Signature file v4.1
   187.5 +#Version 1.10.1
   187.6 +
   187.7 +CLSS public abstract interface java.io.Serializable
   187.8 +
   187.9 +CLSS public abstract interface java.lang.Comparable<%0 extends java.lang.Object>
  187.10 +meth public abstract int compareTo({java.lang.Comparable%0})
  187.11 +
  187.12 +CLSS public abstract java.lang.Enum<%0 extends java.lang.Enum<{java.lang.Enum%0}>>
  187.13 +cons protected init(java.lang.String,int)
  187.14 +intf java.io.Serializable
  187.15 +intf java.lang.Comparable<{java.lang.Enum%0}>
  187.16 +meth protected final java.lang.Object clone() throws java.lang.CloneNotSupportedException
  187.17 +meth protected final void finalize()
  187.18 +meth public final boolean equals(java.lang.Object)
  187.19 +meth public final int compareTo({java.lang.Enum%0})
  187.20 +meth public final int hashCode()
  187.21 +meth public final int ordinal()
  187.22 +meth public final java.lang.Class<{java.lang.Enum%0}> getDeclaringClass()
  187.23 +meth public final java.lang.String name()
  187.24 +meth public java.lang.String toString()
  187.25 +meth public static <%0 extends java.lang.Enum<{%%0}>> {%%0} valueOf(java.lang.Class<{%%0}>,java.lang.String)
  187.26 +supr java.lang.Object
  187.27 +hfds name,ordinal
  187.28 +
  187.29 +CLSS public java.lang.Object
  187.30 +cons public init()
  187.31 +meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
  187.32 +meth protected void finalize() throws java.lang.Throwable
  187.33 +meth public boolean equals(java.lang.Object)
  187.34 +meth public final java.lang.Class<?> getClass()
  187.35 +meth public final void notify()
  187.36 +meth public final void notifyAll()
  187.37 +meth public final void wait() throws java.lang.InterruptedException
  187.38 +meth public final void wait(long) throws java.lang.InterruptedException
  187.39 +meth public final void wait(long,int) throws java.lang.InterruptedException
  187.40 +meth public int hashCode()
  187.41 +meth public java.lang.String toString()
  187.42 +
  187.43 +CLSS public abstract interface java.lang.annotation.Annotation
  187.44 +meth public abstract boolean equals(java.lang.Object)
  187.45 +meth public abstract int hashCode()
  187.46 +meth public abstract java.lang.Class<? extends java.lang.annotation.Annotation> annotationType()
  187.47 +meth public abstract java.lang.String toString()
  187.48 +
  187.49 +CLSS public abstract interface !annotation java.lang.annotation.Documented
  187.50 + anno 0 java.lang.annotation.Documented()
  187.51 + anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=RUNTIME)
  187.52 + anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[ANNOTATION_TYPE])
  187.53 +intf java.lang.annotation.Annotation
  187.54 +
  187.55 +CLSS public abstract interface !annotation java.lang.annotation.Retention
  187.56 + anno 0 java.lang.annotation.Documented()
  187.57 + anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=RUNTIME)
  187.58 + anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[ANNOTATION_TYPE])
  187.59 +intf java.lang.annotation.Annotation
  187.60 +meth public abstract java.lang.annotation.RetentionPolicy value()
  187.61 +
  187.62 +CLSS public abstract interface !annotation java.lang.annotation.Target
  187.63 + anno 0 java.lang.annotation.Documented()
  187.64 + anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=RUNTIME)
  187.65 + anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[ANNOTATION_TYPE])
  187.66 +intf java.lang.annotation.Annotation
  187.67 +meth public abstract java.lang.annotation.ElementType[] value()
  187.68 +
  187.69 +CLSS public abstract interface !annotation org.netbeans.spi.java.hints.BooleanOption
  187.70 + anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=SOURCE)
  187.71 + anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[FIELD])
  187.72 +intf java.lang.annotation.Annotation
  187.73 +meth public abstract boolean defaultValue()
  187.74 +meth public abstract java.lang.String displayName()
  187.75 +meth public abstract java.lang.String tooltip()
  187.76 +
  187.77 +CLSS public abstract interface !annotation org.netbeans.spi.java.hints.ConstraintVariableType
  187.78 + anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[])
  187.79 +intf java.lang.annotation.Annotation
  187.80 +meth public abstract java.lang.String type()
  187.81 +meth public abstract java.lang.String variable()
  187.82 +
  187.83 +CLSS public abstract interface org.netbeans.spi.java.hints.CustomizerProvider
  187.84 +meth public abstract javax.swing.JComponent getCustomizer(java.util.prefs.Preferences)
  187.85 + anno 0 org.netbeans.api.annotations.common.NonNull()
  187.86 + anno 1 org.netbeans.api.annotations.common.NonNull()
  187.87 +
  187.88 +CLSS public org.netbeans.spi.java.hints.ErrorDescriptionFactory
  187.89 +meth public !varargs static org.netbeans.spi.editor.hints.ErrorDescription forName(org.netbeans.spi.java.hints.HintContext,com.sun.source.tree.Tree,java.lang.String,org.netbeans.spi.editor.hints.Fix[])
  187.90 +meth public !varargs static org.netbeans.spi.editor.hints.ErrorDescription forName(org.netbeans.spi.java.hints.HintContext,com.sun.source.util.TreePath,java.lang.String,org.netbeans.spi.editor.hints.Fix[])
  187.91 +meth public !varargs static org.netbeans.spi.editor.hints.ErrorDescription forSpan(org.netbeans.spi.java.hints.HintContext,int,int,java.lang.String,org.netbeans.spi.editor.hints.Fix[])
  187.92 +meth public !varargs static org.netbeans.spi.editor.hints.ErrorDescription forTree(org.netbeans.spi.java.hints.HintContext,com.sun.source.tree.Tree,java.lang.String,org.netbeans.spi.editor.hints.Fix[])
  187.93 +meth public !varargs static org.netbeans.spi.editor.hints.ErrorDescription forTree(org.netbeans.spi.java.hints.HintContext,com.sun.source.util.TreePath,java.lang.String,org.netbeans.spi.editor.hints.Fix[])
  187.94 +supr java.lang.Object
  187.95 +hfds DECLARATION
  187.96 +hcls DisableConfigure,FixImpl,InspectFix,TopLevelConfigureFix
  187.97 +
  187.98 +CLSS public abstract interface !annotation org.netbeans.spi.java.hints.Hint
  187.99 + anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=SOURCE)
 187.100 + anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[TYPE, METHOD])
 187.101 +innr public final static !enum Kind
 187.102 +innr public final static !enum Options
 187.103 +intf java.lang.annotation.Annotation
 187.104 +meth public abstract !hasdefault boolean enabled()
 187.105 +meth public abstract !hasdefault java.lang.Class<? extends org.netbeans.spi.java.hints.CustomizerProvider> customizerProvider()
 187.106 +meth public abstract !hasdefault java.lang.String id()
 187.107 +meth public abstract !hasdefault java.lang.String[] suppressWarnings()
 187.108 +meth public abstract !hasdefault org.netbeans.spi.editor.hints.Severity severity()
 187.109 +meth public abstract !hasdefault org.netbeans.spi.java.hints.Hint$Kind hintKind()
 187.110 +meth public abstract !hasdefault org.netbeans.spi.java.hints.Hint$Options[] options()
 187.111 +meth public abstract java.lang.String category()
 187.112 +meth public abstract java.lang.String description()
 187.113 +meth public abstract java.lang.String displayName()
 187.114 +
 187.115 +CLSS public final static !enum org.netbeans.spi.java.hints.Hint$Kind
 187.116 + outer org.netbeans.spi.java.hints.Hint
 187.117 +fld public final static org.netbeans.spi.java.hints.Hint$Kind ACTION
 187.118 +fld public final static org.netbeans.spi.java.hints.Hint$Kind INSPECTION
 187.119 +meth public static org.netbeans.spi.java.hints.Hint$Kind valueOf(java.lang.String)
 187.120 +meth public static org.netbeans.spi.java.hints.Hint$Kind[] values()
 187.121 +supr java.lang.Enum<org.netbeans.spi.java.hints.Hint$Kind>
 187.122 +
 187.123 +CLSS public final static !enum org.netbeans.spi.java.hints.Hint$Options
 187.124 + outer org.netbeans.spi.java.hints.Hint
 187.125 +fld public final static org.netbeans.spi.java.hints.Hint$Options NO_BATCH
 187.126 +fld public final static org.netbeans.spi.java.hints.Hint$Options QUERY
 187.127 +meth public static org.netbeans.spi.java.hints.Hint$Options valueOf(java.lang.String)
 187.128 +meth public static org.netbeans.spi.java.hints.Hint$Options[] values()
 187.129 +supr java.lang.Enum<org.netbeans.spi.java.hints.Hint$Options>
 187.130 +
 187.131 +CLSS public org.netbeans.spi.java.hints.HintContext
 187.132 +innr public final static !enum MessageKind
 187.133 +meth public boolean isBulkMode()
 187.134 +meth public boolean isCanceled()
 187.135 +meth public com.sun.source.util.TreePath getPath()
 187.136 +meth public int getCaretLocation()
 187.137 +meth public java.util.Map<java.lang.String,com.sun.source.util.TreePath> getVariables()
 187.138 +meth public java.util.Map<java.lang.String,java.lang.String> getVariableNames()
 187.139 +meth public java.util.Map<java.lang.String,java.util.Collection<? extends com.sun.source.util.TreePath>> getMultiVariables()
 187.140 +meth public java.util.Map<java.lang.String,javax.lang.model.type.TypeMirror> getConstraints()
 187.141 +meth public java.util.prefs.Preferences getPreferences()
 187.142 +meth public org.netbeans.api.java.source.CompilationInfo getInfo()
 187.143 +meth public org.netbeans.spi.editor.hints.Severity getSeverity()
 187.144 +meth public void reportMessage(org.netbeans.spi.java.hints.HintContext$MessageKind,java.lang.String)
 187.145 +supr java.lang.Object
 187.146 +hfds bulkMode,cancel,caret,constraints,info,messages,metadata,multiVariables,path,preferences,severity,variableNames,variables
 187.147 +
 187.148 +CLSS public final static !enum org.netbeans.spi.java.hints.HintContext$MessageKind
 187.149 + outer org.netbeans.spi.java.hints.HintContext
 187.150 +fld public final static org.netbeans.spi.java.hints.HintContext$MessageKind ERROR
 187.151 +fld public final static org.netbeans.spi.java.hints.HintContext$MessageKind WARNING
 187.152 +meth public static org.netbeans.spi.java.hints.HintContext$MessageKind valueOf(java.lang.String)
 187.153 +meth public static org.netbeans.spi.java.hints.HintContext$MessageKind[] values()
 187.154 +supr java.lang.Enum<org.netbeans.spi.java.hints.HintContext$MessageKind>
 187.155 +
 187.156 +CLSS public final !enum org.netbeans.spi.java.hints.HintSeverity
 187.157 +fld public final static org.netbeans.spi.java.hints.HintSeverity CURRENT_LINE_WARNING
 187.158 +fld public final static org.netbeans.spi.java.hints.HintSeverity ERROR
 187.159 +fld public final static org.netbeans.spi.java.hints.HintSeverity WARNING
 187.160 +meth public org.netbeans.spi.editor.hints.Severity toEditorSeverity()
 187.161 +meth public static org.netbeans.spi.java.hints.HintSeverity valueOf(java.lang.String)
 187.162 +meth public static org.netbeans.spi.java.hints.HintSeverity[] values()
 187.163 +supr java.lang.Enum<org.netbeans.spi.java.hints.HintSeverity>
 187.164 +
 187.165 +CLSS public abstract org.netbeans.spi.java.hints.JavaFix
 187.166 +cons protected init(org.netbeans.api.java.source.CompilationInfo,com.sun.source.util.TreePath)
 187.167 + anno 1 org.netbeans.api.annotations.common.NonNull()
 187.168 + anno 2 org.netbeans.api.annotations.common.NonNull()
 187.169 +cons protected init(org.netbeans.api.java.source.TreePathHandle)
 187.170 + anno 1 org.netbeans.api.annotations.common.NonNull()
 187.171 +innr public final static TransformationContext
 187.172 +meth protected abstract java.lang.String getText()
 187.173 + anno 0 org.netbeans.api.annotations.common.NonNull()
 187.174 +meth protected abstract void performRewrite(org.netbeans.spi.java.hints.JavaFix$TransformationContext) throws java.lang.Exception
 187.175 + anno 1 org.netbeans.api.annotations.common.NonNull()
 187.176 +meth public final org.netbeans.spi.editor.hints.Fix toEditorFix()
 187.177 +supr java.lang.Object
 187.178 +hfds LOG,handle,options
 187.179 +
 187.180 +CLSS public final static org.netbeans.spi.java.hints.JavaFix$TransformationContext
 187.181 + outer org.netbeans.spi.java.hints.JavaFix
 187.182 +meth public com.sun.source.util.TreePath getPath()
 187.183 + anno 0 org.netbeans.api.annotations.common.NonNull()
 187.184 +meth public java.io.InputStream getResourceContent(org.openide.filesystems.FileObject) throws java.io.IOException
 187.185 + anno 0 org.netbeans.api.annotations.common.NonNull()
 187.186 + anno 1 org.netbeans.api.annotations.common.NonNull()
 187.187 +meth public java.io.OutputStream getResourceOutput(org.openide.filesystems.FileObject) throws java.io.IOException
 187.188 + anno 0 org.netbeans.api.annotations.common.NonNull()
 187.189 + anno 1 org.netbeans.api.annotations.common.NonNull()
 187.190 +meth public org.netbeans.api.java.source.WorkingCopy getWorkingCopy()
 187.191 + anno 0 org.netbeans.api.annotations.common.NonNull()
 187.192 +supr java.lang.Object
 187.193 +hfds canShowUI,fileChanges,path,resourceContentChanges,workingCopy
 187.194 +
 187.195 +CLSS public org.netbeans.spi.java.hints.JavaFixUtilities
 187.196 +cons public init()
 187.197 +meth public static boolean requiresParenthesis(com.sun.source.tree.Tree,com.sun.source.tree.Tree,com.sun.source.tree.Tree)
 187.198 +meth public static org.netbeans.spi.editor.hints.Fix removeFromParent(org.netbeans.spi.java.hints.HintContext,java.lang.String,com.sun.source.util.TreePath)
 187.199 +meth public static org.netbeans.spi.editor.hints.Fix rewriteFix(org.netbeans.spi.java.hints.HintContext,java.lang.String,com.sun.source.util.TreePath,java.lang.String)
 187.200 +supr java.lang.Object
 187.201 +hfds NUMBER_LITERAL_KINDS,OPERATOR_PRIORITIES,SPEC_VERSION
 187.202 +hcls JavaFixRealImpl,MoveFile,RemoveFromParent,ReplaceParameters
 187.203 +
 187.204 +CLSS public org.netbeans.spi.java.hints.MatcherUtilities
 187.205 +cons public init()
 187.206 +meth public static boolean matches(org.netbeans.spi.java.hints.HintContext,com.sun.source.util.TreePath,java.lang.String)
 187.207 + anno 1 org.netbeans.api.annotations.common.NonNull()
 187.208 + anno 2 org.netbeans.api.annotations.common.NonNull()
 187.209 + anno 3 org.netbeans.api.annotations.common.NonNull()
 187.210 +meth public static boolean matches(org.netbeans.spi.java.hints.HintContext,com.sun.source.util.TreePath,java.lang.String,boolean)
 187.211 + anno 1 org.netbeans.api.annotations.common.NonNull()
 187.212 + anno 2 org.netbeans.api.annotations.common.NonNull()
 187.213 + anno 3 org.netbeans.api.annotations.common.NonNull()
 187.214 +meth public static boolean matches(org.netbeans.spi.java.hints.HintContext,com.sun.source.util.TreePath,java.lang.String,java.util.Map<java.lang.String,com.sun.source.util.TreePath>,java.util.Map<java.lang.String,java.util.Collection<? extends com.sun.source.util.TreePath>>,java.util.Map<java.lang.String,java.lang.String>)
 187.215 + anno 1 org.netbeans.api.annotations.common.NonNull()
 187.216 + anno 2 org.netbeans.api.annotations.common.NonNull()
 187.217 + anno 3 org.netbeans.api.annotations.common.NonNull()
 187.218 +meth public static boolean matches(org.netbeans.spi.java.hints.HintContext,java.util.Collection<? extends com.sun.source.util.TreePath>,java.lang.String,java.util.Map<java.lang.String,com.sun.source.util.TreePath>,java.util.Map<java.lang.String,java.util.Collection<? extends com.sun.source.util.TreePath>>,java.util.Map<java.lang.String,java.lang.String>)
 187.219 + anno 1 org.netbeans.api.annotations.common.NonNull()
 187.220 + anno 2 org.netbeans.api.annotations.common.NonNull()
 187.221 + anno 3 org.netbeans.api.annotations.common.NonNull()
 187.222 +supr java.lang.Object
 187.223 +
 187.224 +CLSS public abstract interface !annotation org.netbeans.spi.java.hints.TriggerPattern
 187.225 + anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=SOURCE)
 187.226 + anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[METHOD])
 187.227 +intf java.lang.annotation.Annotation
 187.228 +meth public abstract !hasdefault org.netbeans.spi.java.hints.ConstraintVariableType[] constraints()
 187.229 +meth public abstract java.lang.String value()
 187.230 +
 187.231 +CLSS public abstract interface !annotation org.netbeans.spi.java.hints.TriggerPatterns
 187.232 + anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=SOURCE)
 187.233 + anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[METHOD])
 187.234 +intf java.lang.annotation.Annotation
 187.235 +meth public abstract org.netbeans.spi.java.hints.TriggerPattern[] value()
 187.236 +
 187.237 +CLSS public abstract interface !annotation org.netbeans.spi.java.hints.TriggerTreeKind
 187.238 + anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=SOURCE)
 187.239 + anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[METHOD])
 187.240 +intf java.lang.annotation.Annotation
 187.241 +meth public abstract com.sun.source.tree.Tree$Kind[] value()
 187.242 +
 187.243 +CLSS public abstract interface !annotation org.netbeans.spi.java.hints.UseOptions
 187.244 + anno 0 java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy value=SOURCE)
 187.245 + anno 0 java.lang.annotation.Target(java.lang.annotation.ElementType[] value=[METHOD])
 187.246 +intf java.lang.annotation.Annotation
 187.247 +meth public abstract java.lang.String[] value()
 187.248 +
 187.249 +CLSS public final org.netbeans.spi.java.hints.support.FixFactory
 187.250 +meth public final static org.netbeans.spi.editor.hints.Fix addModifiersFix(org.netbeans.api.java.source.CompilationInfo,com.sun.source.util.TreePath,java.util.Set<javax.lang.model.element.Modifier>,java.lang.String)
 187.251 +meth public final static org.netbeans.spi.editor.hints.Fix changeModifiersFix(org.netbeans.api.java.source.CompilationInfo,com.sun.source.util.TreePath,java.util.Set<javax.lang.model.element.Modifier>,java.util.Set<javax.lang.model.element.Modifier>,java.lang.String)
 187.252 +meth public final static org.netbeans.spi.editor.hints.Fix removeModifiersFix(org.netbeans.api.java.source.CompilationInfo,com.sun.source.util.TreePath,java.util.Set<javax.lang.model.element.Modifier>,java.lang.String)
 187.253 +supr java.lang.Object
 187.254 +hcls ChangeModifiersFixImpl
 187.255 +
 187.256 +CLSS public final org.netbeans.spi.java.hints.support.TransformationSupport
 187.257 +innr public abstract interface static Transformer
 187.258 +meth public java.util.Collection<? extends org.netbeans.api.java.source.ModificationResult> processAllProjects()
 187.259 + anno 0 org.netbeans.api.annotations.common.NonNull()
 187.260 +meth public org.netbeans.spi.java.hints.support.TransformationSupport setCancel(java.util.concurrent.atomic.AtomicBoolean)
 187.261 + anno 0 org.netbeans.api.annotations.common.NonNull()
 187.262 + anno 1 org.netbeans.api.annotations.common.NonNull()
 187.263 +meth public static org.netbeans.spi.java.hints.support.TransformationSupport create(java.lang.String)
 187.264 + anno 0 org.netbeans.api.annotations.common.NonNull()
 187.265 + anno 1 org.netbeans.api.annotations.common.NonNull()
 187.266 +meth public static org.netbeans.spi.java.hints.support.TransformationSupport create(java.lang.String,org.netbeans.spi.java.hints.support.TransformationSupport$Transformer)
 187.267 + anno 0 org.netbeans.api.annotations.common.NonNull()
 187.268 + anno 1 org.netbeans.api.annotations.common.NonNull()
 187.269 + anno 2 org.netbeans.api.annotations.common.NonNull()
 187.270 +meth public void transformTreePath(org.netbeans.api.java.source.WorkingCopy,com.sun.source.util.TreePath)
 187.271 + anno 1 org.netbeans.api.annotations.common.NonNull()
 187.272 + anno 2 org.netbeans.api.annotations.common.NonNull()
 187.273 +supr java.lang.Object
 187.274 +hfds cancel,jackpotPattern,transformer
 187.275 +
 187.276 +CLSS public abstract interface static org.netbeans.spi.java.hints.support.TransformationSupport$Transformer
 187.277 + outer org.netbeans.spi.java.hints.support.TransformationSupport
 187.278 +meth public abstract void transform(org.netbeans.api.java.source.WorkingCopy,org.netbeans.api.java.source.matching.Occurrence)
 187.279 +
   188.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   188.2 +++ b/sandbox/java.hints/spi.java.hints/nbproject/project.properties	Sun Oct 23 11:50:54 2016 +0200
   188.3 @@ -0,0 +1,7 @@
   188.4 +is.autoload=true
   188.5 +javac.source=1.7
   188.6 +javac.compilerargs=-Xlint -Xlint:-serial
   188.7 +spec.version.base=2.0.0
   188.8 +requires.nb.javac=true
   188.9 +javadoc.arch=${basedir}/arch.xml
  188.10 +javadoc.apichanges=${basedir}/apichanges.xml
   189.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   189.2 +++ b/sandbox/java.hints/spi.java.hints/nbproject/project.xml	Sun Oct 23 11:50:54 2016 +0200
   189.3 @@ -0,0 +1,480 @@
   189.4 +<?xml version="1.0" encoding="UTF-8"?>
   189.5 +<project xmlns="http://www.netbeans.org/ns/project/1">
   189.6 +    <type>org.netbeans.modules.apisupport.project</type>
   189.7 +    <configuration>
   189.8 +        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
   189.9 +            <code-name-base>org.netbeans.spi.java.hints</code-name-base>
  189.10 +            <suite-component/>
  189.11 +            <module-dependencies>
  189.12 +                <dependency>
  189.13 +                    <code-name-base>org.netbeans.api.annotations.common</code-name-base>
  189.14 +                    <build-prerequisite/>
  189.15 +                    <compile-dependency/>
  189.16 +                    <run-dependency>
  189.17 +                        <release-version>1</release-version>
  189.18 +                        <specification-version>1.4</specification-version>
  189.19 +                    </run-dependency>
  189.20 +                </dependency>
  189.21 +                <dependency>
  189.22 +                    <code-name-base>org.netbeans.api.java</code-name-base>
  189.23 +                    <build-prerequisite/>
  189.24 +                    <compile-dependency/>
  189.25 +                    <run-dependency>
  189.26 +                        <release-version>1</release-version>
  189.27 +                        <specification-version>1.18</specification-version>
  189.28 +                    </run-dependency>
  189.29 +                </dependency>
  189.30 +                <dependency>
  189.31 +                    <code-name-base>org.netbeans.api.java.classpath</code-name-base>
  189.32 +                    <build-prerequisite/>
  189.33 +                    <compile-dependency/>
  189.34 +                    <run-dependency>
  189.35 +                        <release-version>1</release-version>
  189.36 +                        <specification-version>1.24</specification-version>
  189.37 +                    </run-dependency>
  189.38 +                </dependency>
  189.39 +                <dependency>
  189.40 +                    <code-name-base>org.netbeans.api.progress</code-name-base>
  189.41 +                    <build-prerequisite/>
  189.42 +                    <compile-dependency/>
  189.43 +                    <run-dependency>
  189.44 +                        <release-version>1</release-version>
  189.45 +                        <specification-version>1.16</specification-version>
  189.46 +                    </run-dependency>
  189.47 +                </dependency>
  189.48 +                <dependency>
  189.49 +                    <code-name-base>org.netbeans.api.progress.nb</code-name-base>
  189.50 +                    <build-prerequisite/>
  189.51 +                    <compile-dependency/>
  189.52 +                    <run-dependency>
  189.53 +                        <specification-version>1.45</specification-version>
  189.54 +                    </run-dependency>
  189.55 +                </dependency>
  189.56 +                <dependency>
  189.57 +                    <code-name-base>org.netbeans.lib.nbjavac</code-name-base>
  189.58 +                    <build-prerequisite/>
  189.59 +                    <compile-dependency/>
  189.60 +                    <run-dependency>
  189.61 +                        <implementation-version/>
  189.62 +                    </run-dependency>
  189.63 +                </dependency>
  189.64 +                <dependency>
  189.65 +                    <code-name-base>org.netbeans.libs.javacapi</code-name-base>
  189.66 +                    <build-prerequisite/>
  189.67 +                    <compile-dependency/>
  189.68 +                    <run-dependency>
  189.69 +                        <specification-version>8.0</specification-version>
  189.70 +                    </run-dependency>
  189.71 +                </dependency>
  189.72 +                <dependency>
  189.73 +                    <code-name-base>org.netbeans.libs.javacimpl</code-name-base>
  189.74 +                    <build-prerequisite/>
  189.75 +                    <compile-dependency/>
  189.76 +                    <run-dependency>
  189.77 +                        <release-version>1</release-version>
  189.78 +                        <implementation-version/>
  189.79 +                    </run-dependency>
  189.80 +                </dependency>
  189.81 +                <dependency>
  189.82 +                    <code-name-base>org.netbeans.libs.lucene</code-name-base>
  189.83 +                    <build-prerequisite/>
  189.84 +                    <compile-dependency/>
  189.85 +                    <run-dependency>
  189.86 +                        <release-version>3</release-version>
  189.87 +                        <specification-version>3.0</specification-version>
  189.88 +                    </run-dependency>
  189.89 +                </dependency>
  189.90 +                <dependency>
  189.91 +                    <code-name-base>org.netbeans.modules.code.analysis</code-name-base>
  189.92 +                    <build-prerequisite/>
  189.93 +                    <compile-dependency/>
  189.94 +                    <run-dependency>
  189.95 +                        <release-version>0</release-version>
  189.96 +                        <specification-version>1.8</specification-version>
  189.97 +                    </run-dependency>
  189.98 +                </dependency>
  189.99 +                <dependency>
 189.100 +                    <code-name-base>org.netbeans.modules.editor</code-name-base>
 189.101 +                    <build-prerequisite/>
 189.102 +                    <compile-dependency/>
 189.103 +                    <run-dependency>
 189.104 +                        <release-version>3</release-version>
 189.105 +                        <specification-version>1.53</specification-version>
 189.106 +                    </run-dependency>
 189.107 +                </dependency>
 189.108 +                <dependency>
 189.109 +                    <code-name-base>org.netbeans.modules.editor.errorstripe.api</code-name-base>
 189.110 +                    <build-prerequisite/>
 189.111 +                    <compile-dependency/>
 189.112 +                    <run-dependency>
 189.113 +                        <release-version>1</release-version>
 189.114 +                        <specification-version>2.3</specification-version>
 189.115 +                    </run-dependency>
 189.116 +                </dependency>
 189.117 +                <dependency>
 189.118 +                    <code-name-base>org.netbeans.modules.editor.lib</code-name-base>
 189.119 +                    <build-prerequisite/>
 189.120 +                    <compile-dependency/>
 189.121 +                    <run-dependency>
 189.122 +                        <release-version>3</release-version>
 189.123 +                        <specification-version>3.1</specification-version>
 189.124 +                    </run-dependency>
 189.125 +                </dependency>
 189.126 +                <dependency>
 189.127 +                    <code-name-base>org.netbeans.modules.editor.lib2</code-name-base>
 189.128 +                    <build-prerequisite/>
 189.129 +                    <compile-dependency/>
 189.130 +                    <run-dependency>
 189.131 +                        <release-version>1</release-version>
 189.132 +                        <specification-version>1.8</specification-version>
 189.133 +                    </run-dependency>
 189.134 +                </dependency>
 189.135 +                <dependency>
 189.136 +                    <code-name-base>org.netbeans.modules.editor.mimelookup</code-name-base>
 189.137 +                    <build-prerequisite/>
 189.138 +                    <compile-dependency/>
 189.139 +                    <run-dependency>
 189.140 +                        <release-version>1</release-version>
 189.141 +                        <specification-version>1.15</specification-version>
 189.142 +                    </run-dependency>
 189.143 +                </dependency>
 189.144 +                <dependency>
 189.145 +                    <code-name-base>org.netbeans.modules.editor.settings</code-name-base>
 189.146 +                    <build-prerequisite/>
 189.147 +                    <compile-dependency/>
 189.148 +                    <run-dependency>
 189.149 +                        <release-version>1</release-version>
 189.150 +                        <specification-version>1.28</specification-version>
 189.151 +                    </run-dependency>
 189.152 +                </dependency>
 189.153 +                <dependency>
 189.154 +                    <code-name-base>org.netbeans.modules.editor.util</code-name-base>
 189.155 +                    <build-prerequisite/>
 189.156 +                    <compile-dependency/>
 189.157 +                    <run-dependency>
 189.158 +                        <release-version>1</release-version>
 189.159 +                        <specification-version>1.33</specification-version>
 189.160 +                    </run-dependency>
 189.161 +                </dependency>
 189.162 +                <dependency>
 189.163 +                    <code-name-base>org.netbeans.modules.java.lexer</code-name-base>
 189.164 +                    <build-prerequisite/>
 189.165 +                    <compile-dependency/>
 189.166 +                    <run-dependency>
 189.167 +                        <release-version>1</release-version>
 189.168 +                        <specification-version>1.0</specification-version>
 189.169 +                    </run-dependency>
 189.170 +                </dependency>
 189.171 +                <dependency>
 189.172 +                    <code-name-base>org.netbeans.modules.java.platform</code-name-base>
 189.173 +                    <build-prerequisite/>
 189.174 +                    <compile-dependency/>
 189.175 +                    <run-dependency>
 189.176 +                        <release-version>1</release-version>
 189.177 +                        <specification-version>1.16</specification-version>
 189.178 +                    </run-dependency>
 189.179 +                </dependency>
 189.180 +                <dependency>
 189.181 +                    <code-name-base>org.netbeans.modules.java.project</code-name-base>
 189.182 +                    <build-prerequisite/>
 189.183 +                    <compile-dependency/>
 189.184 +                    <run-dependency>
 189.185 +                        <release-version>1</release-version>
 189.186 +                        <specification-version>1.41</specification-version>
 189.187 +                    </run-dependency>
 189.188 +                </dependency>
 189.189 +                <dependency>
 189.190 +                    <code-name-base>org.netbeans.modules.java.source</code-name-base>
 189.191 +                    <build-prerequisite/>
 189.192 +                    <compile-dependency/>
 189.193 +                    <run-dependency>
 189.194 +                        <implementation-version/>
 189.195 +                    </run-dependency>
 189.196 +                </dependency>
 189.197 +                <dependency>
 189.198 +                    <code-name-base>org.netbeans.modules.java.source.base</code-name-base>
 189.199 +                    <build-prerequisite/>
 189.200 +                    <compile-dependency/>
 189.201 +                    <run-dependency>
 189.202 +                        <implementation-version/>
 189.203 +                    </run-dependency>
 189.204 +                </dependency>
 189.205 +                <dependency>
 189.206 +                    <code-name-base>org.netbeans.modules.lexer</code-name-base>
 189.207 +                    <build-prerequisite/>
 189.208 +                    <compile-dependency/>
 189.209 +                    <run-dependency>
 189.210 +                        <release-version>2</release-version>
 189.211 +                        <specification-version>1.25</specification-version>
 189.212 +                    </run-dependency>
 189.213 +                </dependency>
 189.214 +                <dependency>
 189.215 +                    <code-name-base>org.netbeans.modules.options.api</code-name-base>
 189.216 +                    <build-prerequisite/>
 189.217 +                    <compile-dependency/>
 189.218 +                    <run-dependency>
 189.219 +                        <release-version>1</release-version>
 189.220 +                        <specification-version>1.5</specification-version>
 189.221 +                    </run-dependency>
 189.222 +                </dependency>
 189.223 +                <dependency>
 189.224 +                    <code-name-base>org.netbeans.modules.options.editor</code-name-base>
 189.225 +                    <build-prerequisite/>
 189.226 +                    <compile-dependency/>
 189.227 +                    <run-dependency>
 189.228 +                        <release-version>1</release-version>
 189.229 +                        <specification-version>1.28</specification-version>
 189.230 +                    </run-dependency>
 189.231 +                </dependency>
 189.232 +                <dependency>
 189.233 +                    <code-name-base>org.netbeans.modules.parsing.api</code-name-base>
 189.234 +                    <build-prerequisite/>
 189.235 +                    <compile-dependency/>
 189.236 +                    <run-dependency>
 189.237 +                        <release-version>1</release-version>
 189.238 +                        <implementation-version/>
 189.239 +                    </run-dependency>
 189.240 +                </dependency>
 189.241 +                <dependency>
 189.242 +                    <code-name-base>org.netbeans.modules.projectapi</code-name-base>
 189.243 +                    <build-prerequisite/>
 189.244 +                    <compile-dependency/>
 189.245 +                    <run-dependency>
 189.246 +                        <release-version>1</release-version>
 189.247 +                        <specification-version>1.42</specification-version>
 189.248 +                    </run-dependency>
 189.249 +                </dependency>
 189.250 +                <dependency>
 189.251 +                    <code-name-base>org.netbeans.modules.queries</code-name-base>
 189.252 +                    <build-prerequisite/>
 189.253 +                    <compile-dependency/>
 189.254 +                    <run-dependency>
 189.255 +                        <release-version>1</release-version>
 189.256 +                        <specification-version>1.18</specification-version>
 189.257 +                    </run-dependency>
 189.258 +                </dependency>
 189.259 +                <dependency>
 189.260 +                    <code-name-base>org.netbeans.modules.refactoring.api</code-name-base>
 189.261 +                    <build-prerequisite/>
 189.262 +                    <compile-dependency/>
 189.263 +                    <run-dependency>
 189.264 +                        <specification-version>1.23</specification-version>
 189.265 +                    </run-dependency>
 189.266 +                </dependency>
 189.267 +                <dependency>
 189.268 +                    <code-name-base>org.netbeans.spi.editor.hints</code-name-base>
 189.269 +                    <build-prerequisite/>
 189.270 +                    <compile-dependency/>
 189.271 +                    <run-dependency>
 189.272 +                        <release-version>0-1</release-version>
 189.273 +                        <specification-version>1.22</specification-version>
 189.274 +                    </run-dependency>
 189.275 +                </dependency>
 189.276 +                <dependency>
 189.277 +                    <code-name-base>org.openide.actions</code-name-base>
 189.278 +                    <build-prerequisite/>
 189.279 +                    <compile-dependency/>
 189.280 +                    <run-dependency>
 189.281 +                        <specification-version>6.15</specification-version>
 189.282 +                    </run-dependency>
 189.283 +                </dependency>
 189.284 +                <dependency>
 189.285 +                    <code-name-base>org.openide.awt</code-name-base>
 189.286 +                    <build-prerequisite/>
 189.287 +                    <compile-dependency/>
 189.288 +                    <run-dependency>
 189.289 +                        <specification-version>6.10</specification-version>
 189.290 +                    </run-dependency>
 189.291 +                </dependency>
 189.292 +                <dependency>
 189.293 +                    <code-name-base>org.openide.dialogs</code-name-base>
 189.294 +                    <build-prerequisite/>
 189.295 +                    <compile-dependency/>
 189.296 +                    <run-dependency>
 189.297 +                        <specification-version>7.0</specification-version>
 189.298 +                    </run-dependency>
 189.299 +                </dependency>
 189.300 +                <dependency>
 189.301 +                    <code-name-base>org.openide.explorer</code-name-base>
 189.302 +                    <build-prerequisite/>
 189.303 +                    <compile-dependency/>
 189.304 +                    <run-dependency>
 189.305 +                        <specification-version>6.22</specification-version>
 189.306 +                    </run-dependency>
 189.307 +                </dependency>
 189.308 +                <dependency>
 189.309 +                    <code-name-base>org.openide.filesystems</code-name-base>
 189.310 +                    <build-prerequisite/>
 189.311 +                    <compile-dependency/>
 189.312 +                    <run-dependency>
 189.313 +                        <specification-version>7.19</specification-version>
 189.314 +                    </run-dependency>
 189.315 +                </dependency>
 189.316 +                <dependency>
 189.317 +                    <code-name-base>org.openide.loaders</code-name-base>
 189.318 +                    <build-prerequisite/>
 189.319 +                    <compile-dependency/>
 189.320 +                    <run-dependency/>
 189.321 +                </dependency>
 189.322 +                <dependency>
 189.323 +                    <code-name-base>org.openide.modules</code-name-base>
 189.324 +                    <build-prerequisite/>
 189.325 +                    <compile-dependency/>
 189.326 +                    <run-dependency>
 189.327 +                        <specification-version>7.3</specification-version>
 189.328 +                    </run-dependency>
 189.329 +                </dependency>
 189.330 +                <dependency>
 189.331 +                    <code-name-base>org.openide.nodes</code-name-base>
 189.332 +                    <build-prerequisite/>
 189.333 +                    <compile-dependency/>
 189.334 +                    <run-dependency>
 189.335 +                        <specification-version>6.2</specification-version>
 189.336 +                    </run-dependency>
 189.337 +                </dependency>
 189.338 +                <dependency>
 189.339 +                    <code-name-base>org.openide.text</code-name-base>
 189.340 +                    <build-prerequisite/>
 189.341 +                    <compile-dependency/>
 189.342 +                    <run-dependency>
 189.343 +                        <specification-version>6.16</specification-version>
 189.344 +                    </run-dependency>
 189.345 +                </dependency>
 189.346 +                <dependency>
 189.347 +                    <code-name-base>org.openide.util</code-name-base>
 189.348 +                    <build-prerequisite/>
 189.349 +                    <compile-dependency/>
 189.350 +                    <run-dependency>
 189.351 +                        <specification-version>8.32</specification-version>
 189.352 +                    </run-dependency>
 189.353 +                </dependency>
 189.354 +                <dependency>
 189.355 +                    <code-name-base>org.openide.util.lookup</code-name-base>
 189.356 +                    <build-prerequisite/>
 189.357 +                    <compile-dependency/>
 189.358 +                    <run-dependency>
 189.359 +                        <specification-version>8.0</specification-version>
 189.360 +                    </run-dependency>
 189.361 +                </dependency>
 189.362 +                <dependency>
 189.363 +                    <code-name-base>org.openide.windows</code-name-base>
 189.364 +                    <build-prerequisite/>
 189.365 +                    <compile-dependency/>
 189.366 +                    <run-dependency>
 189.367 +                        <specification-version>6.16</specification-version>
 189.368 +                    </run-dependency>
 189.369 +                </dependency>
 189.370 +            </module-dependencies>
 189.371 +            <test-dependencies>
 189.372 +                <test-type>
 189.373 +                    <name>unit</name>
 189.374 +                    <test-dependency>
 189.375 +                        <code-name-base>org.netbeans.core</code-name-base>
 189.376 +                        <compile-dependency/>
 189.377 +                    </test-dependency>
 189.378 +                    <test-dependency>
 189.379 +                        <code-name-base>org.netbeans.insane</code-name-base>
 189.380 +                        <compile-dependency/>
 189.381 +                    </test-dependency>
 189.382 +                    <test-dependency>
 189.383 +                        <code-name-base>org.netbeans.libs.freemarker</code-name-base>
 189.384 +                        <recursive/>
 189.385 +                        <compile-dependency/>
 189.386 +                    </test-dependency>
 189.387 +                    <test-dependency>
 189.388 +                        <code-name-base>org.netbeans.libs.junit4</code-name-base>
 189.389 +                        <compile-dependency/>
 189.390 +                    </test-dependency>
 189.391 +                    <test-dependency>
 189.392 +                        <code-name-base>org.netbeans.modules.classfile</code-name-base>
 189.393 +                    </test-dependency>
 189.394 +                    <test-dependency>
 189.395 +                        <code-name-base>org.netbeans.modules.defaults</code-name-base>
 189.396 +                    </test-dependency>
 189.397 +                    <test-dependency>
 189.398 +                        <code-name-base>org.netbeans.modules.editor</code-name-base>
 189.399 +                        <test/>
 189.400 +                    </test-dependency>
 189.401 +                    <test-dependency>
 189.402 +                        <code-name-base>org.netbeans.modules.editor.mimelookup</code-name-base>
 189.403 +                        <compile-dependency/>
 189.404 +                        <test/>
 189.405 +                    </test-dependency>
 189.406 +                    <test-dependency>
 189.407 +                        <code-name-base>org.netbeans.modules.editor.settings</code-name-base>
 189.408 +                    </test-dependency>
 189.409 +                    <test-dependency>
 189.410 +                        <code-name-base>org.netbeans.modules.editor.settings.storage</code-name-base>
 189.411 +                    </test-dependency>
 189.412 +                    <test-dependency>
 189.413 +                        <code-name-base>org.netbeans.modules.editor.util</code-name-base>
 189.414 +                    </test-dependency>
 189.415 +                    <test-dependency>
 189.416 +                        <code-name-base>org.netbeans.modules.jackpot30.test.borrowed</code-name-base>
 189.417 +                        <compile-dependency/>
 189.418 +                    </test-dependency>
 189.419 +                    <test-dependency>
 189.420 +                        <code-name-base>org.netbeans.modules.java.editor</code-name-base>
 189.421 +                        <recursive/>
 189.422 +                        <compile-dependency/>
 189.423 +                    </test-dependency>
 189.424 +                    <test-dependency>
 189.425 +                        <code-name-base>org.netbeans.modules.java.hints</code-name-base>
 189.426 +                        <compile-dependency/>
 189.427 +                    </test-dependency>
 189.428 +                    <test-dependency>
 189.429 +                        <code-name-base>org.netbeans.modules.java.hints.declarative</code-name-base>
 189.430 +                        <compile-dependency/>
 189.431 +                    </test-dependency>
 189.432 +                    <test-dependency>
 189.433 +                        <code-name-base>org.netbeans.modules.java.source</code-name-base>
 189.434 +                        <compile-dependency/>
 189.435 +                        <test/>
 189.436 +                    </test-dependency>
 189.437 +                    <test-dependency>
 189.438 +                        <code-name-base>org.netbeans.modules.masterfs</code-name-base>
 189.439 +                    </test-dependency>
 189.440 +                    <test-dependency>
 189.441 +                        <code-name-base>org.netbeans.modules.nbjunit</code-name-base>
 189.442 +                        <compile-dependency/>
 189.443 +                    </test-dependency>
 189.444 +                    <test-dependency>
 189.445 +                        <code-name-base>org.netbeans.modules.parsing.api</code-name-base>
 189.446 +                        <compile-dependency/>
 189.447 +                        <test/>
 189.448 +                    </test-dependency>
 189.449 +                    <test-dependency>
 189.450 +                        <code-name-base>org.netbeans.modules.parsing.nb</code-name-base>
 189.451 +                        <compile-dependency/>
 189.452 +                    </test-dependency>
 189.453 +                    <test-dependency>
 189.454 +                        <code-name-base>org.netbeans.modules.progress.ui</code-name-base>
 189.455 +                    </test-dependency>
 189.456 +                    <test-dependency>
 189.457 +                        <code-name-base>org.netbeans.modules.projectapi.nb</code-name-base>
 189.458 +                        <compile-dependency/>
 189.459 +                    </test-dependency>
 189.460 +                    <test-dependency>
 189.461 +                        <code-name-base>org.netbeans.modules.projectui</code-name-base>
 189.462 +                    </test-dependency>
 189.463 +                    <test-dependency>
 189.464 +                        <code-name-base>org.openide.util</code-name-base>
 189.465 +                        <compile-dependency/>
 189.466 +                        <test/>
 189.467 +                    </test-dependency>
 189.468 +                    <test-dependency>
 189.469 +                        <code-name-base>org.openide.util.lookup</code-name-base>
 189.470 +                        <compile-dependency/>
 189.471 +                        <test/>
 189.472 +                    </test-dependency>
 189.473 +                </test-type>
 189.474 +            </test-dependencies>
 189.475 +            <public-packages>
 189.476 +                <package>org.netbeans.spi.java.hints</package>
 189.477 +                <package>org.netbeans.spi.java.hints.annotations</package>
 189.478 +                <package>org.netbeans.spi.java.hints.matching</package>
 189.479 +                <package>org.netbeans.spi.java.hints.support</package>
 189.480 +            </public-packages>
 189.481 +        </data>
 189.482 +    </configuration>
 189.483 +</project>
   190.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   190.2 +++ b/sandbox/java.hints/spi.java.hints/nbproject/suite.properties	Sun Oct 23 11:50:54 2016 +0200
   190.3 @@ -0,0 +1,1 @@
   190.4 +suite.dir=${basedir}/..
   191.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   191.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/jackpot/spi/Bundle.properties	Sun Oct 23 11:50:54 2016 +0200
   191.3 @@ -0,0 +1,42 @@
   191.4 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   191.5 +#
   191.6 +# Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
   191.7 +#
   191.8 +# Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   191.9 +# Other names may be trademarks of their respective owners.
  191.10 +#
  191.11 +# The contents of this file are subject to the terms of either the GNU
  191.12 +# General Public License Version 2 only ("GPL") or the Common
  191.13 +# Development and Distribution License("CDDL") (collectively, the
  191.14 +# "License"). You may not use this file except in compliance with the
  191.15 +# License. You can obtain a copy of the License at
  191.16 +# http://www.netbeans.org/cddl-gplv2.html
  191.17 +# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  191.18 +# specific language governing permissions and limitations under the
  191.19 +# License.  When distributing the software, include this License Header
  191.20 +# Notice in each file and include the License file at
  191.21 +# nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  191.22 +# particular file as subject to the "Classpath" exception as provided
  191.23 +# by Oracle in the GPL Version 2 section of the License file that
  191.24 +# accompanied this code. If applicable, add the following below the
  191.25 +# License Header, with the fields enclosed by brackets [] replaced by
  191.26 +# your own identifying information:
  191.27 +# "Portions Copyrighted [year] [name of copyright owner]"
  191.28 +#
  191.29 +# Contributor(s):
  191.30 +#
  191.31 +# The Original Software is NetBeans. The Initial Developer of the Original
  191.32 +# Software is Sun Microsystems, Inc. Portions Copyright 2008-2009 Sun
  191.33 +# Microsystems, Inc. All Rights Reserved.
  191.34 +#
  191.35 +# If you wish your version of this file to be governed by only the CDDL
  191.36 +# or only the GPL Version 2, indicate your decision by adding
  191.37 +# "[Contributor] elects to include this software in this distribution
  191.38 +# under the [CDDL or GPL Version 2] license." If you do not indicate a
  191.39 +# single choice of license, a recipient has the option to distribute
  191.40 +# your version of this file under either the CDDL, the GPL Version 2 or
  191.41 +# to extend the choice of license to its licensees as provided above.
  191.42 +# However, if you add GPL Version 2 code and therefore, elected the GPL
  191.43 +# Version 2 license, then the option applies only if the new code is
  191.44 +# made subject to such option by the copyright holder.
  191.45 +LBL_UpdateDependencyQuestion=Update dependency on module {0} to specification version {1}?
  191.46 \ No newline at end of file
   192.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   192.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/jackpot/spi/HintsRunner.java	Sun Oct 23 11:50:54 2016 +0200
   192.3 @@ -0,0 +1,69 @@
   192.4 +/*
   192.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   192.6 + *
   192.7 + * Copyright 2009-2010 Oracle and/or its affiliates. All rights reserved.
   192.8 + *
   192.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  192.10 + * Other names may be trademarks of their respective owners.
  192.11 + *
  192.12 + * The contents of this file are subject to the terms of either the GNU
  192.13 + * General Public License Version 2 only ("GPL") or the Common
  192.14 + * Development and Distribution License("CDDL") (collectively, the
  192.15 + * "License"). You may not use this file except in compliance with the
  192.16 + * License. You can obtain a copy of the License at
  192.17 + * http://www.netbeans.org/cddl-gplv2.html
  192.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  192.19 + * specific language governing permissions and limitations under the
  192.20 + * License.  When distributing the software, include this License Header
  192.21 + * Notice in each file and include the License file at
  192.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  192.23 + * particular file as subject to the "Classpath" exception as provided
  192.24 + * by Oracle in the GPL Version 2 section of the License file that
  192.25 + * accompanied this code. If applicable, add the following below the
  192.26 + * License Header, with the fields enclosed by brackets [] replaced by
  192.27 + * your own identifying information:
  192.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  192.29 + *
  192.30 + * If you wish your version of this file to be governed by only the CDDL
  192.31 + * or only the GPL Version 2, indicate your decision by adding
  192.32 + * "[Contributor] elects to include this software in this distribution
  192.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  192.34 + * single choice of license, a recipient has the option to distribute
  192.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  192.36 + * to extend the choice of license to its licensees as provided above.
  192.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  192.38 + * Version 2 license, then the option applies only if the new code is
  192.39 + * made subject to such option by the copyright holder.
  192.40 + *
  192.41 + * Contributor(s):
  192.42 + *
  192.43 + * Portions Copyrighted 2009-2010 Sun Microsystems, Inc.
  192.44 + */
  192.45 +
  192.46 +package org.netbeans.modules.java.hints.jackpot.spi;
  192.47 +
  192.48 +import org.netbeans.modules.java.hints.providers.spi.HintDescription;
  192.49 +import com.sun.source.util.TreePath;
  192.50 +import java.util.LinkedList;
  192.51 +import java.util.List;
  192.52 +import java.util.Map;
  192.53 +import java.util.concurrent.atomic.AtomicBoolean;
  192.54 +import org.netbeans.api.annotations.common.CheckForNull;
  192.55 +import org.netbeans.api.java.source.CompilationInfo;
  192.56 +import org.netbeans.modules.java.hints.spiimpl.MessageImpl;
  192.57 +import org.netbeans.modules.java.hints.spiimpl.hints.HintsInvoker;
  192.58 +import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings;
  192.59 +import org.netbeans.spi.editor.hints.ErrorDescription;
  192.60 +
  192.61 +/**XXX: probably unused
  192.62 + *
  192.63 + * @author lahvac
  192.64 + */
  192.65 +public class HintsRunner {
  192.66 +
  192.67 +    @CheckForNull
  192.68 +    public static Map<HintDescription, List<ErrorDescription>> computeErrors(CompilationInfo info, Iterable<? extends HintDescription> hints, AtomicBoolean cancel) {
  192.69 +        return new HintsInvoker(HintsSettings.getSettingsFor(info.getFileObject()), cancel).computeHints(info, new TreePath(info.getCompilationUnit()), hints, new LinkedList<MessageImpl>());
  192.70 +    }
  192.71 +
  192.72 +}
   193.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   193.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/jackpot/spi/PatternConvertor.java	Sun Oct 23 11:50:54 2016 +0200
   193.3 @@ -0,0 +1,113 @@
   193.4 +/*
   193.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   193.6 + *
   193.7 + * Copyright 2009-2011 Sun Microsystems, Inc. All rights reserved.
   193.8 + *
   193.9 + * The contents of this file are subject to the terms of either the GNU
  193.10 + * General Public License Version 2 only ("GPL") or the Common
  193.11 + * Development and Distribution License("CDDL") (collectively, the
  193.12 + * "License"). You may not use this file except in compliance with the
  193.13 + * License. You can obtain a copy of the License at
  193.14 + * http://www.netbeans.org/cddl-gplv2.html
  193.15 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  193.16 + * specific language governing permissions and limitations under the
  193.17 + * License.  When distributing the software, include this License Header
  193.18 + * Notice in each file and include the License file at
  193.19 + * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
  193.20 + * particular file as subject to the "Classpath" exception as provided
  193.21 + * by Sun in the GPL Version 2 section of the License file that
  193.22 + * accompanied this code. If applicable, add the following below the
  193.23 + * License Header, with the fields enclosed by brackets [] replaced by
  193.24 + * your own identifying information:
  193.25 + * "Portions Copyrighted [year] [name of copyright owner]"
  193.26 + *
  193.27 + * If you wish your version of this file to be governed by only the CDDL
  193.28 + * or only the GPL Version 2, indicate your decision by adding
  193.29 + * "[Contributor] elects to include this software in this distribution
  193.30 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  193.31 + * single choice of license, a recipient has the option to distribute
  193.32 + * your version of this file under either the CDDL, the GPL Version 2 or
  193.33 + * to extend the choice of license to its licensees as provided above.
  193.34 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  193.35 + * Version 2 license, then the option applies only if the new code is
  193.36 + * made subject to such option by the copyright holder.
  193.37 + *
  193.38 + * Contributor(s):
  193.39 + *
  193.40 + * Portions Copyrighted 2009-2011 Sun Microsystems, Inc.
  193.41 + */
  193.42 +
  193.43 +package org.netbeans.modules.java.hints.jackpot.spi;
  193.44 +
  193.45 +import org.netbeans.modules.java.hints.providers.spi.HintDescriptionFactory;
  193.46 +import org.netbeans.spi.java.hints.HintContext;
  193.47 +import java.util.ArrayList;
  193.48 +import java.util.Collection;
  193.49 +import java.util.Collections;
  193.50 +import org.netbeans.api.annotations.common.CheckForNull;
  193.51 +import org.netbeans.api.annotations.common.NonNull;
  193.52 +import org.netbeans.modules.java.hints.providers.spi.HintDescription.Worker;
  193.53 +import org.netbeans.modules.java.hints.providers.spi.Trigger.PatternDescription;
  193.54 +import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
  193.55 +import org.netbeans.spi.editor.hints.ErrorDescription;
  193.56 +import org.netbeans.modules.java.hints.providers.spi.HintDescription;
  193.57 +import org.openide.util.Lookup;
  193.58 +
  193.59 +/**XXX: big hack?
  193.60 + *
  193.61 + * @author lahvac
  193.62 + */
  193.63 +public abstract class PatternConvertor {
  193.64 +
  193.65 +    protected abstract @CheckForNull Iterable<? extends HintDescription> parseString(@NonNull String code);
  193.66 +
  193.67 +    public static @CheckForNull Iterable<? extends HintDescription> create(@NonNull String code) {
  193.68 +        Collection<String> patterns = new ArrayList<String>();
  193.69 +        
  193.70 +        //XXX:
  193.71 +        if (code.contains(";;")) {
  193.72 +            PatternConvertor c = Lookup.getDefault().lookup(PatternConvertor.class);
  193.73 +
  193.74 +            if (c != null) {
  193.75 +                return c.parseString(code);
  193.76 +            }
  193.77 +
  193.78 +            for (String s : code.split(";;")) {
  193.79 +                s = s.trim();
  193.80 +                if (s.isEmpty()) {
  193.81 +                    continue;
  193.82 +                }
  193.83 +                
  193.84 +                patterns.add(s);
  193.85 +            }
  193.86 +        } else {
  193.87 +            patterns.add(code);
  193.88 +        }
  193.89 +
  193.90 +        Collection<HintDescription> result = new ArrayList<HintDescription>(patterns.size());
  193.91 +
  193.92 +        for (String pattern : patterns) {
  193.93 +            PatternDescription pd = PatternDescription.create(pattern, Collections.<String, String>emptyMap());
  193.94 +
  193.95 +            HintDescription desc = HintDescriptionFactory.create()
  193.96 +    //                                                     .setDisplayName("Pattern Matches")
  193.97 +                                                         .setTrigger(pd)
  193.98 +                                                         .setWorker(new WorkerImpl())
  193.99 +                                                         .produce();
 193.100 +            
 193.101 +            result.add(desc);
 193.102 +        }
 193.103 +
 193.104 +        return result;
 193.105 +    }
 193.106 +
 193.107 +    private static final class WorkerImpl implements Worker {
 193.108 +
 193.109 +        public Collection<? extends ErrorDescription> createErrors(HintContext ctx) {
 193.110 +            ErrorDescription ed = ErrorDescriptionFactory.forTree(ctx, ctx.getPath(), "Found pattern occurrence");
 193.111 +
 193.112 +            return Collections.singleton(ed);
 193.113 +        }
 193.114 +        
 193.115 +    }
 193.116 +}
   194.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   194.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/jackpot/spi/ProjectDependencyUpgrader.java	Sun Oct 23 11:50:54 2016 +0200
   194.3 @@ -0,0 +1,64 @@
   194.4 +/*
   194.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   194.6 + *
   194.7 + * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
   194.8 + *
   194.9 + * The contents of this file are subject to the terms of either the GNU
  194.10 + * General Public License Version 2 only ("GPL") or the Common
  194.11 + * Development and Distribution License("CDDL") (collectively, the
  194.12 + * "License"). You may not use this file except in compliance with the
  194.13 + * License. You can obtain a copy of the License at
  194.14 + * http://www.netbeans.org/cddl-gplv2.html
  194.15 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  194.16 + * specific language governing permissions and limitations under the
  194.17 + * License.  When distributing the software, include this License Header
  194.18 + * Notice in each file and include the License file at
  194.19 + * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
  194.20 + * particular file as subject to the "Classpath" exception as provided
  194.21 + * by Sun in the GPL Version 2 section of the License file that
  194.22 + * accompanied this code. If applicable, add the following below the
  194.23 + * License Header, with the fields enclosed by brackets [] replaced by
  194.24 + * your own identifying information:
  194.25 + * "Portions Copyrighted [year] [name of copyright owner]"
  194.26 + *
  194.27 + * If you wish your version of this file to be governed by only the CDDL
  194.28 + * or only the GPL Version 2, indicate your decision by adding
  194.29 + * "[Contributor] elects to include this software in this distribution
  194.30 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  194.31 + * single choice of license, a recipient has the option to distribute
  194.32 + * your version of this file under either the CDDL, the GPL Version 2 or
  194.33 + * to extend the choice of license to its licensees as provided above.
  194.34 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  194.35 + * Version 2 license, then the option applies only if the new code is
  194.36 + * made subject to such option by the copyright holder.
  194.37 + *
  194.38 + * Contributor(s):
  194.39 + *
  194.40 + * Portions Copyrighted 2010 Sun Microsystems, Inc.
  194.41 + */
  194.42 +package org.netbeans.modules.java.hints.jackpot.spi;
  194.43 +
  194.44 +import org.netbeans.api.project.Project;
  194.45 +import org.openide.DialogDisplayer;
  194.46 +import org.openide.NotifyDescriptor;
  194.47 +import org.openide.filesystems.FileObject;
  194.48 +import org.openide.modules.SpecificationVersion;
  194.49 +
  194.50 +/**
  194.51 + *
  194.52 + * @author lahvac
  194.53 + */
  194.54 +public abstract class ProjectDependencyUpgrader {
  194.55 +
  194.56 +    public abstract boolean ensureDependency(Project p, FileObject dep, SpecificationVersion spec, boolean canShowUI);
  194.57 +    public abstract boolean ensureDependency(Project p, String specification, boolean b);
  194.58 +
  194.59 +    protected final boolean showDependencyUpgradeDialog(Project p, String dep, SpecificationVersion currentDependency, SpecificationVersion spec, boolean newDepenency, boolean canShowUI) {
  194.60 +        if (!canShowUI) return true;
  194.61 +        
  194.62 +        NotifyDescriptor nd = new NotifyDescriptor.Confirmation("New version: " + spec, "Update spec version.", NotifyDescriptor.YES_NO_OPTION);
  194.63 +
  194.64 +        return DialogDisplayer.getDefault().notify(nd) == NotifyDescriptor.YES_OPTION;
  194.65 +    }
  194.66 +
  194.67 +}
   195.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   195.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/code/CodeHintProviderImpl.java	Sun Oct 23 11:50:54 2016 +0200
   195.3 @@ -0,0 +1,475 @@
   195.4 +/*
   195.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   195.6 + *
   195.7 + * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
   195.8 + *
   195.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  195.10 + * Other names may be trademarks of their respective owners.
  195.11 + *
  195.12 + * The contents of this file are subject to the terms of either the GNU
  195.13 + * General Public License Version 2 only ("GPL") or the Common
  195.14 + * Development and Distribution License("CDDL") (collectively, the
  195.15 + * "License"). You may not use this file except in compliance with the
  195.16 + * License. You can obtain a copy of the License at
  195.17 + * http://www.netbeans.org/cddl-gplv2.html
  195.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  195.19 + * specific language governing permissions and limitations under the
  195.20 + * License.  When distributing the software, include this License Header
  195.21 + * Notice in each file and include the License file at
  195.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  195.23 + * particular file as subject to the "Classpath" exception as provided
  195.24 + * by Oracle in the GPL Version 2 section of the License file that
  195.25 + * accompanied this code. If applicable, add the following below the
  195.26 + * License Header, with the fields enclosed by brackets [] replaced by
  195.27 + * your own identifying information:
  195.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  195.29 + *
  195.30 + * If you wish your version of this file to be governed by only the CDDL
  195.31 + * or only the GPL Version 2, indicate your decision by adding
  195.32 + * "[Contributor] elects to include this software in this distribution
  195.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  195.34 + * single choice of license, a recipient has the option to distribute
  195.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  195.36 + * to extend the choice of license to its licensees as provided above.
  195.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  195.38 + * Version 2 license, then the option applies only if the new code is
  195.39 + * made subject to such option by the copyright holder.
  195.40 + *
  195.41 + * Contributor(s):
  195.42 + *
  195.43 + * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
  195.44 + */
  195.45 +
  195.46 +package org.netbeans.modules.java.hints.providers.code;
  195.47 +
  195.48 +import com.sun.source.tree.Tree.Kind;
  195.49 +import java.lang.annotation.Annotation;
  195.50 +import java.lang.reflect.InvocationTargetException;
  195.51 +import java.lang.reflect.Method;
  195.52 +import java.util.ArrayList;
  195.53 +import java.util.Arrays;
  195.54 +import java.util.Collection;
  195.55 +import java.util.Collections;
  195.56 +import java.util.EnumSet;
  195.57 +import java.util.HashMap;
  195.58 +import java.util.HashSet;
  195.59 +import java.util.LinkedList;
  195.60 +import java.util.List;
  195.61 +import java.util.Map;
  195.62 +import java.util.Set;
  195.63 +import java.util.concurrent.atomic.AtomicReference;
  195.64 +import java.util.logging.Level;
  195.65 +import java.util.logging.Logger;
  195.66 +import java.util.prefs.Preferences;
  195.67 +import javax.swing.JComponent;
  195.68 +import javax.swing.JPanel;
  195.69 +import org.netbeans.modules.java.hints.providers.code.FSWrapper.ClassWrapper;
  195.70 +import org.netbeans.modules.java.hints.providers.code.FSWrapper.FieldWrapper;
  195.71 +import org.netbeans.modules.java.hints.providers.code.FSWrapper.MethodWrapper;
  195.72 +import org.netbeans.modules.java.hints.providers.code.ReflectiveCustomizerProvider.OptionDescriptor;
  195.73 +import org.netbeans.spi.java.hints.CustomizerProvider;
  195.74 +import org.netbeans.modules.java.hints.providers.spi.HintDescription;
  195.75 +import org.netbeans.modules.java.hints.providers.spi.HintDescription.Worker;
  195.76 +import org.netbeans.modules.java.hints.providers.spi.HintDescriptionFactory;
  195.77 +import org.netbeans.modules.java.hints.providers.spi.HintMetadata;
  195.78 +import org.netbeans.modules.java.hints.providers.spi.HintMetadata.Options;
  195.79 +import org.netbeans.modules.java.hints.providers.spi.HintProvider;
  195.80 +import org.netbeans.modules.java.hints.providers.spi.Trigger.DecisionTrigger;
  195.81 +import org.netbeans.modules.java.hints.providers.spi.Trigger.Kinds;
  195.82 +import org.netbeans.modules.java.hints.providers.spi.Trigger.PatternDescription;
  195.83 +import org.netbeans.spi.editor.hints.ErrorDescription;
  195.84 +import org.netbeans.spi.editor.hints.Severity;
  195.85 +import org.netbeans.spi.java.hints.BooleanOption;
  195.86 +import org.netbeans.spi.java.hints.ConstraintVariableType;
  195.87 +import org.netbeans.spi.java.hints.Hint;
  195.88 +import org.netbeans.spi.java.hints.IntegerOption;
  195.89 +import org.netbeans.spi.java.hints.TriggerDecision;
  195.90 +import org.netbeans.spi.java.hints.TriggerPattern;
  195.91 +import org.netbeans.spi.java.hints.TriggerPatterns;
  195.92 +import org.netbeans.spi.java.hints.TriggerTreeKind;
  195.93 +import org.netbeans.spi.java.hints.UseOptions;
  195.94 +import org.openide.util.Exceptions;
  195.95 +import org.openide.util.Lookup;
  195.96 +import org.openide.util.NbCollections;
  195.97 +import org.openide.util.lookup.ServiceProvider;
  195.98 +
  195.99 +/**
 195.100 + *
 195.101 + * @author lahvac
 195.102 + */
 195.103 +@ServiceProvider(service=HintProvider.class)
 195.104 +public class CodeHintProviderImpl implements HintProvider {
 195.105 +
 195.106 +    private static final Logger LOG = Logger.getLogger(WorkerImpl.class.getName());
 195.107 +    
 195.108 +    public Map<HintMetadata, ? extends Collection<? extends HintDescription>> computeHints() {
 195.109 +        return computeHints(findLoader(), "META-INF/nb-hints/hints");
 195.110 +    }
 195.111 +
 195.112 +    private Map<HintMetadata, ? extends Collection<? extends HintDescription>> computeHints(ClassLoader l, String path) {
 195.113 +        Map<HintMetadata, Collection<HintDescription>> result = new HashMap<HintMetadata, Collection<HintDescription>>();
 195.114 +        
 195.115 +        for (ClassWrapper c : FSWrapper.listClasses()) {
 195.116 +            try {
 195.117 +                processClass(c, result);
 195.118 +            } catch (ThreadDeath td) {
 195.119 +                throw td;
 195.120 +            } catch (Throwable t) {
 195.121 +                Exceptions.printStackTrace(t);
 195.122 +            }
 195.123 +        }
 195.124 +
 195.125 +        return result;
 195.126 +    }
 195.127 +
 195.128 +    static ClassLoader findLoader() {
 195.129 +        ClassLoader l = Lookup.getDefault().lookup(ClassLoader.class);
 195.130 +
 195.131 +        if (l == null) {
 195.132 +            return CodeHintProviderImpl.class.getClassLoader();
 195.133 +        }
 195.134 +
 195.135 +        return l;
 195.136 +    }
 195.137 +
 195.138 +    public static void processClass(ClassWrapper clazz, Map<HintMetadata, Collection<HintDescription>> result) throws SecurityException {
 195.139 +        Hint metadata = clazz.getAnnotation(Hint.class);
 195.140 +        HintMetadata hm;
 195.141 +        
 195.142 +        if (metadata != null) {
 195.143 +            String id = metadata.id();
 195.144 +
 195.145 +            if (id == null || id.length() == 0) {
 195.146 +                id = clazz.getName();
 195.147 +            }
 195.148 +            hm = fromAnnotation(id, clazz, null, metadata);
 195.149 +        } else {
 195.150 +            hm = null;
 195.151 +        }
 195.152 +        
 195.153 +        for (MethodWrapper m : clazz.getMethods()) {
 195.154 +            Hint localMetadataAnnotation = m.getAnnotation(Hint.class);
 195.155 +            HintMetadata localMetadata;
 195.156 +
 195.157 +            if (localMetadataAnnotation != null) {
 195.158 +                String localID = localMetadataAnnotation.id();
 195.159 +
 195.160 +                if (localID == null || localID.length() == 0) {
 195.161 +                    localID = clazz.getName() + "." + m.getName();
 195.162 +                }
 195.163 +
 195.164 +                localMetadata = fromAnnotation(localID, clazz, m, localMetadataAnnotation);
 195.165 +            } else {
 195.166 +                localMetadata = hm;
 195.167 +            }
 195.168 +
 195.169 +            if (localMetadata != null) {
 195.170 +                processMethod(result, m, localMetadata);
 195.171 +            }
 195.172 +        }
 195.173 +    }
 195.174 +
 195.175 +    private static HintMetadata fromAnnotation(String id, ClassWrapper clazz, MethodWrapper method, Hint metadata) {
 195.176 +        HintMetadata hm = HintMetadata.Builder.create(id)
 195.177 +                                              .setDescription(metadata.displayName(), metadata.description())
 195.178 +                                              .setCategory(metadata.category())
 195.179 +                                              .setEnabled(metadata.enabled())
 195.180 +                                              .setSeverity(metadata.severity())
 195.181 +                                              .setKind(metadata.hintKind())
 195.182 +                                              .setCustomizerProvider(createCustomizerProvider(clazz, method, id, metadata))
 195.183 +                                              .addSuppressWarnings(metadata.suppressWarnings())
 195.184 +                                              .addOptions(Options.fromHintOptions(metadata.options()).toArray(new Options[0]))
 195.185 +                                              .build();
 195.186 +        return hm;
 195.187 +    }
 195.188 +
 195.189 +    private static CustomizerProvider createCustomizerProvider(ClassWrapper clazz, MethodWrapper method, String id, Hint hint) {
 195.190 +        Class<? extends CustomizerProvider> customizerClass = hint.customizerProvider();
 195.191 +
 195.192 +        if (customizerClass != CustomizerProvider.class) {
 195.193 +            return new DelegatingCustomizerProvider(customizerClass);
 195.194 +        }
 195.195 +
 195.196 +        Set<String> allowedOptions = null;
 195.197 +
 195.198 +        if (method != null) {
 195.199 +            UseOptions useOptions = method.getAnnotation(UseOptions.class);
 195.200 +
 195.201 +            if (useOptions == null) return null;
 195.202 +
 195.203 +            allowedOptions = new HashSet<String>(Arrays.asList(useOptions.value()));
 195.204 +        }
 195.205 +
 195.206 +        List<OptionDescriptor> declarativeOptions = new ArrayList<OptionDescriptor>();
 195.207 +
 195.208 +        for (FieldWrapper fw : clazz.getFields()) {
 195.209 +            BooleanOption option = fw.getAnnotation(BooleanOption.class);
 195.210 +            IntegerOption iOption = fw.getAnnotation(IntegerOption.class);
 195.211 +            
 195.212 +            String key = fw.getConstantValue();
 195.213 +
 195.214 +            if (key == null) continue;
 195.215 +            if (allowedOptions != null && !allowedOptions.contains(key)) continue;
 195.216 +            
 195.217 +            Object defValue;
 195.218 +            String displayName;
 195.219 +            String tooltip;
 195.220 +            if (option != null) {
 195.221 +                defValue = option.defaultValue();
 195.222 +                displayName = option.displayName();
 195.223 +                tooltip = option.tooltip();
 195.224 +            } else if (iOption != null) {
 195.225 +                defValue = iOption.defaultValue();
 195.226 +                displayName = iOption.displayName();
 195.227 +                tooltip = iOption.tooltip();
 195.228 +            } else {
 195.229 +                return null;
 195.230 +            }
 195.231 +            
 195.232 +            declarativeOptions.add(
 195.233 +                new OptionDescriptor(
 195.234 +                    key, 
 195.235 +                    defValue,
 195.236 +                    displayName,
 195.237 +                    tooltip,
 195.238 +                    option != null ? option : iOption)
 195.239 +            );
 195.240 +        }
 195.241 +
 195.242 +        return !declarativeOptions.isEmpty() ? new ReflectiveCustomizerProvider(clazz.getName(), id, declarativeOptions) : null;
 195.243 +    }
 195.244 +    
 195.245 +    static void processMethod(Map<HintMetadata, Collection<HintDescription>> hints, MethodWrapper m, HintMetadata metadata) {
 195.246 +        //XXX: combinations of TriggerTreeKind and TriggerPattern?
 195.247 +        processTreeKindHint(hints, m, metadata);
 195.248 +        processPatternHint(hints, m, metadata);
 195.249 +        processDecisionHint(hints, m, metadata);
 195.250 +    }
 195.251 +    
 195.252 +    private static void processTreeKindHint(Map<HintMetadata, Collection<HintDescription>> hints, MethodWrapper m, HintMetadata metadata) {
 195.253 +        TriggerTreeKind kindTrigger = m.getAnnotation(TriggerTreeKind.class);
 195.254 +
 195.255 +        if (kindTrigger == null) {
 195.256 +            return ;
 195.257 +        }
 195.258 +
 195.259 +        Worker w = new WorkerImpl(m.getClazz().getName(), m.getName());
 195.260 +
 195.261 +        Set<Kind> kinds = EnumSet.noneOf(Kind.class);
 195.262 +        
 195.263 +        kinds.addAll(Arrays.asList(kindTrigger.value()));
 195.264 +
 195.265 +        addHint(hints, metadata, HintDescriptionFactory.create()
 195.266 +                                                       .setTrigger(new Kinds(kinds))
 195.267 +                                                       .setWorker(w)
 195.268 +                                                       .setMetadata(metadata)
 195.269 +                                                       .produce());
 195.270 +    }
 195.271 +    
 195.272 +    private static void processPatternHint(Map<HintMetadata, Collection<HintDescription>> hints, MethodWrapper m, HintMetadata metadata) {
 195.273 +        TriggerPattern patternTrigger = m.getAnnotation(TriggerPattern.class);
 195.274 +
 195.275 +        if (patternTrigger != null) {
 195.276 +            processPatternHint(hints, patternTrigger, m, metadata);
 195.277 +            return ;
 195.278 +        }
 195.279 +
 195.280 +        TriggerPatterns patternTriggers = m.getAnnotation(TriggerPatterns.class);
 195.281 +
 195.282 +        if (patternTriggers != null) {
 195.283 +            for (TriggerPattern pattern : patternTriggers.value()) {
 195.284 +                processPatternHint(hints, pattern, m, metadata);
 195.285 +            }
 195.286 +            return ;
 195.287 +        }
 195.288 +    }
 195.289 +
 195.290 +    private static void processPatternHint(Map<HintMetadata, Collection<HintDescription>> hints, TriggerPattern patternTrigger, MethodWrapper m, HintMetadata metadata) {
 195.291 +        String pattern = patternTrigger.value();
 195.292 +        Map<String, String> constraints = new HashMap<String, String>();
 195.293 +
 195.294 +        for (ConstraintVariableType c : patternTrigger.constraints()) {
 195.295 +            constraints.put(c.variable(), c.type());
 195.296 +        }
 195.297 +
 195.298 +        PatternDescription pd = PatternDescription.create(pattern, constraints);
 195.299 +
 195.300 +        addHint(hints, metadata, HintDescriptionFactory.create()
 195.301 +                                                       .setTrigger(pd)
 195.302 +                                                       .setWorker(new WorkerImpl(m.getClazz().getName(), m.getName()))
 195.303 +                                                       .setMetadata(metadata)
 195.304 +                                                       .produce());
 195.305 +    }
 195.306 +
 195.307 +    private static void processDecisionHint(Map<HintMetadata, Collection<HintDescription>> hints, MethodWrapper m, HintMetadata metadata) {
 195.308 +        TriggerDecision decisionTrigger = m.getAnnotation(TriggerDecision.class);
 195.309 +
 195.310 +        if (decisionTrigger == null) {
 195.311 +            return ;
 195.312 +        }
 195.313 +
 195.314 +        Worker w = new WorkerImpl(m.getClazz().getName(), m.getName());
 195.315 +
 195.316 +        addHint(hints, metadata, HintDescriptionFactory.create()
 195.317 +                                                       .setTrigger(new DecisionTrigger(decisionTrigger.value()))
 195.318 +                                                       .setWorker(w)
 195.319 +                                                       .setMetadata(metadata)
 195.320 +                                                       .produce());
 195.321 +    }
 195.322 +    
 195.323 +    private static void addHint(Map<HintMetadata, Collection<HintDescription>> hints, HintMetadata metadata, HintDescription hint) {
 195.324 +        Collection<HintDescription> list = hints.get(metadata);
 195.325 +
 195.326 +        if (list == null) {
 195.327 +            hints.put(metadata, list = new LinkedList<HintDescription>());
 195.328 +        }
 195.329 +
 195.330 +        list.add(hint);
 195.331 +    }
 195.332 +
 195.333 +    //accessed by tests:
 195.334 +    static final class WorkerImpl implements Worker {
 195.335 +
 195.336 +        private final String className;
 195.337 +        private final String methodName;
 195.338 +
 195.339 +        public WorkerImpl(String className, String methodName) {
 195.340 +            this.className = className;
 195.341 +            this.methodName = methodName;
 195.342 +        }
 195.343 +
 195.344 +        private final AtomicReference<Method> methodRef = new AtomicReference<Method>();
 195.345 +
 195.346 +        public Collection<? extends ErrorDescription> createErrors(org.netbeans.spi.java.hints.HintContext ctx) {
 195.347 +            try {
 195.348 +                Method method = methodRef.get();
 195.349 +
 195.350 +                if (method == null) {
 195.351 +                    methodRef.set(method = getMethod());
 195.352 +                }
 195.353 +                
 195.354 +                Object result = method.invoke(null, ctx);
 195.355 +
 195.356 +                if (result == null) {
 195.357 +                    return null;
 195.358 +                }
 195.359 +
 195.360 +                if (result instanceof Iterable) {
 195.361 +                    List<ErrorDescription> out = new LinkedList<ErrorDescription>();
 195.362 +
 195.363 +                    for (ErrorDescription ed : NbCollections.iterable(NbCollections.checkedIteratorByFilter(((Iterable) result).iterator(), ErrorDescription.class, false))) {
 195.364 +                        out.add(ed);
 195.365 +                    }
 195.366 +
 195.367 +                    return out;
 195.368 +                }
 195.369 +
 195.370 +                if (result instanceof ErrorDescription) {
 195.371 +                    return Collections.singletonList((ErrorDescription) result);
 195.372 +                }
 195.373 +
 195.374 +                //XXX: log if result was ignored...
 195.375 +            } catch (IllegalAccessException ex) {
 195.376 +                Exceptions.printStackTrace(ex);
 195.377 +            } catch (IllegalArgumentException ex) {
 195.378 +                Exceptions.printStackTrace(ex);
 195.379 +            } catch (ClassNotFoundException ex) {
 195.380 +                Exceptions.printStackTrace(ex);
 195.381 +            } catch (NoSuchMethodException ex) {
 195.382 +                Exceptions.printStackTrace(ex);
 195.383 +            } catch (InvocationTargetException ex) {
 195.384 +                LOG.log(Level.INFO, className + "." + methodName, ex);
 195.385 +                //so that the exceptions are categorized better:
 195.386 +                Exceptions.printStackTrace(ex.getCause());
 195.387 +            }
 195.388 +
 195.389 +            return null;
 195.390 +        }
 195.391 +
 195.392 +        //used by tests:
 195.393 +        Method getMethod() throws NoSuchMethodException, ClassNotFoundException {
 195.394 +            return FSWrapper.resolveMethod(className, methodName);
 195.395 +        }
 195.396 +
 195.397 +    }
 195.398 +
 195.399 +    private static final class EmptyHintMetadataDescription implements Hint {
 195.400 +
 195.401 +        public String id() {
 195.402 +            return "";
 195.403 +        }
 195.404 +
 195.405 +        public String category() {
 195.406 +            return "general";
 195.407 +        }
 195.408 +
 195.409 +        public boolean enabled() {
 195.410 +            return true;
 195.411 +        }
 195.412 +
 195.413 +        public Severity severity() {
 195.414 +            return Severity.VERIFIER;
 195.415 +        }
 195.416 +
 195.417 +        private static final String[] EMPTY_SW = new String[0];
 195.418 +        
 195.419 +        public String[] suppressWarnings() {
 195.420 +            return EMPTY_SW;
 195.421 +        }
 195.422 +
 195.423 +        public Class<? extends Annotation> annotationType() {
 195.424 +            return Hint.class;
 195.425 +        }
 195.426 +
 195.427 +        public Class<? extends CustomizerProvider> customizerProvider() {
 195.428 +            return CustomizerProvider.class;
 195.429 +        }
 195.430 +
 195.431 +        public Kind hintKind() {
 195.432 +            return Kind.INSPECTION;
 195.433 +        }
 195.434 +
 195.435 +        private static final Options[] EMPTY_OPTIONS = new Options[0];
 195.436 +
 195.437 +        public Options[] options() {
 195.438 +            return EMPTY_OPTIONS;
 195.439 +        }
 195.440 +
 195.441 +        @Override public String displayName() {
 195.442 +            return "";
 195.443 +        }
 195.444 +
 195.445 +        @Override public String description() {
 195.446 +            return "";
 195.447 +        }
 195.448 +
 195.449 +    }
 195.450 +
 195.451 +    private static final class DelegatingCustomizerProvider implements CustomizerProvider {
 195.452 +
 195.453 +        private final Class<? extends CustomizerProvider> component;
 195.454 +
 195.455 +        public DelegatingCustomizerProvider(Class<? extends CustomizerProvider> component) {
 195.456 +            this.component = component;
 195.457 +        }
 195.458 +
 195.459 +        @Override
 195.460 +        public JComponent getCustomizer(Preferences prefs) {
 195.461 +            try {
 195.462 +                return component.newInstance().getCustomizer(prefs);
 195.463 +            } catch (SecurityException ex) {
 195.464 +                Exceptions.printStackTrace(ex);
 195.465 +            } catch (InstantiationException ex) {
 195.466 +                Exceptions.printStackTrace(ex);
 195.467 +            } catch (IllegalAccessException ex) {
 195.468 +                Exceptions.printStackTrace(ex);
 195.469 +            } catch (IllegalArgumentException ex) {
 195.470 +                Exceptions.printStackTrace(ex);
 195.471 +            }
 195.472 +
 195.473 +            return new JPanel();
 195.474 +        }
 195.475 +
 195.476 +    }
 195.477 +
 195.478 +}
   196.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   196.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/code/FSWrapper.java	Sun Oct 23 11:50:54 2016 +0200
   196.3 @@ -0,0 +1,319 @@
   196.4 +/*
   196.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   196.6 + *
   196.7 + * Copyright 2010-2011 Oracle and/or its affiliates. All rights reserved.
   196.8 + *
   196.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  196.10 + * Other names may be trademarks of their respective owners.
  196.11 + *
  196.12 + * The contents of this file are subject to the terms of either the GNU
  196.13 + * General Public License Version 2 only ("GPL") or the Common
  196.14 + * Development and Distribution License("CDDL") (collectively, the
  196.15 + * "License"). You may not use this file except in compliance with the
  196.16 + * License. You can obtain a copy of the License at
  196.17 + * http://www.netbeans.org/cddl-gplv2.html
  196.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  196.19 + * specific language governing permissions and limitations under the
  196.20 + * License.  When distributing the software, include this License Header
  196.21 + * Notice in each file and include the License file at
  196.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  196.23 + * particular file as subject to the "Classpath" exception as provided
  196.24 + * by Oracle in the GPL Version 2 section of the License file that
  196.25 + * accompanied this code. If applicable, add the following below the
  196.26 + * License Header, with the fields enclosed by brackets [] replaced by
  196.27 + * your own identifying information:
  196.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  196.29 + *
  196.30 + * If you wish your version of this file to be governed by only the CDDL
  196.31 + * or only the GPL Version 2, indicate your decision by adding
  196.32 + * "[Contributor] elects to include this software in this distribution
  196.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  196.34 + * single choice of license, a recipient has the option to distribute
  196.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  196.36 + * to extend the choice of license to its licensees as provided above.
  196.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  196.38 + * Version 2 license, then the option applies only if the new code is
  196.39 + * made subject to such option by the copyright holder.
  196.40 + *
  196.41 + * Contributor(s):
  196.42 + *
  196.43 + * Portions Copyrighted 2010-2011 Sun Microsystems, Inc.
  196.44 + */
  196.45 +
  196.46 +package org.netbeans.modules.java.hints.providers.code;
  196.47 +
  196.48 +import java.lang.annotation.Annotation;
  196.49 +import java.lang.reflect.Array;
  196.50 +import java.lang.reflect.InvocationHandler;
  196.51 +import java.lang.reflect.Method;
  196.52 +import java.lang.reflect.Proxy;
  196.53 +import java.util.HashMap;
  196.54 +import java.util.LinkedList;
  196.55 +import java.util.List;
  196.56 +import java.util.Map;
  196.57 +import java.util.logging.Level;
  196.58 +import java.util.logging.Logger;
  196.59 +import org.netbeans.spi.java.hints.HintContext;
  196.60 +import org.openide.filesystems.FileObject;
  196.61 +import org.openide.filesystems.FileUtil;
  196.62 +import org.openide.util.Exceptions;
  196.63 +
  196.64 +/**
  196.65 + *
  196.66 + * @author lahvac
  196.67 + */
  196.68 +public class FSWrapper {
  196.69 +
  196.70 +    public static Iterable<? extends ClassWrapper> listClasses() {
  196.71 +        ClassLoader loader = FSWrapper.class.getClassLoader();
  196.72 +
  196.73 +        if (loader == null) {
  196.74 +            loader = ClassLoader.getSystemClassLoader();
  196.75 +        }
  196.76 +
  196.77 +        List<ClassWrapper> result = new LinkedList<ClassWrapper>();
  196.78 +        FileObject main = FileUtil.getConfigFile("org-netbeans-modules-java-hints/code-hints/");
  196.79 +
  196.80 +        if (main != null) {
  196.81 +            for (FileObject c : main.getChildren()) {
  196.82 +                result.add(new ClassWrapper(loader, c));
  196.83 +            }
  196.84 +        }
  196.85 +
  196.86 +        return result;
  196.87 +    }
  196.88 +
  196.89 +    public static Method resolveMethod(String className, String methodName) throws NoSuchMethodException, ClassNotFoundException {
  196.90 +        Class<?> clazz = CodeHintProviderImpl.findLoader().loadClass(className);
  196.91 +
  196.92 +        return clazz.getDeclaredMethod(methodName, HintContext.class);
  196.93 +    }
  196.94 +
  196.95 +    public static class AnnotatableWrapper {
  196.96 +        protected final ClassLoader loader;
  196.97 +        protected final FileObject folder;
  196.98 +        protected AnnotatableWrapper(ClassLoader loader, FileObject folder) {
  196.99 +            this.loader = loader;
 196.100 +            this.folder = folder;
 196.101 +        }
 196.102 +
 196.103 +        private final Map<Class<? extends Annotation>, Annotation> annotations = new HashMap<Class<? extends Annotation>, Annotation>();
 196.104 +
 196.105 +        public synchronized <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
 196.106 +            if (!this.annotations.containsKey(annotationClass)) {
 196.107 +                FileObject f = folder.getFileObject(annotationClass.getName().replace('.', '-') + ".annotation");
 196.108 +                T result = null;
 196.109 +
 196.110 +                if (f != null) {
 196.111 +                    try {
 196.112 +                        Annotation a = loadAnnotation(loader, f);
 196.113 +
 196.114 +                        result = annotationClass.cast(a);
 196.115 +                    } catch (ClassNotFoundException ex) {
 196.116 +                        Exceptions.printStackTrace(ex);
 196.117 +                    }
 196.118 +                }
 196.119 +
 196.120 +                this.annotations.put(annotationClass, result);
 196.121 +            }
 196.122 +
 196.123 +            return annotationClass.cast(this.annotations.get(annotationClass));
 196.124 +        }
 196.125 +    }
 196.126 +
 196.127 +    public static class ClassWrapper extends AnnotatableWrapper {
 196.128 +        private final String className;
 196.129 +        public ClassWrapper(ClassLoader loader, FileObject folder) {
 196.130 +            super(loader, folder);
 196.131 +            className = folder.getName().replace('-', '.');
 196.132 +        }
 196.133 +
 196.134 +        private Iterable<? extends MethodWrapper> methods;
 196.135 +
 196.136 +        public synchronized Iterable<? extends MethodWrapper> getMethods() {
 196.137 +            if (this.methods == null) {
 196.138 +                List<MethodWrapper> methods = new LinkedList<MethodWrapper>();
 196.139 +
 196.140 +                for (FileObject c : folder.getChildren()) {
 196.141 +                    if (c.getExt().equals("method")) {
 196.142 +                        methods.add(new MethodWrapper(loader, c, this));
 196.143 +                    }
 196.144 +                }
 196.145 +
 196.146 +                this.methods = methods;
 196.147 +            }
 196.148 +
 196.149 +            return this.methods;
 196.150 +        }
 196.151 +
 196.152 +        private Iterable<? extends FieldWrapper> fields;
 196.153 +
 196.154 +        public synchronized Iterable<? extends FieldWrapper> getFields() {
 196.155 +            if (this.fields == null) {
 196.156 +                List<FieldWrapper> fields = new LinkedList<FieldWrapper>();
 196.157 +
 196.158 +                for (FileObject c : folder.getChildren()) {
 196.159 +                    if (c.getExt().equals("field")) {
 196.160 +                        fields.add(new FieldWrapper(loader, c, this));
 196.161 +                    }
 196.162 +                }
 196.163 +
 196.164 +                this.fields = fields;
 196.165 +            }
 196.166 +
 196.167 +            return this.fields;
 196.168 +        }
 196.169 +
 196.170 +        public String getName() {
 196.171 +            return className;
 196.172 +        }
 196.173 +
 196.174 +        private Class<?> clazz;
 196.175 +        public synchronized Class<?> getDeclaredClass() {
 196.176 +            if (clazz != null) {
 196.177 +                return clazz;
 196.178 +            }
 196.179 +
 196.180 +            try {
 196.181 +                return this.clazz = loader.loadClass(className);
 196.182 +            } catch (ClassNotFoundException ex) {
 196.183 +                Exceptions.printStackTrace(ex);
 196.184 +            }
 196.185 +
 196.186 +            return null; //XXX
 196.187 +        }
 196.188 +    }
 196.189 +
 196.190 +    public static class MethodWrapper extends AnnotatableWrapper {
 196.191 +        private final ClassWrapper clazz;
 196.192 +        public MethodWrapper(ClassLoader loader, FileObject folder, ClassWrapper clazz) {
 196.193 +            super(loader, folder);
 196.194 +            this.clazz = clazz;
 196.195 +        }
 196.196 +
 196.197 +        ClassWrapper getClazz() {
 196.198 +            return clazz;
 196.199 +        }
 196.200 +        
 196.201 +        String getName() {
 196.202 +            return folder.getName();
 196.203 +        }
 196.204 +    }
 196.205 +
 196.206 +    public static class FieldWrapper extends AnnotatableWrapper {
 196.207 +        private final ClassWrapper clazz;
 196.208 +        public FieldWrapper(ClassLoader loader, FileObject folder, ClassWrapper clazz) {
 196.209 +            super(loader, folder);
 196.210 +            this.clazz = clazz;
 196.211 +        }
 196.212 +
 196.213 +        ClassWrapper getClazz() {
 196.214 +            return clazz;
 196.215 +        }
 196.216 +
 196.217 +        String getName() {
 196.218 +            return folder.getName();
 196.219 +        }
 196.220 +
 196.221 +        String getConstantValue() {
 196.222 +            Object constantValue = folder.getAttribute("constantValue");
 196.223 +
 196.224 +            if (constantValue instanceof String) {
 196.225 +                return (String) constantValue;
 196.226 +            }
 196.227 +
 196.228 +            return null;
 196.229 +        }
 196.230 +    }
 196.231 +
 196.232 +    private static final Object MARKER = new Object();
 196.233 +    
 196.234 +    private static Object computeAttributeValue(ClassLoader loader, FileObject folder, String attributeName, Class<?> returnType, Object defaulValue) throws ClassNotFoundException {
 196.235 +        Object result = folder.getAttribute(attributeName);
 196.236 +
 196.237 +        if (result == null) {
 196.238 +            FileObject embedded = folder.getFileObject(attributeName);
 196.239 +
 196.240 +            if (embedded == null) {
 196.241 +                result = defaulValue;
 196.242 +            } else {
 196.243 +                if (returnType.isArray()) {
 196.244 +                    List<Object> items = new LinkedList<Object>();
 196.245 +                    int c = 0;
 196.246 +
 196.247 +                    while (true) {
 196.248 +                        Object val = computeAttributeValue(loader, embedded, "item" + c, returnType.getComponentType(), MARKER);
 196.249 +
 196.250 +                        if (val == MARKER) {
 196.251 +                            break;
 196.252 +                        }
 196.253 +
 196.254 +                        items.add(val);
 196.255 +                        c++;
 196.256 +                    }
 196.257 +
 196.258 +                    Object res = Array.newInstance(returnType.getComponentType(), items.size());
 196.259 +                    int ci = 0;
 196.260 +
 196.261 +                    for (Object i : items) {
 196.262 +                        Array.set(res, ci++, i);
 196.263 +                    }
 196.264 +
 196.265 +                    result = res;
 196.266 +                } else if (returnType.isAnnotation()) {
 196.267 +                    result = loadAnnotation(loader, embedded.getChildren()[0]);
 196.268 +                }
 196.269 +            }
 196.270 +        } else {
 196.271 +            if (returnType.isEnum()) {
 196.272 +                String fqn = (String) result;
 196.273 +                int lastDot = fqn.lastIndexOf('.');
 196.274 +                Class<? extends Enum> enumClass = (Class<? extends Enum>) loader.loadClass(fqn.substring(0, lastDot));
 196.275 +
 196.276 +                result = Enum.valueOf(enumClass, fqn.substring(lastDot + 1));
 196.277 +            } else if (returnType == Class.class) {
 196.278 +                String fqn = (String) result;
 196.279 +
 196.280 +                try {
 196.281 +                    result = loader.loadClass(fqn);
 196.282 +                } catch (ClassNotFoundException ex) {
 196.283 +                    Logger.getLogger(FSWrapper.class.getName()).log(Level.FINE, null, ex);
 196.284 +                    result = CodeHintProviderImpl.findLoader().loadClass(fqn);
 196.285 +                }
 196.286 +            }
 196.287 +        }
 196.288 +
 196.289 +        return result;
 196.290 +    }
 196.291 +
 196.292 +    
 196.293 +    private static <T extends Annotation> T loadAnnotation(ClassLoader l, FileObject annotationFolder) throws ClassNotFoundException {
 196.294 +        Class<?> clazz = l.loadClass(annotationFolder.getName().replace('-', '.'));
 196.295 +
 196.296 +        return (T) Proxy.newProxyInstance(l, new Class[] {clazz}, new InvocationHandlerImpl(l, annotationFolder));
 196.297 +    }
 196.298 +    
 196.299 +    private static final class InvocationHandlerImpl implements InvocationHandler {
 196.300 +
 196.301 +        private final ClassLoader loader;
 196.302 +        private final FileObject folder;
 196.303 +        private final Map<String, Object> attributes = new HashMap<String, Object>();
 196.304 +
 196.305 +        public InvocationHandlerImpl(ClassLoader loader, FileObject folder) {
 196.306 +            this.loader = loader;
 196.307 +            this.folder = folder;
 196.308 +        }
 196.309 +
 196.310 +        public synchronized Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
 196.311 +            if (!attributes.containsKey(method.getName())) {
 196.312 +                Object result = computeAttributeValue(loader, folder, method.getName(), method.getReturnType(), method.getDefaultValue());
 196.313 +
 196.314 +                attributes.put(method.getName(), result);
 196.315 +            }
 196.316 +
 196.317 +            return attributes.get(method.getName());
 196.318 +        }
 196.319 +
 196.320 +    }
 196.321 +
 196.322 +}
   197.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   197.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/code/ReflectiveCustomizerProvider.java	Sun Oct 23 11:50:54 2016 +0200
   197.3 @@ -0,0 +1,261 @@
   197.4 +/*
   197.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   197.6 + *
   197.7 + * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
   197.8 + *
   197.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  197.10 + * Other names may be trademarks of their respective owners.
  197.11 + *
  197.12 + * The contents of this file are subject to the terms of either the GNU
  197.13 + * General Public License Version 2 only ("GPL") or the Common
  197.14 + * Development and Distribution License("CDDL") (collectively, the
  197.15 + * "License"). You may not use this file except in compliance with the
  197.16 + * License. You can obtain a copy of the License at
  197.17 + * http://www.netbeans.org/cddl-gplv2.html
  197.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  197.19 + * specific language governing permissions and limitations under the
  197.20 + * License.  When distributing the software, include this License Header
  197.21 + * Notice in each file and include the License file at
  197.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  197.23 + * particular file as subject to the "Classpath" exception as provided
  197.24 + * by Oracle in the GPL Version 2 section of the License file that
  197.25 + * accompanied this code. If applicable, add the following below the
  197.26 + * License Header, with the fields enclosed by brackets [] replaced by
  197.27 + * your own identifying information:
  197.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  197.29 + *
  197.30 + * If you wish your version of this file to be governed by only the CDDL
  197.31 + * or only the GPL Version 2, indicate your decision by adding
  197.32 + * "[Contributor] elects to include this software in this distribution
  197.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  197.34 + * single choice of license, a recipient has the option to distribute
  197.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  197.36 + * to extend the choice of license to its licensees as provided above.
  197.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  197.38 + * Version 2 license, then the option applies only if the new code is
  197.39 + * made subject to such option by the copyright holder.
  197.40 + *
  197.41 + * Contributor(s):
  197.42 + *
  197.43 + * Portions Copyrighted 2012 Sun Microsystems, Inc.
  197.44 + */
  197.45 +package org.netbeans.modules.java.hints.providers.code;
  197.46 +
  197.47 +import java.awt.GridBagConstraints;
  197.48 +import java.awt.GridBagLayout;
  197.49 +import java.awt.Insets;
  197.50 +import java.awt.event.ActionEvent;
  197.51 +import java.awt.event.ActionListener;
  197.52 +import java.util.List;
  197.53 +import java.util.prefs.Preferences;
  197.54 +import javax.swing.JCheckBox;
  197.55 +import javax.swing.JComponent;
  197.56 +import javax.swing.JFormattedTextField;
  197.57 +import javax.swing.JLabel;
  197.58 +import javax.swing.JPanel;
  197.59 +import javax.swing.JSpinner;
  197.60 +import javax.swing.SpinnerNumberModel;
  197.61 +import javax.swing.event.ChangeEvent;
  197.62 +import javax.swing.event.ChangeListener;
  197.63 +import javax.swing.text.NumberFormatter;
  197.64 +import org.netbeans.spi.java.hints.BooleanOption;
  197.65 +import org.netbeans.spi.java.hints.CustomizerProvider;
  197.66 +import org.netbeans.spi.java.hints.IntegerOption;
  197.67 +import org.openide.util.Exceptions;
  197.68 +
  197.69 +/**
  197.70 + *
  197.71 + * @author lahvac
  197.72 + */
  197.73 +public class ReflectiveCustomizerProvider implements CustomizerProvider {
  197.74 +    private final String hintClassName;
  197.75 +    private final String hintId;
  197.76 +    private final List<OptionDescriptor> options;
  197.77 +
  197.78 +    public ReflectiveCustomizerProvider(String hintClassName, String hintId, List<OptionDescriptor> options) {
  197.79 +        this.hintClassName = hintClassName;
  197.80 +        this.hintId = hintId;
  197.81 +        this.options = options;
  197.82 +    }
  197.83 +
  197.84 +    @Override
  197.85 +    public JComponent getCustomizer(Preferences prefs) {
  197.86 +        return new CustomizerImpl(prefs, hintClassName, hintId, options);
  197.87 +    }
  197.88 +
  197.89 +    private static final class CustomizerImpl extends JPanel {
  197.90 +        private int row;
  197.91 +        
  197.92 +        public CustomizerImpl(Preferences prefs, String hintClassName, String hintId, List<OptionDescriptor> options) {
  197.93 +            try {
  197.94 +                setLayout(new GridBagLayout());
  197.95 +                row = 0;
  197.96 +                
  197.97 +                for (OptionDescriptor option : options) {
  197.98 +                    if (option.parameters instanceof IntegerOption) {
  197.99 +                        createIntegerOption(option, prefs);
 197.100 +                    }
 197.101 +                }
 197.102 +
 197.103 +                for (OptionDescriptor option : options) {
 197.104 +                    if (option.parameters instanceof BooleanOption) {
 197.105 +                        createBooleanOption(option, prefs);
 197.106 +                    }
 197.107 +                }
 197.108 +
 197.109 +                GridBagConstraints constraints = new GridBagConstraints();
 197.110 +
 197.111 +                constraints.anchor = GridBagConstraints.NORTHWEST;
 197.112 +                constraints.fill = GridBagConstraints.BOTH;
 197.113 +                constraints.gridheight = 1;
 197.114 +                constraints.gridwidth = GridBagConstraints.REMAINDER;
 197.115 +                constraints.gridx = 0;
 197.116 +                constraints.gridy = row++;
 197.117 +                constraints.weightx = 1;
 197.118 +                constraints.weighty = 1;
 197.119 +
 197.120 +                add(new JPanel(), constraints);
 197.121 +            } catch (IllegalArgumentException ex) {
 197.122 +                Exceptions.printStackTrace(ex);
 197.123 +            } catch (SecurityException ex) {
 197.124 +                Exceptions.printStackTrace(ex);
 197.125 +            }
 197.126 +        }
 197.127 +        
 197.128 +        private void createIntegerOption(OptionDescriptor option, Preferences prefs) {
 197.129 +            IntegerOption iopt = (IntegerOption)option.parameters;
 197.130 +            JLabel l = new JLabel();
 197.131 +            org.openide.awt.Mnemonics.setLocalizedText(l, option.displayName + ":");
 197.132 +            
 197.133 +            GridBagConstraints constraints = new GridBagConstraints();
 197.134 +            constraints.anchor = GridBagConstraints.WEST;
 197.135 +            constraints.fill = GridBagConstraints.NONE;
 197.136 +            constraints.gridheight = 1;
 197.137 +            constraints.gridwidth = 1;
 197.138 +            constraints.gridx = 0;
 197.139 +            constraints.gridy = row;
 197.140 +            constraints.weightx = 0;
 197.141 +            constraints.weighty = 0;
 197.142 +            constraints.insets = new Insets(0, 0, 0, 8);
 197.143 +            
 197.144 +            add(l, constraints);
 197.145 +            
 197.146 +            JComponent field;
 197.147 +            int val = prefs.getInt(option.preferencesKey, ((Integer)option.defaultValue).intValue());
 197.148 +            if (iopt.step() > 0) {
 197.149 +                val = Math.min(iopt.maxValue(), Math.max(iopt.minValue(), val));
 197.150 +                JSpinner spinner = new JSpinner(
 197.151 +                        new SpinnerNumberModel(val, iopt.minValue(), iopt.maxValue(), iopt.step()));
 197.152 +                spinner.addChangeListener(new ActionListenerImpl(option.preferencesKey, prefs));
 197.153 +                field = spinner;
 197.154 +            } else {
 197.155 +                NumberFormatter nf = new NumberFormatter();
 197.156 +                nf.setValueClass(Integer.class);
 197.157 +                nf.setMaximum(iopt.maxValue());
 197.158 +                nf.setMinimum(iopt.minValue());
 197.159 +                JFormattedTextField formatted = new JFormattedTextField(nf);
 197.160 +                field = formatted;
 197.161 +            }
 197.162 +            if (option.tooltip != null && !option.tooltip.isEmpty()) {
 197.163 +                field.setToolTipText(option.tooltip);
 197.164 +            }
 197.165 +            constraints = new GridBagConstraints();
 197.166 +            constraints.anchor = GridBagConstraints.WEST;
 197.167 +            constraints.fill = GridBagConstraints.HORIZONTAL;
 197.168 +            constraints.gridheight = 1;
 197.169 +            constraints.gridwidth = 1;
 197.170 +            constraints.gridx = 1;
 197.171 +            constraints.gridy = row;
 197.172 +            constraints.weightx = 0;
 197.173 +            constraints.weighty = 0;
 197.174 +            
 197.175 +            add(field, constraints);
 197.176 +
 197.177 +            constraints = new GridBagConstraints();
 197.178 +            constraints.anchor = GridBagConstraints.WEST;
 197.179 +            constraints.fill = GridBagConstraints.HORIZONTAL;
 197.180 +            constraints.gridheight = 1;
 197.181 +            constraints.gridwidth = GridBagConstraints.REMAINDER;
 197.182 +            constraints.gridx = 2;
 197.183 +            constraints.gridy = row++;
 197.184 +            constraints.weightx = 1;
 197.185 +            constraints.weighty = 0;
 197.186 +            
 197.187 +            add(new JPanel(), constraints);
 197.188 +        }
 197.189 +        
 197.190 +        private JComponent createBooleanOption(OptionDescriptor option, Preferences prefs)  {
 197.191 +            JCheckBox checkBox = new JCheckBox();
 197.192 +
 197.193 +            org.openide.awt.Mnemonics.setLocalizedText(checkBox, option.displayName);
 197.194 +            checkBox.setToolTipText(option.tooltip);
 197.195 +            checkBox.addActionListener(new ActionListenerImpl(option.preferencesKey, prefs));
 197.196 +
 197.197 +            checkBox.setSelected(prefs.getBoolean(option.preferencesKey, 
 197.198 +                    Boolean.TRUE == option.defaultValue));
 197.199 +            GridBagConstraints constraints = new GridBagConstraints();
 197.200 +
 197.201 +            constraints.anchor = GridBagConstraints.WEST;
 197.202 +            constraints.fill = GridBagConstraints.NONE;
 197.203 +            constraints.gridheight = 1;
 197.204 +            constraints.gridwidth = 2;
 197.205 +            constraints.gridx = 0;
 197.206 +            constraints.gridy = row++;
 197.207 +            constraints.weightx = 0;
 197.208 +            constraints.weighty = 0;
 197.209 +
 197.210 +            add(checkBox, constraints);
 197.211 +            return checkBox;
 197.212 +        }
 197.213 +                
 197.214 +        
 197.215 +        private static final class ActionListenerImpl implements ActionListener, ChangeListener {
 197.216 +            private final String key;
 197.217 +            private final Preferences prefs;
 197.218 +
 197.219 +            public ActionListenerImpl(String key, Preferences prefs) {
 197.220 +                this.key = key;
 197.221 +                this.prefs = prefs;
 197.222 +            }
 197.223 +
 197.224 +            @Override
 197.225 +            public void actionPerformed(ActionEvent e) {
 197.226 +                JCheckBox checkBox = ((JCheckBox)e.getSource());
 197.227 +                prefs.putBoolean(key, checkBox.isSelected());
 197.228 +            }
 197.229 +
 197.230 +            @Override
 197.231 +            public void stateChanged(ChangeEvent e) {
 197.232 +                Integer i = (Integer)((JSpinner)e.getSource()).getValue();
 197.233 +                prefs.putInt(key, i);
 197.234 +            }
 197.235 +
 197.236 +        }
 197.237 +        
 197.238 +    }
 197.239 +
 197.240 +    public static final class OptionDescriptor {
 197.241 +        public final String preferencesKey;
 197.242 +        public final Object defaultValue;
 197.243 +        public final String displayName;
 197.244 +        public final String tooltip;
 197.245 +        /**
 197.246 +         * The original Annotation object, type-specific parameters.
 197.247 +         */
 197.248 +        public final Object parameters;
 197.249 +
 197.250 +        public OptionDescriptor(
 197.251 +                String preferencesKey, 
 197.252 +                Object defaultValue, 
 197.253 +                String displayName, String tooltip, 
 197.254 +                Object parameters) {
 197.255 +            this.preferencesKey = preferencesKey;
 197.256 +            this.defaultValue = defaultValue;
 197.257 +            this.displayName = displayName;
 197.258 +            this.tooltip = tooltip;
 197.259 +            this.parameters = parameters;
 197.260 +        }
 197.261 +
 197.262 +    }
 197.263 +
 197.264 +}
   198.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   198.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/ClassPathBasedHintProvider.java	Sun Oct 23 11:50:54 2016 +0200
   198.3 @@ -0,0 +1,57 @@
   198.4 +/*
   198.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   198.6 + *
   198.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
   198.8 + *
   198.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  198.10 + * Other names may be trademarks of their respective owners.
  198.11 + *
  198.12 + * The contents of this file are subject to the terms of either the GNU
  198.13 + * General Public License Version 2 only ("GPL") or the Common
  198.14 + * Development and Distribution License("CDDL") (collectively, the
  198.15 + * "License"). You may not use this file except in compliance with the
  198.16 + * License. You can obtain a copy of the License at
  198.17 + * http://www.netbeans.org/cddl-gplv2.html
  198.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  198.19 + * specific language governing permissions and limitations under the
  198.20 + * License.  When distributing the software, include this License Header
  198.21 + * Notice in each file and include the License file at
  198.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  198.23 + * particular file as subject to the "Classpath" exception as provided
  198.24 + * by Oracle in the GPL Version 2 section of the License file that
  198.25 + * accompanied this code. If applicable, add the following below the
  198.26 + * License Header, with the fields enclosed by brackets [] replaced by
  198.27 + * your own identifying information:
  198.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  198.29 + *
  198.30 + * If you wish your version of this file to be governed by only the CDDL
  198.31 + * or only the GPL Version 2, indicate your decision by adding
  198.32 + * "[Contributor] elects to include this software in this distribution
  198.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  198.34 + * single choice of license, a recipient has the option to distribute
  198.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  198.36 + * to extend the choice of license to its licensees as provided above.
  198.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  198.38 + * Version 2 license, then the option applies only if the new code is
  198.39 + * made subject to such option by the copyright holder.
  198.40 + *
  198.41 + * Contributor(s):
  198.42 + *
  198.43 + * Portions Copyrighted 2009 Sun Microsystems, Inc.
  198.44 + */
  198.45 +
  198.46 +package org.netbeans.modules.java.hints.providers.spi;
  198.47 +
  198.48 +import java.util.Collection;
  198.49 +import org.netbeans.api.java.classpath.ClassPath;
  198.50 +import org.netbeans.modules.java.hints.providers.spi.HintDescription;
  198.51 +
  198.52 +/**
  198.53 + * XXX: this is another ugly hack!
  198.54 + * @author lahvac
  198.55 + */
  198.56 +public interface ClassPathBasedHintProvider {
  198.57 +
  198.58 +    public Collection<? extends HintDescription> computeHints(ClassPath cp);
  198.59 +
  198.60 +}
   199.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   199.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/ElementBasedHintProvider.java	Sun Oct 23 11:50:54 2016 +0200
   199.3 @@ -0,0 +1,57 @@
   199.4 +/*
   199.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   199.6 + *
   199.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
   199.8 + *
   199.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  199.10 + * Other names may be trademarks of their respective owners.
  199.11 + *
  199.12 + * The contents of this file are subject to the terms of either the GNU
  199.13 + * General Public License Version 2 only ("GPL") or the Common
  199.14 + * Development and Distribution License("CDDL") (collectively, the
  199.15 + * "License"). You may not use this file except in compliance with the
  199.16 + * License. You can obtain a copy of the License at
  199.17 + * http://www.netbeans.org/cddl-gplv2.html
  199.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  199.19 + * specific language governing permissions and limitations under the
  199.20 + * License.  When distributing the software, include this License Header
  199.21 + * Notice in each file and include the License file at
  199.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  199.23 + * particular file as subject to the "Classpath" exception as provided
  199.24 + * by Oracle in the GPL Version 2 section of the License file that
  199.25 + * accompanied this code. If applicable, add the following below the
  199.26 + * License Header, with the fields enclosed by brackets [] replaced by
  199.27 + * your own identifying information:
  199.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  199.29 + *
  199.30 + * If you wish your version of this file to be governed by only the CDDL
  199.31 + * or only the GPL Version 2, indicate your decision by adding
  199.32 + * "[Contributor] elects to include this software in this distribution
  199.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  199.34 + * single choice of license, a recipient has the option to distribute
  199.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  199.36 + * to extend the choice of license to its licensees as provided above.
  199.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  199.38 + * Version 2 license, then the option applies only if the new code is
  199.39 + * made subject to such option by the copyright holder.
  199.40 + *
  199.41 + * Contributor(s):
  199.42 + *
  199.43 + * Portions Copyrighted 2009 Sun Microsystems, Inc.
  199.44 + */
  199.45 +
  199.46 +package org.netbeans.modules.java.hints.providers.spi;
  199.47 +
  199.48 +import java.util.Collection;
  199.49 +import org.netbeans.api.java.source.CompilationInfo;
  199.50 +import org.netbeans.modules.java.hints.providers.spi.HintDescription;
  199.51 +
  199.52 +/**
  199.53 + * XXX: this is an ugly hack!
  199.54 + * @author lahvac
  199.55 + */
  199.56 +public interface ElementBasedHintProvider {
  199.57 +
  199.58 +    public Collection<? extends HintDescription> computeHints(CompilationInfo info);
  199.59 +
  199.60 +}
   200.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   200.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/HintDescription.java	Sun Oct 23 11:50:54 2016 +0200
   200.3 @@ -0,0 +1,127 @@
   200.4 +/*
   200.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   200.6 + *
   200.7 + * Copyright 2009-2010 Oracle and/or its affiliates. All rights reserved.
   200.8 + *
   200.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  200.10 + * Other names may be trademarks of their respective owners.
  200.11 + *
  200.12 + * The contents of this file are subject to the terms of either the GNU
  200.13 + * General Public License Version 2 only ("GPL") or the Common
  200.14 + * Development and Distribution License("CDDL") (collectively, the
  200.15 + * "License"). You may not use this file except in compliance with the
  200.16 + * License. You can obtain a copy of the License at
  200.17 + * http://www.netbeans.org/cddl-gplv2.html
  200.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  200.19 + * specific language governing permissions and limitations under the
  200.20 + * License.  When distributing the software, include this License Header
  200.21 + * Notice in each file and include the License file at
  200.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  200.23 + * particular file as subject to the "Classpath" exception as provided
  200.24 + * by Oracle in the GPL Version 2 section of the License file that
  200.25 + * accompanied this code. If applicable, add the following below the
  200.26 + * License Header, with the fields enclosed by brackets [] replaced by
  200.27 + * your own identifying information:
  200.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  200.29 + *
  200.30 + * If you wish your version of this file to be governed by only the CDDL
  200.31 + * or only the GPL Version 2, indicate your decision by adding
  200.32 + * "[Contributor] elects to include this software in this distribution
  200.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  200.34 + * single choice of license, a recipient has the option to distribute
  200.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  200.36 + * to extend the choice of license to its licensees as provided above.
  200.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  200.38 + * Version 2 license, then the option applies only if the new code is
  200.39 + * made subject to such option by the copyright holder.
  200.40 + *
  200.41 + * Contributor(s):
  200.42 + *
  200.43 + * Portions Copyrighted 2009-2010 Sun Microsystems, Inc.
  200.44 + */
  200.45 +
  200.46 +package org.netbeans.modules.java.hints.providers.spi;
  200.47 +
  200.48 +import java.util.Collection;
  200.49 +import java.util.Collections;
  200.50 +import java.util.HashSet;
  200.51 +import java.util.Set;
  200.52 +import org.netbeans.modules.java.hints.providers.spi.HintMetadata.Options;
  200.53 +import org.netbeans.spi.editor.hints.ErrorDescription;
  200.54 +import org.netbeans.spi.java.hints.HintContext;
  200.55 +
  200.56 +/**
  200.57 + *
  200.58 + * @author Jan Lahoda
  200.59 + */
  200.60 +public final class HintDescription {
  200.61 +
  200.62 +    private final HintMetadata metadata;
  200.63 +    private final Trigger trigger;
  200.64 +    private final Worker worker;
  200.65 +    private final AdditionalQueryConstraints additionalConstraints;
  200.66 +    private final String hintText;
  200.67 +    private final Set<Options> options;
  200.68 +
  200.69 +    private HintDescription(HintMetadata metadata, Trigger trigger, Worker worker, AdditionalQueryConstraints additionalConstraints, String hintText, Set<Options> options) {
  200.70 +        this.metadata = metadata;
  200.71 +        this.trigger = trigger;
  200.72 +        this.worker = worker;
  200.73 +        this.additionalConstraints = additionalConstraints;
  200.74 +        this.hintText = hintText;
  200.75 +        this.options = options;
  200.76 +    }
  200.77 +
  200.78 +    static HintDescription create(HintMetadata metadata, Trigger trigger, Worker worker, AdditionalQueryConstraints additionalConstraints, String hintText, Set<Options> options) {
  200.79 +        return new HintDescription(metadata, trigger, worker, additionalConstraints, hintText, options);
  200.80 +    }
  200.81 +
  200.82 +    @Override
  200.83 +    public String toString() {
  200.84 +        return "[HintDescription:" + trigger + "]";
  200.85 +    }
  200.86 +
  200.87 +    public AdditionalQueryConstraints getAdditionalConstraints() {
  200.88 +        return additionalConstraints;
  200.89 +    }
  200.90 +
  200.91 +    public String getHintText() {
  200.92 +        return hintText;
  200.93 +    }
  200.94 +
  200.95 +    public HintMetadata getMetadata() {
  200.96 +        return metadata;
  200.97 +    }
  200.98 +
  200.99 +    public Trigger getTrigger() {
 200.100 +        return trigger;
 200.101 +    }
 200.102 +
 200.103 +    public Worker getWorker() {
 200.104 +        return worker;
 200.105 +    }
 200.106 +
 200.107 +    public Set<Options> getOptions() {
 200.108 +        return options;
 200.109 +    }
 200.110 +
 200.111 +    public static interface Worker {
 200.112 +
 200.113 +        public Collection<? extends ErrorDescription> createErrors(HintContext ctx);
 200.114 +
 200.115 +    }
 200.116 +
 200.117 +    public static final class AdditionalQueryConstraints {
 200.118 +        public final Set<String> requiredErasedTypes;
 200.119 +
 200.120 +        public AdditionalQueryConstraints(Set<String> requiredErasedTypes) {
 200.121 +            this.requiredErasedTypes = Collections.unmodifiableSet(new HashSet<String>(requiredErasedTypes));
 200.122 +        }
 200.123 +
 200.124 +        private static final AdditionalQueryConstraints EMPTY = new AdditionalQueryConstraints(Collections.<String>emptySet());
 200.125 +        public static AdditionalQueryConstraints empty() {
 200.126 +            return EMPTY;
 200.127 +        }
 200.128 +    }
 200.129 +
 200.130 +}
   201.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   201.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/HintDescriptionFactory.java	Sun Oct 23 11:50:54 2016 +0200
   201.3 @@ -0,0 +1,127 @@
   201.4 +/*
   201.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   201.6 + *
   201.7 + * Copyright 2009-2010 Oracle and/or its affiliates. All rights reserved.
   201.8 + *
   201.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  201.10 + * Other names may be trademarks of their respective owners.
  201.11 + *
  201.12 + * The contents of this file are subject to the terms of either the GNU
  201.13 + * General Public License Version 2 only ("GPL") or the Common
  201.14 + * Development and Distribution License("CDDL") (collectively, the
  201.15 + * "License"). You may not use this file except in compliance with the
  201.16 + * License. You can obtain a copy of the License at
  201.17 + * http://www.netbeans.org/cddl-gplv2.html
  201.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  201.19 + * specific language governing permissions and limitations under the
  201.20 + * License.  When distributing the software, include this License Header
  201.21 + * Notice in each file and include the License file at
  201.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  201.23 + * particular file as subject to the "Classpath" exception as provided
  201.24 + * by Oracle in the GPL Version 2 section of the License file that
  201.25 + * accompanied this code. If applicable, add the following below the
  201.26 + * License Header, with the fields enclosed by brackets [] replaced by
  201.27 + * your own identifying information:
  201.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  201.29 + *
  201.30 + * If you wish your version of this file to be governed by only the CDDL
  201.31 + * or only the GPL Version 2, indicate your decision by adding
  201.32 + * "[Contributor] elects to include this software in this distribution
  201.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  201.34 + * single choice of license, a recipient has the option to distribute
  201.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  201.36 + * to extend the choice of license to its licensees as provided above.
  201.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  201.38 + * Version 2 license, then the option applies only if the new code is
  201.39 + * made subject to such option by the copyright holder.
  201.40 + *
  201.41 + * Contributor(s):
  201.42 + *
  201.43 + * Portions Copyrighted 2009-2010 Sun Microsystems, Inc.
  201.44 + */
  201.45 +
  201.46 +package org.netbeans.modules.java.hints.providers.spi;
  201.47 +
  201.48 +import java.util.Arrays;
  201.49 +import java.util.Collections;
  201.50 +import java.util.EnumSet;
  201.51 +import java.util.Set;
  201.52 +import org.netbeans.api.annotations.common.NonNull;
  201.53 +import org.netbeans.modules.java.hints.providers.spi.HintDescription.AdditionalQueryConstraints;
  201.54 +import org.netbeans.modules.java.hints.providers.spi.HintDescription.Worker;
  201.55 +import org.netbeans.modules.java.hints.providers.spi.HintMetadata.Options;
  201.56 +
  201.57 +/**
  201.58 + *
  201.59 + * @author lahvac
  201.60 + */
  201.61 +public class HintDescriptionFactory {
  201.62 +
  201.63 +    private       HintMetadata metadata;
  201.64 +    private       Trigger trigger;
  201.65 +    private       Worker worker;
  201.66 +    private       AdditionalQueryConstraints additionalConstraints;
  201.67 +    private       String hintText;
  201.68 +    private       Set<Options> options;
  201.69 +    private       boolean finished;
  201.70 +
  201.71 +    private HintDescriptionFactory() {
  201.72 +    }
  201.73 +
  201.74 +    public static HintDescriptionFactory create() {
  201.75 +        return new HintDescriptionFactory();
  201.76 +    }
  201.77 +
  201.78 +    /**TODO: move to create?
  201.79 +     *
  201.80 +     * @param metadata
  201.81 +     * @return
  201.82 +     */
  201.83 +    public HintDescriptionFactory setMetadata(HintMetadata metadata) {
  201.84 +        this.metadata = metadata;
  201.85 +        return this;
  201.86 +    }
  201.87 +
  201.88 +    public HintDescriptionFactory setTrigger(Trigger trigger) {
  201.89 +        if (this.trigger != null) {
  201.90 +            throw new IllegalStateException(this.trigger.toString());
  201.91 +        }
  201.92 +
  201.93 +        this.trigger = trigger;
  201.94 +        return this;
  201.95 +    }
  201.96 +
  201.97 +    public HintDescriptionFactory setWorker(Worker worker) {
  201.98 +        this.worker = worker;
  201.99 +        return this;
 201.100 +    }
 201.101 +
 201.102 +    public HintDescriptionFactory setAdditionalConstraints(AdditionalQueryConstraints additionalConstraints) {
 201.103 +        this.additionalConstraints = additionalConstraints;
 201.104 +        return this;
 201.105 +    }
 201.106 +
 201.107 +    public HintDescriptionFactory setHintText(@NonNull String hintText) {
 201.108 +        this.hintText = hintText;
 201.109 +        return this;
 201.110 +    }
 201.111 +
 201.112 +    public HintDescriptionFactory addOptions(Options... options) {
 201.113 +        if (this.options == null) {
 201.114 +            this.options = EnumSet.noneOf(Options.class);
 201.115 +        }
 201.116 +        this.options.addAll(Arrays.asList(options));
 201.117 +        return this;
 201.118 +    }
 201.119 +        
 201.120 +    public HintDescription produce() {
 201.121 +        if (metadata == null) {
 201.122 +            metadata = HintMetadata.Builder.create("no-id").addOptions(Options.NON_GUI).build();
 201.123 +        }
 201.124 +        if (this.additionalConstraints == null) {
 201.125 +            this.additionalConstraints = AdditionalQueryConstraints.empty();
 201.126 +        }
 201.127 +        return HintDescription.create(metadata, trigger, worker, additionalConstraints, hintText, options != null ? options : Collections.<Options>emptySet());
 201.128 +    }
 201.129 +    
 201.130 +}
   202.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   202.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/HintMetadata.java	Sun Oct 23 11:50:54 2016 +0200
   202.3 @@ -0,0 +1,224 @@
   202.4 +/*
   202.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   202.6 + *
   202.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
   202.8 + *
   202.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  202.10 + * Other names may be trademarks of their respective owners.
  202.11 + *
  202.12 + * The contents of this file are subject to the terms of either the GNU
  202.13 + * General Public License Version 2 only ("GPL") or the Common
  202.14 + * Development and Distribution License("CDDL") (collectively, the
  202.15 + * "License"). You may not use this file except in compliance with the
  202.16 + * License. You can obtain a copy of the License at
  202.17 + * http://www.netbeans.org/cddl-gplv2.html
  202.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  202.19 + * specific language governing permissions and limitations under the
  202.20 + * License.  When distributing the software, include this License Header
  202.21 + * Notice in each file and include the License file at
  202.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  202.23 + * particular file as subject to the "Classpath" exception as provided
  202.24 + * by Oracle in the GPL Version 2 section of the License file that
  202.25 + * accompanied this code. If applicable, add the following below the
  202.26 + * License Header, with the fields enclosed by brackets [] replaced by
  202.27 + * your own identifying information:
  202.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  202.29 + *
  202.30 + * If you wish your version of this file to be governed by only the CDDL
  202.31 + * or only the GPL Version 2, indicate your decision by adding
  202.32 + * "[Contributor] elects to include this software in this distribution
  202.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  202.34 + * single choice of license, a recipient has the option to distribute
  202.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  202.36 + * to extend the choice of license to its licensees as provided above.
  202.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  202.38 + * Version 2 license, then the option applies only if the new code is
  202.39 + * made subject to such option by the copyright holder.
  202.40 + *
  202.41 + * Contributor(s):
  202.42 + *
  202.43 + * Portions Copyrighted 2010 Sun Microsystems, Inc.
  202.44 + */
  202.45 +
  202.46 +package org.netbeans.modules.java.hints.providers.spi;
  202.47 +
  202.48 +import java.util.ArrayList;
  202.49 +import java.util.Arrays;
  202.50 +import java.util.Collection;
  202.51 +import java.util.EnumSet;
  202.52 +import java.util.HashSet;
  202.53 +import java.util.MissingResourceException;
  202.54 +import java.util.ResourceBundle;
  202.55 +import java.util.Set;
  202.56 +import java.util.logging.Level;
  202.57 +import java.util.logging.Logger;
  202.58 +import org.netbeans.spi.editor.hints.Severity;
  202.59 +import org.netbeans.spi.java.hints.CustomizerProvider;
  202.60 +import org.netbeans.spi.java.hints.Hint;
  202.61 +import org.openide.util.NbBundle;
  202.62 +
  202.63 +/**
  202.64 + *
  202.65 + * @author lahvac
  202.66 + */
  202.67 +public class HintMetadata {
  202.68 +
  202.69 +    public final String id;
  202.70 +    public final String displayName;
  202.71 +    public final String description;
  202.72 +    public final String category;
  202.73 +    public final boolean enabled;
  202.74 +    public final Hint.Kind kind;
  202.75 +    public final Severity severity;
  202.76 +    public final Collection<? extends String> suppressWarnings;
  202.77 +    public final CustomizerProvider customizer;
  202.78 +    public final boolean showInTaskList = false;
  202.79 +    public final Set<Options> options;
  202.80 +
  202.81 +    HintMetadata(String id, String displayName, String description, String category, boolean enabled, Hint.Kind kind, Severity severity, Collection<? extends String> suppressWarnings, CustomizerProvider customizer, Set<Options> options) {
  202.82 +        this.id = id;
  202.83 +        this.displayName = displayName;
  202.84 +        this.description = description;
  202.85 +        this.category = category;
  202.86 +        this.enabled = enabled;
  202.87 +        this.kind = kind;
  202.88 +        this.severity = severity;
  202.89 +        this.suppressWarnings = suppressWarnings;
  202.90 +        this.customizer = customizer;
  202.91 +        this.options = options;
  202.92 +    }
  202.93 +
  202.94 +    @Override
  202.95 +    public String toString() {
  202.96 +        return this.displayName;
  202.97 +    }
  202.98 +
  202.99 +    private static String lookup(ResourceBundle bundle, String key, String def) {
 202.100 +        try {
 202.101 +            return bundle != null ? bundle.getString(key) : def;
 202.102 +        } catch (MissingResourceException mre) {
 202.103 +            Logger.getLogger(HintMetadata.class.getName()).log(Level.FINE, null, mre);
 202.104 +            return def;
 202.105 +        }
 202.106 +    }
 202.107 +
 202.108 +    public static final class Builder {
 202.109 +        private final String id;
 202.110 +        private String displayName;
 202.111 +        private String description;
 202.112 +        private String category;
 202.113 +        private boolean enabled;
 202.114 +        private Hint.Kind kind;
 202.115 +        private Severity severity;
 202.116 +        private final Collection<String> suppressWarnings = new ArrayList<String>();
 202.117 +        private CustomizerProvider customizer;
 202.118 +        private final Set<Options> options = EnumSet.noneOf(Options.class);
 202.119 +
 202.120 +        private Builder(String id) {
 202.121 +            this.id = id;
 202.122 +            this.displayName = "";
 202.123 +            this.description = "";
 202.124 +            this.category = "";
 202.125 +            this.enabled = true;
 202.126 +            this.kind = Hint.Kind.INSPECTION;
 202.127 +            this.severity = Severity.VERIFIER;
 202.128 +        }
 202.129 +
 202.130 +        public static Builder create(String id) {
 202.131 +            return new Builder(id);
 202.132 +        }
 202.133 +
 202.134 +        public Builder setDescription(String displayName, String description) {
 202.135 +            this.displayName = displayName;
 202.136 +            this.description = description;
 202.137 +            return this;
 202.138 +        }
 202.139 +
 202.140 +        public Builder setBundle(ResourceBundle bundle) {
 202.141 +            return setBundle(bundle, null, null);
 202.142 +        }
 202.143 +
 202.144 +        public Builder setBundle(ResourceBundle bundle, String fallbackDisplayName, String fallbackDescription) {
 202.145 +            if (fallbackDisplayName == null) fallbackDisplayName = "No Display Name";
 202.146 +            if (fallbackDescription == null) fallbackDescription = "No Description";
 202.147 +            
 202.148 +            this.displayName = lookup(bundle, "DN_" + id.replace('$', '.'), fallbackDisplayName);
 202.149 +            this.description = lookup(bundle, "DESC_" + id.replace('$', '.'), fallbackDescription);
 202.150 +            return this;
 202.151 +        }
 202.152 +
 202.153 +        public Builder setBundle(String bundleForFQN) {
 202.154 +            ResourceBundle bundle;
 202.155 +
 202.156 +            try {
 202.157 +                int lastDot = bundleForFQN.lastIndexOf('.');
 202.158 +
 202.159 +                assert lastDot >= 0;
 202.160 +
 202.161 +                bundle = NbBundle.getBundle(bundleForFQN.substring(0, lastDot + 1) + "Bundle");
 202.162 +            } catch (MissingResourceException mre) {
 202.163 +                Logger.getLogger(HintMetadata.class.getName()).log(Level.FINE, null, mre);
 202.164 +                bundle = null;
 202.165 +            }
 202.166 +            return setBundle(bundle);
 202.167 +        }
 202.168 +
 202.169 +        public Builder setCategory(String category) {
 202.170 +            this.category = category;
 202.171 +            return this;
 202.172 +        }
 202.173 +
 202.174 +        public Builder setEnabled(boolean enabled) {
 202.175 +            this.enabled = enabled;
 202.176 +            return this;
 202.177 +        }
 202.178 +
 202.179 +        public Builder setKind(Hint.Kind kind) {
 202.180 +            this.kind = kind;
 202.181 +            return this;
 202.182 +        }
 202.183 +
 202.184 +        public Builder setSeverity(Severity severity) {
 202.185 +            this.severity = severity;
 202.186 +            return this;
 202.187 +        }
 202.188 +
 202.189 +
 202.190 +        public Builder addSuppressWarnings(String... keys) {
 202.191 +            this.suppressWarnings.addAll(Arrays.asList(keys));
 202.192 +            return this;
 202.193 +        }
 202.194 +
 202.195 +        public Builder setCustomizerProvider(CustomizerProvider customizer) {
 202.196 +            this.customizer = customizer;
 202.197 +            return this;
 202.198 +        }
 202.199 +
 202.200 +        public Builder addOptions(Options... options) {
 202.201 +            this.options.addAll(Arrays.asList(options));
 202.202 +            return this;
 202.203 +        }
 202.204 +
 202.205 +        public HintMetadata build() {
 202.206 +            return new HintMetadata(id, displayName, description, category, enabled, kind, severity, suppressWarnings, customizer, options);
 202.207 +        }
 202.208 +
 202.209 +    }
 202.210 +
 202.211 +    public enum Options {
 202.212 +        NON_GUI,
 202.213 +        QUERY,
 202.214 +        NO_BATCH,
 202.215 +        HEAVY;
 202.216 +
 202.217 +        public static Set<Options> fromHintOptions(Hint.Options... options) {
 202.218 +            Set<Options> result = new HashSet<Options>();
 202.219 +
 202.220 +            for (Hint.Options opt : options) {
 202.221 +                result.add(valueOf(opt.name()));
 202.222 +            }
 202.223 +
 202.224 +            return result;
 202.225 +        }
 202.226 +    }
 202.227 +}
   203.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   203.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/HintProvider.java	Sun Oct 23 11:50:54 2016 +0200
   203.3 @@ -0,0 +1,54 @@
   203.4 +/*
   203.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   203.6 + *
   203.7 + * Copyright 2009-2010 Oracle and/or its affiliates. All rights reserved.
   203.8 + *
   203.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  203.10 + * Other names may be trademarks of their respective owners.
  203.11 + *
  203.12 + * The contents of this file are subject to the terms of either the GNU
  203.13 + * General Public License Version 2 only ("GPL") or the Common
  203.14 + * Development and Distribution License("CDDL") (collectively, the
  203.15 + * "License"). You may not use this file except in compliance with the
  203.16 + * License. You can obtain a copy of the License at
  203.17 + * http://www.netbeans.org/cddl-gplv2.html
  203.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  203.19 + * specific language governing permissions and limitations under the
  203.20 + * License.  When distributing the software, include this License Header
  203.21 + * Notice in each file and include the License file at
  203.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  203.23 + * particular file as subject to the "Classpath" exception as provided
  203.24 + * by Oracle in the GPL Version 2 section of the License file that
  203.25 + * accompanied this code. If applicable, add the following below the
  203.26 + * License Header, with the fields enclosed by brackets [] replaced by
  203.27 + * your own identifying information:
  203.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  203.29 + *
  203.30 + * If you wish your version of this file to be governed by only the CDDL
  203.31 + * or only the GPL Version 2, indicate your decision by adding
  203.32 + * "[Contributor] elects to include this software in this distribution
  203.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  203.34 + * single choice of license, a recipient has the option to distribute
  203.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  203.36 + * to extend the choice of license to its licensees as provided above.
  203.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  203.38 + * Version 2 license, then the option applies only if the new code is
  203.39 + * made subject to such option by the copyright holder.
  203.40 + *
  203.41 + * Contributor(s):
  203.42 + *
  203.43 + * Portions Copyrighted 2009-2010 Sun Microsystems, Inc.
  203.44 + */
  203.45 +
  203.46 +package org.netbeans.modules.java.hints.providers.spi;
  203.47 +
  203.48 +import java.util.Collection;
  203.49 +import java.util.Map;
  203.50 +import org.netbeans.modules.java.hints.providers.spi.HintDescription;
  203.51 +import org.netbeans.modules.java.hints.providers.spi.HintMetadata;
  203.52 +
  203.53 +public interface HintProvider {
  203.54 +
  203.55 +    public Map<HintMetadata, ? extends Collection<? extends HintDescription>> computeHints();
  203.56 +
  203.57 +}
   204.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   204.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/PositionRefresherHelper.java	Sun Oct 23 11:50:54 2016 +0200
   204.3 @@ -0,0 +1,105 @@
   204.4 +/*
   204.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   204.6 + *
   204.7 + * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
   204.8 + *
   204.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  204.10 + * Other names may be trademarks of their respective owners.
  204.11 + *
  204.12 + * The contents of this file are subject to the terms of either the GNU
  204.13 + * General Public License Version 2 only ("GPL") or the Common
  204.14 + * Development and Distribution License("CDDL") (collectively, the
  204.15 + * "License"). You may not use this file except in compliance with the
  204.16 + * License. You can obtain a copy of the License at
  204.17 + * http://www.netbeans.org/cddl-gplv2.html
  204.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  204.19 + * specific language governing permissions and limitations under the
  204.20 + * License.  When distributing the software, include this License Header
  204.21 + * Notice in each file and include the License file at
  204.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  204.23 + * particular file as subject to the "Classpath" exception as provided
  204.24 + * by Oracle in the GPL Version 2 section of the License file that
  204.25 + * accompanied this code. If applicable, add the following below the
  204.26 + * License Header, with the fields enclosed by brackets [] replaced by
  204.27 + * your own identifying information:
  204.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  204.29 + *
  204.30 + * If you wish your version of this file to be governed by only the CDDL
  204.31 + * or only the GPL Version 2, indicate your decision by adding
  204.32 + * "[Contributor] elects to include this software in this distribution
  204.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  204.34 + * single choice of license, a recipient has the option to distribute
  204.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  204.36 + * to extend the choice of license to its licensees as provided above.
  204.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  204.38 + * Version 2 license, then the option applies only if the new code is
  204.39 + * made subject to such option by the copyright holder.
  204.40 + *
  204.41 + * Contributor(s):
  204.42 + *
  204.43 + * Portions Copyrighted 2012 Sun Microsystems, Inc.
  204.44 + */
  204.45 +package org.netbeans.modules.java.hints.providers.spi;
  204.46 +
  204.47 +import java.util.List;
  204.48 +import javax.swing.text.Document;
  204.49 +import org.netbeans.api.annotations.common.CheckForNull;
  204.50 +import org.netbeans.api.java.source.CompilationInfo;
  204.51 +import org.netbeans.lib.editor.util.swing.DocumentUtilities;
  204.52 +import org.netbeans.spi.editor.hints.Context;
  204.53 +import org.netbeans.spi.editor.hints.ErrorDescription;
  204.54 +import org.netbeans.modules.java.hints.providers.spi.PositionRefresherHelper.DocumentVersion;
  204.55 +
  204.56 +/**TODO: should be public?
  204.57 + *
  204.58 + * @author lahvac
  204.59 + */
  204.60 +public abstract class PositionRefresherHelper<V extends DocumentVersion> {
  204.61 +
  204.62 +    private final Object documentKey = new Object();
  204.63 +    private final String key;
  204.64 +
  204.65 +    protected PositionRefresherHelper(String key) {
  204.66 +        this.key = key;
  204.67 +    }
  204.68 +
  204.69 +    protected abstract boolean isUpToDate(Context context, Document doc, V oldVersion);
  204.70 +    /**XXX: should be protected*/public abstract @CheckForNull List<ErrorDescription> getErrorDescriptionsAt(CompilationInfo info, Context context, Document doc) throws Exception;
  204.71 +
  204.72 +    protected final void setVersion(Document doc, V version) {
  204.73 +        if (doc != null) {
  204.74 +            doc.putProperty(documentKey, version);
  204.75 +        }
  204.76 +    }
  204.77 +
  204.78 +    protected @CheckForNull V getUpToDateDocumentVersion(Context context, Document doc) {
  204.79 +        V oldVersion = (V) doc.getProperty(documentKey);
  204.80 +
  204.81 +        if (oldVersion == null) return null;
  204.82 +
  204.83 +        if (((DocumentVersion) oldVersion).version != DocumentUtilities.getDocumentVersion(doc)) return null;
  204.84 +        
  204.85 +        return oldVersion;
  204.86 +    }
  204.87 +    
  204.88 +    /**XXX*/ public boolean upToDateCheck(Context context, Document doc) {
  204.89 +        V oldVersion = getUpToDateDocumentVersion(context, doc);
  204.90 +
  204.91 +        if (oldVersion == null) return false;
  204.92 +
  204.93 +        return isUpToDate(context, doc, oldVersion);
  204.94 +    }
  204.95 +
  204.96 +    /**XXX*/ public String getKey() {
  204.97 +        return key;
  204.98 +    }
  204.99 +
 204.100 +    public static class DocumentVersion {
 204.101 +        private final long version;
 204.102 +
 204.103 +        public DocumentVersion(Document doc) {
 204.104 +            this.version = doc != null ? DocumentUtilities.getDocumentVersion(doc) : 0;
 204.105 +        }
 204.106 +
 204.107 +    }
 204.108 +}
   205.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   205.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/providers/spi/Trigger.java	Sun Oct 23 11:50:54 2016 +0200
   205.3 @@ -0,0 +1,171 @@
   205.4 +/*
   205.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   205.6 + *
   205.7 + * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
   205.8 + *
   205.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  205.10 + * Other names may be trademarks of their respective owners.
  205.11 + *
  205.12 + * The contents of this file are subject to the terms of either the GNU
  205.13 + * General Public License Version 2 only ("GPL") or the Common
  205.14 + * Development and Distribution License("CDDL") (collectively, the
  205.15 + * "License"). You may not use this file except in compliance with the
  205.16 + * License. You can obtain a copy of the License at
  205.17 + * http://www.netbeans.org/cddl-gplv2.html
  205.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  205.19 + * specific language governing permissions and limitations under the
  205.20 + * License.  When distributing the software, include this License Header
  205.21 + * Notice in each file and include the License file at
  205.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  205.23 + * particular file as subject to the "Classpath" exception as provided
  205.24 + * by Oracle in the GPL Version 2 section of the License file that
  205.25 + * accompanied this code. If applicable, add the following below the
  205.26 + * License Header, with the fields enclosed by brackets [] replaced by
  205.27 + * your own identifying information:
  205.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  205.29 + *
  205.30 + * If you wish your version of this file to be governed by only the CDDL
  205.31 + * or only the GPL Version 2, indicate your decision by adding
  205.32 + * "[Contributor] elects to include this software in this distribution
  205.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  205.34 + * single choice of license, a recipient has the option to distribute
  205.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  205.36 + * to extend the choice of license to its licensees as provided above.
  205.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  205.38 + * Version 2 license, then the option applies only if the new code is
  205.39 + * made subject to such option by the copyright holder.
  205.40 + *
  205.41 + * Contributor(s):
  205.42 + *
  205.43 + * Portions Copyrighted 2011 Sun Microsystems, Inc.
  205.44 + */
  205.45 +package org.netbeans.modules.java.hints.providers.spi;
  205.46 +
  205.47 +import com.sun.source.tree.Tree.Kind;
  205.48 +import java.util.Arrays;
  205.49 +import java.util.Map;
  205.50 +import java.util.Set;
  205.51 +import org.netbeans.api.java.source.matching.Pattern;
  205.52 +import org.netbeans.spi.java.hints.Decision;
  205.53 +import org.openide.util.Parameters;
  205.54 +
  205.55 +/**A base class for triggers.
  205.56 + *
  205.57 + * @author lahvac
  205.58 + */
  205.59 +public abstract class Trigger {
  205.60 +
  205.61 +    Trigger() {}
  205.62 +
  205.63 +    /**Invoke the given hint's worker on the specified {@link Tree.Kind}(s).
  205.64 +     *
  205.65 +     */
  205.66 +    public static final class Kinds extends Trigger {
  205.67 +        private final Set<Kind> kinds;
  205.68 +
  205.69 +        /**Create the trigger for the specified set of {@link Tree.Kind}s.
  205.70 +         *
  205.71 +         * @param kinds on which the hint's worker should be invoked.
  205.72 +         */
  205.73 +        public Kinds(Set<Kind> kinds) {
  205.74 +            this.kinds = kinds;
  205.75 +        }
  205.76 +
  205.77 +        public Iterable<? extends Kind> getKinds() {
  205.78 +            return kinds;
  205.79 +        }
  205.80 +
  205.81 +        @Override
  205.82 +        public String toString() {
  205.83 +            return kinds.toString();
  205.84 +        }
  205.85 +    }
  205.86 +
  205.87 +    /**Invoke the hint's worker on tree nodes that match the given pattern.
  205.88 +     *
  205.89 +     */
  205.90 +    public static final class PatternDescription extends Trigger {
  205.91 +
  205.92 +        private final String pattern;
  205.93 +        private final Map<String, String> constraints;
  205.94 +        private final Iterable<? extends String> imports;
  205.95 +
  205.96 +        private PatternDescription(String pattern, Map<String, String> constraints, String... imports) {
  205.97 +            this.pattern = pattern;
  205.98 +            this.constraints = constraints;
  205.99 +            this.imports = Arrays.asList(imports);
 205.100 +        }
 205.101 +
 205.102 +        /** Create the trigger to invoke the hint's worker on tree nodes that match the given pattern.
 205.103 +         *
 205.104 +         * @param pattern which will be interpreted as a pattern with free variables ({@link Pattern#createPatternWithFreeVariables(com.sun.source.util.TreePath, java.util.Map) }.
 205.105 +         * @param constraints are expected to be mapping from a free variable name to the expected type.
 205.106 +         * @param XXX: document the imports
 205.107 +         * @return the created trigger.
 205.108 +         */
 205.109 +        public static PatternDescription create(String pattern, Map<String, String> constraints, String... imports) {
 205.110 +            Parameters.notNull("pattern", pattern);
 205.111 +            Parameters.notNull("constraints", constraints);
 205.112 +            Parameters.notNull("imports", imports);
 205.113 +
 205.114 +            return new PatternDescription(pattern, constraints, imports);
 205.115 +        }
 205.116 +
 205.117 +        @Override
 205.118 +        public boolean equals(Object obj) {
 205.119 +            if (obj == null) {
 205.120 +                return false;
 205.121 +            }
 205.122 +            if (getClass() != obj.getClass()) {
 205.123 +                return false;
 205.124 +            }
 205.125 +            final PatternDescription other = (PatternDescription) obj;
 205.126 +            if ((this.pattern == null) ? (other.pattern != null) : !this.pattern.equals(other.pattern)) {
 205.127 +                return false;
 205.128 +            }
 205.129 +            if (this.constraints != other.constraints && (this.constraints == null || !this.constraints.equals(other.constraints))) {
 205.130 +                return false;
 205.131 +            }
 205.132 +            return true;
 205.133 +        }
 205.134 +
 205.135 +        @Override
 205.136 +        public int hashCode() {
 205.137 +            int hash = 7;
 205.138 +            hash = 71 * hash + (this.pattern != null ? this.pattern.hashCode() : 0);
 205.139 +            hash = 71 * hash + (this.constraints != null ? this.constraints.hashCode() : 0);
 205.140 +            return hash;
 205.141 +        }
 205.142 +
 205.143 +        public String getPattern() {
 205.144 +            return pattern;
 205.145 +        }
 205.146 +
 205.147 +        public Map<String, String> getConstraints() {
 205.148 +            return constraints;
 205.149 +        }
 205.150 +
 205.151 +        public Iterable<? extends String> getImports() {
 205.152 +            return imports;
 205.153 +        }
 205.154 +
 205.155 +        @Override
 205.156 +        public String toString() {
 205.157 +            return pattern;
 205.158 +        }
 205.159 +
 205.160 +    }
 205.161 +    
 205.162 +    public static final class DecisionTrigger extends Trigger {
 205.163 +        private final Class<? extends Decision> decisionClass;
 205.164 +
 205.165 +        public DecisionTrigger(Class<? extends Decision> decisionClass) {
 205.166 +            this.decisionClass = decisionClass;
 205.167 +        }
 205.168 +
 205.169 +        public Class<? extends Decision> getDecisionClass() {
 205.170 +            return decisionClass;
 205.171 +        }
 205.172 +    }
 205.173 +
 205.174 +}
   206.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   206.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/Bundle.properties	Sun Oct 23 11:50:54 2016 +0200
   206.3 @@ -0,0 +1,4 @@
   206.4 +OpenIDE-Module-Name=Java Hints SPI
   206.5 +
   206.6 +#refresh hints
   206.7 +Refresh_hints=Refresh Hints
   207.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   207.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/Hacks.java	Sun Oct 23 11:50:54 2016 +0200
   207.3 @@ -0,0 +1,219 @@
   207.4 +/*
   207.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   207.6 + *
   207.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
   207.8 + *
   207.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  207.10 + * Other names may be trademarks of their respective owners.
  207.11 + *
  207.12 + * The contents of this file are subject to the terms of either the GNU
  207.13 + * General Public License Version 2 only ("GPL") or the Common
  207.14 + * Development and Distribution License("CDDL") (collectively, the
  207.15 + * "License"). You may not use this file except in compliance with the
  207.16 + * License. You can obtain a copy of the License at
  207.17 + * http://www.netbeans.org/cddl-gplv2.html
  207.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  207.19 + * specific language governing permissions and limitations under the
  207.20 + * License.  When distributing the software, include this License Header
  207.21 + * Notice in each file and include the License file at
  207.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  207.23 + * particular file as subject to the "Classpath" exception as provided
  207.24 + * by Oracle in the GPL Version 2 section of the License file that
  207.25 + * accompanied this code. If applicable, add the following below the
  207.26 + * License Header, with the fields enclosed by brackets [] replaced by
  207.27 + * your own identifying information:
  207.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  207.29 + *
  207.30 + * If you wish your version of this file to be governed by only the CDDL
  207.31 + * or only the GPL Version 2, indicate your decision by adding
  207.32 + * "[Contributor] elects to include this software in this distribution
  207.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  207.34 + * single choice of license, a recipient has the option to distribute
  207.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  207.36 + * to extend the choice of license to its licensees as provided above.
  207.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  207.38 + * Version 2 license, then the option applies only if the new code is
  207.39 + * made subject to such option by the copyright holder.
  207.40 + *
  207.41 + * Contributor(s):
  207.42 + *
  207.43 + * Portions Copyrighted 2009 Sun Microsystems, Inc.
  207.44 + */
  207.45 +
  207.46 +package org.netbeans.modules.java.hints.spiimpl;
  207.47 +
  207.48 +import com.sun.source.tree.BlockTree;
  207.49 +import com.sun.source.tree.CompilationUnitTree;
  207.50 +import com.sun.source.tree.MethodTree;
  207.51 +import com.sun.source.tree.Scope;
  207.52 +import com.sun.source.tree.Tree;
  207.53 +import com.sun.source.util.TreePath;
  207.54 +import com.sun.source.util.TreePathScanner;
  207.55 +import com.sun.tools.javac.api.JavacTaskImpl;
  207.56 +import com.sun.tools.javac.code.Symbol.ClassSymbol;
  207.57 +import com.sun.tools.javac.comp.AttrContext;
  207.58 +import com.sun.tools.javac.comp.Enter;
  207.59 +import com.sun.tools.javac.comp.Env;
  207.60 +import com.sun.tools.javac.main.JavaCompiler;
  207.61 +import com.sun.tools.javac.tree.JCTree;
  207.62 +import com.sun.tools.javac.tree.JCTree.JCErroneous;
  207.63 +import com.sun.tools.javac.util.Context;
  207.64 +import com.sun.tools.javac.util.Log;
  207.65 +import java.io.File;
  207.66 +import java.io.IOException;
  207.67 +import javax.lang.model.element.Element;
  207.68 +import javax.lang.model.element.TypeElement;
  207.69 +import javax.lang.model.element.VariableElement;
  207.70 +import javax.lang.model.type.TypeMirror;
  207.71 +import javax.tools.JavaFileObject;
  207.72 +import org.netbeans.api.annotations.common.CheckForNull;
  207.73 +import org.netbeans.api.annotations.common.NonNull;
  207.74 +import org.netbeans.api.java.source.CompilationInfo;
  207.75 +import org.netbeans.api.java.source.TreeUtilities;
  207.76 +import org.netbeans.modules.java.hints.providers.spi.HintMetadata;
  207.77 +import org.netbeans.modules.java.source.JavaSourceAccessor;
  207.78 +import org.netbeans.modules.java.source.parsing.FileObjects;
  207.79 +import org.openide.util.Exceptions;
  207.80 +
  207.81 +/**
  207.82 + *
  207.83 + * @author lahvac
  207.84 + */
  207.85 +public class Hacks {
  207.86 +
  207.87 +    //XXX: copied from Utilities, for declarative hints, different import management:
  207.88 +    private static long inc;
  207.89 +
  207.90 +    public static Scope constructScope(CompilationInfo info, String... importedClasses) {
  207.91 +        StringBuilder clazz = new StringBuilder();
  207.92 +
  207.93 +        clazz.append("package $$;\n");
  207.94 +
  207.95 +        for (String i : importedClasses) {
  207.96 +            clazz.append("import ").append(i).append(";\n");
  207.97 +        }
  207.98 +
  207.99 +        clazz.append("public class $").append(inc++).append("{");
 207.100 +
 207.101 +        clazz.append("private void test() {\n");
 207.102 +        clazz.append("}\n");
 207.103 +        clazz.append("}\n");
 207.104 +
 207.105 +        JavacTaskImpl jti = JavaSourceAccessor.getINSTANCE().getJavacTask(info);
 207.106 +        Context context = jti.getContext();
 207.107 +
 207.108 +        JavaCompiler jc = JavaCompiler.instance(context);
 207.109 +        Log.instance(context).nerrors = 0;
 207.110 +
 207.111 +        JavaFileObject jfo = FileObjects.memoryFileObject("$$", "$", new File("/tmp/t.java").toURI(), System.currentTimeMillis(), clazz.toString());
 207.112 +        boolean oldSkipAPs = jc.skipAnnotationProcessing;
 207.113 +
 207.114 +        try {
 207.115 +            jc.skipAnnotationProcessing = true;
 207.116 +
 207.117 +            Iterable<? extends CompilationUnitTree> parsed = jti.parse(jfo);
 207.118 +            CompilationUnitTree cut = parsed.iterator().next();
 207.119 +
 207.120 +            jti.analyze(jti.enter(parsed));
 207.121 +
 207.122 +            return new ScannerImpl().scan(cut, info);
 207.123 +        } catch (IOException ex) {
 207.124 +            Exceptions.printStackTrace(ex);
 207.125 +            return null;
 207.126 +        } finally {
 207.127 +            jc.skipAnnotationProcessing = oldSkipAPs;
 207.128 +        }
 207.129 +    }
 207.130 +
 207.131 +    private static final class ScannerImpl extends TreePathScanner<Scope, CompilationInfo> {
 207.132 +
 207.133 +        @Override
 207.134 +        public Scope visitBlock(BlockTree node, CompilationInfo p) {
 207.135 +            return p.getTrees().getScope(getCurrentPath());
 207.136 +        }
 207.137 +
 207.138 +        @Override
 207.139 +        public Scope visitMethod(MethodTree node, CompilationInfo p) {
 207.140 +            if (node.getReturnType() == null) {
 207.141 +                return null;
 207.142 +            }
 207.143 +            return super.visitMethod(node, p);
 207.144 +        }
 207.145 +
 207.146 +        @Override
 207.147 +        public Scope reduce(Scope r1, Scope r2) {
 207.148 +            return r1 != null ? r1 : r2;
 207.149 +        }
 207.150 +
 207.151 +    }
 207.152 +
 207.153 +
 207.154 +    public static Tree createRenameTree(@NonNull Tree originalTree, @NonNull String newName) {
 207.155 +        return new RenameTree(originalTree, newName);
 207.156 +    }
 207.157 +
 207.158 +    public static final class RenameTree extends JCErroneous {
 207.159 +
 207.160 +        public final Tree originalTree;
 207.161 +        public final String newName;
 207.162 +
 207.163 +        public RenameTree(@NonNull Tree originalTree, @NonNull String newName) {
 207.164 +            super(com.sun.tools.javac.util.List.<JCTree>nil());
 207.165 +            this.originalTree = originalTree;
 207.166 +            this.newName = newName;
 207.167 +        }
 207.168 +
 207.169 +    }
 207.170 +
 207.171 +    public static @CheckForNull TypeMirror parseFQNType(@NonNull CompilationInfo info, @NonNull String spec) {
 207.172 +        if (spec.length() == 0) {
 207.173 +            return null;
 207.174 +        }
 207.175 +        
 207.176 +        TypeElement jlObject = info.getElements().getTypeElement("java.lang.Object");
 207.177 +        
 207.178 +        //XXX:
 207.179 +        TypeElement scope;
 207.180 +
 207.181 +        if (info.getTopLevelElements().isEmpty()) {
 207.182 +            scope = jlObject;
 207.183 +        } else {
 207.184 +            scope = info.getTopLevelElements().iterator().next();
 207.185 +        }
 207.186 +        //XXX end
 207.187 +        
 207.188 +        return info.getTreeUtilities().parseType(spec, /*XXX: jlObject*/scope);
 207.189 +    }
 207.190 +
 207.191 +    public static VariableElement attributeThis(CompilationInfo info, TreePath tp) {
 207.192 +        //XXX:
 207.193 +        while (tp != null) {
 207.194 +            if (TreeUtilities.CLASS_TREE_KINDS.contains(tp.getLeaf().getKind())) {
 207.195 +                Element currentElement = info.getTrees().getElement(tp);
 207.196 +
 207.197 +                if (currentElement == null || !(currentElement instanceof ClassSymbol)) return null;
 207.198 +
 207.199 +                Enter enter = Enter.instance(JavaSourceAccessor.getINSTANCE().getJavacTask(info).getContext());
 207.200 +                Env<AttrContext> env = enter.getEnv((ClassSymbol) currentElement);
 207.201 +
 207.202 +                if (env == null) return null;
 207.203 +
 207.204 +                for (Element el : env.info.getLocalElements()) {
 207.205 +                    if (el.getSimpleName().contentEquals("this")) {
 207.206 +                        return (VariableElement) el;
 207.207 +                    }
 207.208 +                }
 207.209 +
 207.210 +                return null;
 207.211 +            }
 207.212 +
 207.213 +            tp = tp.getParentPath();
 207.214 +        }
 207.215 +
 207.216 +        return null;
 207.217 +    }
 207.218 +    
 207.219 +    public static interface InspectAndTransformOpener {
 207.220 +        public void openIAT(HintMetadata hm);
 207.221 +    }
 207.222 +}
   208.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   208.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/JackpotTrees.java	Sun Oct 23 11:50:54 2016 +0200
   208.3 @@ -0,0 +1,246 @@
   208.4 +/*
   208.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   208.6 + *
   208.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
   208.8 + *
   208.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  208.10 + * Other names may be trademarks of their respective owners.
  208.11 + *
  208.12 + * The contents of this file are subject to the terms of either the GNU
  208.13 + * General Public License Version 2 only ("GPL") or the Common
  208.14 + * Development and Distribution License("CDDL") (collectively, the
  208.15 + * "License"). You may not use this file except in compliance with the
  208.16 + * License. You can obtain a copy of the License at
  208.17 + * http://www.netbeans.org/cddl-gplv2.html
  208.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  208.19 + * specific language governing permissions and limitations under the
  208.20 + * License.  When distributing the software, include this License Header
  208.21 + * Notice in each file and include the License file at
  208.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  208.23 + * particular file as subject to the "Classpath" exception as provided
  208.24 + * by Oracle in the GPL Version 2 section of the License file that
  208.25 + * accompanied this code. If applicable, add the following below the
  208.26 + * License Header, with the fields enclosed by brackets [] replaced by
  208.27 + * your own identifying information:
  208.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  208.29 + *
  208.30 + * If you wish your version of this file to be governed by only the CDDL
  208.31 + * or only the GPL Version 2, indicate your decision by adding
  208.32 + * "[Contributor] elects to include this software in this distribution
  208.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  208.34 + * single choice of license, a recipient has the option to distribute
  208.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  208.36 + * to extend the choice of license to its licensees as provided above.
  208.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  208.38 + * Version 2 license, then the option applies only if the new code is
  208.39 + * made subject to such option by the copyright holder.
  208.40 + *
  208.41 + * Contributor(s):
  208.42 + *
  208.43 + * Portions Copyrighted 2010 Sun Microsystems, Inc.
  208.44 + */
  208.45 +
  208.46 +package org.netbeans.modules.java.hints.spiimpl;
  208.47 +
  208.48 +import com.sun.source.tree.IdentifierTree;
  208.49 +import com.sun.source.tree.TreeVisitor;
  208.50 +import com.sun.tools.javac.code.Symbol.VarSymbol;
  208.51 +import com.sun.tools.javac.code.Symtab;
  208.52 +import com.sun.tools.javac.tree.JCTree;
  208.53 +import com.sun.tools.javac.tree.JCTree.JCAnnotation;
  208.54 +import com.sun.tools.javac.tree.JCTree.JCBlock;
  208.55 +import com.sun.tools.javac.tree.JCTree.JCCase;
  208.56 +import com.sun.tools.javac.tree.JCTree.JCCatch;
  208.57 +import com.sun.tools.javac.tree.JCTree.JCModifiers;
  208.58 +import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
  208.59 +import com.sun.tools.javac.tree.TreeMaker;
  208.60 +import com.sun.tools.javac.util.Context;
  208.61 +import com.sun.tools.javac.util.List;
  208.62 +import com.sun.tools.javac.util.Name;
  208.63 +
  208.64 +
  208.65 +/**
  208.66 + *
  208.67 + * @author lahvac
  208.68 + */
  208.69 +public class JackpotTrees {
  208.70 +    public static class AnnotationWildcard extends JCAnnotation implements IdentifierTree {
  208.71 +
  208.72 +        private final Name ident;
  208.73 +        private final JCIdent jcIdent;
  208.74 +
  208.75 +        public AnnotationWildcard(Name ident, JCIdent jcIdent) {
  208.76 +            super(Tag.ANNOTATION, jcIdent, List.<JCExpression>nil());
  208.77 +            this.ident = ident;
  208.78 +            this.jcIdent = jcIdent;
  208.79 +        }
  208.80 +
  208.81 +        public Name getName() {
  208.82 +            return ident;
  208.83 +        }
  208.84 +
  208.85 +        @Override
  208.86 +        public Kind getKind() {
  208.87 +            return Kind.IDENTIFIER;
  208.88 +        }
  208.89 +
  208.90 +        @Override
  208.91 +        public void accept(Visitor v) {
  208.92 +            v.visitIdent(jcIdent);
  208.93 +        }
  208.94 +
  208.95 +        @Override
  208.96 +        public <R, D> R accept(TreeVisitor<R, D> v, D d) {
  208.97 +            return v.visitIdentifier(this, d);
  208.98 +        }
  208.99 +
 208.100 +        @Override
 208.101 +        public String toString() {
 208.102 +            return ident.toString();
 208.103 +        }
 208.104 +
 208.105 +    }
 208.106 +    
 208.107 +    public static class CatchWildcard extends JCCatch implements IdentifierTree {
 208.108 +
 208.109 +        private final Name ident;
 208.110 +        private final JCIdent jcIdent;
 208.111 +
 208.112 +        public CatchWildcard(Context ctx, Name ident, JCIdent jcIdent) {
 208.113 +            super(new FakeVariable(ctx, ident, jcIdent), TreeMaker.instance(ctx).Block(0, List.<JCStatement>nil()));
 208.114 +            this.ident = ident;
 208.115 +            this.jcIdent = jcIdent;
 208.116 +        }
 208.117 +
 208.118 +        public Name getName() {
 208.119 +            return ident;
 208.120 +        }
 208.121 +
 208.122 +        @Override
 208.123 +        public Kind getKind() {
 208.124 +            return Kind.IDENTIFIER;
 208.125 +        }
 208.126 +
 208.127 +        @Override
 208.128 +        public void accept(Visitor v) {
 208.129 +            v.visitIdent(jcIdent);
 208.130 +        }
 208.131 +
 208.132 +        @Override
 208.133 +        public <R, D> R accept(TreeVisitor<R, D> v, D d) {
 208.134 +            return v.visitIdentifier(this, d);
 208.135 +        }
 208.136 +
 208.137 +        @Override
 208.138 +        public String toString() {
 208.139 +            return "catch " + ident.toString();
 208.140 +        }
 208.141 +
 208.142 +    }
 208.143 +    
 208.144 +    public static class VariableWildcard extends FakeVariable implements IdentifierTree {
 208.145 +
 208.146 +        private final Name ident;
 208.147 +
 208.148 +        public VariableWildcard(Context ctx, Name ident, JCIdent jcIdent) {
 208.149 +            super(ctx, ident, jcIdent);
 208.150 +            this.ident = ident;
 208.151 +        }
 208.152 +
 208.153 +        public Name getName() {
 208.154 +            return ident;
 208.155 +        }
 208.156 +
 208.157 +        @Override
 208.158 +        public Kind getKind() {
 208.159 +            return Kind.IDENTIFIER;
 208.160 +        }
 208.161 +
 208.162 +        @Override
 208.163 +        public <R, D> R accept(TreeVisitor<R, D> v, D d) {
 208.164 +            return v.visitIdentifier(this, d);
 208.165 +        }
 208.166 +
 208.167 +        @Override
 208.168 +        public String toString() {
 208.169 +            return ident.toString();
 208.170 +        }
 208.171 +    }
 208.172 +
 208.173 +    private static class FakeVariable extends JCVariableDecl {
 208.174 +        
 208.175 +        private final JCIdent jcIdent;
 208.176 +
 208.177 +        public FakeVariable(Context ctx, Name ident, JCIdent jcIdent) {
 208.178 +            super(new FakeModifiers(), ident, createType(ctx), null, null);
 208.179 +            this.sym = new VarSymbol(0, name, type, Symtab.instance(ctx).errSymbol);
 208.180 +            this.type = vartype.type;
 208.181 +            this.jcIdent = jcIdent;
 208.182 +        }
 208.183 +
 208.184 +        private static JCErroneous createType(Context ctx) {
 208.185 +            JCErroneous err = new JCErroneous(List.<JCTree>nil()) {};
 208.186 +
 208.187 +            err.type = Symtab.instance(ctx).errType;
 208.188 +
 208.189 +            return err;
 208.190 +        }
 208.191 +
 208.192 +        @Override
 208.193 +        public void accept(Visitor v) {
 208.194 +            v.visitIdent(jcIdent);
 208.195 +        }
 208.196 +
 208.197 +    }
 208.198 +
 208.199 +    private static class FakeModifiers extends JCModifiers {
 208.200 +        public FakeModifiers() {
 208.201 +            super(0, List.<JCAnnotation>nil());
 208.202 +        }
 208.203 +    }
 208.204 +
 208.205 +    public static class CaseWildcard extends JCCase implements IdentifierTree {
 208.206 +
 208.207 +        private final Name ident;
 208.208 +        private final JCIdent jcIdent;
 208.209 +
 208.210 +        public CaseWildcard(Context ctx, Name ident, JCIdent jcIdent) {
 208.211 +            super(jcIdent, List.<JCStatement>nil());
 208.212 +            this.ident = ident;
 208.213 +            this.jcIdent = jcIdent;
 208.214 +        }
 208.215 +
 208.216 +        public Name getName() {
 208.217 +            return ident;
 208.218 +        }
 208.219 +
 208.220 +        @Override
 208.221 +        public Kind getKind() {
 208.222 +            return Kind.IDENTIFIER;
 208.223 +        }
 208.224 +
 208.225 +        @Override
 208.226 +        public void accept(Visitor v) {
 208.227 +            v.visitIdent(jcIdent);
 208.228 +        }
 208.229 +
 208.230 +        @Override
 208.231 +        public <R, D> R accept(TreeVisitor<R, D> v, D d) {
 208.232 +            return v.visitIdentifier(this, d);
 208.233 +        }
 208.234 +
 208.235 +        @Override
 208.236 +        public String toString() {
 208.237 +            return "case " + ident.toString();
 208.238 +        }
 208.239 +
 208.240 +    }
 208.241 +    
 208.242 +    public static class FakeBlock extends JCBlock {
 208.243 +
 208.244 +        public FakeBlock(long flags, List<JCStatement> stats) {
 208.245 +            super(flags, stats);
 208.246 +        }
 208.247 +        
 208.248 +    }
 208.249 +}
   209.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   209.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/JavaFixImpl.java	Sun Oct 23 11:50:54 2016 +0200
   209.3 @@ -0,0 +1,146 @@
   209.4 +/*
   209.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   209.6 + *
   209.7 + * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
   209.8 + *
   209.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  209.10 + * Other names may be trademarks of their respective owners.
  209.11 + *
  209.12 + * The contents of this file are subject to the terms of either the GNU
  209.13 + * General Public License Version 2 only ("GPL") or the Common
  209.14 + * Development and Distribution License("CDDL") (collectively, the
  209.15 + * "License"). You may not use this file except in compliance with the
  209.16 + * License. You can obtain a copy of the License at
  209.17 + * http://www.netbeans.org/cddl-gplv2.html
  209.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  209.19 + * specific language governing permissions and limitations under the
  209.20 + * License.  When distributing the software, include this License Header
  209.21 + * Notice in each file and include the License file at
  209.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  209.23 + * particular file as subject to the "Classpath" exception as provided
  209.24 + * by Oracle in the GPL Version 2 section of the License file that
  209.25 + * accompanied this code. If applicable, add the following below the
  209.26 + * License Header, with the fields enclosed by brackets [] replaced by
  209.27 + * your own identifying information:
  209.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  209.29 + *
  209.30 + * If you wish your version of this file to be governed by only the CDDL
  209.31 + * or only the GPL Version 2, indicate your decision by adding
  209.32 + * "[Contributor] elects to include this software in this distribution
  209.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  209.34 + * single choice of license, a recipient has the option to distribute
  209.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  209.36 + * to extend the choice of license to its licensees as provided above.
  209.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  209.38 + * Version 2 license, then the option applies only if the new code is
  209.39 + * made subject to such option by the copyright holder.
  209.40 + *
  209.41 + * Contributor(s):
  209.42 + *
  209.43 + * Portions Copyrighted 2008-2009 Sun Microsystems, Inc.
  209.44 + */
  209.45 +
  209.46 +package org.netbeans.modules.java.hints.spiimpl;
  209.47 +
  209.48 +import com.sun.source.util.TreePath;
  209.49 +import java.util.ArrayList;
  209.50 +import java.util.Collection;
  209.51 +import java.util.Collections;
  209.52 +import java.util.HashMap;
  209.53 +import java.util.IdentityHashMap;
  209.54 +import java.util.List;
  209.55 +import java.util.Map;
  209.56 +import java.util.Set;
  209.57 +import javax.lang.model.type.TypeMirror;
  209.58 +import org.netbeans.api.java.source.CompilationInfo;
  209.59 +import org.netbeans.api.java.source.JavaSource;
  209.60 +import org.netbeans.api.java.source.JavaSource.Phase;
  209.61 +import org.netbeans.api.java.source.ModificationResult.Difference;
  209.62 +import org.netbeans.api.java.source.Task;
  209.63 +import org.netbeans.api.java.source.WorkingCopy;
  209.64 +import org.netbeans.api.project.Project;
  209.65 +import org.netbeans.modules.java.hints.spiimpl.batch.BatchUtilities;
  209.66 +import org.netbeans.modules.java.source.JavaSourceAccessor;
  209.67 +import org.netbeans.modules.refactoring.spi.RefactoringElementImplementation;
  209.68 +import org.netbeans.spi.editor.hints.ChangeInfo;
  209.69 +import org.netbeans.spi.editor.hints.Fix;
  209.70 +import org.netbeans.spi.java.hints.HintContext;
  209.71 +import org.netbeans.spi.java.hints.JavaFix;
  209.72 +import org.openide.filesystems.FileObject;
  209.73 +import org.openide.util.Exceptions;
  209.74 +
  209.75 +/**TODO: move to better package
  209.76 + *
  209.77 + * @author Jan Lahoda
  209.78 + */
  209.79 +public final class JavaFixImpl implements Fix {
  209.80 +
  209.81 +    public final JavaFix jf;
  209.82 +
  209.83 +    public JavaFixImpl(JavaFix jf) {
  209.84 +        this.jf = jf;
  209.85 +    }
  209.86 +
  209.87 +    public String getText() {
  209.88 +        return Accessor.INSTANCE.getText(jf);
  209.89 +    }
  209.90 +
  209.91 +    public ChangeInfo implement() throws Exception {
  209.92 +        FileObject file = Accessor.INSTANCE.getFile(jf);
  209.93 +        
  209.94 +        BatchUtilities.fixDependencies(file, Collections.singletonList(jf), new IdentityHashMap<Project, Set<String>>());
  209.95 +
  209.96 +        JavaSource js = JavaSource.forFileObject(file);
  209.97 +
  209.98 +        js.runModificationTask(new Task<WorkingCopy>() {
  209.99 +            public void run(WorkingCopy wc) throws Exception {
 209.100 +                if (wc.toPhase(Phase.RESOLVED).compareTo(Phase.RESOLVED) < 0) {
 209.101 +                    return;
 209.102 +                }
 209.103 +
 209.104 +                Map<FileObject, byte[]> resourceContentChanges = new HashMap<FileObject, byte[]>();
 209.105 +                Accessor.INSTANCE.process(jf, wc, true, resourceContentChanges, /*Ignored in editor:*/new ArrayList<RefactoringElementImplementation>());
 209.106 +                Map<FileObject, List<Difference>> resourceContentDiffs = new HashMap<FileObject, List<Difference>>();
 209.107 +                BatchUtilities.addResourceContentChanges(resourceContentChanges, resourceContentDiffs);
 209.108 +                JavaSourceAccessor.getINSTANCE().createModificationResult(resourceContentDiffs, Collections.<Object, int[]>emptyMap()).commit();
 209.109 +            }
 209.110 +        }).commit();
 209.111 +
 209.112 +        return null;
 209.113 +    }
 209.114 +
 209.115 +    @Override
 209.116 +    public boolean equals(Object obj) {
 209.117 +        if (obj instanceof JavaFixImpl) {
 209.118 +            return jf.equals(((JavaFixImpl)obj).jf);
 209.119 +        }
 209.120 +        return super.equals(obj);
 209.121 +    }
 209.122 +
 209.123 +    @Override
 209.124 +    public int hashCode() {
 209.125 +        return jf.hashCode();
 209.126 +    }
 209.127 +
 209.128 +    public static abstract class Accessor {
 209.129 +
 209.130 +        static {
 209.131 +            try {
 209.132 +                Class.forName(JavaFix.class.getCanonicalName(), true, JavaFix.class.getClassLoader());
 209.133 +            } catch (ClassNotFoundException ex) {
 209.134 +                Exceptions.printStackTrace(ex);
 209.135 +            }
 209.136 +        }
 209.137 +        
 209.138 +        public static Accessor INSTANCE;
 209.139 +
 209.140 +        public abstract String getText(JavaFix jf);
 209.141 +        public abstract ChangeInfo process(JavaFix jf, WorkingCopy wc, boolean canShowUI, Map<FileObject, byte[]> resourceContent, Collection<? super RefactoringElementImplementation> fileChanges) throws Exception;
 209.142 +        public abstract FileObject getFile(JavaFix jf);
 209.143 +        public abstract Map<String, String> getOptions(JavaFix jf);
 209.144 +        public abstract Fix rewriteFix(CompilationInfo info, String displayName, TreePath what, final String to, Map<String, TreePath> parameters, Map<String, Collection<? extends TreePath>> parametersMulti, final Map<String, String> parameterNames, Map<String, TypeMirror> constraints, Map<String, String> options, String... imports);
 209.145 +        public abstract Fix createSuppressWarningsFix(CompilationInfo compilationInfo, TreePath treePath, String... keys);
 209.146 +        public abstract List<Fix> createSuppressWarnings(CompilationInfo compilationInfo, TreePath treePath, String... keys);
 209.147 +        public abstract List<Fix> resolveDefaultFixes(HintContext ctx, Fix... provided);
 209.148 +    }
 209.149 +}
   210.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   210.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/JavaHintsPositionRefresher.java	Sun Oct 23 11:50:54 2016 +0200
   210.3 @@ -0,0 +1,161 @@
   210.4 +/*
   210.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   210.6 + *
   210.7 + * Copyright 2009-2010 Oracle and/or its affiliates. All rights reserved.
   210.8 + *
   210.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  210.10 + * Other names may be trademarks of their respective owners.
  210.11 + *
  210.12 + * The contents of this file are subject to the terms of either the GNU
  210.13 + * General Public License Version 2 only ("GPL") or the Common
  210.14 + * Development and Distribution License("CDDL") (collectively, the
  210.15 + * "License"). You may not use this file except in compliance with the
  210.16 + * License. You can obtain a copy of the License at
  210.17 + * http://www.netbeans.org/cddl-gplv2.html
  210.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  210.19 + * specific language governing permissions and limitations under the
  210.20 + * License.  When distributing the software, include this License Header
  210.21 + * Notice in each file and include the License file at
  210.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  210.23 + * particular file as subject to the "Classpath" exception as provided
  210.24 + * by Oracle in the GPL Version 2 section of the License file that
  210.25 + * accompanied this code. If applicable, add the following below the
  210.26 + * License Header, with the fields enclosed by brackets [] replaced by
  210.27 + * your own identifying information:
  210.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  210.29 + *
  210.30 + * If you wish your version of this file to be governed by only the CDDL
  210.31 + * or only the GPL Version 2, indicate your decision by adding
  210.32 + * "[Contributor] elects to include this software in this distribution
  210.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  210.34 + * single choice of license, a recipient has the option to distribute
  210.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  210.36 + * to extend the choice of license to its licensees as provided above.
  210.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  210.38 + * Version 2 license, then the option applies only if the new code is
  210.39 + * made subject to such option by the copyright holder.
  210.40 + *
  210.41 + * Contributor(s):
  210.42 + *
  210.43 + * Portions Copyrighted 2009-2010 Sun Microsystems, Inc.
  210.44 + */
  210.45 +
  210.46 +package org.netbeans.modules.java.hints.spiimpl;
  210.47 +
  210.48 +import java.io.IOException;
  210.49 +import java.util.ArrayList;
  210.50 +import java.util.Collections;
  210.51 +import java.util.HashMap;
  210.52 +import java.util.Iterator;
  210.53 +import java.util.List;
  210.54 +import java.util.Map;
  210.55 +import java.util.logging.Level;
  210.56 +import java.util.logging.Logger;
  210.57 +import javax.swing.text.Document;
  210.58 +import org.netbeans.api.editor.mimelookup.MimeLookup;
  210.59 +import org.netbeans.api.editor.mimelookup.MimeRegistration;
  210.60 +import org.netbeans.api.java.source.CompilationController;
  210.61 +import org.netbeans.api.java.source.JavaSource;
  210.62 +import org.netbeans.api.java.source.JavaSource.Phase;
  210.63 +import org.netbeans.api.java.source.Task;
  210.64 +import org.netbeans.api.progress.ProgressUtils;
  210.65 +import org.netbeans.spi.editor.hints.Context;
  210.66 +import org.netbeans.spi.editor.hints.ErrorDescription;
  210.67 +import org.netbeans.spi.editor.hints.PositionRefresher;
  210.68 +import org.netbeans.modules.java.hints.providers.spi.PositionRefresherHelper;
  210.69 +import org.openide.util.Exceptions;
  210.70 +import org.openide.util.NbBundle;
  210.71 +
  210.72 +/**
  210.73 + * Refreshes all Java Hints on current line upon Alt-Enter or mouseclick
  210.74 + * @author Max Sauer
  210.75 + */
  210.76 +@MimeRegistration(mimeType="text/x-java", service=PositionRefresher.class)
  210.77 +public class JavaHintsPositionRefresher implements PositionRefresher {
  210.78 +
  210.79 +    private static final Logger LOG = Logger.getLogger(JavaHintsPositionRefresher.class.getName());
  210.80 +
  210.81 +    @Override
  210.82 +    public Map<String, List<ErrorDescription>> getErrorDescriptionsAt(final Context context, final Document doc) {
  210.83 +        final List<PositionRefresherHelper> refreshers = new ArrayList<PositionRefresherHelper>(MimeLookup.getLookup("text/x-java").lookupAll(PositionRefresherHelper.class));
  210.84 +
  210.85 +        for (Iterator<PositionRefresherHelper> it = refreshers.iterator(); it.hasNext();) {
  210.86 +            PositionRefresherHelper h = it.next();
  210.87 +
  210.88 +            if (h.upToDateCheck(context, doc)) {
  210.89 +                LOG.log(Level.FINE, "Not computing warnings for {0}, results are up-to-date.", h.getKey());
  210.90 +                it.remove();
  210.91 +            } else {
  210.92 +                LOG.log(Level.FINE, "Will compute warnings for {0}, results not up-to-date.", h.getKey());
  210.93 +            }
  210.94 +        }
  210.95 +
  210.96 +        if (refreshers.isEmpty()) return Collections.emptyMap();
  210.97 +        
  210.98 +        final JavaSource js = JavaSource.forDocument(doc);
  210.99 +
 210.100 +        if (js == null) {
 210.101 +            LOG.log(Level.FINE, "No JavaSource associated to: {0}", new Object[] {doc, doc.getProperty(Document.StreamDescriptionProperty)});
 210.102 +            return Collections.emptyMap();
 210.103 +        }
 210.104 +
 210.105 +        final Map<String, List<ErrorDescription>> eds = new HashMap<String, List<ErrorDescription>>();
 210.106 +
 210.107 +        Runnable r = new Runnable() {
 210.108 +
 210.109 +            public void run() {
 210.110 +                try {
 210.111 +                    js.runUserActionTask(new RefreshTask(eds, refreshers, context, doc), true);
 210.112 +                } catch (IOException ex) {
 210.113 +                    Exceptions.printStackTrace(ex);
 210.114 +                }
 210.115 +            }
 210.116 +        };
 210.117 +        
 210.118 +        ProgressUtils.runOffEventDispatchThread(r, NbBundle.getMessage(JavaHintsPositionRefresher.class, "Refresh_hints"), context.getCancel(), false); // NOI18N
 210.119 +
 210.120 +        return eds;
 210.121 +    }
 210.122 +
 210.123 +
 210.124 +    private class RefreshTask implements Task<CompilationController> {
 210.125 +
 210.126 +        private final Map<String, List<ErrorDescription>> eds;
 210.127 +        private final List<PositionRefresherHelper> refreshers;
 210.128 +        private final Context ctx;
 210.129 +        private final Document doc;
 210.130 +
 210.131 +        public RefreshTask(Map<String, List<ErrorDescription>> eds, List<PositionRefresherHelper> refreshers, Context ctx, Document doc) {
 210.132 +            this.eds = eds;
 210.133 +            this.refreshers = refreshers;
 210.134 +            this.ctx = ctx;
 210.135 +            this.doc = doc;
 210.136 +        }
 210.137 +
 210.138 +        public void run(CompilationController controller) throws Exception {
 210.139 +            if (controller.toPhase(JavaSource.Phase.RESOLVED).compareTo(Phase.RESOLVED) < 0) {
 210.140 +                return ;
 210.141 +            }
 210.142 +
 210.143 +            Document doc = controller.getDocument();
 210.144 +
 210.145 +            if (doc == null) {
 210.146 +                return;
 210.147 +            }
 210.148 +
 210.149 +            for (PositionRefresherHelper h : refreshers) {
 210.150 +                if (ctx.isCanceled()) {
 210.151 +                    return;
 210.152 +                }
 210.153 +                
 210.154 +                List errors = h.getErrorDescriptionsAt(controller, ctx, doc);
 210.155 +                
 210.156 +                if (errors == null) continue;
 210.157 +                
 210.158 +                eds.put(h.getKey(), errors);
 210.159 +            }
 210.160 +        }
 210.161 +        
 210.162 +    }
 210.163 +
 210.164 +}
   211.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   211.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/MessageImpl.java	Sun Oct 23 11:50:54 2016 +0200
   211.3 @@ -0,0 +1,61 @@
   211.4 +/*
   211.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   211.6 + *
   211.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
   211.8 + *
   211.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  211.10 + * Other names may be trademarks of their respective owners.
  211.11 + *
  211.12 + * The contents of this file are subject to the terms of either the GNU
  211.13 + * General Public License Version 2 only ("GPL") or the Common
  211.14 + * Development and Distribution License("CDDL") (collectively, the
  211.15 + * "License"). You may not use this file except in compliance with the
  211.16 + * License. You can obtain a copy of the License at
  211.17 + * http://www.netbeans.org/cddl-gplv2.html
  211.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  211.19 + * specific language governing permissions and limitations under the
  211.20 + * License.  When distributing the software, include this License Header
  211.21 + * Notice in each file and include the License file at
  211.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  211.23 + * particular file as subject to the "Classpath" exception as provided
  211.24 + * by Oracle in the GPL Version 2 section of the License file that
  211.25 + * accompanied this code. If applicable, add the following below the
  211.26 + * License Header, with the fields enclosed by brackets [] replaced by
  211.27 + * your own identifying information:
  211.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  211.29 + *
  211.30 + * If you wish your version of this file to be governed by only the CDDL
  211.31 + * or only the GPL Version 2, indicate your decision by adding
  211.32 + * "[Contributor] elects to include this software in this distribution
  211.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  211.34 + * single choice of license, a recipient has the option to distribute
  211.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  211.36 + * to extend the choice of license to its licensees as provided above.
  211.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  211.38 + * Version 2 license, then the option applies only if the new code is
  211.39 + * made subject to such option by the copyright holder.
  211.40 + *
  211.41 + * Contributor(s):
  211.42 + *
  211.43 + * Portions Copyrighted 2009 Sun Microsystems, Inc.
  211.44 + */
  211.45 +
  211.46 +package org.netbeans.modules.java.hints.spiimpl;
  211.47 +
  211.48 +import org.netbeans.spi.java.hints.HintContext.MessageKind;
  211.49 +
  211.50 +/**
  211.51 + *
  211.52 + * @author lahvacc
  211.53 + */
  211.54 +public class MessageImpl {
  211.55 +
  211.56 +    public final MessageKind kind;
  211.57 +    public final String text;
  211.58 +
  211.59 +    public MessageImpl(MessageKind kind, String text) {
  211.60 +        this.kind = kind;
  211.61 +        this.text = text;
  211.62 +    }
  211.63 +
  211.64 +}
   212.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   212.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/RulesManager.java	Sun Oct 23 11:50:54 2016 +0200
   212.3 @@ -0,0 +1,68 @@
   212.4 +/*
   212.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   212.6 + *
   212.7 + * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
   212.8 + *
   212.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  212.10 + * Other names may be trademarks of their respective owners.
  212.11 + *
  212.12 + * The contents of this file are subject to the terms of either the GNU
  212.13 + * General Public License Version 2 only ("GPL") or the Common
  212.14 + * Development and Distribution License("CDDL") (collectively, the
  212.15 + * "License"). You may not use this file except in compliance with the
  212.16 + * License. You can obtain a copy of the License at
  212.17 + * http://www.netbeans.org/cddl-gplv2.html
  212.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  212.19 + * specific language governing permissions and limitations under the
  212.20 + * License.  When distributing the software, include this License Header
  212.21 + * Notice in each file and include the License file at
  212.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  212.23 + * particular file as subject to the "Classpath" exception as provided
  212.24 + * by Oracle in the GPL Version 2 section of the License file that
  212.25 + * accompanied this code. If applicable, add the following below the
  212.26 + * License Header, with the fields enclosed by brackets [] replaced by
  212.27 + * your own identifying information:
  212.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  212.29 + *
  212.30 + * If you wish your version of this file to be governed by only the CDDL
  212.31 + * or only the GPL Version 2, indicate your decision by adding
  212.32 + * "[Contributor] elects to include this software in this distribution
  212.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  212.34 + * single choice of license, a recipient has the option to distribute
  212.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  212.36 + * to extend the choice of license to its licensees as provided above.
  212.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  212.38 + * Version 2 license, then the option applies only if the new code is
  212.39 + * made subject to such option by the copyright holder.
  212.40 + *
  212.41 + * Contributor(s):
  212.42 + *
  212.43 + * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
  212.44 + */
  212.45 +
  212.46 +package org.netbeans.modules.java.hints.spiimpl;
  212.47 +
  212.48 +import java.util.Collection;
  212.49 +import java.util.Map;
  212.50 +import java.util.concurrent.atomic.AtomicBoolean;
  212.51 +import org.netbeans.api.annotations.common.NullAllowed;
  212.52 +import org.netbeans.api.java.classpath.ClassPath;
  212.53 +import org.netbeans.api.java.source.CompilationInfo;
  212.54 +import org.netbeans.modules.java.hints.providers.spi.HintDescription;
  212.55 +import org.netbeans.modules.java.hints.providers.spi.HintMetadata;
  212.56 +import org.openide.util.Lookup;
  212.57 +
  212.58 +/**
  212.59 + *
  212.60 + * @author lahvac
  212.61 + */
  212.62 +public abstract class RulesManager {
  212.63 +
  212.64 +    public static RulesManager getInstance() {
  212.65 +        return Lookup.getDefault().lookup(RulesManager.class);
  212.66 +    }
  212.67 +
  212.68 +    public abstract Map<HintMetadata, ? extends Collection<? extends HintDescription>> readHints(@NullAllowed CompilationInfo info, @NullAllowed Collection<? extends ClassPath> from, @NullAllowed AtomicBoolean cancel);
  212.69 +    public abstract void reload(); //XXX
  212.70 +    
  212.71 +}
   213.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   213.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/RulesManagerImpl.java	Sun Oct 23 11:50:54 2016 +0200
   213.3 @@ -0,0 +1,140 @@
   213.4 +/*
   213.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   213.6 + *
   213.7 + * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
   213.8 + *
   213.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  213.10 + * Other names may be trademarks of their respective owners.
  213.11 + *
  213.12 + * The contents of this file are subject to the terms of either the GNU
  213.13 + * General Public License Version 2 only ("GPL") or the Common
  213.14 + * Development and Distribution License("CDDL") (collectively, the
  213.15 + * "License"). You may not use this file except in compliance with the
  213.16 + * License. You can obtain a copy of the License at
  213.17 + * http://www.netbeans.org/cddl-gplv2.html
  213.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  213.19 + * specific language governing permissions and limitations under the
  213.20 + * License.  When distributing the software, include this License Header
  213.21 + * Notice in each file and include the License file at
  213.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  213.23 + * particular file as subject to the "Classpath" exception as provided
  213.24 + * by Oracle in the GPL Version 2 section of the License file that
  213.25 + * accompanied this code. If applicable, add the following below the
  213.26 + * License Header, with the fields enclosed by brackets [] replaced by
  213.27 + * your own identifying information:
  213.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  213.29 + *
  213.30 + * If you wish your version of this file to be governed by only the CDDL
  213.31 + * or only the GPL Version 2, indicate your decision by adding
  213.32 + * "[Contributor] elects to include this software in this distribution
  213.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  213.34 + * single choice of license, a recipient has the option to distribute
  213.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  213.36 + * to extend the choice of license to its licensees as provided above.
  213.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  213.38 + * Version 2 license, then the option applies only if the new code is
  213.39 + * made subject to such option by the copyright holder.
  213.40 + *
  213.41 + * Contributor(s):
  213.42 + *
  213.43 + * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
  213.44 + */
  213.45 +
  213.46 +package org.netbeans.modules.java.hints.spiimpl;
  213.47 +
  213.48 +import java.util.ArrayList;
  213.49 +import java.util.Collection;
  213.50 +import java.util.Collections;
  213.51 +import java.util.HashMap;
  213.52 +import java.util.LinkedList;
  213.53 +import java.util.Map;
  213.54 +import java.util.Map.Entry;
  213.55 +import java.util.concurrent.atomic.AtomicBoolean;
  213.56 +import org.netbeans.api.java.classpath.ClassPath;
  213.57 +import org.netbeans.api.java.source.ClasspathInfo;
  213.58 +import org.netbeans.api.java.source.ClasspathInfo.PathKind;
  213.59 +import org.netbeans.api.java.source.CompilationInfo;
  213.60 +import org.netbeans.modules.java.hints.providers.spi.HintDescription;
  213.61 +import org.netbeans.modules.java.hints.providers.spi.HintMetadata;
  213.62 +import org.netbeans.modules.java.hints.providers.spi.ClassPathBasedHintProvider;
  213.63 +import org.netbeans.modules.java.hints.providers.spi.ElementBasedHintProvider;
  213.64 +import org.netbeans.modules.java.hints.providers.spi.HintProvider;
  213.65 +import org.netbeans.spi.java.classpath.support.ClassPathSupport;
  213.66 +import org.openide.util.Lookup;
  213.67 +import org.openide.util.lookup.ServiceProvider;
  213.68 +
  213.69 +/**
  213.70 + *
  213.71 + * @author lahvac
  213.72 + */
  213.73 +@ServiceProvider(service=RulesManager.class)
  213.74 +public class RulesManagerImpl extends RulesManager {
  213.75 +
  213.76 +    private final Map<HintMetadata, Collection<HintDescription>> globalHints = new HashMap<HintMetadata, Collection<HintDescription>>();
  213.77 +
  213.78 +    public RulesManagerImpl() {
  213.79 +        reload();
  213.80 +    }
  213.81 +    
  213.82 +    @Override
  213.83 +    public void reload() {
  213.84 +        globalHints.clear();
  213.85 +
  213.86 +        for (HintProvider p : Lookup.getDefault().lookupAll(HintProvider.class)) {
  213.87 +            Map<HintMetadata, ? extends Collection<? extends HintDescription>> pHints = p.computeHints();
  213.88 +
  213.89 +            if (pHints != null) {
  213.90 +                for (Entry<HintMetadata, ? extends Collection<? extends HintDescription>> e : pHints.entrySet()) {
  213.91 +                    globalHints.put(e.getKey(), new ArrayList<HintDescription>(e.getValue()));
  213.92 +                }
  213.93 +            }
  213.94 +        }
  213.95 +    }
  213.96 +
  213.97 +    @Override
  213.98 +    public Map<HintMetadata, ? extends Collection<? extends HintDescription>> readHints(CompilationInfo info, Collection<? extends ClassPath> from, AtomicBoolean cancel) {
  213.99 +        Map<HintMetadata, Collection<HintDescription>> result = new HashMap<HintMetadata, Collection<HintDescription>>(globalHints);
 213.100 +
 213.101 +        if (info != null) {
 213.102 +            for (ElementBasedHintProvider provider : Lookup.getDefault().lookupAll(ElementBasedHintProvider.class)) {
 213.103 +                sortByMetadata(provider.computeHints(info), result);
 213.104 +            }
 213.105 +        }
 213.106 +
 213.107 +        if (from == null) {
 213.108 +            if (info != null) {
 213.109 +                ClasspathInfo cpInfo = info.getClasspathInfo();
 213.110 +                LinkedList<ClassPath> cps = new LinkedList<ClassPath>();
 213.111 +
 213.112 +                cps.add(cpInfo.getClassPath(PathKind.BOOT));
 213.113 +                cps.add(cpInfo.getClassPath(PathKind.COMPILE));
 213.114 +                cps.add(cpInfo.getClassPath(PathKind.SOURCE));
 213.115 +
 213.116 +                from = cps;
 213.117 +            } else {
 213.118 +                from = Collections.emptyList();
 213.119 +            }
 213.120 +        }
 213.121 +
 213.122 +        ClassPath compound = ClassPathSupport.createProxyClassPath(from.toArray(new ClassPath[0]));
 213.123 +
 213.124 +        for (ClassPathBasedHintProvider p : Lookup.getDefault().lookupAll(ClassPathBasedHintProvider.class)) {
 213.125 +            sortByMetadata(p.computeHints(compound), result);
 213.126 +        }
 213.127 +
 213.128 +        return result;
 213.129 +    }
 213.130 +
 213.131 +    public static void sortByMetadata(Collection<? extends HintDescription> listedHints, Map<HintMetadata, Collection<HintDescription>> into) {
 213.132 +        for (HintDescription hd : listedHints) {
 213.133 +            Collection<HintDescription> h = into.get(hd.getMetadata());
 213.134 +
 213.135 +            if (h == null) {
 213.136 +                into.put(hd.getMetadata(), h = new ArrayList<HintDescription>());
 213.137 +            }
 213.138 +
 213.139 +            h.add(hd);
 213.140 +        }
 213.141 +    }
 213.142 +
 213.143 +}
   214.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   214.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/SPIAccessor.java	Sun Oct 23 11:50:54 2016 +0200
   214.3 @@ -0,0 +1,86 @@
   214.4 +/*
   214.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   214.6 + *
   214.7 + * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
   214.8 + *
   214.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  214.10 + * Other names may be trademarks of their respective owners.
  214.11 + *
  214.12 + * The contents of this file are subject to the terms of either the GNU
  214.13 + * General Public License Version 2 only ("GPL") or the Common
  214.14 + * Development and Distribution License("CDDL") (collectively, the
  214.15 + * "License"). You may not use this file except in compliance with the
  214.16 + * License. You can obtain a copy of the License at
  214.17 + * http://www.netbeans.org/cddl-gplv2.html
  214.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  214.19 + * specific language governing permissions and limitations under the
  214.20 + * License.  When distributing the software, include this License Header
  214.21 + * Notice in each file and include the License file at
  214.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  214.23 + * particular file as subject to the "Classpath" exception as provided
  214.24 + * by Oracle in the GPL Version 2 section of the License file that
  214.25 + * accompanied this code. If applicable, add the following below the
  214.26 + * License Header, with the fields enclosed by brackets [] replaced by
  214.27 + * your own identifying information:
  214.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  214.29 + *
  214.30 + * If you wish your version of this file to be governed by only the CDDL
  214.31 + * or only the GPL Version 2, indicate your decision by adding
  214.32 + * "[Contributor] elects to include this software in this distribution
  214.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  214.34 + * single choice of license, a recipient has the option to distribute
  214.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  214.36 + * to extend the choice of license to its licensees as provided above.
  214.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  214.38 + * Version 2 license, then the option applies only if the new code is
  214.39 + * made subject to such option by the copyright holder.
  214.40 + *
  214.41 + * Contributor(s):
  214.42 + *
  214.43 + * Portions Copyrighted 2012 Sun Microsystems, Inc.
  214.44 + */
  214.45 +package org.netbeans.modules.java.hints.spiimpl;
  214.46 +
  214.47 +import com.sun.source.util.TreePath;
  214.48 +import java.util.Collection;
  214.49 +import java.util.Map;
  214.50 +import java.util.concurrent.atomic.AtomicBoolean;
  214.51 +import javax.lang.model.type.TypeMirror;
  214.52 +import org.netbeans.api.java.source.CompilationInfo;
  214.53 +import org.netbeans.modules.java.hints.providers.spi.HintMetadata;
  214.54 +import org.netbeans.modules.java.hints.spiimpl.hints.GlobalProcessingContext;
  214.55 +import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings;
  214.56 +import org.netbeans.spi.java.hints.HintContext;
  214.57 +import org.openide.util.Exceptions;
  214.58 +
  214.59 +/**
  214.60 + *
  214.61 + * @author lahvac
  214.62 + */
  214.63 +public abstract class SPIAccessor {
  214.64 +
  214.65 +    private static volatile SPIAccessor accessor;
  214.66 +
  214.67 +    public static synchronized SPIAccessor getINSTANCE() {
  214.68 +        if (accessor == null) {
  214.69 +            try {
  214.70 +                Class.forName(HintContext.class.getName(), true, HintContext.class.getClassLoader());
  214.71 +                assert accessor != null;
  214.72 +            } catch (ClassNotFoundException e) {
  214.73 +                Exceptions.printStackTrace(e);
  214.74 +            }
  214.75 +        }
  214.76 +        return accessor;
  214.77 +    }
  214.78 +
  214.79 +    public static void setINSTANCE(SPIAccessor instance) {
  214.80 +        assert instance != null;
  214.81 +        accessor = instance;
  214.82 +    }
  214.83 +
  214.84 +    public abstract HintContext createHintContext(CompilationInfo info, HintsSettings settings, HintMetadata metadata, GlobalProcessingContext globalContext, TreePath path, Map<String, TreePath> variables, Map<String, Collection<? extends TreePath>> multiVariables, Map<String, String> variableNames, Map<String, TypeMirror> constraints, Collection<? super MessageImpl> problems, boolean bulkMode, AtomicBoolean cancel, int caret);
  214.85 +    public abstract HintContext createHintContext(CompilationInfo info, HintsSettings settings, HintMetadata metadata, GlobalProcessingContext globalContext, TreePath path, Map<String, TreePath> variables, Map<String, Collection<? extends TreePath>> multiVariables, Map<String, String> variableNames);
  214.86 +    public abstract HintMetadata getHintMetadata(HintContext ctx);
  214.87 +    public abstract HintsSettings getHintSettings(HintContext ctx);
  214.88 +
  214.89 +}
   215.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   215.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/SyntheticFix.java	Sun Oct 23 11:50:54 2016 +0200
   215.3 @@ -0,0 +1,46 @@
   215.4 +/*
   215.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   215.6 + *
   215.7 + * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
   215.8 + *
   215.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  215.10 + * Other names may be trademarks of their respective owners.
  215.11 + *
  215.12 + * The contents of this file are subject to the terms of either the GNU
  215.13 + * General Public License Version 2 only ("GPL") or the Common Development and
  215.14 + * Distribution License("CDDL") (collectively, the "License"). You may not use
  215.15 + * this file except in compliance with the License. You can obtain a copy of
  215.16 + * the License at http://www.netbeans.org/cddl-gplv2.html or
  215.17 + * nbbuild/licenses/CDDL-GPL-2-CP. See the License for the specific language
  215.18 + * governing permissions and limitations under the License. When distributing
  215.19 + * the software, include this License Header Notice in each file and include
  215.20 + * the License file at nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
  215.21 + * particular file as subject to the "Classpath" exception as provided by
  215.22 + * Oracle in the GPL Version 2 section of the License file that accompanied
  215.23 + * this code. If applicable, add the following below the License Header, with
  215.24 + * the fields enclosed by brackets [] replaced by your own identifying
  215.25 + * information: "Portions Copyrighted [year] [name of copyright owner]"
  215.26 + *
  215.27 + * If you wish your version of this file to be governed by only the CDDL or
  215.28 + * only the GPL Version 2, indicate your decision by adding "[Contributor]
  215.29 + * elects to include this software in this distribution under the [CDDL or GPL
  215.30 + * Version 2] license." If you do not indicate a single choice of license, a
  215.31 + * recipient has the option to distribute your version of this file under
  215.32 + * either the CDDL, the GPL Version 2 or to extend the choice of license to its
  215.33 + * licensees as provided above. However, if you add GPL Version 2 code and
  215.34 + * therefore, elected the GPL Version 2 license, then the option applies only
  215.35 + * if the new code is made subject to such option by the copyright holder.
  215.36 + *
  215.37 + * Contributor(s):
  215.38 + *
  215.39 + * Portions Copyrighted 2011 Sun Microsystems, Inc.
  215.40 + */
  215.41 +package org.netbeans.modules.java.hints.spiimpl;
  215.42 +
  215.43 +/**
  215.44 + *
  215.45 + * @author lahvac
  215.46 + */
  215.47 +public interface SyntheticFix {
  215.48 +
  215.49 +}
   216.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   216.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/Utilities.java	Sun Oct 23 11:50:54 2016 +0200
   216.3 @@ -0,0 +1,1554 @@
   216.4 +/*
   216.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   216.6 + *
   216.7 + * Copyright 2008-2010 Sun Microsystems, Inc. All rights reserved.
   216.8 + *
   216.9 + * The contents of this file are subject to the terms of either the GNU
  216.10 + * General Public License Version 2 only ("GPL") or the Common
  216.11 + * Development and Distribution License("CDDL") (collectively, the
  216.12 + * "License"). You may not use this file except in compliance with the
  216.13 + * License. You can obtain a copy of the License at
  216.14 + * http://www.netbeans.org/cddl-gplv2.html
  216.15 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  216.16 + * specific language governing permissions and limitations under the
  216.17 + * License.  When distributing the software, include this License Header
  216.18 + * Notice in each file and include the License file at
  216.19 + * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
  216.20 + * particular file as subject to the "Classpath" exception as provided
  216.21 + * by Sun in the GPL Version 2 section of the License file that
  216.22 + * accompanied this code. If applicable, add the following below the
  216.23 + * License Header, with the fields enclosed by brackets [] replaced by
  216.24 + * your own identifying information:
  216.25 + * "Portions Copyrighted [year] [name of copyright owner]"
  216.26 + *
  216.27 + * If you wish your version of this file to be governed by only the CDDL
  216.28 + * or only the GPL Version 2, indicate your decision by adding
  216.29 + * "[Contributor] elects to include this software in this distribution
  216.30 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  216.31 + * single choice of license, a recipient has the option to distribute
  216.32 + * your version of this file under either the CDDL, the GPL Version 2 or
  216.33 + * to extend the choice of license to its licensees as provided above.
  216.34 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  216.35 + * Version 2 license, then the option applies only if the new code is
  216.36 + * made subject to such option by the copyright holder.
  216.37 + *
  216.38 + * Contributor(s):
  216.39 + *
  216.40 + * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
  216.41 + */
  216.42 +
  216.43 +package org.netbeans.modules.java.hints.spiimpl;
  216.44 +
  216.45 +import com.sun.source.tree.AnnotationTree;
  216.46 +import com.sun.source.tree.AssignmentTree;
  216.47 +import com.sun.source.tree.BlockTree;
  216.48 +import com.sun.source.tree.ClassTree;
  216.49 +import com.sun.source.tree.CompilationUnitTree;
  216.50 +import com.sun.source.tree.ExpressionStatementTree;
  216.51 +import com.sun.source.tree.ExpressionTree;
  216.52 +import com.sun.source.tree.IdentifierTree;
  216.53 +import com.sun.source.tree.ImportTree;
  216.54 +import com.sun.source.tree.LiteralTree;
  216.55 +import com.sun.source.tree.MemberSelectTree;
  216.56 +import com.sun.source.tree.MethodInvocationTree;
  216.57 +import com.sun.source.tree.MethodTree;
  216.58 +import com.sun.source.tree.ModifiersTree;
  216.59 +import com.sun.source.tree.NewArrayTree;
  216.60 +import com.sun.source.tree.NewClassTree;
  216.61 +import com.sun.source.tree.Scope;
  216.62 +import com.sun.source.tree.StatementTree;
  216.63 +import com.sun.source.tree.SwitchTree;
  216.64 +import com.sun.source.tree.Tree;
  216.65 +import com.sun.source.tree.Tree.Kind;
  216.66 +import com.sun.source.tree.TypeParameterTree;
  216.67 +import com.sun.source.tree.VariableTree;
  216.68 +import com.sun.source.util.SourcePositions;
  216.69 +import com.sun.source.util.TreePath;
  216.70 +import com.sun.source.util.TreePathScanner;
  216.71 +import com.sun.source.util.TreeScanner;
  216.72 +import com.sun.source.util.Trees;
  216.73 +import com.sun.tools.javac.api.JavacScope;
  216.74 +import com.sun.tools.javac.api.JavacTaskImpl;
  216.75 +import com.sun.tools.javac.api.JavacTrees;
  216.76 +import com.sun.tools.javac.code.Flags;
  216.77 +import com.sun.tools.javac.code.Symtab;
  216.78 +import com.sun.tools.javac.code.Type;
  216.79 +import com.sun.tools.javac.comp.Attr;
  216.80 +import com.sun.tools.javac.comp.AttrContext;
  216.81 +import com.sun.tools.javac.comp.Env;
  216.82 +import com.sun.tools.javac.comp.Todo;
  216.83 +import com.sun.tools.javac.main.JavaCompiler;
  216.84 +import com.sun.tools.javac.parser.JavacParser;
  216.85 +import com.sun.tools.javac.parser.Lexer;
  216.86 +import com.sun.tools.javac.parser.Parser;
  216.87 +import com.sun.tools.javac.parser.ParserFactory;
  216.88 +import com.sun.tools.javac.parser.Scanner;
  216.89 +import com.sun.tools.javac.parser.ScannerFactory;
  216.90 +import com.sun.tools.javac.parser.Tokens.Token;
  216.91 +import com.sun.tools.javac.parser.Tokens.TokenKind;
  216.92 +import com.sun.tools.javac.tree.JCTree;
  216.93 +import com.sun.tools.javac.tree.JCTree.JCCase;
  216.94 +import com.sun.tools.javac.tree.JCTree.JCCatch;
  216.95 +import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
  216.96 +import com.sun.tools.javac.tree.JCTree.JCExpression;
  216.97 +import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
  216.98 +import com.sun.tools.javac.tree.JCTree.JCIdent;
  216.99 +import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
 216.100 +import com.sun.tools.javac.tree.JCTree.JCModifiers;
 216.101 +import com.sun.tools.javac.tree.JCTree.JCStatement;
 216.102 +import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
 216.103 +import com.sun.tools.javac.util.Context;
 216.104 +import com.sun.tools.javac.util.JCDiagnostic;
 216.105 +import com.sun.tools.javac.util.ListBuffer;
 216.106 +import com.sun.tools.javac.util.Log;
 216.107 +import com.sun.tools.javac.util.Names;
 216.108 +import com.sun.tools.javadoc.Messager;
 216.109 +import java.io.File;
 216.110 +import java.io.IOException;
 216.111 +import java.net.URI;
 216.112 +import java.nio.CharBuffer;
 216.113 +import java.util.Arrays;
 216.114 +import java.util.Collection;
 216.115 +import java.util.Collections;
 216.116 +import java.util.EnumSet;
 216.117 +import java.util.HashMap;
 216.118 +import java.util.HashSet;
 216.119 +import java.util.Iterator;
 216.120 +import java.util.LinkedList;
 216.121 +import java.util.List;
 216.122 +import java.util.Locale;
 216.123 +import java.util.Map;
 216.124 +import java.util.Map.Entry;
 216.125 +import java.util.Set;
 216.126 +import java.util.concurrent.atomic.AtomicBoolean;
 216.127 +import javax.lang.model.element.AnnotationMirror;
 216.128 +import javax.lang.model.element.AnnotationValue;
 216.129 +import javax.lang.model.element.AnnotationValueVisitor;
 216.130 +import javax.lang.model.element.Element;
 216.131 +import javax.lang.model.element.ElementKind;
 216.132 +import javax.lang.model.element.ExecutableElement;
 216.133 +import javax.lang.model.element.Modifier;
 216.134 +import javax.lang.model.element.Name;
 216.135 +import javax.lang.model.element.TypeElement;
 216.136 +import javax.lang.model.element.VariableElement;
 216.137 +import javax.lang.model.type.TypeKind;
 216.138 +import javax.lang.model.type.TypeMirror;
 216.139 +import javax.lang.model.util.Elements;
 216.140 +import javax.tools.Diagnostic;
 216.141 +import javax.tools.JavaCompiler.CompilationTask;
 216.142 +import javax.tools.JavaFileObject;
 216.143 +import javax.tools.SimpleJavaFileObject;
 216.144 +import org.netbeans.api.annotations.common.CheckForNull;
 216.145 +import org.netbeans.api.annotations.common.NonNull;
 216.146 +import org.netbeans.api.java.classpath.ClassPath;
 216.147 +import org.netbeans.api.java.platform.JavaPlatform;
 216.148 +import org.netbeans.api.java.platform.JavaPlatformManager;
 216.149 +import org.netbeans.api.java.queries.SourceForBinaryQuery;
 216.150 +import org.netbeans.api.java.queries.SourceForBinaryQuery.Result2;
 216.151 +import org.netbeans.api.java.source.ClasspathInfo;
 216.152 +import org.netbeans.api.java.source.CompilationInfo;
 216.153 +import org.netbeans.api.java.source.CompilationInfo.CacheClearPolicy;
 216.154 +import org.netbeans.api.java.source.SourceUtils;
 216.155 +import org.netbeans.api.java.source.TreeMaker;
 216.156 +import org.netbeans.modules.java.hints.providers.spi.ClassPathBasedHintProvider;
 216.157 +import org.netbeans.modules.java.hints.providers.spi.HintDescription;
 216.158 +import org.netbeans.modules.java.hints.providers.spi.Trigger.PatternDescription;
 216.159 +import org.netbeans.modules.java.hints.spiimpl.JackpotTrees.CatchWildcard;
 216.160 +import org.netbeans.modules.java.hints.spiimpl.JackpotTrees.VariableWildcard;
 216.161 +import org.netbeans.modules.java.source.JavaSourceAccessor;
 216.162 +import org.netbeans.modules.java.source.builder.TreeFactory;
 216.163 +import org.netbeans.lib.nbjavac.services.CancelService;
 216.164 +import org.netbeans.lib.nbjavac.services.NBParserFactory.NBJavacParser;
 216.165 +import org.netbeans.lib.nbjavac.services.NBParserFactory;
 216.166 +import org.netbeans.lib.nbjavac.services.NBResolve;
 216.167 +import org.netbeans.modules.java.hints.spiimpl.JackpotTrees.AnnotationWildcard;
 216.168 +import org.netbeans.modules.java.hints.spiimpl.JackpotTrees.FakeBlock;
 216.169 +import org.netbeans.modules.java.source.parsing.FileObjects;
 216.170 +import org.netbeans.modules.java.source.pretty.ImportAnalysis2;
 216.171 +import org.netbeans.modules.java.source.transform.ImmutableTreeTranslator;
 216.172 +import org.netbeans.spi.editor.hints.Severity;
 216.173 +import org.netbeans.spi.java.classpath.support.ClassPathSupport;
 216.174 +import org.openide.filesystems.FileObject;
 216.175 +import org.openide.filesystems.FileUtil;
 216.176 +import org.openide.util.Lookup;
 216.177 +import org.openide.util.NbCollections;
 216.178 +import org.openide.util.lookup.ServiceProvider;
 216.179 +
 216.180 +/**
 216.181 + *
 216.182 + * @author Jan Lahoda
 216.183 + */
 216.184 +public class Utilities {
 216.185 +
 216.186 +    private Utilities() {}
 216.187 +    
 216.188 +    public static Set<Severity> disableErrors(FileObject file) {
 216.189 +        if (file.getAttribute(DISABLE_ERRORS) != null) {
 216.190 +            return EnumSet.allOf(Severity.class);
 216.191 +        }
 216.192 +        if (!file.canWrite() && FileUtil.getArchiveFile(file) != null) {
 216.193 +            return EnumSet.allOf(Severity.class);
 216.194 +        }
 216.195 +
 216.196 +        return EnumSet.noneOf(Severity.class);
 216.197 +    }
 216.198 +
 216.199 +    private static final String DISABLE_ERRORS = "disable-java-errors";
 216.200 +    
 216.201 +
 216.202 +    public static <E> Iterable<E> checkedIterableByFilter(final Iterable raw, final Class<E> type, final boolean strict) {
 216.203 +        return new Iterable<E>() {
 216.204 +            public Iterator<E> iterator() {
 216.205 +                return NbCollections.checkedIteratorByFilter(raw.iterator(), type, strict);
 216.206 +            }
 216.207 +        };
 216.208 +    }
 216.209 +    
 216.210 +//    public static AnnotationTree constructConstraint(WorkingCopy wc, String name, TypeMirror tm) {
 216.211 +//        TreeMaker make = wc.getTreeMaker();
 216.212 +//        ExpressionTree variable = prepareAssignment(make, "variable", make.Literal(name));
 216.213 +//        ExpressionTree type     = prepareAssignment(make, "type", make.MemberSelect((ExpressionTree) make.Type(wc.getTypes().erasure(tm)), "class"));
 216.214 +//        TypeElement constraint  = wc.getElements().getTypeElement(Annotations.CONSTRAINT.toFQN());
 216.215 +//
 216.216 +//        return make.Annotation(make.QualIdent(constraint), Arrays.asList(variable, type));
 216.217 +//    }
 216.218 +
 216.219 +    public static ExpressionTree prepareAssignment(TreeMaker make, String name, ExpressionTree value) {
 216.220 +        return make.Assignment(make.Identifier(name), value);
 216.221 +    }
 216.222 +
 216.223 +    public static ExpressionTree findValue(AnnotationTree m, String name) {
 216.224 +        for (ExpressionTree et : m.getArguments()) {
 216.225 +            if (et.getKind() == Kind.ASSIGNMENT) {
 216.226 +                AssignmentTree at = (AssignmentTree) et;
 216.227 +                String varName = ((IdentifierTree) at.getVariable()).getName().toString();
 216.228 +
 216.229 +                if (varName.equals(name)) {
 216.230 +                    return at.getExpression();
 216.231 +                }
 216.232 +            }
 216.233 +
 216.234 +            if (et instanceof LiteralTree/*XXX*/ && "value".equals(name)) {
 216.235 +                return et;
 216.236 +            }
 216.237 +        }
 216.238 +
 216.239 +        return null;
 216.240 +    }
 216.241 +
 216.242 +    public static List<AnnotationTree> findArrayValue(AnnotationTree at, String name) {
 216.243 +        ExpressionTree fixesArray = findValue(at, name);
 216.244 +        List<AnnotationTree> fixes = new LinkedList<AnnotationTree>();
 216.245 +
 216.246 +        if (fixesArray != null && fixesArray.getKind() == Kind.NEW_ARRAY) {
 216.247 +            NewArrayTree trees = (NewArrayTree) fixesArray;
 216.248 +
 216.249 +            for (ExpressionTree fix : trees.getInitializers()) {
 216.250 +                if (fix.getKind() == Kind.ANNOTATION) {
 216.251 +                    fixes.add((AnnotationTree) fix);
 216.252 +                }
 216.253 +            }
 216.254 +        }
 216.255 +
 216.256 +        if (fixesArray != null && fixesArray.getKind() == Kind.ANNOTATION) {
 216.257 +            fixes.add((AnnotationTree) fixesArray);
 216.258 +        }
 216.259 +        
 216.260 +        return fixes;
 216.261 +    }
 216.262 +
 216.263 +    public static boolean isPureMemberSelect(Tree mst, boolean allowVariables) {
 216.264 +        switch (mst.getKind()) {
 216.265 +            case IDENTIFIER: return allowVariables || ((IdentifierTree) mst).getName().charAt(0) != '$';
 216.266 +            case MEMBER_SELECT: return isPureMemberSelect(((MemberSelectTree) mst).getExpression(), allowVariables);
 216.267 +            default: return false;
 216.268 +        }
 216.269 +    }
 216.270 +
 216.271 +    public static Map<String, Collection<HintDescription>> sortOutHints(Iterable<? extends HintDescription> hints, Map<String, Collection<HintDescription>> output) {
 216.272 +        for (HintDescription d : hints) {
 216.273 +            Collection<HintDescription> h = output.get(d.getMetadata().displayName);
 216.274 +
 216.275 +            if (h == null) {
 216.276 +                output.put(d.getMetadata().displayName, h = new LinkedList<HintDescription>());
 216.277 +            }
 216.278 +
 216.279 +            h.add(d);
 216.280 +        }
 216.281 +
 216.282 +        return output;
 216.283 +    }
 216.284 +
 216.285 +    public static List<HintDescription> listAllHints(Set<ClassPath> cps) {
 216.286 +        List<HintDescription> result = new LinkedList<HintDescription>();
 216.287 +
 216.288 +        for (Collection<? extends HintDescription> hints : RulesManager.getInstance().readHints(null, cps, new AtomicBoolean()).values()) {
 216.289 +            for (HintDescription hd : hints) {
 216.290 +                if (!(hd.getTrigger() instanceof PatternDescription)) continue; //TODO: only pattern based hints are currently supported
 216.291 +                result.add(hd);
 216.292 +            }
 216.293 +        }
 216.294 +
 216.295 +        result.addAll(listClassPathHints(Collections.<ClassPath>emptySet(), cps));
 216.296 +
 216.297 +        return result;
 216.298 +    }
 216.299 +
 216.300 +    public static List<HintDescription> listClassPathHints(Set<ClassPath> sourceCPs, Set<ClassPath> binaryCPs) {
 216.301 +        List<HintDescription> result = new LinkedList<HintDescription>();
 216.302 +        Set<FileObject> roots = new HashSet<FileObject>();
 216.303 +
 216.304 +        for (ClassPath cp : binaryCPs) {
 216.305 +            for (FileObject r : cp.getRoots()) {
 216.306 +                Result2 src = SourceForBinaryQuery.findSourceRoots2(r.toURL());
 216.307 +
 216.308 +                if (src != null && src.preferSources()) {
 216.309 +                    roots.addAll(Arrays.asList(src.getRoots()));
 216.310 +                } else {
 216.311 +                    roots.add(r);
 216.312 +                }
 216.313 +            }
 216.314 +        }
 216.315 +
 216.316 +        Set<ClassPath> cps = new HashSet<ClassPath>(sourceCPs);
 216.317 +
 216.318 +        cps.add(ClassPathSupport.createClassPath(roots.toArray(new FileObject[0])));
 216.319 +
 216.320 +        ClassPath cp = ClassPathSupport.createProxyClassPath(cps.toArray(new ClassPath[0]));
 216.321 +
 216.322 +        for (ClassPathBasedHintProvider p : Lookup.getDefault().lookupAll(ClassPathBasedHintProvider.class)) {
 216.323 +            result.addAll(p.computeHints(cp));
 216.324 +        }
 216.325 +
 216.326 +        return result;
 216.327 +    }
 216.328 +    
 216.329 +    public static Tree parseAndAttribute(CompilationInfo info, String pattern, Scope scope) {
 216.330 +        return parseAndAttribute(info, pattern, scope, null);
 216.331 +    }
 216.332 +
 216.333 +    public static Tree parseAndAttribute(CompilationInfo info, String pattern, Scope scope, Collection<Diagnostic<? extends JavaFileObject>> errors) {
 216.334 +        return parseAndAttribute(info, JavaSourceAccessor.getINSTANCE().getJavacTask(info), pattern, scope, errors);
 216.335 +    }
 216.336 +
 216.337 +    public static Tree parseAndAttribute(CompilationInfo info, String pattern, Scope scope, SourcePositions[] sourcePositions, Collection<Diagnostic<? extends JavaFileObject>> errors) {
 216.338 +        return parseAndAttribute(info, JavaSourceAccessor.getINSTANCE().getJavacTask(info), pattern, scope, sourcePositions, errors);
 216.339 +    }
 216.340 +
 216.341 +    public static Tree parseAndAttribute(JavacTaskImpl jti, String pattern) {
 216.342 +        return parseAndAttribute(jti, pattern, null);
 216.343 +    }
 216.344 +
 216.345 +    public static Tree parseAndAttribute(JavacTaskImpl jti, String pattern, Collection<Diagnostic<? extends JavaFileObject>> errors) {
 216.346 +        return parseAndAttribute(null, jti, pattern, null, errors);
 216.347 +    }
 216.348 +
 216.349 +    public static Tree parseAndAttribute(JavacTaskImpl jti, String pattern, SourcePositions[] sourcePositions, Collection<Diagnostic<? extends JavaFileObject>> errors) {
 216.350 +        return parseAndAttribute(null, jti, pattern, null, sourcePositions, errors);
 216.351 +    }
 216.352 +
 216.353 +    private static Tree parseAndAttribute(CompilationInfo info, JavacTaskImpl jti, String pattern, Scope scope, Collection<Diagnostic<? extends JavaFileObject>> errors) {
 216.354 +        return parseAndAttribute(info, jti, pattern, scope, new SourcePositions[1], errors);
 216.355 +    }
 216.356 +
 216.357 +    private static Tree parseAndAttribute(CompilationInfo info, JavacTaskImpl jti, String pattern, Scope scope, SourcePositions[] sourcePositions, Collection<Diagnostic<? extends JavaFileObject>> errors) {
 216.358 +        Context c = jti.getContext();
 216.359 +        TreeFactory make = TreeFactory.instance(c);
 216.360 +        List<Diagnostic<? extends JavaFileObject>> patternTreeErrors = new LinkedList<Diagnostic<? extends JavaFileObject>>();
 216.361 +        Tree toAttribute;
 216.362 +        Tree patternTree = toAttribute = !isStatement(pattern) ? parseExpression(c, pattern, true, sourcePositions, patternTreeErrors) : null;
 216.363 +        int offset = 0;
 216.364 +        boolean expression = true;
 216.365 +        boolean classMember = false;
 216.366 +
 216.367 +        if (pattern.startsWith("case ")) {//XXX: should be a lexer token
 216.368 +            List<Diagnostic<? extends JavaFileObject>> currentPatternTreeErrors = new LinkedList<Diagnostic<? extends JavaFileObject>>();
 216.369 +            Tree switchTree = parseStatement(c, "switch ($$foo) {" + pattern + "}", sourcePositions, currentPatternTreeErrors);
 216.370 +
 216.371 +            offset = "switch ($$foo) {".length();
 216.372 +            patternTreeErrors = currentPatternTreeErrors;
 216.373 +            patternTree = toAttribute = ((SwitchTree) switchTree).getCases().get(0);
 216.374 +        }
 216.375 +
 216.376 +        if (patternTree == null || isErrorTree(patternTree)) {
 216.377 +            SourcePositions[] currentPatternTreePositions = new SourcePositions[1];
 216.378 +            List<Diagnostic<? extends JavaFileObject>> currentPatternTreeErrors = new LinkedList<Diagnostic<? extends JavaFileObject>>();
 216.379 +            Tree currentPatternTree = parseStatement(c, "{" + pattern + "}", currentPatternTreePositions, currentPatternTreeErrors);
 216.380 +
 216.381 +            assert currentPatternTree.getKind() == Kind.BLOCK : currentPatternTree.getKind();
 216.382 +
 216.383 +            List<? extends StatementTree> statements = ((BlockTree) currentPatternTree).getStatements();
 216.384 +
 216.385 +            if (statements.size() == 1) {
 216.386 +                currentPatternTree = statements.get(0);
 216.387 +            } else {
 216.388 +                com.sun.tools.javac.util.List<JCStatement> newStatements = com.sun.tools.javac.util.List.<JCStatement>nil();
 216.389 +
 216.390 +                if (!statements.isEmpty() && !Utilities.isMultistatementWildcardTree(statements.get(0)))
 216.391 +                    newStatements = newStatements.append((JCStatement) make.ExpressionStatement(make.Identifier("$$1$")));
 216.392 +                for (StatementTree st : statements) {
 216.393 +                    newStatements = newStatements.append((JCStatement) st);
 216.394 +                }
 216.395 +                if (!statements.isEmpty() && !Utilities.isMultistatementWildcardTree(statements.get(statements.size() - 1)))
 216.396 +                    newStatements = newStatements.append((JCStatement) make.ExpressionStatement(make.Identifier("$$2$")));
 216.397 +
 216.398 +                currentPatternTree = new FakeBlock(0L, newStatements);
 216.399 +            }
 216.400 +
 216.401 +            if (!currentPatternTreeErrors.isEmpty() || containsError(currentPatternTree)) {
 216.402 +                //maybe a class member?
 216.403 +                SourcePositions[] classPatternTreePositions = new SourcePositions[1];
 216.404 +                List<Diagnostic<? extends JavaFileObject>> classPatternTreeErrors = new LinkedList<Diagnostic<? extends JavaFileObject>>();
 216.405 +                Tree classPatternTree = parseExpression(c, "new Object() {" + pattern + "}", false, classPatternTreePositions, classPatternTreeErrors);
 216.406 +
 216.407 +                if (!containsError(classPatternTree)) {
 216.408 +                    sourcePositions[0] = classPatternTreePositions[0];
 216.409 +                    offset = "new Object() {".length();
 216.410 +                    patternTreeErrors = classPatternTreeErrors;
 216.411 +                    patternTree = toAttribute = classPatternTree;
 216.412 +                    classMember = true;
 216.413 +                } else {
 216.414 +                    offset = 1;
 216.415 +                    sourcePositions[0] = currentPatternTreePositions[0];
 216.416 +                    VariableTree var;
 216.417 +                    Names names = Names.instance(jti.getContext());
 216.418 +                    if (currentPatternTree.getKind() == Kind.VARIABLE && (var = ((VariableTree) currentPatternTree)).getType().getKind() == Kind.ERRONEOUS && var.getName() == names.error && var.getInitializer() == null && var.getModifiers().getAnnotations().size() == 1 && !containsError(var.getModifiers().getAnnotations().get(0))) {
 216.419 +                        patternTreeErrors = currentPatternTreeErrors; //TODO: the errors are incorrect
 216.420 +                        toAttribute = currentPatternTree;
 216.421 +                        patternTree = var.getModifiers().getAnnotations().get(0);
 216.422 +                    } else {
 216.423 +                        patternTreeErrors = currentPatternTreeErrors;
 216.424 +                        patternTree = toAttribute = currentPatternTree;
 216.425 +                    }
 216.426 +                }
 216.427 +            } else {
 216.428 +                sourcePositions[0] = currentPatternTreePositions[0];
 216.429 +                offset = 1;
 216.430 +                patternTreeErrors = currentPatternTreeErrors;
 216.431 +                patternTree = toAttribute = currentPatternTree;
 216.432 +            }
 216.433 +
 216.434 +            expression = false;
 216.435 +        }
 216.436 +
 216.437 +        if (scope != null) {
 216.438 +            TypeMirror type = attributeTree(jti, toAttribute, scope, patternTreeErrors);
 216.439 +
 216.440 +            if (isError(type) && expression) {
 216.441 +                //maybe type?
 216.442 +                if (Utilities.isPureMemberSelect(patternTree, false)) {
 216.443 +                    SourcePositions[] varPositions = new SourcePositions[1];
 216.444 +                    List<Diagnostic<? extends JavaFileObject>> varErrors = new LinkedList<Diagnostic<? extends JavaFileObject>>();
 216.445 +                    Tree var = parseExpression(c, pattern + ".Class.class;", false, varPositions, varErrors);
 216.446 +
 216.447 +                    attributeTree(jti, var, scope, varErrors);
 216.448 +
 216.449 +                    ExpressionTree typeTree = ((MemberSelectTree) ((MemberSelectTree) var).getExpression()).getExpression();
 216.450 +                    final Symtab symtab = Symtab.instance(c);
 216.451 +                    final Elements el = jti.getElements();
 216.452 +                    final Trees trees = JavacTrees.instance(c);
 216.453 +                    CompilationUnitTree cut = ((JavacScope) scope).getEnv().toplevel;
 216.454 +                    final boolean[] found = new boolean[1];
 216.455 +
 216.456 +                    new TreePathScanner<Void, Void>() {
 216.457 +                        @Override public Void visitMemberSelect(MemberSelectTree node, Void p) {
 216.458 +                            Element currentElement = trees.getElement(getCurrentPath());
 216.459 +
 216.460 +                            if (!isError(currentElement)) {
 216.461 +                                if (currentElement.getKind() == ElementKind.PACKAGE && el.getPackageElement(node.toString()) == null) {
 216.462 +                                    ((JCFieldAccess) node).sym = symtab.errSymbol;
 216.463 +                                    ((JCFieldAccess) node).type = symtab.errType;
 216.464 +                                } else {
 216.465 +                                    found[0] = true;
 216.466 +                                    return null;
 216.467 +                                }
 216.468 +                            }
 216.469 +
 216.470 +                            return super.visitMemberSelect(node, p);
 216.471 +                        }
 216.472 +                        @Override public Void visitIdentifier(IdentifierTree node, Void p) {
 216.473 +                            Element currentElement = trees.getElement(getCurrentPath());
 216.474 +
 216.475 +                            if (!isError(currentElement)) {
 216.476 +                                if (currentElement.getKind() == ElementKind.PACKAGE && el.getPackageElement(node.toString()) == null) {
 216.477 +                                    ((JCIdent) node).sym = symtab.errSymbol;
 216.478 +                                    ((JCIdent) node).type = symtab.errType;
 216.479 +                                } else {
 216.480 +                                    found[0] = true;
 216.481 +                                    return null;
 216.482 +                                }
 216.483 +                            }
 216.484 +                            return super.visitIdentifier(node, p);
 216.485 +                        }
 216.486 +
 216.487 +                    }.scan(new TreePath(new TreePath(cut), typeTree), null);
 216.488 +
 216.489 +                    if (found[0]) {
 216.490 +                        sourcePositions[0] = varPositions[0];
 216.491 +                        offset = 0;
 216.492 +                        patternTreeErrors = varErrors;
 216.493 +                        patternTree = typeTree;
 216.494 +                    }
 216.495 +                }
 216.496 +            }
 216.497 +        }
 216.498 +
 216.499 +        if (classMember) {
 216.500 +            List<? extends Tree> members = ((NewClassTree) patternTree).getClassBody().getMembers();
 216.501 +            
 216.502 +            int syntheticOffset = !members.isEmpty() && members.get(0).getKind() == Kind.METHOD && (((JCMethodDecl) members.get(0)).mods.flags & Flags.GENERATEDCONSTR) != 0 ? 1 : 0;
 216.503 +
 216.504 +            if (members.size() > 1 + syntheticOffset) {
 216.505 +                ModifiersTree mt = make.Modifiers(EnumSet.noneOf(Modifier.class));
 216.506 +                List<Tree> newMembers = new LinkedList<Tree>();
 216.507 +
 216.508 +                newMembers.add(make.ExpressionStatement(make.Identifier("$$1$")));
 216.509 +                newMembers.addAll(members.subList(syntheticOffset, members.size()));
 216.510 +
 216.511 +                patternTree = make.Class(mt, "$", Collections.<TypeParameterTree>emptyList(), null, Collections.<Tree>emptyList(), newMembers);
 216.512 +            } else {
 216.513 +                patternTree = members.get(0 + syntheticOffset);
 216.514 +            }
 216.515 +        }
 216.516 +
 216.517 +        if (errors != null) {
 216.518 +            for (Diagnostic<? extends JavaFileObject> d : patternTreeErrors) {
 216.519 +                errors.add(new OffsetDiagnostic<JavaFileObject>(d, -offset));
 216.520 +            }
 216.521 +        }
 216.522 +
 216.523 +        sourcePositions[0] = new OffsetSourcePositions(sourcePositions[0], -offset);
 216.524 +        
 216.525 +        return patternTree;
 216.526 +    }
 216.527 +
 216.528 +    static boolean isError(Element el) {
 216.529 +        return (el == null || (el.getKind() == ElementKind.CLASS) && isError(((TypeElement) el).asType()));
 216.530 +    }
 216.531 +
 216.532 +    private static boolean isError(TypeMirror type) {
 216.533 +        return type == null || type.getKind() == TypeKind.ERROR;
 216.534 +    }
 216.535 +
 216.536 +    private static boolean isStatement(String pattern) {
 216.537 +        return pattern.trim().endsWith(";");
 216.538 +    }
 216.539 +
 216.540 +    private static boolean isErrorTree(Tree t) {
 216.541 +        return t.getKind() == Kind.ERRONEOUS || (t.getKind() == Kind.IDENTIFIER && ((IdentifierTree) t).getName().contentEquals("<error>")); //TODO: <error>...
 216.542 +    }
 216.543 +    
 216.544 +    private static boolean containsError(Tree t) {
 216.545 +        return new TreeScanner<Boolean, Void>() {
 216.546 +            @Override
 216.547 +            public Boolean scan(Tree node, Void p) {
 216.548 +                if (node != null && isErrorTree(node)) {
 216.549 +                    return true;
 216.550 +                }
 216.551 +                return super.scan(node, p) ==Boolean.TRUE;
 216.552 +            }
 216.553 +            @Override
 216.554 +            public Boolean reduce(Boolean r1, Boolean r2) {
 216.555 +                return r1 == Boolean.TRUE || r2 == Boolean.TRUE;
 216.556 +            }
 216.557 +        }.scan(t, null);
 216.558 +    }
 216.559 +
 216.560 +    private static JCStatement parseStatement(Context context, CharSequence stmt, SourcePositions[] pos, final List<Diagnostic<? extends JavaFileObject>> errors) {
 216.561 +        if (stmt == null || (pos != null && pos.length != 1))
 216.562 +            throw new IllegalArgumentException();
 216.563 +        JavaCompiler compiler = JavaCompiler.instance(context);
 216.564 +        JavaFileObject prev = compiler.log.useSource(new DummyJFO());
 216.565 +        Log.DiagnosticHandler discardHandler = new Log.DiscardDiagnosticHandler(compiler.log) {
 216.566 +            @Override
 216.567 +            public void report(JCDiagnostic diag) {
 216.568 +                errors.add(diag);
 216.569 +            }            
 216.570 +        };
 216.571 +        try {
 216.572 +            CharBuffer buf = CharBuffer.wrap((stmt+"\u0000").toCharArray(), 0, stmt.length());
 216.573 +            ParserFactory factory = ParserFactory.instance(context);
 216.574 +            ScannerFactory scannerFactory = ScannerFactory.instance(context);
 216.575 +            Names names = Names.instance(context);
 216.576 +            Parser parser = new JackpotJavacParser(context, (NBParserFactory) factory, scannerFactory.newScanner(buf, false), false, false, CancelService.instance(context), names);
 216.577 +            if (parser instanceof JavacParser) {
 216.578 +                if (pos != null)
 216.579 +                    pos[0] = new ParserSourcePositions((JavacParser)parser);
 216.580 +                return parser.parseStatement();
 216.581 +            }
 216.582 +            return null;
 216.583 +        } finally {
 216.584 +            compiler.log.useSource(prev);
 216.585 +            compiler.log.popDiagnosticHandler(discardHandler);
 216.586 +        }
 216.587 +    }
 216.588 +
 216.589 +    private static JCExpression parseExpression(Context context, CharSequence expr, boolean onlyFullInput, SourcePositions[] pos, final List<Diagnostic<? extends JavaFileObject>> errors) {
 216.590 +        if (expr == null || (pos != null && pos.length != 1))
 216.591 +            throw new IllegalArgumentException();
 216.592 +        JavaCompiler compiler = JavaCompiler.instance(context);
 216.593 +        JavaFileObject prev = compiler.log.useSource(new DummyJFO());
 216.594 +        Log.DiagnosticHandler discardHandler = new Log.DiscardDiagnosticHandler(compiler.log) {
 216.595 +            @Override
 216.596 +            public void report(JCDiagnostic diag) {
 216.597 +                errors.add(diag);
 216.598 +            }            
 216.599 +        };
 216.600 +        try {
 216.601 +            CharBuffer buf = CharBuffer.wrap((expr+"\u0000").toCharArray(), 0, expr.length());
 216.602 +            ParserFactory factory = ParserFactory.instance(context);
 216.603 +            ScannerFactory scannerFactory = ScannerFactory.instance(context);
 216.604 +            Names names = Names.instance(context);
 216.605 +            Scanner scanner = scannerFactory.newScanner(buf, false);
 216.606 +            Parser parser = new JackpotJavacParser(context, (NBParserFactory) factory, scanner, false, false, CancelService.instance(context), names);
 216.607 +            if (parser instanceof JavacParser) {
 216.608 +                if (pos != null)
 216.609 +                    pos[0] = new ParserSourcePositions((JavacParser)parser);
 216.610 +                JCExpression result = parser.parseExpression();
 216.611 +
 216.612 +                if (!onlyFullInput || scanner.token().kind == TokenKind.EOF) {
 216.613 +                    return result;
 216.614 +                }
 216.615 +            }
 216.616 +            return null;
 216.617 +        } finally {
 216.618 +            compiler.log.useSource(prev);
 216.619 +            compiler.log.popDiagnosticHandler(discardHandler);
 216.620 +        }
 216.621 +    }
 216.622 +
 216.623 +    private static TypeMirror attributeTree(JavacTaskImpl jti, Tree tree, Scope scope, final List<Diagnostic<? extends JavaFileObject>> errors) {
 216.624 +        Log log = Log.instance(jti.getContext());
 216.625 +        JavaFileObject prev = log.useSource(new DummyJFO());
 216.626 +        Log.DiagnosticHandler discardHandler = new Log.DiscardDiagnosticHandler(log) {
 216.627 +            @Override
 216.628 +            public void report(JCDiagnostic diag) {
 216.629 +                errors.add(diag);
 216.630 +            }            
 216.631 +        };
 216.632 +        NBResolve resolve = NBResolve.instance(jti.getContext());
 216.633 +        resolve.disableAccessibilityChecks();
 216.634 +        try {
 216.635 +            Attr attr = Attr.instance(jti.getContext());
 216.636 +            Env<AttrContext> env = ((JavacScope) scope).getEnv();
 216.637 +            if (tree instanceof JCExpression)
 216.638 +                return attr.attribExpr((JCTree) tree,env, Type.noType);
 216.639 +            return attr.attribStat((JCTree) tree,env);
 216.640 +        } finally {
 216.641 +            log.useSource(prev);
 216.642 +            log.popDiagnosticHandler(discardHandler);
 216.643 +            resolve.restoreAccessbilityChecks();
 216.644 +        }
 216.645 +    }
 216.646 +
 216.647 +    public static @CheckForNull CharSequence getWildcardTreeName(@NonNull Tree t) {
 216.648 +        if (t.getKind() == Kind.EXPRESSION_STATEMENT && ((ExpressionStatementTree) t).getExpression().getKind() == Kind.IDENTIFIER) {
 216.649 +            IdentifierTree identTree = (IdentifierTree) ((ExpressionStatementTree) t).getExpression();
 216.650 +            
 216.651 +            return identTree.getName().toString();
 216.652 +        }
 216.653 +
 216.654 +        if (t.getKind() == Kind.IDENTIFIER) {
 216.655 +            IdentifierTree identTree = (IdentifierTree) t;
 216.656 +            String name = identTree.getName().toString();
 216.657 +
 216.658 +            if (name.startsWith("$")) {
 216.659 +                return name;
 216.660 +            }
 216.661 +        }
 216.662 +        
 216.663 +        if (t.getKind() == Kind.TYPE_PARAMETER) {
 216.664 +            String name = ((TypeParameterTree) t).getName().toString();
 216.665 +
 216.666 +            if (name.startsWith("$")) {
 216.667 +                return name;
 216.668 +            }
 216.669 +        }
 216.670 +
 216.671 +        return null;
 216.672 +    }
 216.673 +
 216.674 +    public static boolean isMultistatementWildcard(@NonNull CharSequence name) {
 216.675 +        return name.charAt(name.length() - 1) == '$';
 216.676 +    }
 216.677 +
 216.678 +    public static boolean isMultistatementWildcardTree(Tree tree) {
 216.679 +        CharSequence name = Utilities.getWildcardTreeName(tree);
 216.680 +
 216.681 +        return name != null && Utilities.isMultistatementWildcard(name);
 216.682 +    }
 216.683 +
 216.684 +    private static long inc;
 216.685 +
 216.686 +    public static Scope constructScope(CompilationInfo info, Map<String, TypeMirror> constraints) {
 216.687 +        return constructScope(info, constraints, Collections.<String>emptyList());
 216.688 +    }
 216.689 +
 216.690 +    public static Scope constructScope(CompilationInfo info, Map<String, TypeMirror> constraints, Iterable<? extends String> auxiliaryImports) {
 216.691 +        ScopeDescription desc = new ScopeDescription(constraints, auxiliaryImports);
 216.692 +        Scope result = (Scope) info.getCachedValue(desc);
 216.693 +
 216.694 +        if (result != null) return result;
 216.695 +        
 216.696 +        StringBuilder clazz = new StringBuilder();
 216.697 +
 216.698 +        clazz.append("package $;");
 216.699 +
 216.700 +        for (String i : auxiliaryImports) {
 216.701 +            clazz.append(i);
 216.702 +        }
 216.703 +
 216.704 +        long count = inc++;
 216.705 +
 216.706 +        clazz.append("public class $" + count + "{");
 216.707 +
 216.708 +        for (Entry<String, TypeMirror> e : constraints.entrySet()) {
 216.709 +            if (e.getValue() != null) {
 216.710 +                clazz.append("private ");
 216.711 +                clazz.append(e.getValue().toString()); //XXX
 216.712 +                clazz.append(" ");
 216.713 +                clazz.append(e.getKey());
 216.714 +                clazz.append(";\n");
 216.715 +            }
 216.716 +        }
 216.717 +
 216.718 +        clazz.append("private void test() {\n");
 216.719 +        clazz.append("}\n");
 216.720 +        clazz.append("}\n");
 216.721 +
 216.722 +        JavacTaskImpl jti = JavaSourceAccessor.getINSTANCE().getJavacTask(info);
 216.723 +        Context context = jti.getContext();
 216.724 +        JavaCompiler compiler = JavaCompiler.instance(context);
 216.725 +        Log log = Log.instance(context);
 216.726 +        NBResolve resolve = NBResolve.instance(context);
 216.727 +        Log.DiagnosticHandler discardHandler = new Log.DiscardDiagnosticHandler(compiler.log);
 216.728 +
 216.729 +        JavaFileObject jfo = FileObjects.memoryFileObject("$", "$", new File("/tmp/$" + count + ".java").toURI(), System.currentTimeMillis(), clazz.toString());
 216.730 +
 216.731 +        boolean oldSkipAPs = compiler.skipAnnotationProcessing;
 216.732 +
 216.733 +        try {
 216.734 +            compiler.skipAnnotationProcessing = true;
 216.735 +            resolve.disableAccessibilityChecks();
 216.736 +            
 216.737 +            JCCompilationUnit cut = compiler.parse(jfo);
 216.738 +
 216.739 +            compiler.enterTrees(com.sun.tools.javac.util.List.of(cut));
 216.740 +
 216.741 +            Todo todo = compiler.todo;
 216.742 +            ListBuffer<Env<AttrContext>> defer = new ListBuffer<>();
 216.743 +            
 216.744 +            while (todo.peek() != null) {
 216.745 +                Env<AttrContext> env = todo.remove();
 216.746 +
 216.747 +                if (env.toplevel == cut)
 216.748 +                    compiler.attribute(env);
 216.749 +                else
 216.750 +                    defer = defer.append(env);
 216.751 +            }
 216.752 +
 216.753 +            todo.addAll(defer);
 216.754 +
 216.755 +            Scope res = new ScannerImpl().scan(cut, info);
 216.756 +
 216.757 +            info.putCachedValue(desc, res, CacheClearPolicy.ON_SIGNATURE_CHANGE);
 216.758 +
 216.759 +            return res;
 216.760 +        } finally {
 216.761 +            resolve.restoreAccessbilityChecks();
 216.762 +            log.popDiagnosticHandler(discardHandler);
 216.763 +            compiler.skipAnnotationProcessing = oldSkipAPs;
 216.764 +        }
 216.765 +    }
 216.766 +
 216.767 +    private static final class ScannerImpl extends TreePathScanner<Scope, CompilationInfo> {
 216.768 +
 216.769 +        @Override
 216.770 +        public Scope visitBlock(BlockTree node, CompilationInfo p) {
 216.771 +            return p.getTrees().getScope(getCurrentPath());
 216.772 +        }
 216.773 +
 216.774 +        @Override
 216.775 +        public Scope visitMethod(MethodTree node, CompilationInfo p) {
 216.776 +            if (node.getReturnType() == null) {
 216.777 +                return null;
 216.778 +            }
 216.779 +            return super.visitMethod(node, p);
 216.780 +        }
 216.781 +
 216.782 +        @Override
 216.783 +        public Scope reduce(Scope r1, Scope r2) {
 216.784 +            return r1 != null ? r1 : r2;
 216.785 +        }
 216.786 +
 216.787 +    }
 216.788 +
 216.789 +    private static final class ScopeDescription {
 216.790 +        private final Map<String, TypeMirror> constraints;
 216.791 +        private final Iterable<? extends String> auxiliaryImports;
 216.792 +
 216.793 +        public ScopeDescription(Map<String, TypeMirror> constraints, Iterable<? extends String> auxiliaryImports) {
 216.794 +            this.constraints = constraints;
 216.795 +            this.auxiliaryImports = auxiliaryImports;
 216.796 +        }
 216.797 +
 216.798 +        @Override
 216.799 +        public boolean equals(Object obj) {
 216.800 +            if (obj == null) {
 216.801 +                return false;
 216.802 +            }
 216.803 +            if (getClass() != obj.getClass()) {
 216.804 +                return false;
 216.805 +            }
 216.806 +            final ScopeDescription other = (ScopeDescription) obj;
 216.807 +            if (this.constraints != other.constraints && (this.constraints == null || !this.constraints.equals(other.constraints))) {
 216.808 +                return false;
 216.809 +            }
 216.810 +            if (this.auxiliaryImports != other.auxiliaryImports && (this.auxiliaryImports == null || !this.auxiliaryImports.equals(other.auxiliaryImports))) {
 216.811 +                return false;
 216.812 +            }
 216.813 +            return true;
 216.814 +        }
 216.815 +
 216.816 +        @Override
 216.817 +        public int hashCode() {
 216.818 +            int hash = 7;
 216.819 +            hash = 47 * hash + (this.constraints != null ? this.constraints.hashCode() : 0);
 216.820 +            hash = 47 * hash + (this.auxiliaryImports != null ? this.auxiliaryImports.hashCode() : 0);
 216.821 +            return hash;
 216.822 +        }
 216.823 +
 216.824 +    }
 216.825 +
 216.826 +//    private static Scope constructScope2(CompilationInfo info, Map<String, TypeMirror> constraints) {
 216.827 +//        JavacScope s = (JavacScope) info.getTrees().getScope(new TreePath(info.getCompilationUnit()));
 216.828 +//        Env<AttrContext> env = s.getEnv();
 216.829 +//
 216.830 +//        env = env.dup(env.tree);
 216.831 +//
 216.832 +//        env.info.
 216.833 +//    }
 216.834 +
 216.835 +    public static String toHumanReadableTime(double d) {
 216.836 +        StringBuilder result = new StringBuilder();
 216.837 +        long inSeconds = (long) (d / 1000);
 216.838 +        int seconds = (int) (inSeconds % 60);
 216.839 +        long inMinutes = inSeconds / 60;
 216.840 +        int minutes = (int) (inMinutes % 60);
 216.841 +        long inHours = inMinutes / 60;
 216.842 +
 216.843 +        if (inHours > 0) {
 216.844 +            result.append(inHours);
 216.845 +            result.append("h");
 216.846 +        }
 216.847 +
 216.848 +        if (minutes > 0) {
 216.849 +            result.append(minutes);
 216.850 +            result.append("m");
 216.851 +        }
 216.852 +        
 216.853 +        result.append(seconds);
 216.854 +        result.append("s");
 216.855 +
 216.856 +        return result.toString();
 216.857 +    }
 216.858 +
 216.859 +    public static ClasspathInfo createUniversalCPInfo() {
 216.860 +        return Lookup.getDefault().lookup(SPI.class).createUniversalCPInfo();
 216.861 +    }
 216.862 +
 216.863 +    @SuppressWarnings("deprecation")
 216.864 +    public static void waitScanFinished() throws InterruptedException {
 216.865 +        SourceUtils.waitScanFinished();
 216.866 +    }
 216.867 +
 216.868 +    public static Set<? extends String> findSuppressedWarnings(CompilationInfo info, TreePath path) {
 216.869 +        //TODO: cache?
 216.870 +        Set<String> keys = new HashSet<String>();
 216.871 +
 216.872 +        while (path != null) {
 216.873 +            Tree leaf = path.getLeaf();
 216.874 +
 216.875 +            switch (leaf.getKind()) {
 216.876 +                case METHOD:
 216.877 +                    handleSuppressWarnings(info, path, ((MethodTree) leaf).getModifiers(), keys);
 216.878 +                    break;
 216.879 +                case CLASS:
 216.880 +                    handleSuppressWarnings(info, path, ((ClassTree) leaf).getModifiers(), keys);
 216.881 +                    break;
 216.882 +                case VARIABLE:
 216.883 +                    handleSuppressWarnings(info, path, ((VariableTree) leaf).getModifiers(), keys);
 216.884 +                    break;
 216.885 +            }
 216.886 +
 216.887 +            path = path.getParentPath();
 216.888 +        }
 216.889 +
 216.890 +        return Collections.unmodifiableSet(keys);
 216.891 +    }
 216.892 +
 216.893 +    private static void handleSuppressWarnings(CompilationInfo info, TreePath path, ModifiersTree modifiers, final Set<String> keys) {
 216.894 +        Element el = info.getTrees().getElement(path);
 216.895 +
 216.896 +        if (el == null) {
 216.897 +            return ;
 216.898 +        }
 216.899 +
 216.900 +        for (AnnotationMirror am : el.getAnnotationMirrors()) {
 216.901 +            Name fqn = ((TypeElement) am.getAnnotationType().asElement()).getQualifiedName();
 216.902 +            
 216.903 +            if (!fqn.contentEquals("java.lang.SuppressWarnings")) {
 216.904 +                continue;
 216.905 +            }
 216.906 +
 216.907 +            for (Entry<? extends ExecutableElement, ? extends AnnotationValue> e : am.getElementValues().entrySet()) {
 216.908 +                if (!e.getKey().getSimpleName().contentEquals("value"))
 216.909 +                    continue;
 216.910 +
 216.911 +                e.getValue().accept(new AnnotationValueVisitor<Void, Void>() {
 216.912 +                    public Void visit(AnnotationValue av, Void p) {
 216.913 +                        av.accept(this, p);
 216.914 +                        return null;
 216.915 +                    }
 216.916 +                    public Void visit(AnnotationValue av) {
 216.917 +                        av.accept(this, null);
 216.918 +                        return null;
 216.919 +                    }
 216.920 +                    public Void visitBoolean(boolean b, Void p) {
 216.921 +                        return null;
 216.922 +                    }
 216.923 +                    public Void visitByte(byte b, Void p) {
 216.924 +                        return null;
 216.925 +                    }
 216.926 +                    public Void visitChar(char c, Void p) {
 216.927 +                        return null;
 216.928 +                    }
 216.929 +                    public Void visitDouble(double d, Void p) {
 216.930 +                        return null;
 216.931 +                    }
 216.932 +                    public Void visitFloat(float f, Void p) {
 216.933 +                        return null;
 216.934 +                    }
 216.935 +                    public Void visitInt(int i, Void p) {
 216.936 +                        return null;
 216.937 +                    }
 216.938 +                    public Void visitLong(long i, Void p) {
 216.939 +                        return null;
 216.940 +                    }
 216.941 +                    public Void visitShort(short s, Void p) {
 216.942 +                        return null;
 216.943 +                    }
 216.944 +                    public Void visitString(String s, Void p) {
 216.945 +                        keys.add(s);
 216.946 +                        return null;
 216.947 +                    }
 216.948 +                    public Void visitType(TypeMirror t, Void p) {
 216.949 +                        return null;
 216.950 +                    }
 216.951 +                    public Void visitEnumConstant(VariableElement c, Void p) {
 216.952 +                        return null;
 216.953 +                    }
 216.954 +                    public Void visitAnnotation(AnnotationMirror a, Void p) {
 216.955 +                        return null;
 216.956 +                    }
 216.957 +                    public Void visitArray(List<? extends AnnotationValue> vals, Void p) {
 216.958 +                        for (AnnotationValue av : vals) {
 216.959 +                            av.accept(this, p);
 216.960 +                        }
 216.961 +                        return null;
 216.962 +                    }
 216.963 +                    public Void visitUnknown(AnnotationValue av, Void p) {
 216.964 +                        return null;
 216.965 +                    }
 216.966 +                }, null);
 216.967 +            }
 216.968 +        }
 216.969 +    }
 216.970 +
 216.971 +    public static Tree generalizePattern(CompilationInfo info, TreePath original) {
 216.972 +        return generalizePattern(JavaSourceAccessor.getINSTANCE().getJavacTask(info), original);
 216.973 +    }
 216.974 +
 216.975 +    public static Tree generalizePattern(CompilationTask task, TreePath original) {
 216.976 +        JavacTaskImpl jti = (JavacTaskImpl) task;
 216.977 +        com.sun.tools.javac.util.Context c = jti.getContext();
 216.978 +        TreeFactory make = TreeFactory.instance(c);
 216.979 +        Trees javacTrees = Trees.instance(task);
 216.980 +        GeneralizePattern gp = new GeneralizePattern(javacTrees, make);
 216.981 +
 216.982 +        gp.scan(original, null);
 216.983 +
 216.984 +        GeneralizePatternITT itt = new GeneralizePatternITT(gp.tree2Variable);
 216.985 +
 216.986 +        itt.attach(c, new NoImports(c), null);
 216.987 +
 216.988 +        return itt.translate(original.getLeaf());
 216.989 +    }
 216.990 +
 216.991 +    public static Tree generalizePattern(CompilationInfo info, TreePath original, int firstStatement, int lastStatement) {
 216.992 +        JavacTaskImpl jti = JavaSourceAccessor.getINSTANCE().getJavacTask(info);
 216.993 +        com.sun.tools.javac.util.Context c = jti.getContext();
 216.994 +        TreeFactory make = TreeFactory.instance(c);
 216.995 +        Tree translated = Utilities.generalizePattern(jti, original);
 216.996 +
 216.997 +        assert translated.getKind() == Kind.BLOCK;
 216.998 +
 216.999 +        List<StatementTree> newStatements = new LinkedList<StatementTree>();
216.1000 +        BlockTree block = (BlockTree) translated;
216.1001 +
216.1002 +        if (firstStatement != lastStatement) {
216.1003 +            newStatements.add(make.ExpressionStatement(make.Identifier("$s0$")));
216.1004 +            newStatements.addAll(block.getStatements().subList(firstStatement, lastStatement + 1));
216.1005 +            newStatements.add(make.ExpressionStatement(make.Identifier("$s1$")));
216.1006 +
216.1007 +            translated = make.Block(newStatements, block.isStatic());
216.1008 +        } else {
216.1009 +            translated = block.getStatements().get(firstStatement);
216.1010 +        }
216.1011 +
216.1012 +        return translated;
216.1013 +    }
216.1014 +
216.1015 +    public interface SPI {
216.1016 +        public ClasspathInfo createUniversalCPInfo();
216.1017 +    }
216.1018 +
216.1019 +    @ServiceProvider(service=SPI.class)
216.1020 +    public static final class NbSPIImpl implements SPI {
216.1021 +
216.1022 +        public ClasspathInfo createUniversalCPInfo() {
216.1023 +            JavaPlatform select = JavaPlatform.getDefault();
216.1024 +
216.1025 +            if (select.getSpecification().getVersion() != null) {
216.1026 +                for (JavaPlatform p : JavaPlatformManager.getDefault().getInstalledPlatforms()) {
216.1027 +                    if (!"j2se".equals(p.getSpecification().getName()) || p.getSpecification().getVersion() == null) continue;
216.1028 +                    if (p.getSpecification().getVersion().compareTo(select.getSpecification().getVersion()) > 0) {
216.1029 +                        select = p;
216.1030 +                    }
216.1031 +                }
216.1032 +            }
216.1033 +
216.1034 +            return ClasspathInfo.create(select.getBootstrapLibraries(), ClassPath.EMPTY, ClassPath.EMPTY);
216.1035 +        }
216.1036 +
216.1037 +    }
216.1038 +    
216.1039 +    private static final class GeneralizePattern extends TreePathScanner<Void, Void> {
216.1040 +
216.1041 +        public final Map<Tree, Tree> tree2Variable = new HashMap<Tree, Tree>();
216.1042 +        private final Map<Element, String> element2Variable = new HashMap<Element, String>();
216.1043 +        private final Trees javacTrees;
216.1044 +        private final TreeFactory make;
216.1045 +
216.1046 +        private int currentVariableIndex = 0;
216.1047 +
216.1048 +        public GeneralizePattern(Trees javacTrees, TreeFactory make) {
216.1049 +            this.javacTrees = javacTrees;
216.1050 +            this.make = make;
216.1051 +        }
216.1052 +
216.1053 +        private @NonNull String getVariable(@NonNull Element el) {
216.1054 +            String var = element2Variable.get(el);
216.1055 +
216.1056 +            if (var == null) {
216.1057 +                element2Variable.put(el, var = "$" + currentVariableIndex++);
216.1058 +            }
216.1059 +
216.1060 +            return var;
216.1061 +        }
216.1062 +
216.1063 +        private boolean shouldBeGeneralized(@NonNull Element el) {
216.1064 +            if (el.getModifiers().contains(Modifier.PRIVATE)) {
216.1065 +                return true;
216.1066 +            }
216.1067 +
216.1068 +            switch (el.getKind()) {
216.1069 +                case LOCAL_VARIABLE:
216.1070 +                case EXCEPTION_PARAMETER:
216.1071 +                case PARAMETER:
216.1072 +                    return true;
216.1073 +            }
216.1074 +
216.1075 +            return false;
216.1076 +        }
216.1077 +
216.1078 +        @Override
216.1079 +        public Void visitIdentifier(IdentifierTree node, Void p) {
216.1080 +            Element e = javacTrees.getElement(getCurrentPath());
216.1081 +
216.1082 +            if (e != null && shouldBeGeneralized(e)) {
216.1083 +                tree2Variable.put(node, make.Identifier(getVariable(e)));
216.1084 +            }
216.1085 +
216.1086 +            return super.visitIdentifier(node, p);
216.1087 +        }
216.1088 +
216.1089 +        @Override
216.1090 +        public Void visitVariable(VariableTree node, Void p) {
216.1091 +            Element e = javacTrees.getElement(getCurrentPath());
216.1092 +
216.1093 +            if (e != null && shouldBeGeneralized(e)) {
216.1094 +                VariableTree nue = make.Variable(node.getModifiers(), getVariable(e), node.getType(), node.getInitializer());
216.1095 +
216.1096 +                tree2Variable.put(node, nue);
216.1097 +            }
216.1098 +
216.1099 +            return super.visitVariable(node, p);
216.1100 +        }
216.1101 +
216.1102 +        @Override
216.1103 +        public Void visitNewClass(NewClassTree node, Void p) {
216.1104 +            //XXX:
216.1105 +            if (node.getEnclosingExpression() != null) {
216.1106 +                tree2Variable.put(node, make.Identifier("$" + currentVariableIndex++));
216.1107 +                return null;
216.1108 +            }
216.1109 +
216.1110 +            NewClassTree nue = make.NewClass(node.getEnclosingExpression(), Collections.<ExpressionTree>singletonList(make.Identifier("$" + currentVariableIndex++ + "$")), make.Identifier("$" + currentVariableIndex++), Collections.<ExpressionTree>singletonList(make.Identifier("$" + currentVariableIndex++ + "$")), null);
216.1111 +
216.1112 +            tree2Variable.put(node, nue);
216.1113 +
216.1114 +            return null;
216.1115 +        }
216.1116 +
216.1117 +    }
216.1118 +
216.1119 +    private static final class GeneralizePatternITT extends ImmutableTreeTranslator {
216.1120 +
216.1121 +        private final Map<Tree, Tree> tree2Variable;
216.1122 +
216.1123 +        public GeneralizePatternITT(Map<Tree, Tree> tree2Variable) {
216.1124 +            super(null);
216.1125 +            this.tree2Variable = tree2Variable;
216.1126 +        }
216.1127 +
216.1128 +        @Override
216.1129 +        public Tree translate(Tree tree) {
216.1130 +            Tree var = tree2Variable.remove(tree);
216.1131 +
216.1132 +            if (var != null) {
216.1133 +                return super.translate(var);
216.1134 +            }
216.1135 +
216.1136 +            return super.translate(tree);
216.1137 +        }
216.1138 +
216.1139 +    }
216.1140 +
216.1141 +    private static final class NoImports extends ImportAnalysis2 {
216.1142 +
216.1143 +        public NoImports(Context env) {
216.1144 +            super(env);
216.1145 +        }
216.1146 +
216.1147 +        @Override
216.1148 +        public void classEntered(ClassTree clazz) {}
216.1149 +
216.1150 +        @Override
216.1151 +        public void enterVisibleThroughClasses(ClassTree clazz) {}
216.1152 +
216.1153 +        @Override
216.1154 +        public void classLeft() {}
216.1155 +
216.1156 +        @Override
216.1157 +        public ExpressionTree resolveImport(MemberSelectTree orig, Element element) {
216.1158 +            return orig;
216.1159 +        }
216.1160 +
216.1161 +        @Override
216.1162 +        public void setCompilationUnit(CompilationUnitTree cut) {}
216.1163 +
216.1164 +        @Override
216.1165 +        public void setImports(List<? extends ImportTree> importsToAdd) {}
216.1166 +
216.1167 +        @Override
216.1168 +        public Set<? extends Element> getImports() {
216.1169 +            return Collections.emptySet();
216.1170 +        }
216.1171 +
216.1172 +        @Override
216.1173 +        public void setPackage(ExpressionTree packageNameTree) {}
216.1174 +
216.1175 +    }
216.1176 +
216.1177 +    public static long patternValue(Tree pattern) {
216.1178 +        class VisitorImpl extends TreeScanner<Void, Void> {
216.1179 +            private int value;
216.1180 +            @Override
216.1181 +            public Void scan(Tree node, Void p) {
216.1182 +                if (node != null) value++;
216.1183 +                return super.scan(node, p);
216.1184 +            }
216.1185 +            @Override
216.1186 +            public Void visitIdentifier(IdentifierTree node, Void p) {
216.1187 +                if (node.getName().toString().startsWith("$")) value--;
216.1188 +                
216.1189 +                return super.visitIdentifier(node, p);
216.1190 +            }
216.1191 +            @Override
216.1192 +            public Void visitNewClass(NewClassTree node, Void p) {
216.1193 +                return null;
216.1194 +            }
216.1195 +        }
216.1196 +
216.1197 +        VisitorImpl vi = new VisitorImpl();
216.1198 +
216.1199 +        vi.scan(pattern, null);
216.1200 +
216.1201 +        return vi.value;
216.1202 +    }
216.1203 +
216.1204 +    public static boolean containsMultistatementTrees(List<? extends Tree> statements) {
216.1205 +        for (Tree t : statements) {
216.1206 +            if (Utilities.isMultistatementWildcardTree(t)) {
216.1207 +                return true;
216.1208 +            }
216.1209 +        }
216.1210 +
216.1211 +        return false;
216.1212 +    }
216.1213 +
216.1214 +    public static boolean isJavadocSupported(CompilationInfo info) {
216.1215 +        Context c = JavaSourceAccessor.getINSTANCE().getJavacTask(info).getContext();
216.1216 +
216.1217 +        try {
216.1218 +        return c.get(Log.logKey) instanceof Messager;
216.1219 +        } catch (NoClassDefFoundError e) {
216.1220 +            return false;
216.1221 +        }
216.1222 +    }
216.1223 +
216.1224 +    private static class JackpotJavacParser extends NBJavacParser {
216.1225 +
216.1226 +        private final Context ctx;
216.1227 +        private final com.sun.tools.javac.util.Name dollar;
216.1228 +        public JackpotJavacParser(Context ctx, NBParserFactory fac,
216.1229 +                         Lexer S,
216.1230 +                         boolean keepDocComments,
216.1231 +                         boolean keepLineMap,
216.1232 +                         CancelService cancelService,
216.1233 +                         Names names) {
216.1234 +            super(fac, S, keepDocComments, keepLineMap, true, cancelService);
216.1235 +            this.ctx = ctx;
216.1236 +            this.dollar = names.fromString("$");
216.1237 +        }
216.1238 +
216.1239 +        @Override
216.1240 +        protected JCModifiers modifiersOpt(JCModifiers partial) {
216.1241 +            if (token.kind == TokenKind.IDENTIFIER) {
216.1242 +                String ident = token.name().toString();
216.1243 +
216.1244 +                if (Utilities.isMultistatementWildcard(ident)) {
216.1245 +                    com.sun.tools.javac.util.Name name = token.name();
216.1246 +
216.1247 +                    nextToken();
216.1248 +                    
216.1249 +                    JCModifiers result = super.modifiersOpt(partial);
216.1250 +                    
216.1251 +                    result.annotations = result.annotations.prepend(new AnnotationWildcard(name, F.Ident(name)));
216.1252 +
216.1253 +                    return result;
216.1254 +                }
216.1255 +            }
216.1256 +
216.1257 +            return super.modifiersOpt(partial);
216.1258 +        }
216.1259 +
216.1260 +        @Override
216.1261 +        public JCVariableDecl formalParameter(boolean lambdaParam) {
216.1262 +            if (token.kind == TokenKind.IDENTIFIER) {
216.1263 +                if (token.name().startsWith(dollar)) {
216.1264 +                    com.sun.tools.javac.util.Name name = token.name();
216.1265 +
216.1266 +                    Token peeked = S.token(1);
216.1267 +
216.1268 +                    if (peeked.kind == TokenKind.COMMA || peeked.kind == TokenKind.RPAREN) {
216.1269 +                        nextToken();
216.1270 +                        return new VariableWildcard(ctx, name, F.Ident(name));
216.1271 +                    }
216.1272 +                }
216.1273 +            }
216.1274 +
216.1275 +            return super.formalParameter(lambdaParam);
216.1276 +        }
216.1277 +
216.1278 +        @Override
216.1279 +        protected JCVariableDecl implicitParameter() {
216.1280 +            if (token.kind == TokenKind.IDENTIFIER) {
216.1281 +                if (token.name().startsWith(dollar)) {
216.1282 +                    com.sun.tools.javac.util.Name name = token.name();
216.1283 +
216.1284 +                    Token peeked = S.token(1);
216.1285 +
216.1286 +                    if (peeked.kind == TokenKind.COMMA || peeked.kind == TokenKind.RPAREN) {
216.1287 +                        nextToken();
216.1288 +                        return new VariableWildcard(ctx, name, F.Ident(name));
216.1289 +                    }
216.1290 +                }
216.1291 +            }
216.1292 +
216.1293 +            return super.implicitParameter();
216.1294 +        }
216.1295 +        
216.1296 +        @Override
216.1297 +        protected JCCatch catchClause() {
216.1298 +            if (token.kind == TokenKind.CATCH) {
216.1299 +                Token peeked = S.token(1);
216.1300 +                
216.1301 +                if (   peeked.kind == TokenKind.IDENTIFIER
216.1302 +                    && Utilities.isMultistatementWildcard(peeked.name().toString())) {
216.1303 +                    accept(TokenKind.CATCH);
216.1304 +                    
216.1305 +                    com.sun.tools.javac.util.Name name = token.name();
216.1306 +
216.1307 +                    accept(TokenKind.IDENTIFIER);
216.1308 +
216.1309 +                    return new CatchWildcard(ctx, name, F.Ident(name));
216.1310 +                } else {
216.1311 +                    nextToken();
216.1312 +                }
216.1313 +            }
216.1314 +            return super.catchClause();
216.1315 +        }
216.1316 +
216.1317 +        @Override
216.1318 +        public com.sun.tools.javac.util.List<JCTree> classOrInterfaceBodyDeclaration(com.sun.tools.javac.util.Name className, boolean isInterface) {
216.1319 +            if (token.kind == TokenKind.IDENTIFIER) {
216.1320 +                if (token.name().startsWith(dollar)) {
216.1321 +                    com.sun.tools.javac.util.Name name = token.name();
216.1322 +
216.1323 +                    Token peeked = S.token(1);
216.1324 +
216.1325 +                    if (peeked.kind == TokenKind.SEMI) {
216.1326 +                        nextToken();
216.1327 +                        nextToken();
216.1328 +                        
216.1329 +                        return com.sun.tools.javac.util.List.<JCTree>of(F.Ident(name));
216.1330 +                    }
216.1331 +                }
216.1332 +            }
216.1333 +            return super.classOrInterfaceBodyDeclaration(className, isInterface);
216.1334 +        }
216.1335 +        
216.1336 +        @Override
216.1337 +        protected JCExpression checkExprStat(JCExpression t) {
216.1338 +            if (t.getTag() == JCTree.Tag.IDENT) {
216.1339 +                if (((IdentifierTree) t).getName().toString().startsWith("$")) {
216.1340 +                    return t;
216.1341 +                }
216.1342 +            }
216.1343 +            return super.checkExprStat(t);
216.1344 +        }
216.1345 +
216.1346 +        @Override
216.1347 +        protected JCCase switchBlockStatementGroup() {
216.1348 +            if (token.kind == TokenKind.CASE) {
216.1349 +                Token peeked = S.token(1);
216.1350 +
216.1351 +                if (peeked.kind == TokenKind.IDENTIFIER) {
216.1352 +                    String ident = peeked.name().toString();
216.1353 +
216.1354 +                    if (ident.startsWith("$") && ident.endsWith("$")) {
216.1355 +                        nextToken();
216.1356 +                        
216.1357 +                        int pos = token.pos;
216.1358 +                        com.sun.tools.javac.util.Name name = token.name();
216.1359 +
216.1360 +                        nextToken();
216.1361 +
216.1362 +                        if (token.kind == TokenKind.SEMI) {
216.1363 +                            nextToken();
216.1364 +                        }
216.1365 +
216.1366 +                        return new JackpotTrees.CaseWildcard(ctx, name, F.at(pos).Ident(name));
216.1367 +                    }
216.1368 +                }
216.1369 +            }
216.1370 +
216.1371 +            return super.switchBlockStatementGroup();
216.1372 +        }
216.1373 +
216.1374 +
216.1375 +        @Override
216.1376 +        protected JCTree resource() {
216.1377 +            if (token.kind == TokenKind.IDENTIFIER && token.name().startsWith(dollar)) {
216.1378 +                Token peeked = S.token(1);
216.1379 +
216.1380 +                if (peeked.kind == TokenKind.SEMI || peeked.kind == TokenKind.RPAREN) {
216.1381 +                    int pos = token.pos;
216.1382 +                    com.sun.tools.javac.util.Name name = token.name();
216.1383 +
216.1384 +                    nextToken();
216.1385 +
216.1386 +                    return F.at(pos).Ident(name);
216.1387 +                }
216.1388 +            }
216.1389 +            return super.resource();
216.1390 +        }
216.1391 +
216.1392 +    }
216.1393 +
216.1394 +    private static final class DummyJFO extends SimpleJavaFileObject {
216.1395 +        private DummyJFO() {
216.1396 +            super(URI.create("dummy.java"), JavaFileObject.Kind.SOURCE);
216.1397 +        }
216.1398 +        @Override
216.1399 +        public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
216.1400 +            return "";
216.1401 +        }
216.1402 +    };
216.1403 +
216.1404 +    /**
216.1405 +     * Only for members (i.e. generated constructor):
216.1406 +     */
216.1407 +    public static List<? extends Tree> filterHidden(TreePath basePath, Iterable<? extends Tree> members) {
216.1408 +        List<Tree> result = new LinkedList<Tree>();
216.1409 +
216.1410 +        for (Tree t : members) {
216.1411 +            if (!isSynthetic(basePath != null ? basePath.getCompilationUnit() : null, t)) {
216.1412 +                result.add(t);
216.1413 +            }
216.1414 +        }
216.1415 +
216.1416 +        return result;
216.1417 +    }
216.1418 +
216.1419 +    private static boolean isSynthetic(CompilationUnitTree cut, Tree leaf) throws NullPointerException {
216.1420 +        JCTree tree = (JCTree) leaf;
216.1421 +
216.1422 +        if (tree.pos == (-1))
216.1423 +            return true;
216.1424 +
216.1425 +        if (leaf.getKind() == Kind.METHOD) {
216.1426 +            //check for synthetic constructor:
216.1427 +            return (((JCMethodDecl)leaf).mods.flags & Flags.GENERATEDCONSTR) != 0L;
216.1428 +        }
216.1429 +
216.1430 +        //check for synthetic superconstructor call:
216.1431 +        if (cut != null && leaf.getKind() == Kind.EXPRESSION_STATEMENT) {
216.1432 +            ExpressionStatementTree est = (ExpressionStatementTree) leaf;
216.1433 +
216.1434 +            if (est.getExpression().getKind() == Kind.METHOD_INVOCATION) {
216.1435 +                MethodInvocationTree mit = (MethodInvocationTree) est.getExpression();
216.1436 +
216.1437 +                if (mit.getMethodSelect().getKind() == Kind.IDENTIFIER) {
216.1438 +                    IdentifierTree it = (IdentifierTree) mit.getMethodSelect();
216.1439 +
216.1440 +                    if ("super".equals(it.getName().toString())) {
216.1441 +                        return ((JCCompilationUnit) cut).endPositions.getEndPos(tree) == (-1);
216.1442 +                    }
216.1443 +                }
216.1444 +            }
216.1445 +        }
216.1446 +
216.1447 +        return false;
216.1448 +    }
216.1449 +
216.1450 +    public static boolean isFakeBlock(Tree t) {
216.1451 +        return t instanceof FakeBlock;
216.1452 +    }
216.1453 +
216.1454 +    public static boolean isFakeClass(Tree t) {
216.1455 +        if (!(t instanceof ClassTree)) {
216.1456 +            return false;
216.1457 +        }
216.1458 +
216.1459 +        ClassTree ct = (ClassTree) t;
216.1460 +
216.1461 +        if (ct.getMembers().isEmpty()) {
216.1462 +            return false;
216.1463 +        }
216.1464 +
216.1465 +        CharSequence wildcardTreeName = Utilities.getWildcardTreeName(ct.getMembers().get(0));
216.1466 +
216.1467 +        if (wildcardTreeName == null) {
216.1468 +            return false;
216.1469 +        }
216.1470 +
216.1471 +        return wildcardTreeName.toString().startsWith("$$");
216.1472 +    }
216.1473 +
216.1474 +    private static final class OffsetSourcePositions implements SourcePositions {
216.1475 +
216.1476 +        private final SourcePositions delegate;
216.1477 +        private final long offset;
216.1478 +
216.1479 +        public OffsetSourcePositions(SourcePositions delegate, long offset) {
216.1480 +            this.delegate = delegate;
216.1481 +            this.offset = offset;
216.1482 +        }
216.1483 +
216.1484 +        public long getStartPosition(CompilationUnitTree cut, Tree tree) {
216.1485 +            return delegate.getStartPosition(cut, tree) + offset;
216.1486 +        }
216.1487 +
216.1488 +        public long getEndPosition(CompilationUnitTree cut, Tree tree) {
216.1489 +            return delegate.getEndPosition(cut, tree) + offset;
216.1490 +        }
216.1491 +
216.1492 +    }
216.1493 +
216.1494 +    private static final class OffsetDiagnostic<S> implements Diagnostic<S> {
216.1495 +        private final Diagnostic<? extends S> delegate;
216.1496 +        private final long offset;
216.1497 +
216.1498 +        public OffsetDiagnostic(Diagnostic<? extends S> delegate, long offset) {
216.1499 +            this.delegate = delegate;
216.1500 +            this.offset = offset;
216.1501 +        }
216.1502 +
216.1503 +        public Diagnostic.Kind getKind() {
216.1504 +            return delegate.getKind();
216.1505 +        }
216.1506 +
216.1507 +        public S getSource() {
216.1508 +            return delegate.getSource();
216.1509 +        }
216.1510 +
216.1511 +        public long getPosition() {
216.1512 +            return delegate.getPosition() + offset;
216.1513 +        }
216.1514 +
216.1515 +        public long getStartPosition() {
216.1516 +            return delegate.getStartPosition() + offset;
216.1517 +        }
216.1518 +
216.1519 +        public long getEndPosition() {
216.1520 +            return delegate.getEndPosition() + offset;
216.1521 +        }
216.1522 +
216.1523 +        public long getLineNumber() {
216.1524 +            throw new UnsupportedOperationException("Not supported yet.");
216.1525 +        }
216.1526 +
216.1527 +        public long getColumnNumber() {
216.1528 +            throw new UnsupportedOperationException("Not supported yet.");
216.1529 +        }
216.1530 +
216.1531 +        public String getCode() {
216.1532 +            return delegate.getCode();
216.1533 +        }
216.1534 +
216.1535 +        public String getMessage(Locale locale) {
216.1536 +            return delegate.getMessage(locale);
216.1537 +        }
216.1538 +
216.1539 +    }
216.1540 +
216.1541 +    private static class ParserSourcePositions implements SourcePositions {
216.1542 +
216.1543 +        private JavacParser parser;
216.1544 +
216.1545 +        private ParserSourcePositions(JavacParser parser) {
216.1546 +            this.parser = parser;
216.1547 +        }
216.1548 +
216.1549 +        public long getStartPosition(CompilationUnitTree file, Tree tree) {
216.1550 +            return parser.getStartPos((JCTree)tree);
216.1551 +        }
216.1552 +
216.1553 +        public long getEndPosition(CompilationUnitTree file, Tree tree) {
216.1554 +            return parser.getEndPos((JCTree)tree);
216.1555 +        }
216.1556 +    }
216.1557 +}
   217.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   217.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/batch/BatchSearch.java	Sun Oct 23 11:50:54 2016 +0200
   217.3 @@ -0,0 +1,714 @@
   217.4 +/*
   217.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   217.6 + *
   217.7 + * Copyright 2009-2011 Oracle and/or its affiliates. All rights reserved.
   217.8 + *
   217.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  217.10 + * Other names may be trademarks of their respective owners.
  217.11 + *
  217.12 + * The contents of this file are subject to the terms of either the GNU
  217.13 + * General Public License Version 2 only ("GPL") or the Common
  217.14 + * Development and Distribution License("CDDL") (collectively, the
  217.15 + * "License"). You may not use this file except in compliance with the
  217.16 + * License. You can obtain a copy of the License at
  217.17 + * http://www.netbeans.org/cddl-gplv2.html
  217.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  217.19 + * specific language governing permissions and limitations under the
  217.20 + * License.  When distributing the software, include this License Header
  217.21 + * Notice in each file and include the License file at
  217.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  217.23 + * particular file as subject to the "Classpath" exception as provided
  217.24 + * by Oracle in the GPL Version 2 section of the License file that
  217.25 + * accompanied this code. If applicable, add the following below the
  217.26 + * License Header, with the fields enclosed by brackets [] replaced by
  217.27 + * your own identifying information:
  217.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  217.29 + *
  217.30 + * If you wish your version of this file to be governed by only the CDDL
  217.31 + * or only the GPL Version 2, indicate your decision by adding
  217.32 + * "[Contributor] elects to include this software in this distribution
  217.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  217.34 + * single choice of license, a recipient has the option to distribute
  217.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  217.36 + * to extend the choice of license to its licensees as provided above.
  217.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  217.38 + * Version 2 license, then the option applies only if the new code is
  217.39 + * made subject to such option by the copyright holder.
  217.40 + *
  217.41 + * Contributor(s):
  217.42 + *
  217.43 + * Portions Copyrighted 2009-2011 Sun Microsystems, Inc.
  217.44 + */
  217.45 +package org.netbeans.modules.java.hints.spiimpl.batch;
  217.46 +
  217.47 +import org.netbeans.spi.java.hints.HintContext.MessageKind;
  217.48 +import org.netbeans.modules.java.hints.providers.spi.HintDescription;
  217.49 +import com.sun.source.tree.Tree;
  217.50 +import com.sun.source.util.TreePath;
  217.51 +import java.io.IOException;
  217.52 +import java.io.OutputStreamWriter;
  217.53 +import java.io.Writer;
  217.54 +import java.nio.ByteBuffer;
  217.55 +import java.util.ArrayList;
  217.56 +import java.util.Collection;
  217.57 +import java.util.Collections;
  217.58 +import java.util.HashMap;
  217.59 +import java.util.HashSet;
  217.60 +import java.util.LinkedList;
  217.61 +import java.util.List;
  217.62 +import java.util.Map;
  217.63 +import java.util.Map.Entry;
  217.64 +import java.util.Set;
  217.65 +import java.util.concurrent.Callable;
  217.66 +import java.util.concurrent.atomic.AtomicBoolean;
  217.67 +import java.util.concurrent.atomic.AtomicInteger;
  217.68 +import java.util.concurrent.atomic.AtomicReference;
  217.69 +import java.util.logging.Level;
  217.70 +import java.util.logging.Logger;
  217.71 +import org.netbeans.api.annotations.common.NonNull;
  217.72 +import org.netbeans.api.annotations.common.NullAllowed;
  217.73 +import org.netbeans.api.fileinfo.NonRecursiveFolder;
  217.74 +import org.netbeans.api.java.classpath.ClassPath;
  217.75 +import org.netbeans.api.java.classpath.GlobalPathRegistry;
  217.76 +import org.netbeans.api.java.source.ClasspathInfo;
  217.77 +import org.netbeans.api.java.source.ClasspathInfo.PathKind;
  217.78 +import org.netbeans.api.java.source.CompilationController;
  217.79 +import org.netbeans.api.java.source.CompilationInfo;
  217.80 +import org.netbeans.api.java.source.JavaSource;
  217.81 +import org.netbeans.api.java.source.JavaSource.Phase;
  217.82 +import org.netbeans.api.java.source.Task;
  217.83 +import org.netbeans.api.queries.FileEncodingQuery;
  217.84 +import org.netbeans.modules.java.hints.spiimpl.MessageImpl;
  217.85 +import org.netbeans.modules.java.hints.spiimpl.Utilities;
  217.86 +import org.netbeans.modules.java.hints.spiimpl.hints.HintsInvoker;
  217.87 +import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch;
  217.88 +import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch.BulkPattern;
  217.89 +import org.netbeans.modules.java.hints.providers.spi.HintDescription.AdditionalQueryConstraints;
  217.90 +import org.netbeans.modules.java.hints.providers.spi.Trigger.PatternDescription;
  217.91 +import org.netbeans.spi.editor.hints.ErrorDescription;
  217.92 +import org.netbeans.api.java.source.matching.Matcher;
  217.93 +import org.netbeans.api.java.source.matching.Pattern;
  217.94 +import org.netbeans.modules.java.hints.providers.spi.Trigger.DecisionTrigger;
  217.95 +import org.netbeans.modules.java.hints.spiimpl.SPIAccessor;
  217.96 +import org.netbeans.modules.java.hints.spiimpl.hints.GlobalProcessingContext;
  217.97 +import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings;
  217.98 +import org.netbeans.spi.java.hints.Decision;
  217.99 +import org.netbeans.spi.java.hints.HintContext;
 217.100 +import org.openide.filesystems.FileObject;
 217.101 +import org.openide.filesystems.FileUtil;
 217.102 +import org.openide.util.Exceptions;
 217.103 +
 217.104 +/**
 217.105 + *
 217.106 + * @author lahvac
 217.107 + */
 217.108 +public class BatchSearch {
 217.109 +
 217.110 +    private static final Logger LOG = Logger.getLogger(BatchSearch.class.getName());
 217.111 +
 217.112 +    public static BatchResult findOccurrences(Iterable<? extends HintDescription> patterns, Scope scope) {
 217.113 +        return findOccurrences(patterns, scope, new ProgressHandleWrapper(null), HintsSettings.getGlobalSettings());
 217.114 +    }
 217.115 +
 217.116 +    public static BatchResult findOccurrences(final Iterable<? extends HintDescription> patterns, final Scope scope, final ProgressHandleWrapper progress, @NullAllowed HintsSettings settingsProvider) {
 217.117 +        return findOccurrencesLocal(patterns, scope.getIndexMapper(patterns), scope.getTodo(), progress, settingsProvider);
 217.118 +    }
 217.119 +
 217.120 +    private static BatchResult findOccurrencesLocal(final Iterable<? extends HintDescription> patterns, final MapIndices indexMapper, final Collection<? extends Folder> todo, final ProgressHandleWrapper progress, final @NullAllowed HintsSettings settingsProvider) {
 217.121 +        final BatchResult[] result = new BatchResult[1];
 217.122 +
 217.123 +        try {
 217.124 +            JavaSource.create(Utilities.createUniversalCPInfo()).runUserActionTask(new Task<CompilationController>() {
 217.125 +                public void run(CompilationController parameter) throws Exception {
 217.126 +                    result[0] = findOccurrencesLocalImpl(parameter, patterns, indexMapper, todo, progress, settingsProvider);
 217.127 +                }
 217.128 +            }, true);
 217.129 +        } catch (IOException ex) {
 217.130 +            throw new IllegalStateException(ex);
 217.131 +        }
 217.132 +
 217.133 +        return result[0];
 217.134 +    }
 217.135 +    
 217.136 +    private static BatchResult findOccurrencesLocalImpl(final CompilationInfo info, final Iterable<? extends HintDescription> patterns, MapIndices indexMapper, Collection<? extends Folder> todo, ProgressHandleWrapper progress, HintsSettings settingsProvider) {
 217.137 +        boolean hasKindPatterns = false;
 217.138 +
 217.139 +        for (HintDescription pattern : patterns) {
 217.140 +            if (!(pattern.getTrigger() instanceof PatternDescription)) {
 217.141 +                hasKindPatterns = true;
 217.142 +                break;
 217.143 +            }
 217.144 +        }
 217.145 +
 217.146 +        final Callable<BulkPattern> bulkPattern = hasKindPatterns ? null : new Callable<BulkPattern>() {
 217.147 +            private final AtomicReference<BulkPattern> pattern = new AtomicReference<BulkPattern>();
 217.148 +            public BulkPattern call() {
 217.149 +                if (pattern.get() == null) {
 217.150 +                    pattern.set(preparePattern(patterns, info));
 217.151 +                }
 217.152 +
 217.153 +                return pattern.get();
 217.154 +            }
 217.155 +        };
 217.156 +        final Map<IndexEnquirer, Collection<? extends Resource>> result = new HashMap<IndexEnquirer, Collection<? extends Resource>>();
 217.157 +        final Collection<MessageImpl> problems = new LinkedList<MessageImpl>();
 217.158 +        ProgressHandleWrapper innerForAll = progress.startNextPartWithEmbedding(ProgressHandleWrapper.prepareParts(2 * todo.size()));
 217.159 +        
 217.160 +        for (final Folder src : todo) {
 217.161 +            LOG.log(Level.FINE, "Processing: {0}", FileUtil.getFileDisplayName(src.getFileObject()));
 217.162 +            
 217.163 +            IndexEnquirer indexEnquirer;// = indexMapper.findIndex(src.getFileObject(), innerForAll, src.isRecursive());
 217.164 +
 217.165 +//            if (indexEnquirer == null) {
 217.166 +                indexEnquirer = new FileSystemBasedIndexEnquirer(src.getFileObject(), src.isRecursive());
 217.167 +//            }
 217.168 +
 217.169 +            Collection<? extends Resource> occurrences = indexEnquirer.findResources(patterns, innerForAll, bulkPattern, problems, settingsProvider);
 217.170 +
 217.171 +            if (!occurrences.isEmpty()) {
 217.172 +                result.put(indexEnquirer, occurrences);
 217.173 +            }
 217.174 +
 217.175 +            innerForAll.tick();
 217.176 +        }
 217.177 +
 217.178 +        return new BatchResult(result, patterns, problems);
 217.179 +    }
 217.180 +
 217.181 +    private static BulkPattern preparePattern(final Iterable<? extends HintDescription> patterns, CompilationInfo info) {
 217.182 +        Collection<String> code = new LinkedList<String>();
 217.183 +        Collection<Tree> trees = new LinkedList<Tree>();
 217.184 +        Collection<AdditionalQueryConstraints> additionalConstraints = new LinkedList<AdditionalQueryConstraints>();
 217.185 +
 217.186 +        for (HintDescription pattern : patterns) {
 217.187 +            String textPattern = ((PatternDescription) pattern.getTrigger()).getPattern();
 217.188 +
 217.189 +            code.add(textPattern);
 217.190 +            trees.add(Utilities.parseAndAttribute(info, textPattern, null));
 217.191 +            additionalConstraints.add(pattern.getAdditionalConstraints());
 217.192 +        }
 217.193 +
 217.194 +        return BulkSearch.getDefault().create(code, trees, additionalConstraints, new AtomicBoolean());
 217.195 +    }
 217.196 +
 217.197 +    public static void getVerifiedSpans(BatchResult candidates, @NonNull ProgressHandleWrapper progress, final VerifiedSpansCallBack callback, final Collection<? super MessageImpl> problems, AtomicBoolean cancel) {
 217.198 +        getVerifiedSpans(candidates, progress, callback, false, problems, cancel);
 217.199 +    }
 217.200 +
 217.201 +    public static void getVerifiedSpans(BatchResult candidates, @NonNull ProgressHandleWrapper progress, final VerifiedSpansCallBack callback, boolean doNotRegisterClassPath, final Collection<? super MessageImpl> problems, AtomicBoolean cancel) {
 217.202 +        int[] parts = new int[candidates.projectId2Resources.size()];
 217.203 +        int   index = 0;
 217.204 +
 217.205 +        for (Entry<? extends IndexEnquirer, ? extends Collection<? extends Resource>> e : candidates.projectId2Resources.entrySet()) {
 217.206 +            parts[index++] = e.getValue().size();
 217.207 +        }
 217.208 +
 217.209 +        ProgressHandleWrapper inner = progress.startNextPartWithEmbedding(parts);
 217.210 +
 217.211 +        for (Entry<? extends IndexEnquirer, ? extends Collection<? extends Resource>> e : candidates.projectId2Resources.entrySet()) {
 217.212 +            if (cancel.get()) 
 217.213 +                return;
 217.214 +            inner.startNextPart(e.getValue().size());
 217.215 +
 217.216 +            e.getKey().validateResource(e.getValue(), inner, callback, doNotRegisterClassPath, problems, cancel);
 217.217 +        }
 217.218 +    }
 217.219 +
 217.220 +    private static void getLocalVerifiedSpans(Collection<? extends Resource> resources, @NonNull final ProgressHandleWrapper progress, final VerifiedSpansCallBack callback, boolean doNotRegisterClassPath, final Collection<? super MessageImpl> problems, final AtomicBoolean cancel) {
 217.221 +        Collection<FileObject> files = new LinkedList<FileObject>();
 217.222 +        final Map<FileObject, Resource> file2Resource = new HashMap<FileObject, Resource>();
 217.223 +
 217.224 +        for (Resource r : resources) {
 217.225 +            FileObject file = r.getResolvedFile();
 217.226 +
 217.227 +            if (file != null) {
 217.228 +                files.add(file);
 217.229 +                file2Resource.put(file, r);
 217.230 +            } else {
 217.231 +                callback.cannotVerifySpan(r);
 217.232 +                progress.tick();
 217.233 +            }
 217.234 +        }
 217.235 +
 217.236 +        Map<ClasspathInfo, Collection<FileObject>> cp2Files = BatchUtilities.sortFiles(files);
 217.237 +        ClassPath[] toRegister = null;
 217.238 +
 217.239 +        if (!doNotRegisterClassPath) {
 217.240 +            Set<ClassPath> toRegisterSet = new HashSet<ClassPath>();
 217.241 +
 217.242 +            for (ClasspathInfo cpInfo : cp2Files.keySet()) {
 217.243 +                toRegisterSet.add(cpInfo.getClassPath(PathKind.SOURCE));
 217.244 +            }
 217.245 +
 217.246 +            toRegister = !toRegisterSet.isEmpty() ? toRegisterSet.toArray(new ClassPath[0]) : null;
 217.247 +
 217.248 +            if (toRegister != null) {
 217.249 +                GlobalPathRegistry.getDefault().register(ClassPath.SOURCE, toRegister);
 217.250 +                try {
 217.251 +                    Utilities.waitScanFinished();
 217.252 +                } catch (InterruptedException ex) {
 217.253 +                    Exceptions.printStackTrace(ex);
 217.254 +                }
 217.255 +            }
 217.256 +        }
 217.257 +
 217.258 +        callback.groupStarted();
 217.259 +
 217.260 +        try {
 217.261 +            final GlobalProcessingContext gpc = new GlobalProcessingContext();
 217.262 +            for (Entry<ClasspathInfo, Collection<FileObject>> e : cp2Files.entrySet()) {
 217.263 +                try {
 217.264 +                    List<FileObject> toProcess = new ArrayList<FileObject>(e.getValue());
 217.265 +                    final AtomicInteger currentPointer = new AtomicInteger();
 217.266 +
 217.267 +//                    for (FileObject f : toProcess) {
 217.268 +                    while (currentPointer.get() < toProcess.size()) {
 217.269 +                        if (cancel.get())
 217.270 +                            return;
 217.271 +                        final AtomicBoolean stop = new AtomicBoolean();
 217.272 +//                        JavaSource js = JavaSource.create(e.getKey(), f);
 217.273 +                        JavaSource js = JavaSource.create(e.getKey(), toProcess.subList(currentPointer.get(), toProcess.size()));
 217.274 +
 217.275 +                        js.runUserActionTask(new Task<CompilationController>() {
 217.276 +                            public void run(CompilationController parameter) throws Exception {
 217.277 +                                if (stop.get()) return;
 217.278 +                                if (cancel.get()) return;
 217.279 +
 217.280 +                                boolean cont = true;
 217.281 +
 217.282 +                                try {
 217.283 +                                    if (parameter.toPhase(Phase.RESOLVED).compareTo(Phase.RESOLVED) < 0)
 217.284 +                                        return ;
 217.285 +
 217.286 +                                    progress.setMessage("processing: " + FileUtil.getFileDisplayName(parameter.getFileObject()));
 217.287 +                                    Resource r = file2Resource.get(parameter.getFileObject());
 217.288 +
 217.289 +                                    HintsSettings settings = r.settings;
 217.290 +                                    Iterable<? extends HintDescription> enabledHints;
 217.291 +                                    
 217.292 +                                    if (settings == null) {
 217.293 +                                        settings = HintsSettings.getSettingsFor(parameter.getFileObject());
 217.294 +                                        List<HintDescription> hintsCopy = new ArrayList<>();
 217.295 +                                        for (HintDescription hd : r.hints) {
 217.296 +                                            if (settings.isEnabled(hd.getMetadata())) {
 217.297 +                                                hintsCopy.add(hd);
 217.298 +                                            }
 217.299 +                                        }
 217.300 +                                        enabledHints = hintsCopy;
 217.301 +                                    } else {
 217.302 +                                        enabledHints = r.hints;
 217.303 +                                    }
 217.304 +                                    
 217.305 +                                    List<ErrorDescription> hints = new HintsInvoker(settings, gpc, new AtomicBoolean()).computeHints(parameter, r.hints, problems);
 217.306 +
 217.307 +                                    assert hints != null;
 217.308 +                                    
 217.309 +                                    cont = callback.spansVerified(parameter, r, hints);
 217.310 +                                } catch (ThreadDeath td) {
 217.311 +                                    throw td;
 217.312 +                                } catch (Throwable t) {
 217.313 +                                    LOG.log(Level.INFO, "Exception while performing batch processing in " + FileUtil.getFileDisplayName(parameter.getFileObject()), t);
 217.314 +                                    problems.add(new MessageImpl(MessageKind.WARNING, "An exception occurred while processing file: " + FileUtil.getFileDisplayName(parameter.getFileObject()) + " (" + t.getLocalizedMessage() + ")."));
 217.315 +                                }
 217.316 +                                
 217.317 +                                if (cont) {
 217.318 +                                    progress.tick();
 217.319 +                                    currentPointer.incrementAndGet();
 217.320 +                                } else {
 217.321 +                                    stop.set(true);
 217.322 +                                }
 217.323 +                            }
 217.324 +                        }, true);
 217.325 +                    }
 217.326 +                } catch (IOException ex) {
 217.327 +                    Exceptions.printStackTrace(ex);
 217.328 +                }
 217.329 +            }
 217.330 +            
 217.331 +            final Map<FileObject, List<Decision>> file2Decision = new HashMap<FileObject, List<Decision>>();
 217.332 +            for (List<Decision<?, ?>> decisions : gpc.decisions.values()) {
 217.333 +                for (Decision<?, ?> d : decisions) {
 217.334 +                    if (d.makeDecision()) {
 217.335 +                        List<Decision> fileDecisions = file2Decision.get(d.root.getFileObject());
 217.336 +                        
 217.337 +                        if (fileDecisions == null) {
 217.338 +                            file2Decision.put(d.root.getFileObject(), fileDecisions = new ArrayList<Decision>());
 217.339 +                        }
 217.340 +                        
 217.341 +                        fileDecisions.add(d);
 217.342 +                    }
 217.343 +                }
 217.344 +            }
 217.345 +
 217.346 +            Map<ClasspathInfo, Collection<FileObject>> cp2FilesAfterDecision = BatchUtilities.sortFiles(file2Decision.keySet());
 217.347 +            
 217.348 +            for (Entry<ClasspathInfo, Collection<FileObject>> e : cp2FilesAfterDecision.entrySet()) {
 217.349 +                JavaSource js = JavaSource.create(e.getKey(), e.getValue());
 217.350 +                
 217.351 +                try {
 217.352 +                    js.runUserActionTask(new Task<CompilationController>() {
 217.353 +                        @Override public void run(CompilationController parameter) throws Exception {
 217.354 +                            if (parameter.toPhase(Phase.RESOLVED).compareTo(Phase.RESOLVED) < 0)
 217.355 +                                return ;
 217.356 +                            
 217.357 +                            Resource r = file2Resource.get(parameter.getFileObject());
 217.358 +
 217.359 +                            HintsSettings settings = r.settings;
 217.360 +
 217.361 +                            if (settings == null) {
 217.362 +                                settings = HintsSettings.getSettingsFor(parameter.getFileObject());
 217.363 +                            }
 217.364 +
 217.365 +                            for (Decision<?, ?> d : file2Decision.get(parameter.getFileObject())) {
 217.366 +                            for (HintDescription hd : r.hints) {
 217.367 +                                if (!(hd.getTrigger() instanceof DecisionTrigger)) continue;
 217.368 +                                if (r.settings == null && !settings.isEnabled(hd.getMetadata())) continue;
 217.369 +                                DecisionTrigger dt = (DecisionTrigger) hd.getTrigger();
 217.370 +                                if (dt.getDecisionClass() != d.getClass()) continue;
 217.371 +                                TreePath tp = d.root.resolve(parameter);
 217.372 +                                HintContext ctx = SPIAccessor.getINSTANCE().createHintContext(parameter, settings, hd.getMetadata(), new GlobalProcessingContext(), tp, Collections.<String, TreePath>emptyMap(), Collections.<String, Collection<? extends TreePath>>emptyMap(), Collections.<String, String>emptyMap());
 217.373 +                                ctx.decision = d;
 217.374 +                                Collection<? extends ErrorDescription> errors = hd.getWorker().createErrors(ctx);
 217.375 +                                
 217.376 +                                if (errors != null) {
 217.377 +                                    callback.spansVerified(parameter, file2Resource.get(parameter.getFileObject()), errors);
 217.378 +                                }
 217.379 +                            }
 217.380 +                            }
 217.381 +                        }
 217.382 +                    }, true);
 217.383 +                } catch (IOException ex) {
 217.384 +                    Exceptions.printStackTrace(ex);
 217.385 +                }
 217.386 +            }
 217.387 +        } finally {
 217.388 +            callback.groupFinished();
 217.389 +            
 217.390 +            if (toRegister != null) {
 217.391 +                GlobalPathRegistry.getDefault().unregister(ClassPath.SOURCE, toRegister);
 217.392 +            }
 217.393 +            progress.finish();
 217.394 +        }
 217.395 +    }
 217.396 +
 217.397 +    public interface VerifiedSpansCallBack {
 217.398 +        public void groupStarted();
 217.399 +        public boolean spansVerified(CompilationController wc, Resource r, Collection<? extends ErrorDescription> hints) throws Exception;
 217.400 +        public void groupFinished();
 217.401 +        public void cannotVerifySpan(Resource r);
 217.402 +    }
 217.403 +
 217.404 +    
 217.405 +    public static class Folder {
 217.406 +
 217.407 +        private FileObject file;
 217.408 +        private NonRecursiveFolder folder;
 217.409 +        
 217.410 +        public Folder(FileObject file) {
 217.411 +            this.file = file;
 217.412 +        }
 217.413 +        
 217.414 +        public Folder(NonRecursiveFolder folder) {
 217.415 +            this.folder = folder;
 217.416 +        }
 217.417 +        
 217.418 +        public FileObject getFileObject() {
 217.419 +            if (file!=null) {
 217.420 +                return file;
 217.421 +            }
 217.422 +            return folder.getFolder();
 217.423 +            
 217.424 +        }
 217.425 +        
 217.426 +        private boolean isRecursive() {
 217.427 +            if (file!=null) {
 217.428 +                return file.isFolder();
 217.429 +            }
 217.430 +            return false;
 217.431 +        }
 217.432 +
 217.433 +        public static Folder[] convert(FileObject... files) {
 217.434 +            Folder[] result = new Folder[files.length];
 217.435 +            for (int i=0;i<files.length;i++) {
 217.436 +                result[i] = new Folder(files[i]);
 217.437 +            }
 217.438 +            return result;
 217.439 +        }
 217.440 +
 217.441 +        public static Folder[] convert(Collection list) {
 217.442 +            Folder[] result = new Folder[list.size()];
 217.443 +            int i=0;
 217.444 +            for (Object item:list) {
 217.445 +                if (item instanceof FileObject)
 217.446 +                    result[i] = new Folder((FileObject) item);
 217.447 +                else 
 217.448 +                    result[i] = new Folder((NonRecursiveFolder) item);
 217.449 +                i++;
 217.450 +            }
 217.451 +            return result;
 217.452 +        }
 217.453 +
 217.454 +        @Override
 217.455 +        public String toString() {
 217.456 +            return !isRecursive()?"Non":"" + "Recursive file " + getFileObject().getPath();
 217.457 +        }
 217.458 +        
 217.459 +        
 217.460 +    }
 217.461 +    
 217.462 +    public abstract static class Scope {
 217.463 +
 217.464 +        public abstract String getDisplayName();
 217.465 +        public abstract Collection<? extends Folder> getTodo();
 217.466 +        public abstract MapIndices getIndexMapper(Iterable<? extends HintDescription> hints);
 217.467 +        
 217.468 +    }
 217.469 +    
 217.470 +    public static final class BatchResult {
 217.471 +        
 217.472 +        private final Map<? extends IndexEnquirer, ? extends Collection<? extends Resource>> projectId2Resources;
 217.473 +        private final Iterable<? extends HintDescription> patterns;
 217.474 +        public final Collection<? extends MessageImpl> problems;
 217.475 +        
 217.476 +        public BatchResult(Map<? extends IndexEnquirer, ? extends Collection<? extends Resource>> projectId2Resources, Iterable<? extends HintDescription> patterns, Collection<? extends MessageImpl> problems) {
 217.477 +            this.projectId2Resources = projectId2Resources;
 217.478 +            this.patterns = patterns;
 217.479 +            this.problems = problems;
 217.480 +        }
 217.481 +
 217.482 +        public Collection<? extends Collection<? extends Resource>> getResources() {
 217.483 +            return projectId2Resources.values();
 217.484 +        }
 217.485 +
 217.486 +        public Map<FileObject, Collection<? extends Resource>> getResourcesWithRoots() {
 217.487 +            Map<FileObject, Collection<? extends Resource>> result = new HashMap<FileObject, Collection<? extends Resource>>();
 217.488 +
 217.489 +            for (Entry<? extends IndexEnquirer, ? extends Collection<? extends Resource>> e : projectId2Resources.entrySet()) {
 217.490 +                result.put(e.getKey().src, e.getValue());
 217.491 +            }
 217.492 +
 217.493 +            return result;
 217.494 +        }
 217.495 +
 217.496 +        public Iterable<? extends HintDescription> getPatterns() {
 217.497 +            return patterns;
 217.498 +        }
 217.499 +    }
 217.500 +
 217.501 +    public static final class Resource {
 217.502 +        private final IndexEnquirer indexEnquirer;
 217.503 +        private final String relativePath;
 217.504 +        final Iterable<? extends HintDescription> hints;
 217.505 +        private final BulkPattern pattern;
 217.506 +        final HintsSettings settings;
 217.507 +
 217.508 +        public Resource(IndexEnquirer indexEnquirer, String relativePath, Iterable<? extends HintDescription> hints, BulkPattern pattern, HintsSettings settings) {
 217.509 +            this.indexEnquirer = indexEnquirer;
 217.510 +            this.relativePath = relativePath;
 217.511 +            this.hints = hints;
 217.512 +            this.pattern = pattern;
 217.513 +            this.settings = settings;
 217.514 +        }
 217.515 +
 217.516 +        public String getRelativePath() {
 217.517 +            return relativePath;
 217.518 +        }
 217.519 +        
 217.520 +        public Iterable<int[]> getCandidateSpans() {
 217.521 +            FileObject file = getResolvedFile();
 217.522 +            JavaSource js;
 217.523 +
 217.524 +            if (file != null) {
 217.525 +                js = JavaSource.forFileObject(file);
 217.526 +            } else {
 217.527 +                CharSequence text = getSourceCode();
 217.528 +
 217.529 +                if (text == null) {
 217.530 +                    return null;
 217.531 +                }
 217.532 +
 217.533 +                Writer out = null;
 217.534 +
 217.535 +                try {
 217.536 +                    file = FileUtil.createData(FileUtil.createMemoryFileSystem().getRoot(), relativePath);
 217.537 +                    out = new OutputStreamWriter(file.getOutputStream());
 217.538 +
 217.539 +                    out.write(text.toString());
 217.540 +                } catch (IOException ex) {
 217.541 +                    Exceptions.printStackTrace(ex);
 217.542 +                    return null;
 217.543 +                } finally {
 217.544 +                    if (out != null) {
 217.545 +                        try {
 217.546 +                            out.close();
 217.547 +                        } catch (IOException ex) {
 217.548 +                            Exceptions.printStackTrace(ex);
 217.549 +                        }
 217.550 +                    }
 217.551 +                }
 217.552 +
 217.553 +                js = JavaSource.create(Utilities.createUniversalCPInfo(), file);
 217.554 +            }
 217.555 +
 217.556 +            final List<int[]> span = new LinkedList<int[]>();
 217.557 +
 217.558 +            try {
 217.559 +                js.runUserActionTask(new Task<CompilationController>() {
 217.560 +                    public void run(CompilationController cc) throws Exception {
 217.561 +                        cc.toPhase(Phase.PARSED);
 217.562 +
 217.563 +                        span.addAll(doComputeSpans(cc));
 217.564 +                    }
 217.565 +                }, true);
 217.566 +            } catch (IOException ex) {
 217.567 +                Exceptions.printStackTrace(ex);
 217.568 +            }
 217.569 +
 217.570 +            return span;
 217.571 +        }
 217.572 +
 217.573 +        private Collection<int[]> doComputeSpans(CompilationInfo ci) {
 217.574 +            Collection<int[]> result = new LinkedList<int[]>();
 217.575 +            Map<String, Collection<TreePath>> found = BulkSearch.getDefault().match(ci, new AtomicBoolean(), new TreePath(ci.getCompilationUnit()), pattern);
 217.576 +            
 217.577 +            for (Entry<String, Collection<TreePath>> e : found.entrySet()) {
 217.578 +                Tree treePattern = Utilities.parseAndAttribute(ci, e.getKey(), null);
 217.579 +                
 217.580 +                for (TreePath tp : e.getValue()) {
 217.581 +                    //XXX: this pass will not be performed on the web!!!
 217.582 +                    if (   BulkSearch.getDefault().requiresLightweightVerification()
 217.583 +                        && !Matcher.create(ci).setCancel(new AtomicBoolean()).setSearchRoot(tp).setTreeTopSearch().setUntypedMatching().match(Pattern.createSimplePattern(new TreePath(new TreePath(ci.getCompilationUnit()), treePattern))).iterator().hasNext()) {
 217.584 +                        continue;
 217.585 +                    }
 217.586 +                    int[] span = new int[] {
 217.587 +                        (int) ci.getTrees().getSourcePositions().getStartPosition(ci.getCompilationUnit(), tp.getLeaf()),
 217.588 +                        (int) ci.getTrees().getSourcePositions().getEndPosition(ci.getCompilationUnit(), tp.getLeaf())
 217.589 +                    };
 217.590 +
 217.591 +                    result.add(span);
 217.592 +                }
 217.593 +            }
 217.594 +
 217.595 +            return result;
 217.596 +        }
 217.597 +        
 217.598 +        public FileObject getResolvedFile() {
 217.599 +            return indexEnquirer.src.getFileObject(relativePath);
 217.600 +        }
 217.601 +
 217.602 +        public String getDisplayName() {
 217.603 +            FileObject file = getResolvedFile();
 217.604 +
 217.605 +            if (file != null) {
 217.606 +                return FileUtil.getFileDisplayName(file);
 217.607 +            } else {
 217.608 +                return relativePath; //TODO:+container
 217.609 +            }
 217.610 +        }
 217.611 +        
 217.612 +        public CharSequence getSourceCode() {
 217.613 +            try {
 217.614 +                FileObject file = getResolvedFile();
 217.615 +                ByteBuffer bb = ByteBuffer.wrap(file.asBytes());
 217.616 +
 217.617 +                return FileEncodingQuery.getEncoding(file).decode(bb);
 217.618 +            } catch (IOException ex) {
 217.619 +                Exceptions.printStackTrace(ex);
 217.620 +                return null;
 217.621 +            }
 217.622 +        }
 217.623 +
 217.624 +        public FileObject getRoot() {
 217.625 +            return indexEnquirer.src;
 217.626 +        }
 217.627 +    }
 217.628 +
 217.629 +    public static interface MapIndices {
 217.630 +        public IndexEnquirer findIndex(FileObject root, ProgressHandleWrapper progress, boolean recursive);
 217.631 +    }
 217.632 +
 217.633 +    public static abstract class IndexEnquirer {
 217.634 +        final FileObject src;
 217.635 +        public IndexEnquirer(FileObject src) {
 217.636 +            this.src = src;
 217.637 +        }
 217.638 +        public abstract Collection<? extends Resource> findResources(Iterable<? extends HintDescription> hints, ProgressHandleWrapper progress, @NullAllowed Callable<BulkPattern> bulkPattern, Collection<? super MessageImpl> problems, HintsSettings settingsProvider);
 217.639 +        public abstract void validateResource(Collection<? extends Resource> resources, ProgressHandleWrapper progress, VerifiedSpansCallBack callback, boolean doNotRegisterClassPath, Collection<? super MessageImpl> problems, AtomicBoolean cancel);
 217.640 +//        public int[] getEstimatedSpan(Resource r);
 217.641 +    }
 217.642 +
 217.643 +    public static abstract class LocalIndexEnquirer extends IndexEnquirer {
 217.644 +        public LocalIndexEnquirer(FileObject src) {
 217.645 +            super(src);
 217.646 +        }
 217.647 +        public void validateResource(Collection<? extends Resource> resources, ProgressHandleWrapper progress, VerifiedSpansCallBack callback, boolean doNotRegisterClassPath, Collection<? super MessageImpl> problems, AtomicBoolean cancel) {
 217.648 +            getLocalVerifiedSpans(resources, progress, callback, doNotRegisterClassPath, problems, cancel);
 217.649 +        }
 217.650 +    }
 217.651 +
 217.652 +    public static final class FileSystemBasedIndexEnquirer extends LocalIndexEnquirer {
 217.653 +        private boolean recursive;
 217.654 +        public FileSystemBasedIndexEnquirer(FileObject src, boolean recursive) {
 217.655 +            super(src);
 217.656 +            this.recursive = recursive;
 217.657 +        }
 217.658 +        public Collection<? extends Resource> findResources(final Iterable<? extends HintDescription> hints, ProgressHandleWrapper progress, final @NullAllowed Callable<BulkPattern> bulkPattern, final Collection<? super MessageImpl> problems, final HintsSettings settingsProvider) {
 217.659 +            Collection<FileObject> files = new LinkedList<FileObject>();
 217.660 +
 217.661 +            final ProgressHandleWrapper innerProgress = progress.startNextPartWithEmbedding(30, 70);
 217.662 +
 217.663 +            BatchUtilities.recursive(src, src, files, innerProgress, 0, null, null, recursive);
 217.664 +
 217.665 +            LOG.log(Level.FINE, "files: {0}", files);
 217.666 +
 217.667 +            innerProgress.startNextPart(files.size());
 217.668 +
 217.669 +            final Collection<Resource> result = new ArrayList<Resource>();
 217.670 +
 217.671 +            if (!files.isEmpty()) {
 217.672 +                try {
 217.673 +                    if (bulkPattern != null) {
 217.674 +                        long start = System.currentTimeMillis();
 217.675 +
 217.676 +                        JavaSource.create(Utilities.createUniversalCPInfo(), files).runUserActionTask(new Task<CompilationController>() {
 217.677 +                            public void run(CompilationController cc) throws Exception {
 217.678 +                                if (cc.toPhase(Phase.PARSED).compareTo(Phase.PARSED) <0) {
 217.679 +                                    return ;
 217.680 +                                }
 217.681 +
 217.682 +                                try {
 217.683 +                                    boolean matches = BulkSearch.getDefault().matches(cc, new AtomicBoolean(), new TreePath(cc.getCompilationUnit()), bulkPattern.call());
 217.684 +
 217.685 +                                    if (matches) {
 217.686 +                                        result.add(new Resource(FileSystemBasedIndexEnquirer.this, FileUtil.getRelativePath(src, cc.getFileObject()), hints, bulkPattern.call(), settingsProvider));
 217.687 +                                    }
 217.688 +                                } catch (ThreadDeath td) {
 217.689 +                                    throw td;
 217.690 +                                } catch (Throwable t) {
 217.691 +                                    LOG.log(Level.INFO, "Exception while performing batch search in " + FileUtil.getFileDisplayName(cc.getFileObject()), t);
 217.692 +                                    problems.add(new MessageImpl(MessageKind.WARNING, "An exception occurred while testing file: " + FileUtil.getFileDisplayName(cc.getFileObject()) + " (" + t.getLocalizedMessage() + ")."));
 217.693 +                                }
 217.694 +
 217.695 +                                innerProgress.tick();
 217.696 +                            }
 217.697 +                        }, true);
 217.698 +
 217.699 +                        long end = System.currentTimeMillis();
 217.700 +
 217.701 +                        LOG.log(Level.FINE, "took: {0}, per file: {1}", new Object[]{end - start, (end - start) / files.size()});
 217.702 +                    } else {
 217.703 +                        for (FileObject file : files) {
 217.704 +                            result.add(new Resource(this, FileUtil.getRelativePath(src, file), hints, null, settingsProvider));
 217.705 +                        }
 217.706 +                    }
 217.707 +                } catch (IOException ex) {
 217.708 +                    Exceptions.printStackTrace(ex);
 217.709 +                }
 217.710 +            }
 217.711 +
 217.712 +            return result;
 217.713 +        }
 217.714 +
 217.715 +    }
 217.716 +
 217.717 +}
   218.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   218.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/batch/BatchUtilities.java	Sun Oct 23 11:50:54 2016 +0200
   218.3 @@ -0,0 +1,586 @@
   218.4 +/*
   218.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   218.6 + *
   218.7 + * Copyright 2009-2011 Oracle and/or its affiliates. All rights reserved.
   218.8 + *
   218.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  218.10 + * Other names may be trademarks of their respective owners.
  218.11 + *
  218.12 + * The contents of this file are subject to the terms of either the GNU
  218.13 + * General Public License Version 2 only ("GPL") or the Common
  218.14 + * Development and Distribution License("CDDL") (collectively, the
  218.15 + * "License"). You may not use this file except in compliance with the
  218.16 + * License. You can obtain a copy of the License at
  218.17 + * http://www.netbeans.org/cddl-gplv2.html
  218.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  218.19 + * specific language governing permissions and limitations under the
  218.20 + * License.  When distributing the software, include this License Header
  218.21 + * Notice in each file and include the License file at
  218.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  218.23 + * particular file as subject to the "Classpath" exception as provided
  218.24 + * by Oracle in the GPL Version 2 section of the License file that
  218.25 + * accompanied this code. If applicable, add the following below the
  218.26 + * License Header, with the fields enclosed by brackets [] replaced by
  218.27 + * your own identifying information:
  218.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  218.29 + *
  218.30 + * If you wish your version of this file to be governed by only the CDDL
  218.31 + * or only the GPL Version 2, indicate your decision by adding
  218.32 + * "[Contributor] elects to include this software in this distribution
  218.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  218.34 + * single choice of license, a recipient has the option to distribute
  218.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  218.36 + * to extend the choice of license to its licensees as provided above.
  218.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  218.38 + * Version 2 license, then the option applies only if the new code is
  218.39 + * made subject to such option by the copyright holder.
  218.40 + *
  218.41 + * Contributor(s):
  218.42 + *
  218.43 + * Portions Copyrighted 2009-2011 Sun Microsystems, Inc.
  218.44 + */
  218.45 +package org.netbeans.modules.java.hints.spiimpl.batch;
  218.46 +
  218.47 +import com.sun.tools.javac.api.JavacTaskImpl;
  218.48 +import com.sun.tools.javac.util.Log;
  218.49 +import java.io.IOException;
  218.50 +import java.lang.reflect.Constructor;
  218.51 +import java.lang.reflect.Method;
  218.52 +import java.nio.ByteBuffer;
  218.53 +import java.nio.charset.Charset;
  218.54 +import java.util.ArrayList;
  218.55 +import java.util.Collection;
  218.56 +import java.util.Collections;
  218.57 +import java.util.HashMap;
  218.58 +import java.util.HashSet;
  218.59 +import java.util.IdentityHashMap;
  218.60 +import java.util.Iterator;
  218.61 +import java.util.LinkedHashMap;
  218.62 +import java.util.LinkedHashSet;
  218.63 +import java.util.LinkedList;
  218.64 +import java.util.List;
  218.65 +import java.util.Map;
  218.66 +import java.util.Map.Entry;
  218.67 +import java.util.Properties;
  218.68 +import java.util.Set;
  218.69 +import java.util.concurrent.atomic.AtomicBoolean;
  218.70 +import java.util.logging.Level;
  218.71 +import java.util.logging.Logger;
  218.72 +import javax.swing.text.BadLocationException;
  218.73 +import javax.swing.text.Document;
  218.74 +import org.netbeans.api.annotations.common.CheckForNull;
  218.75 +import org.netbeans.api.annotations.common.NonNull;
  218.76 +import org.netbeans.api.java.classpath.ClassPath;
  218.77 +import org.netbeans.api.java.classpath.ClassPath.PathConversionMode;
  218.78 +import org.netbeans.api.java.platform.JavaPlatformManager;
  218.79 +import org.netbeans.api.java.source.ClasspathInfo;
  218.80 +import org.netbeans.api.java.source.CompilationController;
  218.81 +import org.netbeans.api.java.source.CompilationInfo;
  218.82 +import org.netbeans.api.java.source.JavaSource;
  218.83 +import org.netbeans.api.java.source.JavaSource.Phase;
  218.84 +import org.netbeans.api.java.source.ModificationResult;
  218.85 +import org.netbeans.api.java.source.ModificationResult.Difference;
  218.86 +import org.netbeans.api.java.source.Task;
  218.87 +import org.netbeans.api.java.source.WorkingCopy;
  218.88 +import org.netbeans.api.project.FileOwnerQuery;
  218.89 +import org.netbeans.api.project.Project;
  218.90 +import org.netbeans.api.project.ProjectUtils;
  218.91 +import org.netbeans.api.project.SourceGroup;
  218.92 +import org.netbeans.api.project.Sources;
  218.93 +import org.netbeans.api.queries.FileEncodingQuery;
  218.94 +import org.netbeans.api.queries.VisibilityQuery;
  218.95 +//import org.netbeans.modules.java.editor.semantic.SemanticHighlighter;
  218.96 +import org.netbeans.modules.java.hints.spiimpl.JavaFixImpl;
  218.97 +import org.netbeans.modules.java.hints.spiimpl.JavaFixImpl.Accessor;
  218.98 +import org.netbeans.modules.java.hints.spiimpl.MessageImpl;
  218.99 +import org.netbeans.modules.java.hints.spiimpl.SyntheticFix;
 218.100 +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.BatchResult;
 218.101 +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.Resource;
 218.102 +import org.netbeans.modules.java.hints.spiimpl.ipi.upgrade.ProjectDependencyUpgrader;
 218.103 +import org.netbeans.modules.java.source.JavaSourceAccessor;
 218.104 +import org.netbeans.modules.java.source.parsing.CompilationInfoImpl;
 218.105 +import org.netbeans.modules.java.source.save.DiffUtilities;
 218.106 +import org.netbeans.modules.java.source.save.ElementOverlay;
 218.107 +import org.netbeans.modules.parsing.api.Source;
 218.108 +import org.netbeans.modules.refactoring.spi.RefactoringElementImplementation;
 218.109 +import org.netbeans.spi.editor.hints.ErrorDescription;
 218.110 +import org.netbeans.spi.editor.hints.Fix;
 218.111 +import org.netbeans.spi.java.hints.HintContext.MessageKind;
 218.112 +import org.netbeans.spi.java.hints.JavaFix;
 218.113 +import org.openide.cookies.EditorCookie;
 218.114 +import org.openide.filesystems.FileObject;
 218.115 +import org.openide.filesystems.FileUtil;
 218.116 +import org.openide.loaders.DataObject;
 218.117 +import org.openide.loaders.DataObjectNotFoundException;
 218.118 +import org.openide.util.Exceptions;
 218.119 +import org.openide.util.Lookup;
 218.120 +
 218.121 +/**
 218.122 + *
 218.123 + * @author Jan Lahoda
 218.124 + */
 218.125 +public class BatchUtilities {
 218.126 +
 218.127 +    private static final Logger LOG = Logger.getLogger(BatchUtilities.class.getName());
 218.128 +    
 218.129 +    public static Collection<ModificationResult> applyFixes(BatchResult candidates, @NonNull final ProgressHandleWrapper progress, AtomicBoolean cancel, final Collection<? super MessageImpl> problems) {
 218.130 +        return applyFixes(candidates, progress, cancel, new ArrayList<RefactoringElementImplementation>(), problems);
 218.131 +    }
 218.132 +    
 218.133 +    public static Collection<ModificationResult> applyFixes(BatchResult candidates, @NonNull final ProgressHandleWrapper progress, AtomicBoolean cancel, final Collection<? super RefactoringElementImplementation> fileChanges, final Collection<? super MessageImpl> problems) {
 218.134 +        return applyFixes(candidates, progress, cancel, fileChanges, null, problems);
 218.135 +    }
 218.136 +    
 218.137 +    public static Collection<ModificationResult> applyFixes(BatchResult candidates, @NonNull final ProgressHandleWrapper progress, AtomicBoolean cancel, final Collection<? super RefactoringElementImplementation> fileChanges, final Map<JavaFix, ModificationResult> changesPerFix, final Collection<? super MessageImpl> problems) {
 218.138 +        return applyFixes(candidates, progress, cancel, fileChanges, changesPerFix, false, problems);
 218.139 +    }
 218.140 +    
 218.141 +    public static Collection<ModificationResult> applyFixes(BatchResult candidates, @NonNull final ProgressHandleWrapper progress, AtomicBoolean cancel, final Collection<? super RefactoringElementImplementation> fileChanges, final Map<JavaFix, ModificationResult> changesPerFix, boolean doNotRegisterClassPath, final Collection<? super MessageImpl> problems) {
 218.142 +        final Map<Project, Set<String>> processedDependencyChanges = new IdentityHashMap<Project, Set<String>>();
 218.143 +        final Map<FileObject, List<ModificationResult.Difference>> result = new LinkedHashMap<FileObject, List<ModificationResult.Difference>>();
 218.144 +        final Map<FileObject, byte[]> resourceContentChanges = new HashMap<FileObject, byte[]>();
 218.145 +
 218.146 +        BatchSearch.VerifiedSpansCallBack callback = new BatchSearch.VerifiedSpansCallBack() {
 218.147 +            private ElementOverlay overlay;
 218.148 +            public void groupStarted() {
 218.149 +                overlay = ElementOverlay.getOrCreateOverlay();
 218.150 +            }
 218.151 +            public boolean spansVerified(CompilationController wc, Resource r, Collection<? extends ErrorDescription> hints) throws Exception {
 218.152 +                if (hints.isEmpty()) return true;
 218.153 +                
 218.154 +                Constructor<WorkingCopy> wcConstr = WorkingCopy.class.getDeclaredConstructor(CompilationInfoImpl.class, ElementOverlay.class);
 218.155 +                wcConstr.setAccessible(true);
 218.156 +
 218.157 +//                final WorkingCopy copy = new WorkingCopy(JavaSourceAccessor.getINSTANCE().getCompilationInfoImpl(parameter), overlay);
 218.158 +                WorkingCopy copy = wcConstr.newInstance(JavaSourceAccessor.getINSTANCE().getCompilationInfoImpl(wc), overlay);
 218.159 +                Method setJavaSource = CompilationInfo.class.getDeclaredMethod("setJavaSource", JavaSource.class);
 218.160 +                setJavaSource.setAccessible(true);
 218.161 +
 218.162 +//                copy.setJavaSource(JavaSource.this);
 218.163 +                setJavaSource.invoke(copy, wc.getJavaSource());
 218.164 +
 218.165 +                copy.toPhase(Phase.RESOLVED);
 218.166 +                progress.tick();
 218.167 +                
 218.168 +                if (applyFixes(copy, processedDependencyChanges, hints, resourceContentChanges, fileChanges, changesPerFix, problems)) {
 218.169 +                    return false;
 218.170 +                }
 218.171 +
 218.172 +                final JavacTaskImpl jt = JavaSourceAccessor.getINSTANCE().getJavacTask(copy);
 218.173 +                Log.instance(jt.getContext()).nerrors = 0;
 218.174 +                Method getChanges = WorkingCopy.class.getDeclaredMethod("getChanges", Map.class);
 218.175 +                getChanges.setAccessible(true);
 218.176 +
 218.177 +                result.put(copy.getFileObject(), (List<ModificationResult.Difference>) getChanges.invoke(copy, new HashMap<Object, int[]>()));
 218.178 +
 218.179 +                if (LOG.isLoggable(Level.FINE)) {
 218.180 +                    LOG.log(Level.FINE, "fixes applied to: {0}", FileUtil.getFileDisplayName(wc.getFileObject()));
 218.181 +                }
 218.182 +
 218.183 +                return true;
 218.184 +            }
 218.185 +
 218.186 +            public void groupFinished() {
 218.187 +                overlay = null;
 218.188 +            }
 218.189 +
 218.190 +            public void cannotVerifySpan(Resource r) {
 218.191 +                problems.add(new MessageImpl(MessageKind.WARNING, "Cannot parse: " + r.getRelativePath()));
 218.192 +            }
 218.193 +        };
 218.194 +
 218.195 +        BatchSearch.getVerifiedSpans(candidates, progress, callback, doNotRegisterClassPath, problems, cancel);
 218.196 +        
 218.197 +        addResourceContentChanges(resourceContentChanges, result);
 218.198 +
 218.199 +        return Collections.singletonList(JavaSourceAccessor.getINSTANCE().createModificationResult(result, Collections.<Object, int[]>emptyMap()));
 218.200 +    }
 218.201 +
 218.202 +    public static void addResourceContentChanges(final Map<FileObject, byte[]> resourceContentChanges, final Map<FileObject, List<Difference>> result) {
 218.203 +        for (Entry<FileObject, byte[]> e : resourceContentChanges.entrySet()) {
 218.204 +            try {
 218.205 +                Charset encoding = FileEncodingQuery.getEncoding(e.getKey());
 218.206 +                final Document originalDocument = getDocument(e.getKey());
 218.207 +                final String[] origContent = new String[1];
 218.208 +                final Source[] s = new Source[1];
 218.209 +                if (originalDocument != null) {
 218.210 +                    originalDocument.render(new Runnable() {
 218.211 +                        @Override public void run() {
 218.212 +                            try {
 218.213 +                                origContent[0] = originalDocument.getText(0, originalDocument.getLength());
 218.214 +                                s[0] = Source.create(originalDocument);
 218.215 +                            } catch (BadLocationException ex) {
 218.216 +                                Exceptions.printStackTrace(ex);
 218.217 +                            }
 218.218 +                        }
 218.219 +                    });
 218.220 +                }
 218.221 +                
 218.222 +                if (origContent[0] == null) {
 218.223 +                    byte[] origBytes = e.getKey().asBytes();
 218.224 +                    origContent[0] = encoding.newDecoder().decode(ByteBuffer.wrap(origBytes)).toString();
 218.225 +                }
 218.226 +                String newContent  = encoding.newDecoder().decode(ByteBuffer.wrap(e.getValue())).toString();
 218.227 +
 218.228 +                result.put(e.getKey(), DiffUtilities.diff2ModificationResultDifference(e.getKey(), null, Collections.<Integer, String>emptyMap(), origContent[0], newContent, s[0]));
 218.229 +            } catch (BadLocationException ex) {
 218.230 +                Exceptions.printStackTrace(ex);
 218.231 +            } catch (IOException ex) {
 218.232 +                Exceptions.printStackTrace(ex);
 218.233 +            }
 218.234 +        }
 218.235 +    }
 218.236 +    
 218.237 +    public static @CheckForNull Document getDocument(@NonNull FileObject file) {
 218.238 +        try {
 218.239 +            DataObject od = DataObject.find(file);
 218.240 +            EditorCookie ec = od.getLookup().lookup(EditorCookie.class);
 218.241 +
 218.242 +            if (ec == null) return null;
 218.243 +
 218.244 +            return ec.getDocument();
 218.245 +        } catch (DataObjectNotFoundException ex) {
 218.246 +            LOG.log(Level.FINE, null, ex);
 218.247 +            return null;
 218.248 +        }
 218.249 +    }
 218.250 +
 218.251 +    private static String positionToString(ErrorDescription ed) {
 218.252 +        try {
 218.253 +            return ed.getFile().getNameExt() + ":" + ed.getRange().getBegin().getLine();
 218.254 +        } catch (IOException ex) {
 218.255 +            LOG.log(Level.FINE, null, ex);
 218.256 +            return ed.getFile().getNameExt();
 218.257 +        }
 218.258 +    }
 218.259 +
 218.260 +//    public static void removeUnusedImports(Collection<? extends FileObject> files) throws IOException {
 218.261 +//        Map<ClasspathInfo, Collection<FileObject>> sortedFastFiles = sortFiles(files);
 218.262 +//
 218.263 +//        for (Entry<ClasspathInfo, Collection<FileObject>> e : sortedFastFiles.entrySet()) {
 218.264 +//            JavaSource.create(e.getKey(), e.getValue()).runModificationTask(new RemoveUnusedImports()).commit();
 218.265 +//        }
 218.266 +//    }
 218.267 +//
 218.268 +//    private static final class RemoveUnusedImports implements Task<WorkingCopy> {
 218.269 +//        public void run(WorkingCopy wc) throws IOException {
 218.270 +//            Document doc = wc.getSnapshot().getSource().getDocument(true);
 218.271 +//            
 218.272 +//            if (wc.toPhase(Phase.RESOLVED).compareTo(Phase.RESOLVED) < 0) {
 218.273 +//                return;
 218.274 +//            }
 218.275 +//
 218.276 +//            //compute imports to remove:
 218.277 +//            List<TreePathHandle> unusedImports = SemanticHighlighter.computeUnusedImports(wc);
 218.278 +//            CompilationUnitTree cut = wc.getCompilationUnit();
 218.279 +//            // make the changes to the source
 218.280 +//            for (TreePathHandle handle : unusedImports) {
 218.281 +//                TreePath path = handle.resolve(wc);
 218.282 +//                assert path != null;
 218.283 +//                cut = wc.getTreeMaker().removeCompUnitImport(cut,
 218.284 +//                        (ImportTree) path.getLeaf());
 218.285 +//            }
 218.286 +//
 218.287 +//            if (!unusedImports.isEmpty()) {
 218.288 +//                wc.rewrite(wc.getCompilationUnit(), cut);
 218.289 +//            }
 218.290 +//        }
 218.291 +//    }
 218.292 +
 218.293 +    public static boolean applyFixes(WorkingCopy copy, Map<Project, Set<String>> processedDependencyChanges, Collection<? extends ErrorDescription> hints, Map<FileObject, byte[]> resourceContentChanges, Collection<? super RefactoringElementImplementation> fileChanges, Collection<? super MessageImpl> problems) throws IllegalStateException, Exception {
 218.294 +        return applyFixes(copy, processedDependencyChanges, hints, resourceContentChanges, fileChanges, null, problems);
 218.295 +    }
 218.296 +    
 218.297 +    public static boolean applyFixes(WorkingCopy copy, Map<Project, Set<String>> processedDependencyChanges, Collection<? extends ErrorDescription> hints, Map<FileObject, byte[]> resourceContentChanges, Collection<? super RefactoringElementImplementation> fileChanges, Map<JavaFix, ModificationResult> changesPerFix, Collection<? super MessageImpl> problems) throws IllegalStateException, Exception {
 218.298 +        Set<JavaFix> fixes = new LinkedHashSet<JavaFix>();
 218.299 +        for (ErrorDescription ed : hints) {
 218.300 +            if (!ed.getFixes().isComputed()) {
 218.301 +                throw new IllegalStateException();//TODO: should be problem
 218.302 +            }
 218.303 +
 218.304 +            Fix toApply = null;
 218.305 +
 218.306 +            for (Fix f : ed.getFixes().getFixes()) {
 218.307 +                if (f instanceof SyntheticFix) continue;
 218.308 +                if (toApply == null) toApply = f;
 218.309 +                else problems.add(new MessageImpl(MessageKind.WARNING, "More than one fix for: " + ed.getDescription() + " at " + positionToString(ed) + ", only the first one will be used."));
 218.310 +            }
 218.311 +
 218.312 +            if (toApply == null) {
 218.313 +                //TODO: currently giving a warning so that the hints can be augmented with "Options.QUERY", but that should be removed
 218.314 +                //if a non-query hint cannot produce any fix, it is likely Ok - if not, the hint should produce a warning itself
 218.315 +                boolean doWarning = false;
 218.316 +                assert doWarning = true;
 218.317 +                if (doWarning) {
 218.318 +                    problems.add(new MessageImpl(MessageKind.WARNING, "No fix for: " + ed.getDescription() + " at " + positionToString(ed) + "."));
 218.319 +                }
 218.320 +                continue;
 218.321 +            }
 218.322 +
 218.323 +            if (!(toApply instanceof JavaFixImpl)) {
 218.324 +                throw new IllegalStateException(toApply.getClass().getName());//XXX: hints need to provide JavaFixes
 218.325 +            }
 218.326 +
 218.327 +
 218.328 +            fixes.add(((JavaFixImpl) toApply).jf);
 218.329 +        }
 218.330 +        if (fixDependencies(copy.getFileObject(), fixes, processedDependencyChanges)) {
 218.331 +            return true;
 218.332 +        }
 218.333 +        for (JavaFix f : fixes) {
 218.334 +//                    if (cancel.get()) return ;
 218.335 +
 218.336 +            JavaFixImpl.Accessor.INSTANCE.process(f, copy, false, resourceContentChanges, fileChanges);
 218.337 +            
 218.338 +            if (changesPerFix != null) {
 218.339 +                ElementOverlay overlay = ElementOverlay.getOrCreateOverlay(); //XXX: will use the incorrect overlay?
 218.340 +                Constructor<WorkingCopy> wcConstr = WorkingCopy.class.getDeclaredConstructor(CompilationInfoImpl.class, ElementOverlay.class);
 218.341 +                wcConstr.setAccessible(true);
 218.342 +
 218.343 +//                final WorkingCopy copy = new WorkingCopy(JavaSourceAccessor.getINSTANCE().getCompilationInfoImpl(parameter), overlay);
 218.344 +                WorkingCopy perFixCopy = wcConstr.newInstance(JavaSourceAccessor.getINSTANCE().getCompilationInfoImpl(copy), overlay);
 218.345 +                Method setJavaSource = CompilationInfo.class.getDeclaredMethod("setJavaSource", JavaSource.class);
 218.346 +                setJavaSource.setAccessible(true);
 218.347 +
 218.348 +//                copy.setJavaSource(JavaSource.this);
 218.349 +                setJavaSource.invoke(perFixCopy, copy.getJavaSource());
 218.350 +
 218.351 +                perFixCopy.toPhase(Phase.RESOLVED);
 218.352 +                
 218.353 +                final Map<FileObject, byte[]> perFixResourceContentChanges = new HashMap<FileObject, byte[]>();
 218.354 +        
 218.355 +                JavaFixImpl.Accessor.INSTANCE.process(f, perFixCopy, false, perFixResourceContentChanges, new ArrayList<RefactoringElementImplementation>());
 218.356 +                
 218.357 +                final JavacTaskImpl jt = JavaSourceAccessor.getINSTANCE().getJavacTask(perFixCopy);
 218.358 +                Log.instance(jt.getContext()).nerrors = 0;
 218.359 +                Method getChanges = WorkingCopy.class.getDeclaredMethod("getChanges", Map.class);
 218.360 +                getChanges.setAccessible(true);
 218.361 +                
 218.362 +                Map<FileObject, List<Difference>> changes = new HashMap<FileObject, List<Difference>>();
 218.363 +                
 218.364 +                changes.put(perFixCopy.getFileObject(), (List<ModificationResult.Difference>) getChanges.invoke(perFixCopy, new HashMap<Object, int[]>()));
 218.365 +                
 218.366 +                addResourceContentChanges(resourceContentChanges, changes);
 218.367 +                
 218.368 +                for (Iterator<Entry<FileObject, List<Difference>>> it = changes.entrySet().iterator(); it.hasNext();) {
 218.369 +                    if (it.next().getValue().isEmpty()) it.remove();
 218.370 +                }
 218.371 +
 218.372 +                if (!changes.isEmpty()) {
 218.373 +                    ModificationResult perFixResult = JavaSourceAccessor.getINSTANCE().createModificationResult(changes, Collections.<Object, int[]>emptyMap());
 218.374 +
 218.375 +                    changesPerFix.put(f, perFixResult);
 218.376 +                }
 218.377 +            }
 218.378 +        }
 218.379 +        return false;
 218.380 +    }
 218.381 +    
 218.382 +    public static Collection<ModificationResult> applyFixes(final Map<FileObject, Collection<JavaFix>> toRun) {
 218.383 +        final Map<FileObject, List<ModificationResult.Difference>> result = new LinkedHashMap<FileObject, List<ModificationResult.Difference>>();
 218.384 +        final Map<FileObject, byte[]> resourceContentChanges = new HashMap<FileObject, byte[]>();
 218.385 +        Map<ClasspathInfo, Collection<FileObject>> cp2Files = BatchUtilities.sortFiles(toRun.keySet());
 218.386 +
 218.387 +        for (Entry<ClasspathInfo, Collection<FileObject>> e : cp2Files.entrySet()) {
 218.388 +            try {
 218.389 +                ModificationResult mr = JavaSource.create(e.getKey(), e.getValue()).runModificationTask(new Task<WorkingCopy>() {
 218.390 +                    @Override
 218.391 +                    public void run(WorkingCopy parameter) throws Exception {
 218.392 +                        if (parameter.toPhase(Phase.RESOLVED).compareTo(Phase.RESOLVED) < 0) return ;
 218.393 +
 218.394 +                        for (JavaFix jf : toRun.get(parameter.getFileObject())) {
 218.395 +                            JavaFixImpl.Accessor.INSTANCE.process(jf, parameter, false, resourceContentChanges, new ArrayList<RefactoringElementImplementation>());
 218.396 +                        }
 218.397 +                    }
 218.398 +                });
 218.399 +                
 218.400 +                result.putAll(JavaSourceAccessor.getINSTANCE().getDiffsFromModificationResult(mr));
 218.401 +            } catch (IOException ex) {
 218.402 +                Exceptions.printStackTrace(ex);
 218.403 +            }
 218.404 +        }
 218.405 +        
 218.406 +        addResourceContentChanges(resourceContentChanges, result);
 218.407 +        
 218.408 +        return Collections.singletonList(JavaSourceAccessor.getINSTANCE().createModificationResult(result, Collections.<Object, int[]>emptyMap()));
 218.409 +    }
 218.410 +
 218.411 +    public static Collection<FileObject> getSourceGroups(Iterable<? extends Project> prjs) {
 218.412 +        List<FileObject> result = new LinkedList<FileObject>();
 218.413 +        
 218.414 +        for (Project p : prjs) {
 218.415 +            Sources s = ProjectUtils.getSources(p);
 218.416 +
 218.417 +            for (SourceGroup sg : s.getSourceGroups("java")) {
 218.418 +                result.add(sg.getRootFolder());
 218.419 +            }
 218.420 +        }
 218.421 +
 218.422 +        return result;
 218.423 +    }
 218.424 +
 218.425 +    public static Map<ClasspathInfo, Collection<FileObject>> sortFiles(Collection<? extends FileObject> from) {
 218.426 +        Map<CPCategorizer, Collection<FileObject>> m = new HashMap<CPCategorizer, Collection<FileObject>>();
 218.427 +
 218.428 +        for (FileObject f : from) {
 218.429 +            CPCategorizer cpCategorizer = new CPCategorizer(f);
 218.430 +
 218.431 +            Collection<FileObject> files = m.get(cpCategorizer);
 218.432 +
 218.433 +            if (files == null) {
 218.434 +                m.put(cpCategorizer, files = new LinkedList<FileObject>());
 218.435 +            }
 218.436 +
 218.437 +            files.add(f);
 218.438 +        }
 218.439 +        
 218.440 +        Map<ClasspathInfo, Collection<FileObject>> result = new IdentityHashMap<ClasspathInfo, Collection<FileObject>>();
 218.441 +
 218.442 +        for (Entry<CPCategorizer, Collection<FileObject>> e : m.entrySet()) {
 218.443 +            result.put(ClasspathInfo.create(e.getKey().boot, e.getKey().compile, e.getKey().source), e.getValue());
 218.444 +        }
 218.445 +        
 218.446 +        return result;
 218.447 +    }
 218.448 +    
 218.449 +    private static final ClassPath getClassPath(FileObject forFO, String id) {
 218.450 +        ClassPath result = ClassPath.getClassPath(forFO, id);
 218.451 +        
 218.452 +        if (result == null) {
 218.453 +            if (ClassPath.BOOT.equals(id)) {
 218.454 +                result = JavaPlatformManager.getDefault().getDefaultPlatform().getBootstrapLibraries();
 218.455 +            } else {
 218.456 +                result = ClassPath.EMPTY;
 218.457 +            }
 218.458 +        }
 218.459 +        
 218.460 +        return result;
 218.461 +    }
 218.462 +    
 218.463 +    private static final class CPCategorizer {
 218.464 +        private final String cps;
 218.465 +        private final ClassPath boot;
 218.466 +        private final ClassPath compile;
 218.467 +        private final ClassPath source;
 218.468 +        private final FileObject sourceRoot;
 218.469 +
 218.470 +        public CPCategorizer(FileObject file) {
 218.471 +            this.boot = getClassPath(file, ClassPath.BOOT);
 218.472 +            this.compile = getClassPath(file, ClassPath.COMPILE);
 218.473 +            this.source = getClassPath(file, ClassPath.SOURCE);
 218.474 +            this.sourceRoot = source != null ? source.findOwnerRoot(file) : null;
 218.475 +            
 218.476 +            StringBuilder cps = new StringBuilder();
 218.477 +            
 218.478 +            if (boot != null) cps.append(boot.toString(PathConversionMode.PRINT));
 218.479 +            if (compile != null) cps.append(compile.toString(PathConversionMode.PRINT));
 218.480 +            if (source != null) cps.append(source.toString(PathConversionMode.PRINT));
 218.481 +            
 218.482 +            this.cps = cps.toString();
 218.483 +        }
 218.484 +
 218.485 +        @Override
 218.486 +        public int hashCode() {
 218.487 +            int hash = 5;
 218.488 +            hash = 53 * hash + this.cps.hashCode();
 218.489 +            hash = 53 * hash + (this.sourceRoot != null ? this.sourceRoot.hashCode() : 0);
 218.490 +            return hash;
 218.491 +        }
 218.492 +
 218.493 +        @Override
 218.494 +        public boolean equals(Object obj) {
 218.495 +            if (obj == null) {
 218.496 +                return false;
 218.497 +            }
 218.498 +            if (getClass() != obj.getClass()) {
 218.499 +                return false;
 218.500 +            }
 218.501 +            final CPCategorizer other = (CPCategorizer) obj;
 218.502 +            if (!this.cps.equals(other.cps)) {
 218.503 +                return false;
 218.504 +            }
 218.505 +            if (this.sourceRoot != other.sourceRoot && (this.sourceRoot == null || !this.sourceRoot.equals(other.sourceRoot))) {
 218.506 +                return false;
 218.507 +            }
 218.508 +            return true;
 218.509 +        }
 218.510 +        
 218.511 +    }
 218.512 +
 218.513 +    public static final String ENSURE_DEPENDENCY = "ensure-dependency";
 218.514 +
 218.515 +    public static boolean fixDependencies(FileObject file, Iterable<? extends JavaFix> toProcess, Map<Project, Set<String>> alreadyProcessed) {
 218.516 +        boolean modified = false;
 218.517 +//        for (FileObject file : toProcess.keySet()) {
 218.518 +            for (JavaFix fix : toProcess) {
 218.519 +                String updateTo = Accessor.INSTANCE.getOptions(fix).get(ENSURE_DEPENDENCY);
 218.520 +
 218.521 +                if (updateTo != null) {
 218.522 +                    Project p = FileOwnerQuery.getOwner(file);
 218.523 +
 218.524 +                    if (p != null) {
 218.525 +                        Set<String> seen = alreadyProcessed.get(p);
 218.526 +
 218.527 +                        if (seen == null) {
 218.528 +                            alreadyProcessed.put(p, seen = new HashSet<String>());
 218.529 +                        }
 218.530 +
 218.531 +                        if (seen.add(updateTo)) {
 218.532 +                            for (ProjectDependencyUpgrader up : Lookup.getDefault().lookupAll(ProjectDependencyUpgrader.class)) {
 218.533 +                                if (up.ensureDependency(p, updateTo, false)) { //XXX: should check whether the given project was actually modified
 218.534 +                                    modified = true;
 218.535 +                                    break;
 218.536 +                                }
 218.537 +                            }
 218.538 +                            //TODO: fail if cannot update the dependency?
 218.539 +                        }
 218.540 +                    }
 218.541 +                }
 218.542 +            }
 218.543 +
 218.544 +            return modified;
 218.545 +//        }
 218.546 +    }
 218.547 +
 218.548 +    public static void recursive(FileObject root, FileObject file, Collection<FileObject> collected, ProgressHandleWrapper progress, int depth, Properties timeStamps, Set<String> removedFiles, boolean recursive) {
 218.549 +        if (!VisibilityQuery.getDefault().isVisible(file)) return;
 218.550 +
 218.551 +        if (file.isData()) {
 218.552 +            if (timeStamps != null) {
 218.553 +                String relativePath = FileUtil.getRelativePath(root, file);
 218.554 +                String lastModified = Long.toHexString(file.lastModified().getTime());
 218.555 +
 218.556 +                removedFiles.remove(relativePath);
 218.557 +
 218.558 +                if (lastModified.equals(timeStamps.getProperty(relativePath))) {
 218.559 +                    return;
 218.560 +                }
 218.561 +
 218.562 +                timeStamps.setProperty(relativePath, lastModified);
 218.563 +            }
 218.564 +
 218.565 +            if (/*???:*/"java".equals(file.getExt()) || "text/x-java".equals(FileUtil.getMIMEType(file, "text/x-java"))) {
 218.566 +                collected.add(file);
 218.567 +            }
 218.568 +        } else {
 218.569 +            FileObject[] children = file.getChildren();
 218.570 +
 218.571 +            if (children.length == 0) return;
 218.572 +
 218.573 +            ProgressHandleWrapper inner = depth < 2 ? progress.startNextPartWithEmbedding(ProgressHandleWrapper.prepareParts(children.length)) : null;
 218.574 +
 218.575 +            if (inner == null && progress != null) {
 218.576 +                progress.startNextPart(children.length);
 218.577 +            } else {
 218.578 +                progress = null;
 218.579 +            }
 218.580 +
 218.581 +            for (FileObject c : children) {
 218.582 +                if (recursive || c.isData())
 218.583 +                    recursive(root, c, collected, inner, depth + 1, timeStamps, removedFiles, recursive);
 218.584 +
 218.585 +                if (progress != null) progress.tick();
 218.586 +            }
 218.587 +        }
 218.588 +    }    
 218.589 +}
   219.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   219.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/batch/ProgressHandleWrapper.java	Sun Oct 23 11:50:54 2016 +0200
   219.3 @@ -0,0 +1,293 @@
   219.4 +/*
   219.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   219.6 + *
   219.7 + * Copyright 2009-2011 Oracle and/or its affiliates. All rights reserved.
   219.8 + *
   219.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  219.10 + * Other names may be trademarks of their respective owners.
  219.11 + *
  219.12 + * The contents of this file are subject to the terms of either the GNU
  219.13 + * General Public License Version 2 only ("GPL") or the Common
  219.14 + * Development and Distribution License("CDDL") (collectively, the
  219.15 + * "License"). You may not use this file except in compliance with the
  219.16 + * License. You can obtain a copy of the License at
  219.17 + * http://www.netbeans.org/cddl-gplv2.html
  219.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  219.19 + * specific language governing permissions and limitations under the
  219.20 + * License.  When distributing the software, include this License Header
  219.21 + * Notice in each file and include the License file at
  219.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  219.23 + * particular file as subject to the "Classpath" exception as provided
  219.24 + * by Oracle in the GPL Version 2 section of the License file that
  219.25 + * accompanied this code. If applicable, add the following below the
  219.26 + * License Header, with the fields enclosed by brackets [] replaced by
  219.27 + * your own identifying information:
  219.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  219.29 + *
  219.30 + * If you wish your version of this file to be governed by only the CDDL
  219.31 + * or only the GPL Version 2, indicate your decision by adding
  219.32 + * "[Contributor] elects to include this software in this distribution
  219.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  219.34 + * single choice of license, a recipient has the option to distribute
  219.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  219.36 + * to extend the choice of license to its licensees as provided above.
  219.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  219.38 + * Version 2 license, then the option applies only if the new code is
  219.39 + * made subject to such option by the copyright holder.
  219.40 + *
  219.41 + * Contributor(s):
  219.42 + *
  219.43 + * Portions Copyrighted 2009-2011 Sun Microsystems, Inc.
  219.44 + */
  219.45 +package org.netbeans.modules.java.hints.spiimpl.batch;
  219.46 +
  219.47 +import java.util.Arrays;
  219.48 +import java.util.logging.Level;
  219.49 +import java.util.logging.Logger;
  219.50 +import org.netbeans.api.progress.ProgressHandle;
  219.51 +import org.netbeans.modules.analysis.spi.Analyzer.Context;
  219.52 +import org.netbeans.modules.java.hints.spiimpl.Utilities;
  219.53 +
  219.54 +public final class ProgressHandleWrapper {
  219.55 +
  219.56 +    private static final int TOTAL = 1000;
  219.57 +    private final ProgressHandleAbstraction handle;
  219.58 +    private final int[] parts;
  219.59 +    private int currentPart = -1;
  219.60 +    private int currentPartTotalWork;
  219.61 +    private int currentPartWorkDone;
  219.62 +    private long currentPartStartTime;
  219.63 +    private int currentOffset;
  219.64 +    private final long[] spentTime;
  219.65 +    private boolean debug;
  219.66 +
  219.67 +    public ProgressHandleWrapper(int... parts) {
  219.68 +        this((ProgressHandleAbstraction) null, parts);
  219.69 +    }
  219.70 +
  219.71 +    public ProgressHandleWrapper(ProgressHandle handle, int... parts) {
  219.72 +        this(new ProgressHandleBasedProgressHandleAbstraction(handle), parts);
  219.73 +    }
  219.74 +
  219.75 +    public ProgressHandleWrapper(Context handle, int... parts) {
  219.76 +        this(new AnalysisContextBasedProgressHandleAbstraction(handle), parts);
  219.77 +    }
  219.78 +
  219.79 +    public ProgressHandleWrapper(ProgressHandleAbstraction handle, int... parts) {
  219.80 +        this.handle = handle;
  219.81 +        if (handle == null) {
  219.82 +            this.parts = null;
  219.83 +            this.spentTime = null;
  219.84 +        } else {
  219.85 +            int total = 0;
  219.86 +            for (int i : parts) {
  219.87 +                total += i;
  219.88 +            }
  219.89 +            this.parts = new int[parts.length];
  219.90 +            for (int cntr = 0; cntr < parts.length; cntr++) {
  219.91 +                this.parts[cntr] = (TOTAL * parts[cntr]) / total;
  219.92 +            }
  219.93 +            this.spentTime = new long[parts.length];
  219.94 +        }
  219.95 +    }
  219.96 +
  219.97 +    public void setDebug(boolean debug) {
  219.98 +        this.debug = debug;
  219.99 +    }
 219.100 +
 219.101 +    public void startNextPart(int totalWork) {
 219.102 +        if (handle == null) {
 219.103 +            return;
 219.104 +        }
 219.105 +        if (currentPart == (-1)) {
 219.106 +            handle.start(TOTAL);
 219.107 +        } else {
 219.108 +            currentOffset += parts[currentPart];
 219.109 +            spentTime[currentPart] = System.currentTimeMillis() - currentPartStartTime;
 219.110 +        }
 219.111 +        currentPart++;
 219.112 +        currentPartTotalWork = totalWork;
 219.113 +        currentPartWorkDone = 0;
 219.114 +        currentPartStartTime = System.currentTimeMillis();
 219.115 +        currentPartWorkDoneUpdated();
 219.116 +    }
 219.117 +
 219.118 +    public ProgressHandleWrapper startNextPartWithEmbedding(int... embeddedParts) {
 219.119 +//        startNextPart(TOTAL);
 219.120 +        return new ProgressHandleWrapper(new ProgressHandleWrapperBasedProgressHandleAbstraction(this), embeddedParts);
 219.121 +    }
 219.122 +
 219.123 +    public void tick() {
 219.124 +        if (handle == null) {
 219.125 +            return;
 219.126 +        }
 219.127 +        currentPartWorkDone++;
 219.128 +        currentPartWorkDoneUpdated();
 219.129 +    }
 219.130 +
 219.131 +    private void setCurrentPartWorkDone(int done) {
 219.132 +        if (handle == null) {
 219.133 +            return;
 219.134 +        }
 219.135 +        currentPartWorkDone = done;
 219.136 +        currentPartWorkDoneUpdated();
 219.137 +    }
 219.138 +
 219.139 +    private void currentPartWorkDoneUpdated() {
 219.140 +        if (currentPartTotalWork > 0) {
 219.141 +            int parentProgress = currentOffset + (parts[currentPart] * currentPartWorkDone) / currentPartTotalWork;
 219.142 +            if (debug) {
 219.143 +                System.err.println("currentOffset=" + currentOffset);
 219.144 +                System.err.println("currentPart=" + currentPart);
 219.145 +                System.err.println("parts[currentPart]= " +parts[currentPart]);
 219.146 +                System.err.println("currentPartWorkDone=" + currentPartWorkDone);
 219.147 +                System.err.println("currentPartTotalWork= " +currentPartTotalWork);
 219.148 +                System.err.println("parentProgress=" + parentProgress);
 219.149 +            }
 219.150 +            handle.progress(parentProgress);
 219.151 +        } else {
 219.152 +            handle.progress(currentOffset + parts[currentPart]);
 219.153 +        }
 219.154 +        setAutomatedMessage();
 219.155 +    }
 219.156 +
 219.157 +    public void setMessage(String message) {
 219.158 +        if (handle == null) {
 219.159 +            return;
 219.160 +        }
 219.161 +        handle.progress(message);
 219.162 +    }
 219.163 +
 219.164 +    private void setAutomatedMessage() {
 219.165 +        if (handle == null || currentPart == (-1)) {
 219.166 +            return;
 219.167 +        }
 219.168 +        long spentTime = System.currentTimeMillis() - currentPartStartTime;
 219.169 +        double timePerUnit = ((double) spentTime) / currentPartWorkDone;
 219.170 +        String timeString;
 219.171 +        if (spentTime > 0) {
 219.172 +            double totalTime = currentPartTotalWork * timePerUnit;
 219.173 +            timeString = Utilities.toHumanReadableTime(spentTime) + "/" + Utilities.toHumanReadableTime(totalTime);
 219.174 +        } else {
 219.175 +            timeString = "No estimate";
 219.176 +        }
 219.177 +        handle.progress("Part " + (currentPart + 1) + "/" + parts.length + ", " + currentPartWorkDone + "/" + currentPartTotalWork + ", " + timeString);
 219.178 +    }
 219.179 +
 219.180 +    public void finish() {
 219.181 +        if (handle == null) {
 219.182 +            return ;
 219.183 +        }
 219.184 +
 219.185 +        handle.finish();
 219.186 +
 219.187 +        if (currentPart < 0) return ;
 219.188 +        
 219.189 +        spentTime[currentPart] = System.currentTimeMillis() - currentPartStartTime;
 219.190 +
 219.191 +        double total = 0.0;
 219.192 +
 219.193 +        for (long t : spentTime) {
 219.194 +            total += t;
 219.195 +        }
 219.196 +
 219.197 +        double[] actualSplit = new double[spentTime.length];
 219.198 +        int i = 0;
 219.199 +
 219.200 +        for (long t : spentTime) {
 219.201 +            actualSplit[i++] = TOTAL * (t / total);
 219.202 +        }
 219.203 +
 219.204 +        Logger.getLogger(ProgressHandleWrapper.class.getName()).log(Level.FINE, "Progress handle with split: {0}, actual times: {1}, actual split: {2}", new Object[] {Arrays.toString(parts), Arrays.toString(spentTime), Arrays.toString(actualSplit)});
 219.205 +    }
 219.206 +
 219.207 +    public static int[] prepareParts(int count) {
 219.208 +        int[] result = new int[count];
 219.209 +
 219.210 +        for (int cntr = 0; cntr < count; cntr++) {
 219.211 +            result[cntr] = 1;
 219.212 +        }
 219.213 +
 219.214 +        return result;
 219.215 +    }
 219.216 +
 219.217 +    public static interface ProgressHandleAbstraction {
 219.218 +
 219.219 +        public void start(int totalWork);
 219.220 +
 219.221 +        public void progress(int currentWorkDone);
 219.222 +
 219.223 +        public void progress(String message);
 219.224 +
 219.225 +        public void finish();
 219.226 +
 219.227 +    }
 219.228 +
 219.229 +    private static final class ProgressHandleBasedProgressHandleAbstraction implements ProgressHandleAbstraction {
 219.230 +        private final ProgressHandle delegate;
 219.231 +        public ProgressHandleBasedProgressHandleAbstraction(ProgressHandle delegate) {
 219.232 +            this.delegate = delegate;
 219.233 +        }
 219.234 +
 219.235 +        public void start(int totalWork) {
 219.236 +            delegate.start(totalWork);
 219.237 +        }
 219.238 +
 219.239 +        public void progress(int currentWorkDone) {
 219.240 +            delegate.progress(currentWorkDone);
 219.241 +        }
 219.242 +
 219.243 +        public void progress(String message) {
 219.244 +            delegate.progress(message);
 219.245 +        }
 219.246 +
 219.247 +        public void finish() {
 219.248 +            delegate.finish();
 219.249 +        }
 219.250 +    }
 219.251 +
 219.252 +    private static final class AnalysisContextBasedProgressHandleAbstraction implements ProgressHandleAbstraction {
 219.253 +        private final Context delegate;
 219.254 +        AnalysisContextBasedProgressHandleAbstraction(Context delegate) {
 219.255 +            this.delegate = delegate;
 219.256 +        }
 219.257 +
 219.258 +        public void start(int totalWork) {
 219.259 +            delegate.start(totalWork);
 219.260 +        }
 219.261 +
 219.262 +        public void progress(int currentWorkDone) {
 219.263 +            delegate.progress(currentWorkDone);
 219.264 +        }
 219.265 +
 219.266 +        public void progress(String message) {
 219.267 +            delegate.progress(message);
 219.268 +        }
 219.269 +
 219.270 +        public void finish() {
 219.271 +            delegate.finish();
 219.272 +        }
 219.273 +    }
 219.274 +
 219.275 +    private static final class ProgressHandleWrapperBasedProgressHandleAbstraction implements ProgressHandleAbstraction {
 219.276 +        private final ProgressHandleWrapper delegate;
 219.277 +        public ProgressHandleWrapperBasedProgressHandleAbstraction(ProgressHandleWrapper delegate) {
 219.278 +            this.delegate = delegate;
 219.279 +        }
 219.280 +
 219.281 +        public void start(int totalWork) {
 219.282 +            delegate.startNextPart(totalWork);
 219.283 +        }
 219.284 +
 219.285 +        public void progress(int currentWorkDone) {
 219.286 +            delegate.setCurrentPartWorkDone(currentWorkDone);
 219.287 +        }
 219.288 +
 219.289 +        public void progress(String message) {
 219.290 +            delegate.setMessage(message);
 219.291 +        }
 219.292 +
 219.293 +        public void finish() {}
 219.294 +    }
 219.295 +
 219.296 +}
   220.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   220.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/batch/Scopes.java	Sun Oct 23 11:50:54 2016 +0200
   220.3 @@ -0,0 +1,141 @@
   220.4 +/*
   220.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   220.6 + *
   220.7 + * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
   220.8 + *
   220.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  220.10 + * Other names may be trademarks of their respective owners.
  220.11 + *
  220.12 + * The contents of this file are subject to the terms of either the GNU
  220.13 + * General Public License Version 2 only ("GPL") or the Common
  220.14 + * Development and Distribution License("CDDL") (collectively, the
  220.15 + * "License"). You may not use this file except in compliance with the
  220.16 + * License. You can obtain a copy of the License at
  220.17 + * http://www.netbeans.org/cddl-gplv2.html
  220.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  220.19 + * specific language governing permissions and limitations under the
  220.20 + * License.  When distributing the software, include this License Header
  220.21 + * Notice in each file and include the License file at
  220.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  220.23 + * particular file as subject to the "Classpath" exception as provided
  220.24 + * by Oracle in the GPL Version 2 section of the License file that
  220.25 + * accompanied this code. If applicable, add the following below the
  220.26 + * License Header, with the fields enclosed by brackets [] replaced by
  220.27 + * your own identifying information:
  220.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  220.29 + *
  220.30 + * If you wish your version of this file to be governed by only the CDDL
  220.31 + * or only the GPL Version 2, indicate your decision by adding
  220.32 + * "[Contributor] elects to include this software in this distribution
  220.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  220.34 + * single choice of license, a recipient has the option to distribute
  220.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  220.36 + * to extend the choice of license to its licensees as provided above.
  220.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  220.38 + * Version 2 license, then the option applies only if the new code is
  220.39 + * made subject to such option by the copyright holder.
  220.40 + *
  220.41 + * Contributor(s):
  220.42 + *
  220.43 + * Portions Copyrighted 2011 Sun Microsystems, Inc.
  220.44 + */
  220.45 +package org.netbeans.modules.java.hints.spiimpl.batch;
  220.46 +
  220.47 +import java.util.Arrays;
  220.48 +import java.util.Collection;
  220.49 +import java.util.HashSet;
  220.50 +import java.util.Set;
  220.51 +import org.netbeans.api.java.classpath.ClassPath;
  220.52 +import org.netbeans.api.java.classpath.GlobalPathRegistry;
  220.53 +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.Folder;
  220.54 +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.IndexEnquirer;
  220.55 +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.MapIndices;
  220.56 +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.Scope;
  220.57 +import org.netbeans.modules.java.hints.providers.spi.HintDescription;
  220.58 +import org.openide.filesystems.FileObject;
  220.59 +import org.openide.util.Lookup;
  220.60 +
  220.61 +/**
  220.62 + *
  220.63 + * @author lahvac
  220.64 + */
  220.65 +public class Scopes {
  220.66 +
  220.67 +    public static Scope allOpenedProjectsScope() {
  220.68 +        return new AllOpenedProjectsScope();
  220.69 +    }
  220.70 +
  220.71 +    private static final class AllOpenedProjectsScope extends Scope {
  220.72 +
  220.73 +        @Override
  220.74 +        public String getDisplayName() {
  220.75 +            return "All Opened Projects";
  220.76 +        }
  220.77 +
  220.78 +        @Override
  220.79 +        public Collection<? extends Folder> getTodo() {
  220.80 +            Set<Folder> todo = new HashSet<Folder>();
  220.81 +
  220.82 +            for (ClassPath source : GlobalPathRegistry.getDefault().getPaths(ClassPath.SOURCE)) {
  220.83 +                todo.addAll(Arrays.asList(Folder.convert(source.getRoots())));
  220.84 +            }
  220.85 +
  220.86 +            return todo;
  220.87 +        }
  220.88 +
  220.89 +        @Override
  220.90 +        public MapIndices getIndexMapper(Iterable<? extends HintDescription> hints) {
  220.91 +            return getDefaultIndicesMapper();
  220.92 +        }
  220.93 +    }
  220.94 +
  220.95 +    public static Scope specifiedFoldersScope(Folder... roots) {
  220.96 +        return new SpecificFoldersScope(roots);
  220.97 +    }
  220.98 +    
  220.99 +    private static final class SpecificFoldersScope extends Scope {
 220.100 +
 220.101 +        private final Collection<? extends Folder> roots;
 220.102 +
 220.103 +        public SpecificFoldersScope(Folder... roots) {
 220.104 +            this.roots = Arrays.asList(roots);
 220.105 +        }
 220.106 +
 220.107 +        @Override
 220.108 +        public String getDisplayName() {
 220.109 +            return "Specified Root";
 220.110 +        }
 220.111 +
 220.112 +        @Override
 220.113 +        public Collection<? extends Folder> getTodo() {
 220.114 +            return roots;
 220.115 +        }
 220.116 +
 220.117 +        @Override
 220.118 +        public MapIndices getIndexMapper(Iterable<? extends HintDescription> hints) {
 220.119 +            return getDefaultIndicesMapper();
 220.120 +        }
 220.121 +    }
 220.122 +
 220.123 +    public static MapIndices getDefaultIndicesMapper() {
 220.124 +        return new MapIndices() {
 220.125 +            @Override
 220.126 +            public IndexEnquirer findIndex(FileObject root, ProgressHandleWrapper progress, boolean recursive) {
 220.127 +                IndexEnquirer e = findIndexEnquirer(root, progress, recursive);
 220.128 +
 220.129 +                if (e != null) return e;
 220.130 +                else return new BatchSearch.FileSystemBasedIndexEnquirer(root, recursive);
 220.131 +            }
 220.132 +        };
 220.133 +    }
 220.134 +    
 220.135 +    public static IndexEnquirer findIndexEnquirer(FileObject root, ProgressHandleWrapper progress, boolean recursive) {
 220.136 +        for (MapIndices mi : Lookup.getDefault().lookupAll(MapIndices.class)) {
 220.137 +            IndexEnquirer r = mi.findIndex(root, progress, recursive);
 220.138 +
 220.139 +            if (r != null) return r;
 220.140 +        }
 220.141 +
 220.142 +        return null;
 220.143 +    }
 220.144 +}
   221.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   221.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/hints/GlobalProcessingContext.java	Sun Oct 23 11:50:54 2016 +0200
   221.3 @@ -0,0 +1,56 @@
   221.4 +/*
   221.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   221.6 + *
   221.7 + * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
   221.8 + *
   221.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  221.10 + * Other names may be trademarks of their respective owners.
  221.11 + *
  221.12 + * The contents of this file are subject to the terms of either the GNU
  221.13 + * General Public License Version 2 only ("GPL") or the Common
  221.14 + * Development and Distribution License("CDDL") (collectively, the
  221.15 + * "License"). You may not use this file except in compliance with the
  221.16 + * License. You can obtain a copy of the License at
  221.17 + * http://www.netbeans.org/cddl-gplv2.html
  221.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  221.19 + * specific language governing permissions and limitations under the
  221.20 + * License.  When distributing the software, include this License Header
  221.21 + * Notice in each file and include the License file at
  221.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  221.23 + * particular file as subject to the "Classpath" exception as provided
  221.24 + * by Oracle in the GPL Version 2 section of the License file that
  221.25 + * accompanied this code. If applicable, add the following below the
  221.26 + * License Header, with the fields enclosed by brackets [] replaced by
  221.27 + * your own identifying information:
  221.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  221.29 + *
  221.30 + * If you wish your version of this file to be governed by only the CDDL
  221.31 + * or only the GPL Version 2, indicate your decision by adding
  221.32 + * "[Contributor] elects to include this software in this distribution
  221.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  221.34 + * single choice of license, a recipient has the option to distribute
  221.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  221.36 + * to extend the choice of license to its licensees as provided above.
  221.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  221.38 + * Version 2 license, then the option applies only if the new code is
  221.39 + * made subject to such option by the copyright holder.
  221.40 + *
  221.41 + * Contributor(s):
  221.42 + *
  221.43 + * Portions Copyrighted 2013 Sun Microsystems, Inc.
  221.44 + */
  221.45 +package org.netbeans.modules.java.hints.spiimpl.hints;
  221.46 +
  221.47 +import java.util.HashMap;
  221.48 +import java.util.List;
  221.49 +import java.util.Map;
  221.50 +import org.netbeans.api.java.source.TreePathHandle;
  221.51 +import org.netbeans.spi.java.hints.Decision;
  221.52 +
  221.53 +/**
  221.54 + *
  221.55 + * @author lahvac
  221.56 + */
  221.57 +public class GlobalProcessingContext {
  221.58 +    public final Map<TreePathHandle, List<Decision<?, ?>>> decisions = new HashMap<TreePathHandle, List<Decision<?, ?>>>();
  221.59 +}
   222.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   222.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/hints/HintsInvoker.java	Sun Oct 23 11:50:54 2016 +0200
   222.3 @@ -0,0 +1,863 @@
   222.4 +/*
   222.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   222.6 + *
   222.7 + * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
   222.8 + *
   222.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  222.10 + * Other names may be trademarks of their respective owners.
  222.11 + *
  222.12 + * The contents of this file are subject to the terms of either the GNU
  222.13 + * General Public License Version 2 only ("GPL") or the Common
  222.14 + * Development and Distribution License("CDDL") (collectively, the
  222.15 + * "License"). You may not use this file except in compliance with the
  222.16 + * License. You can obtain a copy of the License at
  222.17 + * http://www.netbeans.org/cddl-gplv2.html
  222.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  222.19 + * specific language governing permissions and limitations under the
  222.20 + * License.  When distributing the software, include this License Header
  222.21 + * Notice in each file and include the License file at
  222.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  222.23 + * particular file as subject to the "Classpath" exception as provided
  222.24 + * by Oracle in the GPL Version 2 section of the License file that
  222.25 + * accompanied this code. If applicable, add the following below the
  222.26 + * License Header, with the fields enclosed by brackets [] replaced by
  222.27 + * your own identifying information:
  222.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  222.29 + *
  222.30 + * If you wish your version of this file to be governed by only the CDDL
  222.31 + * or only the GPL Version 2, indicate your decision by adding
  222.32 + * "[Contributor] elects to include this software in this distribution
  222.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  222.34 + * single choice of license, a recipient has the option to distribute
  222.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  222.36 + * to extend the choice of license to its licensees as provided above.
  222.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  222.38 + * Version 2 license, then the option applies only if the new code is
  222.39 + * made subject to such option by the copyright holder.
  222.40 + *
  222.41 + * Contributor(s):
  222.42 + *
  222.43 + * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
  222.44 + */
  222.45 +
  222.46 +package org.netbeans.modules.java.hints.spiimpl.hints;
  222.47 +
  222.48 +import com.sun.source.tree.Tree;
  222.49 +import java.util.Stack;
  222.50 +import java.util.concurrent.atomic.AtomicBoolean;
  222.51 +import javax.lang.model.element.AnnotationMirror;
  222.52 +import javax.lang.model.element.AnnotationValue;
  222.53 +import javax.lang.model.element.Element;
  222.54 +import javax.lang.model.element.ExecutableElement;
  222.55 +import javax.lang.model.element.TypeElement;
  222.56 +import javax.swing.text.Document;
  222.57 +import org.netbeans.api.java.source.support.CancellableTreePathScanner;
  222.58 +import org.netbeans.editor.GuardedDocument;
  222.59 +import org.netbeans.editor.MarkBlock;
  222.60 +import org.netbeans.editor.MarkBlockChain;
  222.61 +import org.openide.filesystems.FileObject;
  222.62 +
  222.63 +import com.sun.source.tree.Tree.Kind;
  222.64 +import com.sun.source.util.TreePath;
  222.65 +import com.sun.source.util.Trees;
  222.66 +import java.io.IOException;
  222.67 +import java.util.ArrayList;
  222.68 +import java.util.Arrays;
  222.69 +import java.util.Collection;
  222.70 +import java.util.Collections;
  222.71 +import java.util.Comparator;
  222.72 +import java.util.EnumMap;
  222.73 +import java.util.HashMap;
  222.74 +import java.util.HashSet;
  222.75 +import java.util.Iterator;
  222.76 +import java.util.LinkedList;
  222.77 +import java.util.List;
  222.78 +import java.util.Map;
  222.79 +import java.util.Map.Entry;
  222.80 +import java.util.Set;
  222.81 +import java.util.prefs.Preferences;
  222.82 +import javax.annotation.processing.ProcessingEnvironment;
  222.83 +import javax.lang.model.type.TypeKind;
  222.84 +import javax.lang.model.type.TypeMirror;
  222.85 +import org.netbeans.api.annotations.common.CheckForNull;
  222.86 +import org.netbeans.api.java.source.CompilationInfo;
  222.87 +import org.netbeans.modules.java.hints.spiimpl.Hacks;
  222.88 +import org.netbeans.spi.java.hints.HintContext;
  222.89 +import org.netbeans.modules.java.hints.providers.spi.HintDescription;
  222.90 +import org.netbeans.modules.java.hints.providers.spi.HintMetadata;
  222.91 +import org.netbeans.modules.java.hints.providers.spi.Trigger;
  222.92 +import org.netbeans.modules.java.hints.providers.spi.Trigger.Kinds;
  222.93 +import org.netbeans.modules.java.hints.providers.spi.Trigger.PatternDescription;
  222.94 +import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings;
  222.95 +import org.netbeans.modules.java.hints.spiimpl.MessageImpl;
  222.96 +import org.netbeans.modules.java.hints.spiimpl.RulesManager;
  222.97 +import org.netbeans.modules.java.hints.spiimpl.SPIAccessor;
  222.98 +import org.netbeans.modules.java.hints.spiimpl.Utilities;
  222.99 +import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch;
 222.100 +import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch.BulkPattern;
 222.101 +import org.netbeans.modules.java.hints.spiimpl.pm.PatternCompiler;
 222.102 +import org.netbeans.spi.editor.hints.ErrorDescription;
 222.103 +import org.netbeans.spi.editor.hints.Severity;
 222.104 +import org.netbeans.spi.java.hints.Hint;
 222.105 +import org.netbeans.api.java.source.matching.Matcher;
 222.106 +import org.netbeans.api.java.source.matching.Occurrence;
 222.107 +import org.netbeans.api.java.source.matching.Pattern;
 222.108 +import org.netbeans.modules.java.hints.providers.spi.Trigger.DecisionTrigger;
 222.109 +import org.openide.util.Exceptions;
 222.110 +
 222.111 +/**
 222.112 + *
 222.113 + * @author lahvac
 222.114 + */
 222.115 +public class HintsInvoker {
 222.116 +
 222.117 +    private final Map<String, Long> timeLog = new HashMap<String, Long>();
 222.118 +
 222.119 +    private final HintsSettings settings;
 222.120 +    private final int caret;
 222.121 +    private final int from;
 222.122 +    private final int to;
 222.123 +    private final GlobalProcessingContext globalContext;
 222.124 +    private final AtomicBoolean cancel;
 222.125 +
 222.126 +    public HintsInvoker(HintsSettings settings, AtomicBoolean cancel) {
 222.127 +        this(settings, null, cancel);
 222.128 +    }
 222.129 +
 222.130 +    public HintsInvoker(HintsSettings settings, GlobalProcessingContext globalContext, AtomicBoolean cancel) {
 222.131 +        this(settings, -1, -1, -1, globalContext, cancel);
 222.132 +    }
 222.133 +
 222.134 +    public HintsInvoker(HintsSettings settings, int caret, AtomicBoolean cancel) {
 222.135 +        this(settings, caret, -1, -1, null, cancel);
 222.136 +    }
 222.137 +
 222.138 +    public HintsInvoker(HintsSettings settings, int from, int to, AtomicBoolean cancel) {
 222.139 +        this(settings, -1, from, to, null, cancel);
 222.140 +    }
 222.141 +
 222.142 +    private HintsInvoker(HintsSettings settings, int caret, int from, int to, GlobalProcessingContext globalContext, AtomicBoolean cancel) {
 222.143 +        this.settings = settings;
 222.144 +        this.caret = caret;
 222.145 +        this.from = from;
 222.146 +        this.to = to;
 222.147 +        this.globalContext = globalContext;
 222.148 +        this.cancel = cancel;
 222.149 +    }
 222.150 +
 222.151 +    @CheckForNull
 222.152 +    public List<ErrorDescription> computeHints(CompilationInfo info) {
 222.153 +        return computeHints(info, new TreePath(info.getCompilationUnit()));
 222.154 +    }
 222.155 +
 222.156 +    private List<ErrorDescription> computeHints(CompilationInfo info, TreePath startAt) {
 222.157 +        List<HintDescription> descs = new LinkedList<HintDescription>();
 222.158 +        Map<HintMetadata, ? extends Collection<? extends HintDescription>> allHints = RulesManager.getInstance().readHints(info, null, cancel);
 222.159 +
 222.160 +        for (Entry<HintMetadata, ? extends Collection<? extends HintDescription>> e : allHints.entrySet()) {
 222.161 +            HintMetadata m = e.getKey();
 222.162 +
 222.163 +            if (!settings.isEnabled(m)) {
 222.164 +                continue;
 222.165 +            }
 222.166 +
 222.167 +            if (caret != -1) {
 222.168 +                if (m.kind == Hint.Kind.ACTION) {
 222.169 +                    descs.addAll(e.getValue());
 222.170 +                } else {
 222.171 +                    if (settings.getSeverity(m) == Severity.HINT) {
 222.172 +                        descs.addAll(e.getValue());
 222.173 +                    }
 222.174 +                }
 222.175 +            } else {
 222.176 +                if (m.kind == Hint.Kind.INSPECTION) {
 222.177 +                    if (settings.getSeverity(m) != Severity.HINT) {
 222.178 +                        descs.addAll(e.getValue());
 222.179 +                    }
 222.180 +                }
 222.181 +            }
 222.182 +        }
 222.183 +
 222.184 +        List<ErrorDescription> errors = join(computeHints(info, startAt, descs, new LinkedList<MessageImpl>()));
 222.185 +
 222.186 +        dumpTimeSpentInHints();
 222.187 +        
 222.188 +        return errors;
 222.189 +    }
 222.190 +
 222.191 +    @CheckForNull
 222.192 +    public List<ErrorDescription> computeHints(CompilationInfo info,
 222.193 +                                               Iterable<? extends HintDescription> hints) {
 222.194 +        return computeHints(info, hints, new LinkedList<MessageImpl>());
 222.195 +    }
 222.196 +
 222.197 +    @CheckForNull
 222.198 +    public List<ErrorDescription> computeHints(CompilationInfo info,
 222.199 +                                               Iterable<? extends HintDescription> hints,
 222.200 +                                               Collection<? super MessageImpl> problems) {
 222.201 +        return join(computeHints(info, new TreePath(info.getCompilationUnit()), hints, problems));
 222.202 +    }
 222.203 +
 222.204 +    private static final Iterable<? extends Class<? extends Trigger>> TRIGGER_KINDS = Arrays.asList(Kinds.class, PatternDescription.class, DecisionTrigger.class);
 222.205 +    
 222.206 +    @CheckForNull
 222.207 +    public Map<HintDescription, List<ErrorDescription>> computeHints(CompilationInfo info,
 222.208 +                                        TreePath startAt,
 222.209 +                                        Iterable<? extends HintDescription> hints,
 222.210 +                                        Collection<? super MessageImpl> problems) {
 222.211 +        return computeHints(info, startAt, true, hints, problems);
 222.212 +    }
 222.213 +    
 222.214 +    @CheckForNull
 222.215 +    public Map<HintDescription, List<ErrorDescription>> computeHints(CompilationInfo info,
 222.216 +                                        TreePath startAt,
 222.217 +                                        boolean recursive,
 222.218 +                                        Iterable<? extends HintDescription> hints,
 222.219 +                                        Collection<? super MessageImpl> problems) {
 222.220 +        Map<Class, List<HintDescription>> triggerKind2Hints = new HashMap<Class, List<HintDescription>>();
 222.221 +
 222.222 +        for (Class<? extends Trigger> c : TRIGGER_KINDS) {
 222.223 +            triggerKind2Hints.put(c, new ArrayList<HintDescription>());
 222.224 +        }
 222.225 +
 222.226 +        for (HintDescription hd : hints) {
 222.227 +            List<HintDescription> sorted = triggerKind2Hints.get(hd.getTrigger().getClass());
 222.228 +
 222.229 +            sorted.add(hd);
 222.230 +        }
 222.231 +
 222.232 +        if (caret != -1) {
 222.233 +            TreePath tp = info.getTreeUtilities().pathFor(caret);
 222.234 +            return computeSuggestions(info, tp, true, triggerKind2Hints, problems);
 222.235 +        } else {
 222.236 +            if (from != (-1) && to != (-1)) {
 222.237 +                return computeHintsInSpan(info, triggerKind2Hints, problems);
 222.238 +            } else if (!recursive) {
 222.239 +                return computeSuggestions(info, startAt, false, triggerKind2Hints, problems);
 222.240 +            } else {
 222.241 +                return computeHintsImpl(info, startAt, triggerKind2Hints, problems);
 222.242 +            }
 222.243 +        }
 222.244 +    }
 222.245 +
 222.246 +    private Map<HintDescription, List<ErrorDescription>> computeHintsImpl(CompilationInfo info,
 222.247 +                                        TreePath startAt,
 222.248 +                                        Map<Class, List<HintDescription>> triggerKind2Hints,
 222.249 +                                        Collection<? super MessageImpl> problems) {
 222.250 +        Map<HintDescription, List<ErrorDescription>> errors = new HashMap<HintDescription, List<ErrorDescription>>();
 222.251 +        List<HintDescription> kindBasedHints = triggerKind2Hints.get(Kinds.class);
 222.252 +
 222.253 +        timeLog.put("[C] Kind Based Hints", (long) kindBasedHints.size());
 222.254 +
 222.255 +        if (!kindBasedHints.isEmpty()) {
 222.256 +            long kindStart = System.currentTimeMillis();
 222.257 +
 222.258 +            new ScannerImpl(info, cancel, sortByKinds(kindBasedHints), problems).scan(startAt, errors);
 222.259 +
 222.260 +            long kindEnd = System.currentTimeMillis();
 222.261 +
 222.262 +            timeLog.put("Kind Based Hints", kindEnd - kindStart);
 222.263 +        }
 222.264 +
 222.265 +        if (cancel.get()) return null;
 222.266 +        
 222.267 +        List<HintDescription> patternBasedHints = triggerKind2Hints.get(PatternDescription.class);
 222.268 +
 222.269 +        timeLog.put("[C] Pattern Based Hints", (long) patternBasedHints.size());
 222.270 +
 222.271 +        long patternStart = System.currentTimeMillis();
 222.272 +
 222.273 +        Map<PatternDescription, List<HintDescription>> patternHints = sortByPatterns(patternBasedHints);
 222.274 +        Map<String, List<PatternDescription>> patternTests = computePatternTests(patternHints);
 222.275 +
 222.276 +        long bulkPatternStart = System.currentTimeMillis();
 222.277 +
 222.278 +        BulkPattern bulkPattern = BulkSearch.getDefault().create(info, cancel, patternTests.keySet());
 222.279 +
 222.280 +        if (bulkPattern == null || cancel.get()) return null;
 222.281 +        
 222.282 +        long bulkPatternEnd = System.currentTimeMillis();
 222.283 +
 222.284 +        timeLog.put("Bulk Pattern preparation", bulkPatternEnd - bulkPatternStart);
 222.285 +
 222.286 +        long bulkStart = System.currentTimeMillis();
 222.287 +
 222.288 +        Map<String, Collection<TreePath>> occurringPatterns = BulkSearch.getDefault().match(info, cancel, startAt, bulkPattern, timeLog);
 222.289 +        
 222.290 +        if (occurringPatterns == null || cancel.get()) return null;
 222.291 +
 222.292 +        long bulkEnd = System.currentTimeMillis();
 222.293 +
 222.294 +        timeLog.put("Bulk Search", bulkEnd - bulkStart);
 222.295 +        
 222.296 +        Map<HintDescription, List<ErrorDescription>> computedHints = doComputeHints(info, occurringPatterns, patternTests, patternHints, problems);
 222.297 +
 222.298 +        if (computedHints == null || cancel.get()) return null;
 222.299 +        
 222.300 +        mergeAll(errors, computedHints);
 222.301 +
 222.302 +        long patternEnd = System.currentTimeMillis();
 222.303 +
 222.304 +        timeLog.put("Pattern Based Hints", patternEnd - patternStart);
 222.305 +
 222.306 +        return errors;
 222.307 +    }
 222.308 +
 222.309 +    private Map<HintDescription, List<ErrorDescription>> computeHintsInSpan(CompilationInfo info,
 222.310 +                                        Map<Class, List<HintDescription>> triggerKind2Hints,
 222.311 +                                        Collection<? super MessageImpl> problems) {
 222.312 +
 222.313 +        TreePath path = info.getTreeUtilities().pathFor((from + to) / 2);
 222.314 +
 222.315 +        while (path.getLeaf().getKind() != Kind.COMPILATION_UNIT) {
 222.316 +            int start = (int) info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), path.getLeaf());
 222.317 +            int end = (int) info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), path.getLeaf());
 222.318 +
 222.319 +            if (start <= from && end >= to) {
 222.320 +                break;
 222.321 +            }
 222.322 +
 222.323 +            path = path.getParentPath();
 222.324 +        }
 222.325 +
 222.326 +        Map<HintDescription, List<ErrorDescription>> errors = new HashMap<HintDescription, List<ErrorDescription>>();
 222.327 +        List<HintDescription> kindBasedHints = triggerKind2Hints.get(Kinds.class);
 222.328 +
 222.329 +        if (!kindBasedHints.isEmpty()) {
 222.330 +            long kindStart = System.currentTimeMillis();
 222.331 +
 222.332 +            new ScannerImpl(info, cancel, sortByKinds(kindBasedHints), problems).scan(path, errors);
 222.333 +
 222.334 +            long kindEnd = System.currentTimeMillis();
 222.335 +
 222.336 +            timeLog.put("Kind Based Hints", kindEnd - kindStart);
 222.337 +        }
 222.338 +
 222.339 +        List<HintDescription> patternBasedHints = triggerKind2Hints.get(PatternDescription.class);
 222.340 +
 222.341 +        if (!patternBasedHints.isEmpty()) {
 222.342 +            long patternStart = System.currentTimeMillis();
 222.343 +
 222.344 +            Map<PatternDescription, List<HintDescription>> patternHints = sortByPatterns(patternBasedHints);
 222.345 +            Map<String, List<PatternDescription>> patternTests = computePatternTests(patternHints);
 222.346 +
 222.347 +            long bulkStart = System.currentTimeMillis();
 222.348 +
 222.349 +            BulkPattern bulkPattern = BulkSearch.getDefault().create(info, cancel, patternTests.keySet());
 222.350 +            
 222.351 +            if (bulkPattern == null || cancel.get()) return null;
 222.352 +            
 222.353 +            Map<String, Collection<TreePath>> occurringPatterns = BulkSearch.getDefault().match(info, cancel, path, bulkPattern, timeLog);
 222.354 +
 222.355 +            long bulkEnd = System.currentTimeMillis();
 222.356 +
 222.357 +            timeLog.put("Bulk Search", bulkEnd - bulkStart);
 222.358 +            
 222.359 +            Map<HintDescription, List<ErrorDescription>> computedHints = doComputeHints(info, occurringPatterns, patternTests, patternHints, problems);
 222.360 +
 222.361 +            if (computedHints == null || cancel.get()) return null;
 222.362 +            
 222.363 +            mergeAll(errors, computedHints);
 222.364 +
 222.365 +            long patternEnd = System.currentTimeMillis();
 222.366 +
 222.367 +            timeLog.put("Pattern Based Hints", patternEnd - patternStart);
 222.368 +        }
 222.369 +
 222.370 +        if (path != null) {
 222.371 +            Map<HintDescription, List<ErrorDescription>> suggestions = computeSuggestions(info, path, true, triggerKind2Hints, problems);
 222.372 +            
 222.373 +            if (suggestions == null || cancel.get()) return null;
 222.374 +            
 222.375 +            mergeAll(errors, suggestions);
 222.376 +        }
 222.377 +
 222.378 +        return errors;
 222.379 +    }
 222.380 +
 222.381 +    private Map<HintDescription, List<ErrorDescription>> computeSuggestions(CompilationInfo info,
 222.382 +                                        TreePath workOn,
 222.383 +                                        boolean up,
 222.384 +                                        Map<Class, List<HintDescription>> triggerKind2Hints,
 222.385 +                                        Collection<? super MessageImpl> problems) {
 222.386 +        Map<HintDescription, List<ErrorDescription>> errors = new HashMap<HintDescription, List<ErrorDescription>>();
 222.387 +        List<HintDescription> kindBasedHints = triggerKind2Hints.get(Kinds.class);
 222.388 +
 222.389 +        if (!kindBasedHints.isEmpty()) {
 222.390 +            long kindStart = System.currentTimeMillis();
 222.391 +            
 222.392 +            Map<Kind, List<HintDescription>> hints = sortByKinds(kindBasedHints);
 222.393 +            TreePath proc = workOn;
 222.394 +
 222.395 +            while (proc != null) {
 222.396 +                new ScannerImpl(info, cancel, hints, problems).scanDoNotGoDeeper(proc, errors);
 222.397 +                if (!up) break;
 222.398 +                proc = proc.getParentPath();
 222.399 +            }
 222.400 +
 222.401 +            long kindEnd = System.currentTimeMillis();
 222.402 +
 222.403 +            timeLog.put("Kind Based Suggestions", kindEnd - kindStart);
 222.404 +        }
 222.405 +        
 222.406 +        if (cancel.get()) return null;
 222.407 +
 222.408 +        List<HintDescription> patternBasedHints = triggerKind2Hints.get(PatternDescription.class);
 222.409 +
 222.410 +        if (!patternBasedHints.isEmpty()) {
 222.411 +            long patternStart = System.currentTimeMillis();
 222.412 +
 222.413 +            Map<PatternDescription, List<HintDescription>> patternHints = sortByPatterns(patternBasedHints);
 222.414 +            Map<String, List<PatternDescription>> patternTests = computePatternTests(patternHints);
 222.415 +
 222.416 +            //pretend that all the patterns occur on all treepaths from the current path
 222.417 +            //up (probably faster than using BulkSearch over whole file)
 222.418 +            //TODO: what about machint trees under the current path?
 222.419 +            Set<TreePath> paths = new HashSet<TreePath>();
 222.420 +
 222.421 +            TreePath tp = workOn;
 222.422 +
 222.423 +            while (tp != null) {
 222.424 +                paths.add(tp);
 222.425 +                if (!up) break;
 222.426 +                tp = tp.getParentPath();
 222.427 +            }
 222.428 +
 222.429 +            Map<String, Collection<TreePath>> occurringPatterns = new HashMap<String, Collection<TreePath>>();
 222.430 +
 222.431 +            for (String p : patternTests.keySet()) {
 222.432 +                occurringPatterns.put(p, paths);
 222.433 +            }
 222.434 +
 222.435 +//            long bulkStart = System.currentTimeMillis();
 222.436 +//
 222.437 +//            BulkPattern bulkPattern = BulkSearch.getDefault().create(info, patternTests.keySet());
 222.438 +//            Map<String, Collection<TreePath>> occurringPatterns = BulkSearch.getDefault().match(info, new TreePath(info.getCompilationUnit()), bulkPattern, timeLog);
 222.439 +//
 222.440 +//            long bulkEnd = System.currentTimeMillis();
 222.441 +//
 222.442 +//            Set<Tree> acceptedLeafs = new HashSet<Tree>();
 222.443 +//
 222.444 +//            TreePath tp = workOn;
 222.445 +//
 222.446 +//            while (tp != null) {
 222.447 +//                acceptedLeafs.add(tp.getLeaf());
 222.448 +//                tp = tp.getParentPath();
 222.449 +//            }
 222.450 +//
 222.451 +//            for (Entry<String, Collection<TreePath>> e : occurringPatterns.entrySet()) {
 222.452 +//                for (Iterator<TreePath> it = e.getValue().iterator(); it.hasNext(); ) {
 222.453 +//                    if (!acceptedLeafs.contains(it.next().getLeaf())) {
 222.454 +//                        it.remove();
 222.455 +//                    }
 222.456 +//                }
 222.457 +//            }
 222.458 +//
 222.459 +//            timeLog.put("Bulk Search", bulkEnd - bulkStart);
 222.460 +
 222.461 +            Map<HintDescription, List<ErrorDescription>> computed = doComputeHints(info, occurringPatterns, patternTests, patternHints, problems);
 222.462 +            
 222.463 +            if (computed == null || cancel.get()) return null;
 222.464 +            
 222.465 +            mergeAll(errors, computed);
 222.466 +
 222.467 +            long patternEnd = System.currentTimeMillis();
 222.468 +
 222.469 +            timeLog.put("Pattern Based Hints", patternEnd - patternStart);
 222.470 +        }
 222.471 +
 222.472 +        return errors;
 222.473 +    }
 222.474 +
 222.475 +    public Map<HintDescription, List<ErrorDescription>> doComputeHints(CompilationInfo info, Map<String, Collection<TreePath>> occurringPatterns, Map<String, List<PatternDescription>> patterns, Map<PatternDescription, List<HintDescription>> patternHints) throws IllegalStateException {
 222.476 +        return doComputeHints(info, occurringPatterns, patterns, patternHints, new LinkedList<MessageImpl>());
 222.477 +    }
 222.478 +
 222.479 +    private static Map<Kind, List<HintDescription>> sortByKinds(List<HintDescription> kindBasedHints) {
 222.480 +        Map<Kind, List<HintDescription>> result = new EnumMap<Kind, List<HintDescription>>(Kind.class);
 222.481 +
 222.482 +        for (HintDescription hd : kindBasedHints) {
 222.483 +            for (Kind k : ((Kinds) hd.getTrigger()).getKinds()) {
 222.484 +                List<HintDescription> hints = result.get(k);
 222.485 +
 222.486 +                if (hints == null) {
 222.487 +                    result.put(k, hints = new ArrayList<HintDescription>());
 222.488 +                }
 222.489 +
 222.490 +                hints.add(hd);
 222.491 +            }
 222.492 +        }
 222.493 +
 222.494 +        return result;
 222.495 +    }
 222.496 +
 222.497 +    private static Map<PatternDescription, List<HintDescription>> sortByPatterns(List<HintDescription> kindBasedHints) {
 222.498 +        Map<PatternDescription, List<HintDescription>> result = new HashMap<PatternDescription, List<HintDescription>>();
 222.499 +
 222.500 +        for (HintDescription hd : kindBasedHints) {
 222.501 +            List<HintDescription> hints = result.get((PatternDescription) hd.getTrigger());
 222.502 +
 222.503 +            if (hints == null) {
 222.504 +                result.put((PatternDescription) hd.getTrigger(), hints = new ArrayList<HintDescription>());
 222.505 +            }
 222.506 +
 222.507 +            hints.add(hd);
 222.508 +        }
 222.509 +
 222.510 +        return result;
 222.511 +    }
 222.512 +
 222.513 +    public static Map<String, List<PatternDescription>> computePatternTests(Map<PatternDescription, List<HintDescription>> patternHints) {
 222.514 +        Map<String, List<PatternDescription>> patternTests = new HashMap<String, List<PatternDescription>>();
 222.515 +        for (Entry<PatternDescription, List<HintDescription>> e : patternHints.entrySet()) {
 222.516 +            String p = e.getKey().getPattern();
 222.517 +            List<PatternDescription> descs = patternTests.get(p);
 222.518 +            if (descs == null) {
 222.519 +                patternTests.put(p, descs = new LinkedList<PatternDescription>());
 222.520 +            }
 222.521 +            descs.add(e.getKey());
 222.522 +        }
 222.523 +        return patternTests;
 222.524 +    }
 222.525 +
 222.526 +    private Map<HintDescription, List<ErrorDescription>> doComputeHints(CompilationInfo info, Map<String, Collection<TreePath>> occurringPatterns, Map<String, List<PatternDescription>> patterns, Map<PatternDescription, List<HintDescription>> patternHints, Collection<? super MessageImpl> problems) throws IllegalStateException {
 222.527 +        Map<HintDescription, List<ErrorDescription>> errors = new HashMap<HintDescription, List<ErrorDescription>>();
 222.528 +
 222.529 +        for (Entry<String, Collection<TreePath>> occ : occurringPatterns.entrySet()) {
 222.530 +            PATTERN_LOOP: for (PatternDescription d : patterns.get(occ.getKey())) {
 222.531 +                if (cancel.get()) return null;
 222.532 +                
 222.533 +                Map<String, TypeMirror> constraints = new HashMap<String, TypeMirror>();
 222.534 +
 222.535 +                for (Entry<String, String> e : d.getConstraints().entrySet()) {
 222.536 +                    TypeMirror designedType = Hacks.parseFQNType(info, e.getValue());
 222.537 +
 222.538 +                    if (designedType == null || designedType.getKind() == TypeKind.ERROR) {
 222.539 +                        //will not bind to anything anyway (#190449), skip pattern:
 222.540 +                        continue PATTERN_LOOP;
 222.541 +                    }
 222.542 +
 222.543 +                    constraints.put(e.getKey(), designedType);
 222.544 +                }
 222.545 +
 222.546 +                Pattern pattern = PatternCompiler.compile(info, occ.getKey(), constraints, d.getImports());
 222.547 +
 222.548 +                for (TreePath candidate : occ.getValue()) {
 222.549 +                    if (cancel.get()) return null;
 222.550 +                
 222.551 +                    Iterator<? extends Occurrence> verified = Matcher.create(info).setCancel(cancel).setSearchRoot(candidate).setTreeTopSearch().match(pattern).iterator();
 222.552 +
 222.553 +                    if (!verified.hasNext()) {
 222.554 +                        continue;
 222.555 +                    }
 222.556 +
 222.557 +                    Set<String> suppressedWarnings = new HashSet<String>(Utilities.findSuppressedWarnings(info, candidate));
 222.558 +                    Occurrence verifiedVariables = verified.next();
 222.559 +
 222.560 +                    for (HintDescription hd : patternHints.get(d)) {
 222.561 +                        HintMetadata hm = hd.getMetadata();
 222.562 +                        HintContext c = SPIAccessor.getINSTANCE().createHintContext(info, settings, hm, globalContext != null ? globalContext : new GlobalProcessingContext(), candidate, verifiedVariables.getVariables(), verifiedVariables.getMultiVariables(), verifiedVariables.getVariables2Names(), constraints, problems, globalContext != null, cancel, caret);
 222.563 +
 222.564 +                        if (!Collections.disjoint(suppressedWarnings, hm.suppressWarnings))
 222.565 +                            continue;
 222.566 +
 222.567 +                        Collection<? extends ErrorDescription> workerErrors = runHint(hd, c);
 222.568 +
 222.569 +                        if (workerErrors != null) {
 222.570 +                            merge(errors, hd, workerErrors);
 222.571 +                        }
 222.572 +                    }
 222.573 +                }
 222.574 +            }
 222.575 +        }
 222.576 +
 222.577 +        return errors;
 222.578 +    }
 222.579 +
 222.580 +//    public static void computeHints(URI file, ProcessingEnvironment env, CompilationUnitTree cut, RulesManager m) {
 222.581 +//        Map<Kind, HintDescription> hints = m.getKindBasedHints();
 222.582 +//
 222.583 +//        if (hints.isEmpty()) {
 222.584 +//            return ;
 222.585 +//        }
 222.586 +//
 222.587 +//        List<ErrorDescription> errors = new  LinkedList<ErrorDescription>();
 222.588 +//
 222.589 +//        File af = new File(file.getPath());
 222.590 +//        FileObject f = FileUtil.toFileObject(af);
 222.591 +//
 222.592 +//        new ScannerImpl(f, env, hints).scan(cut, errors);
 222.593 +//
 222.594 +//        for (ErrorDescription ed : errors) {
 222.595 +//            Diagnostic.Kind k;
 222.596 +//
 222.597 +//            switch (ed.getSeverity()) {
 222.598 +//                case ERROR:
 222.599 +//                    k = Diagnostic.Kind.ERROR;
 222.600 +//                    break;
 222.601 +//                default:
 222.602 +//                    k = Diagnostic.Kind.WARNING;
 222.603 +//                    break;
 222.604 +//            }
 222.605 +//
 222.606 +//            env.getMessager().printMessage(k, ed.getDescription());
 222.607 +//        }
 222.608 +//    }
 222.609 +
 222.610 +    public Map<String, Long> getTimeLog() {
 222.611 +        return timeLog;
 222.612 +    }
 222.613 +
 222.614 +    private final class ScannerImpl extends CancellableTreePathScanner<Void, Map<HintDescription, List<ErrorDescription>>> {
 222.615 +
 222.616 +        private final Stack<Set<String>> suppresWarnings = new Stack<Set<String>>();
 222.617 +        private final CompilationInfo info;
 222.618 +        private final FileObject file;
 222.619 +        private final ProcessingEnvironment env;
 222.620 +        private final Map<Kind, List<HintDescription>> hints;
 222.621 +        private final Collection<? super MessageImpl> problems;
 222.622 +        
 222.623 +        public ScannerImpl(CompilationInfo info, AtomicBoolean cancel, Map<Kind, List<HintDescription>> hints, Collection<? super MessageImpl> problems) {
 222.624 +            super(cancel);
 222.625 +            this.info = info;
 222.626 +            this.file = null;
 222.627 +            this.env  = null;
 222.628 +            this.hints = hints;
 222.629 +            this.problems = problems;
 222.630 +        }
 222.631 +
 222.632 +        public ScannerImpl(FileObject file, ProcessingEnvironment env, Map<Kind, List<HintDescription>> hints, Collection<? super MessageImpl> problems) {
 222.633 +            super(new AtomicBoolean());
 222.634 +            this.info = null;
 222.635 +            this.file = file;
 222.636 +            this.env = env;
 222.637 +            this.hints = hints;
 222.638 +            this.problems = problems;
 222.639 +        }
 222.640 +
 222.641 +        private void runAndAdd(TreePath path, List<HintDescription> rules, Map<HintDescription, List<ErrorDescription>> d) {
 222.642 +            if (rules != null && !isInGuarded(info, path)) {
 222.643 +                OUTER: for (HintDescription hd : rules) {
 222.644 +                    if (isCanceled()) {
 222.645 +                        return ;
 222.646 +                    }
 222.647 +
 222.648 +                    HintMetadata hm = hd.getMetadata();
 222.649 +
 222.650 +                    for (String wname : hm.suppressWarnings) {
 222.651 +                        if( !suppresWarnings.empty() && suppresWarnings.peek().contains(wname)) {
 222.652 +                            continue OUTER;
 222.653 +                        }
 222.654 +                    }
 222.655 +
 222.656 +                    HintContext c = SPIAccessor.getINSTANCE().createHintContext(info, settings, hm, globalContext != null ? globalContext : new GlobalProcessingContext(), path, Collections.<String, TreePath>emptyMap(), Collections.<String, Collection<? extends TreePath>>emptyMap(), Collections.<String, String>emptyMap(), Collections.<String, TypeMirror>emptyMap(), new ArrayList<MessageImpl>(), globalContext != null, cancel, caret);
 222.657 +                    Collection<? extends ErrorDescription> errors = runHint(hd, c);
 222.658 +
 222.659 +                    if (errors != null) {
 222.660 +                        merge(d, hd, errors);
 222.661 +                    }
 222.662 +                }
 222.663 +            }
 222.664 +        }
 222.665 +
 222.666 +        @Override
 222.667 +        public Void scan(Tree tree, Map<HintDescription, List<ErrorDescription>> p) {
 222.668 +            if (tree == null)
 222.669 +                return null;
 222.670 +
 222.671 +            TreePath tp = new TreePath(getCurrentPath(), tree);
 222.672 +            Kind k = tree.getKind();
 222.673 +
 222.674 +            boolean b = pushSuppressWarrnings(tp);
 222.675 +            try {
 222.676 +                runAndAdd(tp, hints.get(k), p);
 222.677 +
 222.678 +                if (isCanceled()) {
 222.679 +                    return null;
 222.680 +                }
 222.681 +
 222.682 +                return super.scan(tree, p);
 222.683 +            } finally {
 222.684 +                if (b) {
 222.685 +                    suppresWarnings.pop();
 222.686 +                }
 222.687 +            }
 222.688 +        }
 222.689 +
 222.690 +        @Override
 222.691 +        public Void scan(TreePath path, Map<HintDescription, List<ErrorDescription>> p) {
 222.692 +            Kind k = path.getLeaf().getKind();
 222.693 +            boolean b = pushSuppressWarrnings(path);
 222.694 +            try {
 222.695 +                runAndAdd(path, hints.get(k), p);
 222.696 +
 222.697 +                if (isCanceled()) {
 222.698 +                    return null;
 222.699 +                }
 222.700 +
 222.701 +                return super.scan(path, p);
 222.702 +            } finally {
 222.703 +                if (b) {
 222.704 +                    suppresWarnings.pop();
 222.705 +                }
 222.706 +            }
 222.707 +        }
 222.708 +
 222.709 +        public void scanDoNotGoDeeper(TreePath path, Map<HintDescription, List<ErrorDescription>> p) {
 222.710 +            Kind k = path.getLeaf().getKind();
 222.711 +            runAndAdd(path, hints.get(k), p);
 222.712 +        }
 222.713 +
 222.714 +        private boolean pushSuppressWarrnings(TreePath path) {
 222.715 +            switch(path.getLeaf().getKind()) {
 222.716 +                case ANNOTATION_TYPE:
 222.717 +                case CLASS:
 222.718 +                case ENUM:
 222.719 +                case INTERFACE:
 222.720 +                case METHOD:
 222.721 +                case VARIABLE:
 222.722 +                    Set<String> current = suppresWarnings.size() == 0 ? null : suppresWarnings.peek();
 222.723 +                    Set<String> nju = current == null ? new HashSet<String>() : new HashSet<String>(current);
 222.724 +
 222.725 +                    Element e = getTrees().getElement(path);
 222.726 +
 222.727 +                    if ( e != null) {
 222.728 +                        for (AnnotationMirror am : e.getAnnotationMirrors()) {
 222.729 +                            String name = ((TypeElement)am.getAnnotationType().asElement()).getQualifiedName().toString();
 222.730 +                            if ( "java.lang.SuppressWarnings".equals(name) ) { // NOI18N
 222.731 +                                Map<? extends ExecutableElement, ? extends AnnotationValue> elementValues = am.getElementValues();
 222.732 +                                for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : elementValues.entrySet()) {
 222.733 +                                    if( "value".equals(entry.getKey().getSimpleName().toString()) ) { // NOI18N
 222.734 +                                        Object value = entry.getValue().getValue();
 222.735 +                                        if ( value instanceof List) {
 222.736 +                                            for (Object av : (List)value) {
 222.737 +                                                if( av instanceof AnnotationValue ) {
 222.738 +                                                    Object wname = ((AnnotationValue)av).getValue();
 222.739 +                                                    if ( wname instanceof String ) {
 222.740 +                                                        nju.add((String)wname);
 222.741 +                                                    }
 222.742 +                                                }
 222.743 +                                            }
 222.744 +                                        }
 222.745 +                                    }
 222.746 +                                }
 222.747 +                            }
 222.748 +                        }
 222.749 +                    }
 222.750 +
 222.751 +                    suppresWarnings.push(nju);
 222.752 +                    return true;
 222.753 +            }
 222.754 +            return false;
 222.755 +        }
 222.756 +
 222.757 +        private Trees getTrees() {
 222.758 +            return info != null ? info.getTrees() : Trees.instance(env);
 222.759 +        }
 222.760 +    }
 222.761 +
 222.762 +    static boolean isInGuarded(CompilationInfo info, TreePath tree) {
 222.763 +        if (info == null) {
 222.764 +            return false;
 222.765 +        }
 222.766 +
 222.767 +        try {
 222.768 +            Document doc = info.getDocument();
 222.769 +
 222.770 +            if (doc instanceof GuardedDocument) {
 222.771 +                int start = (int) info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), tree.getLeaf());
 222.772 +                int end = (int) info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), tree.getLeaf());
 222.773 +                GuardedDocument gdoc = (GuardedDocument) doc;
 222.774 +                MarkBlockChain guardedBlockChain = gdoc.getGuardedBlockChain();
 222.775 +                if (guardedBlockChain.compareBlock(start, end) == MarkBlock.INNER) {
 222.776 +                    return true;
 222.777 +                }
 222.778 +            }
 222.779 +        } catch (IOException ex) {
 222.780 +            Exceptions.printStackTrace(ex);
 222.781 +        }
 222.782 +
 222.783 +        return false;
 222.784 +    }
 222.785 +
 222.786 +    private Collection<? extends ErrorDescription> runHint(HintDescription hd, HintContext ctx) {
 222.787 +        long start = System.nanoTime();
 222.788 +
 222.789 +        try {
 222.790 +            return hd.getWorker().createErrors(ctx);
 222.791 +        } finally {
 222.792 +            long end = System.nanoTime();
 222.793 +            reportSpentTime(hd.getMetadata().id, end - start);
 222.794 +        }
 222.795 +    }
 222.796 +
 222.797 +    public static <K, V> Map<K, List<V>> merge(Map<K, List<V>> to, K key, Collection<? extends V> value) {
 222.798 +        List<V> toColl = to.get(key);
 222.799 +
 222.800 +        if (toColl == null) {
 222.801 +            to.put(key, toColl = new LinkedList<V>());
 222.802 +        }
 222.803 +
 222.804 +        toColl.addAll(value);
 222.805 +
 222.806 +        return to;
 222.807 +    }
 222.808 +
 222.809 +    public static <K, V> Map<K, List<V>> mergeAll(Map<K, List<V>> to, Map<? extends K, ? extends Collection<? extends V>> what) {
 222.810 +        for (Entry<? extends K, ? extends Collection<? extends V>> e : what.entrySet()) {
 222.811 +            List<V> toColl = to.get(e.getKey());
 222.812 +
 222.813 +            if (toColl == null) {
 222.814 +                to.put(e.getKey(), toColl = new LinkedList<V>());
 222.815 +            }
 222.816 +
 222.817 +            toColl.addAll(e.getValue());
 222.818 +        }
 222.819 +
 222.820 +        return to;
 222.821 +    }
 222.822 +
 222.823 +    public static List<ErrorDescription> join(Map<?, ? extends List<? extends ErrorDescription>> errors) {
 222.824 +        if (errors == null) return null;
 222.825 +        
 222.826 +        List<ErrorDescription> result = new LinkedList<ErrorDescription>();
 222.827 +
 222.828 +        for (Entry<?, ? extends Collection<? extends ErrorDescription>> e : errors.entrySet()) {
 222.829 +            result.addAll(e.getValue());
 222.830 +        }
 222.831 +
 222.832 +        return result;
 222.833 +    }
 222.834 +
 222.835 +    private static final boolean logTimeSpentInHints = Boolean.getBoolean("java.HintsInvoker.time.in.hints");
 222.836 +    private final Map<String, Long> hint2SpentTime = new HashMap<String, Long>();
 222.837 +
 222.838 +    private void reportSpentTime(String id, long nanoTime) {
 222.839 +        if (!logTimeSpentInHints) return;
 222.840 +        
 222.841 +        Long prev = hint2SpentTime.get(id);
 222.842 +
 222.843 +        if (prev == null) {
 222.844 +            prev = (long) 0;
 222.845 +        }
 222.846 +
 222.847 +        hint2SpentTime.put(id, prev + nanoTime);
 222.848 +    }
 222.849 +
 222.850 +    private void dumpTimeSpentInHints() {
 222.851 +        if (!logTimeSpentInHints) return;
 222.852 +
 222.853 +        List<Entry<String, Long>> l = new ArrayList<Entry<String, Long>>(hint2SpentTime.entrySet());
 222.854 +
 222.855 +        Collections.sort(l, new Comparator<Entry<String, Long>>() {
 222.856 +            @Override
 222.857 +            public int compare(Entry<String, Long> o1, Entry<String, Long> o2) {
 222.858 +                return (int) Math.signum(o1.getValue() - o2.getValue());
 222.859 +            }
 222.860 +        });
 222.861 +
 222.862 +        for (Entry<String, Long> e : l) {
 222.863 +            System.err.println(e.getKey() + "=" + String.format("%3.2f", e.getValue() / 1000000.0));
 222.864 +        }
 222.865 +    }
 222.866 +}
   223.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   223.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/hints/HintsTask.java	Sun Oct 23 11:50:54 2016 +0200
   223.3 @@ -0,0 +1,254 @@
   223.4 +/*
   223.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   223.6 + *
   223.7 + * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
   223.8 + *
   223.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  223.10 + * Other names may be trademarks of their respective owners.
  223.11 + *
  223.12 + * The contents of this file are subject to the terms of either the GNU
  223.13 + * General Public License Version 2 only ("GPL") or the Common
  223.14 + * Development and Distribution License("CDDL") (collectively, the
  223.15 + * "License"). You may not use this file except in compliance with the
  223.16 + * License. You can obtain a copy of the License at
  223.17 + * http://www.netbeans.org/cddl-gplv2.html
  223.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  223.19 + * specific language governing permissions and limitations under the
  223.20 + * License.  When distributing the software, include this License Header
  223.21 + * Notice in each file and include the License file at
  223.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  223.23 + * particular file as subject to the "Classpath" exception as provided
  223.24 + * by Oracle in the GPL Version 2 section of the License file that
  223.25 + * accompanied this code. If applicable, add the following below the
  223.26 + * License Header, with the fields enclosed by brackets [] replaced by
  223.27 + * your own identifying information:
  223.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  223.29 + *
  223.30 + * If you wish your version of this file to be governed by only the CDDL
  223.31 + * or only the GPL Version 2, indicate your decision by adding
  223.32 + * "[Contributor] elects to include this software in this distribution
  223.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  223.34 + * single choice of license, a recipient has the option to distribute
  223.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  223.36 + * to extend the choice of license to its licensees as provided above.
  223.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  223.38 + * Version 2 license, then the option applies only if the new code is
  223.39 + * made subject to such option by the copyright holder.
  223.40 + *
  223.41 + * Contributor(s):
  223.42 + *
  223.43 + * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
  223.44 + */
  223.45 +
  223.46 +package org.netbeans.modules.java.hints.spiimpl.hints;
  223.47 +
  223.48 +import java.util.List;
  223.49 +import java.util.Map.Entry;
  223.50 +import java.util.concurrent.atomic.AtomicBoolean;
  223.51 +import java.util.logging.Level;
  223.52 +import java.util.logging.Logger;
  223.53 +import javax.swing.event.ChangeEvent;
  223.54 +import javax.swing.event.ChangeListener;
  223.55 +import javax.swing.text.BadLocationException;
  223.56 +import javax.swing.text.Document;
  223.57 +import org.netbeans.api.editor.mimelookup.MimeLookup;
  223.58 +import org.netbeans.api.editor.mimelookup.MimeRegistration;
  223.59 +import org.netbeans.api.java.source.CancellableTask;
  223.60 +import org.netbeans.api.java.source.CompilationInfo;
  223.61 +import org.netbeans.api.java.source.JavaSource.Phase;
  223.62 +import org.netbeans.api.java.source.JavaSource.Priority;
  223.63 +import org.netbeans.api.java.source.JavaSourceTaskFactory;
  223.64 +import org.netbeans.api.java.source.support.CaretAwareJavaSourceTaskFactory;
  223.65 +import org.netbeans.api.java.source.support.EditorAwareJavaSourceTaskFactory;
  223.66 +import org.netbeans.editor.BaseDocument;
  223.67 +import org.netbeans.editor.Utilities;
  223.68 +import org.netbeans.lib.editor.util.swing.DocumentUtilities;
  223.69 +import org.netbeans.modules.java.hints.providers.spi.PositionRefresherHelper;
  223.70 +import org.netbeans.modules.java.hints.providers.spi.PositionRefresherHelper.DocumentVersion;
  223.71 +import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings;
  223.72 +import org.netbeans.modules.parsing.spi.TaskIndexingMode;
  223.73 +import org.netbeans.spi.editor.hints.Context;
  223.74 +import org.netbeans.spi.editor.hints.ErrorDescription;
  223.75 +import org.netbeans.spi.editor.hints.HintsController;
  223.76 +import org.netbeans.spi.editor.hints.Severity;
  223.77 +import org.netbeans.spi.editor.hints.settings.FileHintPreferences;
  223.78 +import org.openide.filesystems.FileObject;
  223.79 +import org.openide.util.WeakListeners;
  223.80 +import org.openide.util.lookup.ServiceProvider;
  223.81 +
  223.82 +/**
  223.83 + *
  223.84 + * @author lahvac
  223.85 + */
  223.86 +public class HintsTask implements CancellableTask<CompilationInfo> {
  223.87 +
  223.88 +    public static final String KEY_HINTS = HintsInvoker.class.getName() + "-hints";
  223.89 +    public static final String KEY_SUGGESTIONS = HintsInvoker.class.getName() + "-suggestions";
  223.90 +
  223.91 +    private static final Logger TIMER = Logger.getLogger("TIMER");
  223.92 +    private static final Logger TIMER_EDITOR = Logger.getLogger("TIMER.editor");
  223.93 +    private static final Logger TIMER_CARET = Logger.getLogger("TIMER.caret");
  223.94 +
  223.95 +    private final AtomicBoolean cancel = new AtomicBoolean();
  223.96 +
  223.97 +    private final boolean caretAware;
  223.98 +
  223.99 +    public HintsTask(boolean caretAware) {
 223.100 +        this.caretAware = caretAware;
 223.101 +    }
 223.102 +    
 223.103 +    public void run(CompilationInfo info) {
 223.104 +        cancel.set(false);
 223.105 +
 223.106 +        if (org.netbeans.modules.java.hints.spiimpl.Utilities.disableErrors(info.getFileObject()).contains(Severity.VERIFIER)) {
 223.107 +            return;
 223.108 +        }
 223.109 +
 223.110 +        Document doc = info.getSnapshot().getSource().getDocument(false);
 223.111 +        long version = doc != null ? DocumentUtilities.getDocumentVersion(doc) : 0;
 223.112 +        long startTime = System.currentTimeMillis();
 223.113 +
 223.114 +        int caret = CaretAwareJavaSourceTaskFactory.getLastPosition(info.getFileObject());
 223.115 +        HintsSettings settings = HintsSettings.getSettingsFor(info.getFileObject());
 223.116 +        HintsInvoker inv = caretAware ? new HintsInvoker(settings, caret, cancel) : new HintsInvoker(settings, cancel);
 223.117 +        List<ErrorDescription> result = inv.computeHints(info);
 223.118 +
 223.119 +        if (result == null || cancel.get()) {
 223.120 +            return;
 223.121 +        }
 223.122 +
 223.123 +        HintsController.setErrors(info.getFileObject(), caretAware ? KEY_SUGGESTIONS : KEY_HINTS, result);
 223.124 +
 223.125 +        if (caretAware) {
 223.126 +            SuggestionsPositionRefresherHelper.setVersion(doc, caret);
 223.127 +        } else {
 223.128 +            HintPositionRefresherHelper.setVersion(doc);
 223.129 +        }
 223.130 +
 223.131 +        long endTime = System.currentTimeMillis();
 223.132 +        
 223.133 +        TIMER.log(Level.FINE, "Jackpot 3.0 Hints Task" + (caretAware ? " - Caret Aware" : ""), new Object[] {info.getFileObject(), endTime - startTime});
 223.134 +
 223.135 +        Logger l = caretAware ? TIMER_CARET : TIMER_EDITOR;
 223.136 +
 223.137 +        for (Entry<String, Long> e : inv.getTimeLog().entrySet()) {
 223.138 +            l.log(Level.FINE, e.getKey(), new Object[] {info.getFileObject(), e.getValue()});
 223.139 +        }
 223.140 +    }
 223.141 +
 223.142 +    public void cancel() {
 223.143 +        cancel.set(true);
 223.144 +    }
 223.145 +
 223.146 +
 223.147 +    @ServiceProvider(service=JavaSourceTaskFactory.class)
 223.148 +    public static final class FactoryImpl extends EditorAwareJavaSourceTaskFactory implements ChangeListener {
 223.149 +
 223.150 +        public FactoryImpl() {
 223.151 +            super(Phase.RESOLVED, Priority.LOW, TaskIndexingMode.ALLOWED_DURING_SCAN);
 223.152 +            FileHintPreferences.addChangeListener(WeakListeners.change(this, HintsSettings.class));
 223.153 +        }
 223.154 +
 223.155 +        @Override
 223.156 +        protected CancellableTask<CompilationInfo> createTask(FileObject file) {
 223.157 +            return new HintsTask(false);
 223.158 +        }
 223.159 +
 223.160 +	@Override
 223.161 +	public void stateChanged(ChangeEvent e) {
 223.162 +	    for (FileObject file : getFileObjects()) {
 223.163 +		reschedule(file);
 223.164 +	    }
 223.165 +	}
 223.166 +        
 223.167 +    }
 223.168 +
 223.169 +    @ServiceProvider(service=JavaSourceTaskFactory.class)
 223.170 +    public static final class CaretFactoryImpl extends CaretAwareJavaSourceTaskFactory implements ChangeListener {
 223.171 +
 223.172 +        public CaretFactoryImpl() {
 223.173 +            super(Phase.RESOLVED, Priority.LOW);
 223.174 +            FileHintPreferences.addChangeListener(WeakListeners.change(this, HintsSettings.class));
 223.175 +        }
 223.176 +
 223.177 +        @Override
 223.178 +        protected CancellableTask<CompilationInfo> createTask(FileObject file) {
 223.179 +            return new HintsTask(true);
 223.180 +        }
 223.181 +
 223.182 +	@Override
 223.183 +	public void stateChanged(ChangeEvent e) {
 223.184 +	    for (FileObject file : getFileObjects()) {
 223.185 +		reschedule(file);
 223.186 +	    }
 223.187 +	}
 223.188 +
 223.189 +    }
 223.190 +
 223.191 +    @MimeRegistration(mimeType="text/x-java", service=PositionRefresherHelper.class)
 223.192 +    public static final class HintPositionRefresherHelper extends PositionRefresherHelper<DocumentVersion> {
 223.193 +
 223.194 +        public HintPositionRefresherHelper() {
 223.195 +            super(KEY_HINTS);
 223.196 +        }
 223.197 +
 223.198 +        @Override
 223.199 +        protected boolean isUpToDate(Context context, Document doc, DocumentVersion oldVersion) {
 223.200 +            return true;
 223.201 +        }
 223.202 +
 223.203 +        @Override
 223.204 +        public List<ErrorDescription> getErrorDescriptionsAt(CompilationInfo info, Context context, Document doc) throws BadLocationException {
 223.205 +            int rowStart = Utilities.getRowStart((BaseDocument) doc, context.getPosition());
 223.206 +            int rowEnd = Utilities.getRowEnd((BaseDocument) doc, context.getPosition());
 223.207 +
 223.208 +            return new HintsInvoker(HintsSettings.getSettingsFor(info.getFileObject()), rowStart, rowEnd, context.getCancel()).computeHints(info);
 223.209 +        }
 223.210 +
 223.211 +        private static void setVersion(Document doc) {
 223.212 +            for (PositionRefresherHelper h : MimeLookup.getLookup("text/x-java").lookupAll(PositionRefresherHelper.class)) {
 223.213 +                if (h instanceof HintPositionRefresherHelper) {
 223.214 +                    ((HintPositionRefresherHelper) h).setVersion(doc, new DocumentVersion(doc));
 223.215 +                }
 223.216 +            }
 223.217 +        }
 223.218 +
 223.219 +    }
 223.220 +
 223.221 +    @MimeRegistration(mimeType="text/x-java", service=PositionRefresherHelper.class)
 223.222 +    public static final class SuggestionsPositionRefresherHelper extends PositionRefresherHelper<SuggestionsDocumentVersion> {
 223.223 +
 223.224 +        public SuggestionsPositionRefresherHelper() {
 223.225 +            super(KEY_SUGGESTIONS);
 223.226 +        }
 223.227 +
 223.228 +        @Override
 223.229 +        protected boolean isUpToDate(Context context, Document doc, SuggestionsDocumentVersion oldVersion) {
 223.230 +            return oldVersion.suggestionsCaret == context.getPosition();
 223.231 +        }
 223.232 +
 223.233 +        @Override
 223.234 +        public List<ErrorDescription> getErrorDescriptionsAt(CompilationInfo info, Context context, Document doc) throws BadLocationException {
 223.235 +            return new HintsInvoker(HintsSettings.getSettingsFor(info.getFileObject()), context.getPosition(), context.getCancel()).computeHints(info);
 223.236 +        }
 223.237 +
 223.238 +        private static void setVersion(Document doc, int caret) {
 223.239 +            for (PositionRefresherHelper h : MimeLookup.getLookup("text/x-java").lookupAll(PositionRefresherHelper.class)) {
 223.240 +                if (h instanceof SuggestionsPositionRefresherHelper) {
 223.241 +                    ((SuggestionsPositionRefresherHelper) h).setVersion(doc, new SuggestionsDocumentVersion(doc, caret));
 223.242 +                }
 223.243 +            }
 223.244 +        }
 223.245 +    }
 223.246 +
 223.247 +    private static class SuggestionsDocumentVersion extends DocumentVersion {
 223.248 +
 223.249 +        private final int suggestionsCaret;
 223.250 +        
 223.251 +        public SuggestionsDocumentVersion(Document doc, int suggestionsCaret) {
 223.252 +            super(doc);
 223.253 +            this.suggestionsCaret = suggestionsCaret;
 223.254 +        }
 223.255 +    }
 223.256 +
 223.257 +}
   224.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   224.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/ipi/upgrade/ProjectDependencyUpgrader.java	Sun Oct 23 11:50:54 2016 +0200
   224.3 @@ -0,0 +1,64 @@
   224.4 +/*
   224.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   224.6 + *
   224.7 + * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
   224.8 + *
   224.9 + * The contents of this file are subject to the terms of either the GNU
  224.10 + * General Public License Version 2 only ("GPL") or the Common
  224.11 + * Development and Distribution License("CDDL") (collectively, the
  224.12 + * "License"). You may not use this file except in compliance with the
  224.13 + * License. You can obtain a copy of the License at
  224.14 + * http://www.netbeans.org/cddl-gplv2.html
  224.15 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  224.16 + * specific language governing permissions and limitations under the
  224.17 + * License.  When distributing the software, include this License Header
  224.18 + * Notice in each file and include the License file at
  224.19 + * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
  224.20 + * particular file as subject to the "Classpath" exception as provided
  224.21 + * by Sun in the GPL Version 2 section of the License file that
  224.22 + * accompanied this code. If applicable, add the following below the
  224.23 + * License Header, with the fields enclosed by brackets [] replaced by
  224.24 + * your own identifying information:
  224.25 + * "Portions Copyrighted [year] [name of copyright owner]"
  224.26 + *
  224.27 + * If you wish your version of this file to be governed by only the CDDL
  224.28 + * or only the GPL Version 2, indicate your decision by adding
  224.29 + * "[Contributor] elects to include this software in this distribution
  224.30 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  224.31 + * single choice of license, a recipient has the option to distribute
  224.32 + * your version of this file under either the CDDL, the GPL Version 2 or
  224.33 + * to extend the choice of license to its licensees as provided above.
  224.34 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  224.35 + * Version 2 license, then the option applies only if the new code is
  224.36 + * made subject to such option by the copyright holder.
  224.37 + *
  224.38 + * Contributor(s):
  224.39 + *
  224.40 + * Portions Copyrighted 2010 Sun Microsystems, Inc.
  224.41 + */
  224.42 +package org.netbeans.modules.java.hints.spiimpl.ipi.upgrade;
  224.43 +
  224.44 +import org.netbeans.api.project.Project;
  224.45 +import org.openide.DialogDisplayer;
  224.46 +import org.openide.NotifyDescriptor;
  224.47 +import org.openide.filesystems.FileObject;
  224.48 +import org.openide.modules.SpecificationVersion;
  224.49 +
  224.50 +/**
  224.51 + *
  224.52 + * @author lahvac
  224.53 + */
  224.54 +public abstract class ProjectDependencyUpgrader {
  224.55 +
  224.56 +    public abstract boolean ensureDependency(Project p, FileObject dep, SpecificationVersion spec, boolean canShowUI);
  224.57 +    public abstract boolean ensureDependency(Project p, String specification, boolean b);
  224.58 +
  224.59 +    protected final boolean showDependencyUpgradeDialog(Project p, String dep, SpecificationVersion currentDependency, SpecificationVersion spec, boolean newDepenency, boolean canShowUI) {
  224.60 +        if (!canShowUI) return true;
  224.61 +        
  224.62 +        NotifyDescriptor nd = new NotifyDescriptor.Confirmation("New version: " + spec, "Update spec version.", NotifyDescriptor.YES_NO_OPTION);
  224.63 +
  224.64 +        return DialogDisplayer.getDefault().notify(nd) == NotifyDescriptor.YES_OPTION;
  224.65 +    }
  224.66 +
  224.67 +}
   225.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   225.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/options/HintsSettings.java	Sun Oct 23 11:50:54 2016 +0200
   225.3 @@ -0,0 +1,149 @@
   225.4 +/*
   225.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   225.6 + *
   225.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
   225.8 + *
   225.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  225.10 + * Other names may be trademarks of their respective owners.
  225.11 + *
  225.12 + * The contents of this file are subject to the terms of either the GNU
  225.13 + * General Public License Version 2 only ("GPL") or the Common
  225.14 + * Development and Distribution License("CDDL") (collectively, the
  225.15 + * "License"). You may not use this file except in compliance with the
  225.16 + * License. You can obtain a copy of the License at
  225.17 + * http://www.netbeans.org/cddl-gplv2.html
  225.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  225.19 + * specific language governing permissions and limitations under the
  225.20 + * License.  When distributing the software, include this License Header
  225.21 + * Notice in each file and include the License file at
  225.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  225.23 + * particular file as subject to the "Classpath" exception as provided
  225.24 + * by Oracle in the GPL Version 2 section of the License file that
  225.25 + * accompanied this code. If applicable, add the following below the
  225.26 + * License Header, with the fields enclosed by brackets [] replaced by
  225.27 + * your own identifying information:
  225.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  225.29 + *
  225.30 + * Contributor(s):
  225.31 + *
  225.32 + * The Original Software is NetBeans. The Initial Developer of the Original
  225.33 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2010 Sun
  225.34 + * Microsystems, Inc. All Rights Reserved.
  225.35 + *
  225.36 + * If you wish your version of this file to be governed by only the CDDL
  225.37 + * or only the GPL Version 2, indicate your decision by adding
  225.38 + * "[Contributor] elects to include this software in this distribution
  225.39 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  225.40 + * single choice of license, a recipient has the option to distribute
  225.41 + * your version of this file under either the CDDL, the GPL Version 2 or
  225.42 + * to extend the choice of license to its licensees as provided above.
  225.43 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  225.44 + * Version 2 license, then the option applies only if the new code is
  225.45 + * made subject to such option by the copyright holder.
  225.46 + */
  225.47 +package org.netbeans.modules.java.hints.spiimpl.options;
  225.48 +
  225.49 +import java.util.prefs.Preferences;
  225.50 +import org.netbeans.api.editor.mimelookup.MimeRegistration;
  225.51 +import org.netbeans.modules.java.hints.providers.spi.HintMetadata;
  225.52 +import org.netbeans.spi.editor.hints.Severity;
  225.53 +import org.netbeans.spi.editor.hints.settings.FileHintPreferences;
  225.54 +import org.netbeans.spi.editor.hints.settings.FileHintPreferences.GlobalHintPreferencesProvider;
  225.55 +import org.openide.filesystems.FileObject;
  225.56 +import org.openide.util.NbPreferences;
  225.57 +
  225.58 +/**
  225.59 + *
  225.60 + * @author Petr Hrebejk
  225.61 + * @author Jan Lahoda
  225.62 + */
  225.63 +public abstract class HintsSettings {
  225.64 +
  225.65 +    private static final String ENABLED_KEY = "enabled";         // NOI18N
  225.66 +    private static final String OLD_SEVERITY_KEY = "severity";       // NOI18N
  225.67 +    private static final String NEW_SEVERITY_KEY = "hintSeverity";       // NOI18N
  225.68 +//    protected static final String IN_TASK_LIST_KEY = "inTaskList"; // NOI18N
  225.69 +
  225.70 +    public abstract boolean isEnabled(HintMetadata hint);
  225.71 +    public abstract void setEnabled(HintMetadata hint, boolean value);
  225.72 +    public abstract Preferences getHintPreferences(HintMetadata hint);
  225.73 +    public abstract Severity getSeverity(HintMetadata hint);
  225.74 +    public abstract void setSeverity(HintMetadata hint, Severity severity);
  225.75 +//    public abstract Iterable<? extends HintDescription> getEnabledHints();
  225.76 +    
  225.77 +    private static final class PreferencesBasedHintsSettings extends HintsSettings {
  225.78 +
  225.79 +        private final Preferences preferences;
  225.80 +        private final boolean useDefaultEnabled;
  225.81 +        private final Severity overrideSeverity;
  225.82 +
  225.83 +        public PreferencesBasedHintsSettings(Preferences preferences, boolean useDefaultEnabled, Severity overrideSeverity) {
  225.84 +            this.preferences = preferences;
  225.85 +            this.useDefaultEnabled = useDefaultEnabled;
  225.86 +            this.overrideSeverity = overrideSeverity;
  225.87 +        }
  225.88 +
  225.89 +        @Override
  225.90 +        public boolean isEnabled(HintMetadata hint) {
  225.91 +            return getHintPreferences(hint).getBoolean(ENABLED_KEY, useDefaultEnabled && hint.enabled);
  225.92 +        }
  225.93 +
  225.94 +        @Override
  225.95 +        public void setEnabled(HintMetadata hint, boolean value) {
  225.96 +            getHintPreferences(hint).putBoolean(ENABLED_KEY, value);
  225.97 +        }
  225.98 +
  225.99 +        @Override
 225.100 +        public Preferences getHintPreferences(HintMetadata hint) {
 225.101 +            return preferences.node(hint.id);
 225.102 +        }
 225.103 +
 225.104 +        @Override
 225.105 +        public Severity getSeverity(HintMetadata hint) {
 225.106 +            Preferences prefs = getHintPreferences(hint);
 225.107 +            String s = prefs.get(NEW_SEVERITY_KEY, null);
 225.108 +            if (s != null) return Severity.valueOf(s);
 225.109 +
 225.110 +            s = prefs.get(OLD_SEVERITY_KEY, null);
 225.111 +
 225.112 +            if (s == null) return overrideSeverity != null ? overrideSeverity : hint != null ? hint.severity : null;
 225.113 +
 225.114 +            if ("ERROR".equals(s)) return Severity.ERROR;
 225.115 +            else if ("WARNING".equals(s)) return Severity.VERIFIER;
 225.116 +            else if ("CURRENT_LINE_WARNING".equals(s)) return Severity.HINT;
 225.117 +
 225.118 +            return overrideSeverity != null ? overrideSeverity : hint != null ? hint.severity : null;
 225.119 +        }
 225.120 +        
 225.121 +        @Override
 225.122 +        public void setSeverity(HintMetadata hint, Severity severity) {
 225.123 +            getHintPreferences(hint).put(NEW_SEVERITY_KEY, severity.name());
 225.124 +        }
 225.125 +    }
 225.126 +    
 225.127 +    public static HintsSettings createPreferencesBasedHintsSettings(Preferences preferences, boolean useDefaultEnabled, Severity overrideSeverity) {
 225.128 +        return new PreferencesBasedHintsSettings(preferences, useDefaultEnabled, overrideSeverity);
 225.129 +    }
 225.130 +    
 225.131 +    public static HintsSettings getSettingsFor(FileObject file) {
 225.132 +        return createPreferencesBasedHintsSettings(FileHintPreferences.getFilePreferences(file, "text/x-java"), true, null);
 225.133 +    }
 225.134 +    
 225.135 +    public static HintsSettings getGlobalSettings() {
 225.136 +        return GLOBAL_SETTINGS;
 225.137 +    }
 225.138 +    
 225.139 +    private static final String DEFAULT_PROFILE = "default"; // NOI18N
 225.140 +    private static final String PREFERENCES_LOCATION = "org/netbeans/modules/java/hints";
 225.141 +    private static final HintsSettings GLOBAL_SETTINGS = createPreferencesBasedHintsSettings(NbPreferences.root().node(PREFERENCES_LOCATION).node(DEFAULT_PROFILE), true, null);
 225.142 +    
 225.143 +    @MimeRegistration(mimeType="text/x-java", service=GlobalHintPreferencesProvider.class)
 225.144 +    public static class GlobalSettingsProvider implements GlobalHintPreferencesProvider {
 225.145 +
 225.146 +        @Override
 225.147 +        public Preferences getGlobalPreferences() {
 225.148 +            return NbPreferences.root().node(PREFERENCES_LOCATION).node(DEFAULT_PROFILE);
 225.149 +        }
 225.150 +        
 225.151 +    }
 225.152 +}
   226.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   226.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/pm/BulkSearch.java	Sun Oct 23 11:50:54 2016 +0200
   226.3 @@ -0,0 +1,190 @@
   226.4 +/*
   226.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   226.6 + *
   226.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
   226.8 + *
   226.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  226.10 + * Other names may be trademarks of their respective owners.
  226.11 + *
  226.12 + * The contents of this file are subject to the terms of either the GNU
  226.13 + * General Public License Version 2 only ("GPL") or the Common
  226.14 + * Development and Distribution License("CDDL") (collectively, the
  226.15 + * "License"). You may not use this file except in compliance with the
  226.16 + * License. You can obtain a copy of the License at
  226.17 + * http://www.netbeans.org/cddl-gplv2.html
  226.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  226.19 + * specific language governing permissions and limitations under the
  226.20 + * License.  When distributing the software, include this License Header
  226.21 + * Notice in each file and include the License file at
  226.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  226.23 + * particular file as subject to the "Classpath" exception as provided
  226.24 + * by Oracle in the GPL Version 2 section of the License file that
  226.25 + * accompanied this code. If applicable, add the following below the
  226.26 + * License Header, with the fields enclosed by brackets [] replaced by
  226.27 + * your own identifying information:
  226.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  226.29 + *
  226.30 + * If you wish your version of this file to be governed by only the CDDL
  226.31 + * or only the GPL Version 2, indicate your decision by adding
  226.32 + * "[Contributor] elects to include this software in this distribution
  226.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  226.34 + * single choice of license, a recipient has the option to distribute
  226.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  226.36 + * to extend the choice of license to its licensees as provided above.
  226.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  226.38 + * Version 2 license, then the option applies only if the new code is
  226.39 + * made subject to such option by the copyright holder.
  226.40 + *
  226.41 + * Contributor(s):
  226.42 + *
  226.43 + * Portions Copyrighted 2009 Sun Microsystems, Inc.
  226.44 + */
  226.45 +
  226.46 +package org.netbeans.modules.java.hints.spiimpl.pm;
  226.47 +
  226.48 +import com.sun.source.tree.Tree;
  226.49 +import com.sun.source.util.TreePath;
  226.50 +import java.io.InputStream;
  226.51 +import java.io.OutputStream;
  226.52 +import java.util.Arrays;
  226.53 +import java.util.Collection;
  226.54 +import java.util.LinkedList;
  226.55 +import java.util.List;
  226.56 +import java.util.Map;
  226.57 +import java.util.Set;
  226.58 +import java.util.concurrent.atomic.AtomicBoolean;
  226.59 +import org.netbeans.api.annotations.common.CheckForNull;
  226.60 +import org.netbeans.api.java.source.CompilationInfo;
  226.61 +import org.netbeans.modules.java.hints.spiimpl.Utilities;
  226.62 +import org.netbeans.modules.java.hints.providers.spi.HintDescription.AdditionalQueryConstraints;
  226.63 +
  226.64 +/**
  226.65 + *
  226.66 + * @author lahvac
  226.67 + */
  226.68 +public abstract class BulkSearch {
  226.69 +
  226.70 +    private static final BulkSearch INSTANCE = new NFABasedBulkSearch();
  226.71 +//    private static final BulkSearch INSTANCE = new REBasedBulkSearch();
  226.72 +
  226.73 +    public static BulkSearch getDefault() {
  226.74 +        return INSTANCE;
  226.75 +    }
  226.76 +    
  226.77 +    private final boolean requiresLightweightVerification;
  226.78 +    
  226.79 +    protected BulkSearch(boolean requiresLightweightVerification) {
  226.80 +        this.requiresLightweightVerification = requiresLightweightVerification;
  226.81 +    }
  226.82 +    
  226.83 +    public final Map<String, Collection<TreePath>> match(CompilationInfo info, AtomicBoolean cancel, TreePath toSearch, BulkPattern pattern) {
  226.84 +        return match(info, cancel, toSearch, pattern, null);
  226.85 +    }
  226.86 +
  226.87 +    public final boolean requiresLightweightVerification() {
  226.88 +        return requiresLightweightVerification;
  226.89 +    }
  226.90 +
  226.91 +    @CheckForNull
  226.92 +    public abstract Map<String, Collection<TreePath>> match(CompilationInfo info, AtomicBoolean cancel, TreePath toSearch, BulkPattern pattern, Map<String, Long> timeLog);
  226.93 +
  226.94 +    public abstract boolean matches(InputStream encoded, AtomicBoolean cancel, BulkPattern pattern);
  226.95 +    
  226.96 +    @CheckForNull
  226.97 +    public abstract Map<String, Integer> matchesWithFrequencies(InputStream encoded, BulkPattern pattern, AtomicBoolean cancel);
  226.98 +    
  226.99 +    public abstract boolean matches(CompilationInfo info, AtomicBoolean cancel, TreePath toSearch, BulkPattern pattern);
 226.100 +
 226.101 +    public abstract void encode(Tree tree, EncodingContext ctx, AtomicBoolean cancel);
 226.102 +    
 226.103 +    @CheckForNull
 226.104 +    public final BulkPattern create(CompilationInfo info, AtomicBoolean cancel, String... code) {
 226.105 +        return create(info, cancel, Arrays.asList(code));
 226.106 +    }
 226.107 +
 226.108 +    @CheckForNull
 226.109 +    public final BulkPattern create(CompilationInfo info, AtomicBoolean cancel, Collection<? extends String> code) {
 226.110 +        List<Tree> patterns = new LinkedList<Tree>();
 226.111 +        List<AdditionalQueryConstraints> additionalConstraints = new LinkedList<AdditionalQueryConstraints>();
 226.112 +
 226.113 +        for (String c : code) {
 226.114 +            patterns.add(Utilities.parseAndAttribute(info, c, null));
 226.115 +            additionalConstraints.add(AdditionalQueryConstraints.empty());
 226.116 +        }
 226.117 +
 226.118 +        return create(code, patterns, additionalConstraints, cancel);
 226.119 +    }
 226.120 +    
 226.121 +    @CheckForNull
 226.122 +    public abstract BulkPattern create(Collection<? extends String> code, Collection<? extends Tree> patterns, Collection<? extends AdditionalQueryConstraints> additionalConstraints, AtomicBoolean cancel);
 226.123 +
 226.124 +    public static abstract class BulkPattern {
 226.125 +
 226.126 +        private final List<? extends String> patterns;
 226.127 +        private final List<? extends Set<? extends String>> identifiers;
 226.128 +        private final List<List<List<String>>> requiredContent;
 226.129 +        private final List<AdditionalQueryConstraints> additionalConstraints;
 226.130 +
 226.131 +        public BulkPattern(List<? extends String> patterns, List<? extends Set<? extends String>> identifiers, List<List<List<String>>> requiredContent, List<AdditionalQueryConstraints> additionalConstraints) {
 226.132 +            this.patterns = patterns;
 226.133 +            this.identifiers = identifiers;//TODO: immutable, maybe clone
 226.134 +            this.requiredContent = requiredContent;
 226.135 +            this.additionalConstraints = additionalConstraints;
 226.136 +        }
 226.137 +
 226.138 +        public List<? extends String> getPatterns() {
 226.139 +            return patterns;
 226.140 +        }
 226.141 +
 226.142 +        public List<? extends Set<? extends String>> getIdentifiers() {
 226.143 +            return identifiers;
 226.144 +        }
 226.145 +
 226.146 +        public List<List<List<String>>> getRequiredContent() {
 226.147 +            return requiredContent;
 226.148 +        }
 226.149 +
 226.150 +        public List<AdditionalQueryConstraints> getAdditionalConstraints() {
 226.151 +            return additionalConstraints;
 226.152 +        }
 226.153 +
 226.154 +    }
 226.155 +
 226.156 +    public static final class EncodingContext {
 226.157 +
 226.158 +        private final OutputStream out;
 226.159 +        private final boolean forDuplicates;
 226.160 +        private Set<? extends String> identifiers;
 226.161 +        private List<String> content;
 226.162 +
 226.163 +        public EncodingContext(OutputStream out, boolean forDuplicates) {
 226.164 +            this.out = out;
 226.165 +            this.forDuplicates = forDuplicates;
 226.166 +        }
 226.167 +
 226.168 +        public Set<? extends String> getIdentifiers() {
 226.169 +            return identifiers;
 226.170 +        }
 226.171 +
 226.172 +        public OutputStream getOut() {
 226.173 +            return out;
 226.174 +        }
 226.175 +
 226.176 +        public boolean isForDuplicates() {
 226.177 +            return forDuplicates;
 226.178 +        }
 226.179 +
 226.180 +        public void setIdentifiers(Set<? extends String> identifiers) {
 226.181 +            this.identifiers = identifiers;
 226.182 +        }
 226.183 +
 226.184 +        public void setContent(List<String> content) {
 226.185 +            this.content = content;
 226.186 +        }
 226.187 +
 226.188 +        public List<String> getContent() {
 226.189 +            return content;
 226.190 +        }
 226.191 +
 226.192 +    }
 226.193 +}
   227.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   227.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/pm/CopyFinderBasedBulkSearch.java	Sun Oct 23 11:50:54 2016 +0200
   227.3 @@ -0,0 +1,141 @@
   227.4 +/*
   227.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   227.6 + *
   227.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
   227.8 + *
   227.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  227.10 + * Other names may be trademarks of their respective owners.
  227.11 + *
  227.12 + * The contents of this file are subject to the terms of either the GNU
  227.13 + * General Public License Version 2 only ("GPL") or the Common
  227.14 + * Development and Distribution License("CDDL") (collectively, the
  227.15 + * "License"). You may not use this file except in compliance with the
  227.16 + * License. You can obtain a copy of the License at
  227.17 + * http://www.netbeans.org/cddl-gplv2.html
  227.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  227.19 + * specific language governing permissions and limitations under the
  227.20 + * License.  When distributing the software, include this License Header
  227.21 + * Notice in each file and include the License file at
  227.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  227.23 + * particular file as subject to the "Classpath" exception as provided
  227.24 + * by Oracle in the GPL Version 2 section of the License file that
  227.25 + * accompanied this code. If applicable, add the following below the
  227.26 + * License Header, with the fields enclosed by brackets [] replaced by
  227.27 + * your own identifying information:
  227.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  227.29 + *
  227.30 + * If you wish your version of this file to be governed by only the CDDL
  227.31 + * or only the GPL Version 2, indicate your decision by adding
  227.32 + * "[Contributor] elects to include this software in this distribution
  227.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  227.34 + * single choice of license, a recipient has the option to distribute
  227.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  227.36 + * to extend the choice of license to its licensees as provided above.
  227.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  227.38 + * Version 2 license, then the option applies only if the new code is
  227.39 + * made subject to such option by the copyright holder.
  227.40 + *
  227.41 + * Contributor(s):
  227.42 + *
  227.43 + * Portions Copyrighted 2009 Sun Microsystems, Inc.
  227.44 + */
  227.45 +
  227.46 +package org.netbeans.modules.java.hints.spiimpl.pm;
  227.47 +
  227.48 +import com.sun.source.tree.Tree;
  227.49 +import com.sun.source.util.TreePath;
  227.50 +import java.io.InputStream;
  227.51 +import java.util.Collection;
  227.52 +import java.util.Collections;
  227.53 +import java.util.HashMap;
  227.54 +import java.util.Iterator;
  227.55 +import java.util.LinkedList;
  227.56 +import java.util.Map;
  227.57 +import java.util.Map.Entry;
  227.58 +import java.util.concurrent.atomic.AtomicBoolean;
  227.59 +import javax.lang.model.type.TypeMirror;
  227.60 +import org.netbeans.api.java.source.CompilationInfo;
  227.61 +import org.netbeans.modules.java.hints.providers.spi.HintDescription.AdditionalQueryConstraints;
  227.62 +import org.netbeans.api.java.source.matching.Matcher;
  227.63 +import org.netbeans.api.java.source.matching.Occurrence;
  227.64 +import org.netbeans.api.java.source.matching.Pattern;
  227.65 +import org.openide.util.Parameters;
  227.66 +
  227.67 +/**
  227.68 + *
  227.69 + * @author lahvac
  227.70 + */
  227.71 +public class CopyFinderBasedBulkSearch extends BulkSearch {
  227.72 +
  227.73 +    public CopyFinderBasedBulkSearch() {
  227.74 +        super(false);
  227.75 +    }
  227.76 +
  227.77 +    @Override
  227.78 +    public Map<String, Collection<TreePath>> match(CompilationInfo info, AtomicBoolean cancel, TreePath toSearch, BulkPattern pattern, Map<String, Long> timeLog) {
  227.79 +        Parameters.notNull("info", info);
  227.80 +        Map<String, Collection<TreePath>> result = new HashMap<String, Collection<TreePath>>();
  227.81 +        TreePath topLevel = new TreePath(info.getCompilationUnit());
  227.82 +        
  227.83 +        for (Entry<Tree, String> e : ((BulkPatternImpl) pattern).pattern2Code.entrySet()) {
  227.84 +            for (Occurrence od : Matcher.create(info).setCancel(new AtomicBoolean()).setUntypedMatching().setCancel(cancel).match(Pattern.createPatternWithFreeVariables(new TreePath(topLevel, e.getKey()), Collections.<String, TypeMirror>emptyMap()))) {
  227.85 +                Collection<TreePath> c = result.get(e.getValue());
  227.86 +
  227.87 +                if (c == null) {
  227.88 +                    result.put(e.getValue(), c = new LinkedList<TreePath>());
  227.89 +                }
  227.90 +
  227.91 +                c.add(od.getOccurrenceRoot());
  227.92 +            }
  227.93 +        }
  227.94 +
  227.95 +        return result;
  227.96 +    }
  227.97 +
  227.98 +    @Override
  227.99 +    public boolean matches(CompilationInfo info, AtomicBoolean cancel, TreePath toSearch, BulkPattern pattern) {
 227.100 +        //XXX: performance
 227.101 +        return !match(info, cancel, toSearch, pattern).isEmpty();
 227.102 +    }
 227.103 +
 227.104 +    @Override
 227.105 +    public BulkPattern create(Collection<? extends String> code, Collection<? extends Tree> patterns, Collection<? extends AdditionalQueryConstraints> additionalConstraints, AtomicBoolean cancel) {
 227.106 +        Map<Tree, String> pattern2Code = new HashMap<Tree, String>();
 227.107 +
 227.108 +        Iterator<? extends String> itCode = code.iterator();
 227.109 +        Iterator<? extends Tree>   itPatt = patterns.iterator();
 227.110 +
 227.111 +        while (itCode.hasNext() && itPatt.hasNext()) {
 227.112 +            pattern2Code.put(itPatt.next(), itCode.next());
 227.113 +        }
 227.114 +
 227.115 +        return new BulkPatternImpl(additionalConstraints, pattern2Code);
 227.116 +    }
 227.117 +
 227.118 +    @Override
 227.119 +    public boolean matches(InputStream encoded, AtomicBoolean cancel, BulkPattern pattern) {
 227.120 +        throw new UnsupportedOperationException("Not supported yet.");
 227.121 +    }
 227.122 +
 227.123 +    @Override
 227.124 +    public void encode(Tree tree, EncodingContext ctx, AtomicBoolean cancel) {
 227.125 +        throw new UnsupportedOperationException("Not supported yet.");
 227.126 +    }
 227.127 +
 227.128 +    @Override
 227.129 +    public Map<String, Integer> matchesWithFrequencies(InputStream encoded, BulkPattern pattern, AtomicBoolean cancel) {
 227.130 +        throw new UnsupportedOperationException("Not supported yet.");
 227.131 +    }
 227.132 +
 227.133 +    private static final class BulkPatternImpl extends BulkPattern {
 227.134 +
 227.135 +        private final Map<Tree, String> pattern2Code;
 227.136 +        
 227.137 +        public BulkPatternImpl(Collection<? extends AdditionalQueryConstraints> additionalConstraints, Map<Tree, String> pattern2Code) {
 227.138 +            super(new LinkedList<String>(pattern2Code.values()), null, null, new LinkedList<AdditionalQueryConstraints>(additionalConstraints));
 227.139 +            this.pattern2Code = pattern2Code;
 227.140 +        }
 227.141 +
 227.142 +    }
 227.143 +
 227.144 +}
   228.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   228.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/pm/NFA.java	Sun Oct 23 11:50:54 2016 +0200
   228.3 @@ -0,0 +1,216 @@
   228.4 +/*
   228.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   228.6 + *
   228.7 + * Copyright 2009-2010 Oracle and/or its affiliates. All rights reserved.
   228.8 + *
   228.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  228.10 + * Other names may be trademarks of their respective owners.
  228.11 + *
  228.12 + * The contents of this file are subject to the terms of either the GNU
  228.13 + * General Public License Version 2 only ("GPL") or the Common
  228.14 + * Development and Distribution License("CDDL") (collectively, the
  228.15 + * "License"). You may not use this file except in compliance with the
  228.16 + * License. You can obtain a copy of the License at
  228.17 + * http://www.netbeans.org/cddl-gplv2.html
  228.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  228.19 + * specific language governing permissions and limitations under the
  228.20 + * License.  When distributing the software, include this License Header
  228.21 + * Notice in each file and include the License file at
  228.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  228.23 + * particular file as subject to the "Classpath" exception as provided
  228.24 + * by Oracle in the GPL Version 2 section of the License file that
  228.25 + * accompanied this code. If applicable, add the following below the
  228.26 + * License Header, with the fields enclosed by brackets [] replaced by
  228.27 + * your own identifying information:
  228.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  228.29 + *
  228.30 + * If you wish your version of this file to be governed by only the CDDL
  228.31 + * or only the GPL Version 2, indicate your decision by adding
  228.32 + * "[Contributor] elects to include this software in this distribution
  228.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  228.34 + * single choice of license, a recipient has the option to distribute
  228.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  228.36 + * to extend the choice of license to its licensees as provided above.
  228.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  228.38 + * Version 2 license, then the option applies only if the new code is
  228.39 + * made subject to such option by the copyright holder.
  228.40 + *
  228.41 + * Contributor(s):
  228.42 + *
  228.43 + * Portions Copyrighted 2009 Sun Microsystems, Inc.
  228.44 + */
  228.45 +
  228.46 +package org.netbeans.modules.java.hints.spiimpl.pm;
  228.47 +
  228.48 +import java.util.BitSet;
  228.49 +import java.util.HashSet;
  228.50 +import java.util.Map;
  228.51 +import java.util.Set;
  228.52 +
  228.53 +/**
  228.54 + *
  228.55 + * @author lahvac
  228.56 + */
  228.57 +public class NFA<I, R> {
  228.58 +
  228.59 +    /*XXX: private*/ final int stateCount;
  228.60 +    private final int startingState;
  228.61 +    private final Set<I> inputs;
  228.62 +    private final Map<Key<I>, State> transitionTable;
  228.63 +    private final Map<Integer, R> finalStates;
  228.64 +
  228.65 +    private final State startingStateObject;
  228.66 +
  228.67 +    private NFA(int startingState, int stateCount, Set<I> inputs, Map<Key<I>, State> transitionTable, Map<Integer, R> finalStates) {
  228.68 +        this.startingState = startingState;
  228.69 +        this.stateCount = stateCount;
  228.70 +        this.inputs = inputs;
  228.71 +        this.transitionTable = transitionTable;
  228.72 +        this.finalStates = finalStates;
  228.73 +
  228.74 +        startingStateObject = State.create().mutableOr(startingState);
  228.75 +    }
  228.76 +
  228.77 +    public State getStartingState() {
  228.78 +        return startingStateObject;
  228.79 +    }
  228.80 +
  228.81 +    public State transition(final State active, final I input) {
  228.82 +        State result = null;
  228.83 +
  228.84 +//        for (int i : active) {
  228.85 +        for (int i = active.nextSetBit(0); i >= 0; i = active.nextSetBit(i+1)) {
  228.86 +             State target = transitionTable.get(Key.create(i, input));
  228.87 +
  228.88 +             if (target != null) {
  228.89 +                 if (result == null) {
  228.90 +                     result = State.create();
  228.91 +                 }
  228.92 +                 
  228.93 +                 result.mutableOr(target);
  228.94 +             }
  228.95 +        }
  228.96 +
  228.97 +        State r;
  228.98 +
  228.99 +        //XXX:
 228.100 +        if (result == null) {
 228.101 +            r = startingStateObject;
 228.102 +        } else {
 228.103 +            r = result.mutableOr(startingState);//???
 228.104 +        }
 228.105 +
 228.106 +        return r;
 228.107 +    }
 228.108 +
 228.109 +    public Set<R> getResults(State bs) {
 228.110 +        Set<R> result = new HashSet<R>();
 228.111 +
 228.112 +        for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) {
 228.113 +            if (finalStates.get(i) != null) {
 228.114 +                result.add(finalStates.get(i));
 228.115 +            }
 228.116 +        }
 228.117 +
 228.118 +        return result;
 228.119 +    }
 228.120 +
 228.121 +    public static <I, R> NFA<I, R> create(int startingState, int stateCount, Set<I> inputs, Map<Key<I>, State> transitionTable, Map<Integer, R> finalStates) {
 228.122 +        return new NFA<I, R>(startingState, stateCount, inputs, transitionTable, finalStates);
 228.123 +    }
 228.124 +
 228.125 +    public State join(State s1, State s2) {
 228.126 +        State bs = State.create();
 228.127 +
 228.128 +        bs.mutableOr(s1);
 228.129 +        bs.mutableOr(s2);
 228.130 +
 228.131 +        return bs;
 228.132 +    }
 228.133 +
 228.134 +    public static final class Key<I> {
 228.135 +        private final int state;
 228.136 +        private final I   input;
 228.137 +
 228.138 +        private Key(int state, I input) {
 228.139 +            this.state = state;
 228.140 +            this.input = input;
 228.141 +        }
 228.142 +
 228.143 +        public static <I> Key<I> create(int state, I input) {
 228.144 +            return new Key<I>(state, input);
 228.145 +        }
 228.146 +
 228.147 +        @Override
 228.148 +        public boolean equals(Object obj) {
 228.149 +            if (obj == null) {
 228.150 +                return false;
 228.151 +            }
 228.152 +            if (getClass() != obj.getClass()) {
 228.153 +                return false;
 228.154 +            }
 228.155 +            final Key<?> other = (Key<?>) obj;
 228.156 +            if (this.state != other.state) {
 228.157 +                return false;
 228.158 +            }
 228.159 +            if (this.input != other.input && (this.input == null || !this.input.equals(other.input))) {
 228.160 +                return false;
 228.161 +            }
 228.162 +            return true;
 228.163 +        }
 228.164 +
 228.165 +        @Override
 228.166 +        public int hashCode() {
 228.167 +            int hash = 3;
 228.168 +            hash = 83 * hash + this.state;
 228.169 +            hash = 83 * hash + (this.input != null ? this.input.hashCode() : 0);
 228.170 +            return hash;
 228.171 +        }
 228.172 +
 228.173 +        @Override
 228.174 +        public String toString() {
 228.175 +            return "[" + state + ", " + input + "]";
 228.176 +        }
 228.177 +
 228.178 +    }
 228.179 +
 228.180 +//    public static final class State extends HashSet<Integer> {
 228.181 +//        private State() {
 228.182 +//        }
 228.183 +//
 228.184 +//        public static State create() {
 228.185 +//            return new State();
 228.186 +//        }
 228.187 +//
 228.188 +//        public State mutableOr(int state) {
 228.189 +//            add(state);
 228.190 +//            return this;
 228.191 +//        }
 228.192 +//
 228.193 +//        public State mutableOr(State or) {
 228.194 +//            addAll(or);
 228.195 +//            return this;
 228.196 +//        }
 228.197 +//
 228.198 +//    }
 228.199 +
 228.200 +    public static final class State extends BitSet {
 228.201 +        private State() {}
 228.202 +
 228.203 +        public static State create() {
 228.204 +            return new State();
 228.205 +        }
 228.206 +
 228.207 +        public State mutableOr(int state) {
 228.208 +            set(state);
 228.209 +            return this;
 228.210 +        }
 228.211 +
 228.212 +        public State mutableOr(State or) {
 228.213 +            or(or);
 228.214 +            return this;
 228.215 +        }
 228.216 +
 228.217 +    }
 228.218 +
 228.219 +}
   229.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   229.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/pm/NFABasedBulkSearch.java	Sun Oct 23 11:50:54 2016 +0200
   229.3 @@ -0,0 +1,826 @@
   229.4 +/*
   229.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   229.6 + *
   229.7 + * Copyright 2009-2010 Oracle and/or its affiliates. All rights reserved.
   229.8 + *
   229.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  229.10 + * Other names may be trademarks of their respective owners.
  229.11 + *
  229.12 + * The contents of this file are subject to the terms of either the GNU
  229.13 + * General Public License Version 2 only ("GPL") or the Common
  229.14 + * Development and Distribution License("CDDL") (collectively, the
  229.15 + * "License"). You may not use this file except in compliance with the
  229.16 + * License. You can obtain a copy of the License at
  229.17 + * http://www.netbeans.org/cddl-gplv2.html
  229.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  229.19 + * specific language governing permissions and limitations under the
  229.20 + * License.  When distributing the software, include this License Header
  229.21 + * Notice in each file and include the License file at
  229.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  229.23 + * particular file as subject to the "Classpath" exception as provided
  229.24 + * by Oracle in the GPL Version 2 section of the License file that
  229.25 + * accompanied this code. If applicable, add the following below the
  229.26 + * License Header, with the fields enclosed by brackets [] replaced by
  229.27 + * your own identifying information:
  229.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  229.29 + *
  229.30 + * If you wish your version of this file to be governed by only the CDDL
  229.31 + * or only the GPL Version 2, indicate your decision by adding
  229.32 + * "[Contributor] elects to include this software in this distribution
  229.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  229.34 + * single choice of license, a recipient has the option to distribute
  229.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  229.36 + * to extend the choice of license to its licensees as provided above.
  229.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  229.38 + * Version 2 license, then the option applies only if the new code is
  229.39 + * made subject to such option by the copyright holder.
  229.40 + *
  229.41 + * Contributor(s):
  229.42 + *
  229.43 + * Portions Copyrighted 2009-2010 Sun Microsystems, Inc.
  229.44 + */
  229.45 +
  229.46 +package org.netbeans.modules.java.hints.spiimpl.pm;
  229.47 +
  229.48 +import com.sun.source.tree.AnnotationTree;
  229.49 +import com.sun.source.tree.BlockTree;
  229.50 +import com.sun.source.tree.ClassTree;
  229.51 +import com.sun.source.tree.IdentifierTree;
  229.52 +import com.sun.source.tree.LiteralTree;
  229.53 +import com.sun.source.tree.MemberSelectTree;
  229.54 +import com.sun.source.tree.MethodTree;
  229.55 +import com.sun.source.tree.ModifiersTree;
  229.56 +import com.sun.source.tree.StatementTree;
  229.57 +import com.sun.source.tree.Tree;
  229.58 +import com.sun.source.tree.Tree.Kind;
  229.59 +import com.sun.source.tree.VariableTree;
  229.60 +import com.sun.source.util.TreePath;
  229.61 +import com.sun.source.util.TreeScanner;
  229.62 +import java.io.ByteArrayOutputStream;
  229.63 +import java.io.IOException;
  229.64 +import java.io.InputStream;
  229.65 +import java.io.UnsupportedEncodingException;
  229.66 +import java.util.ArrayList;
  229.67 +import java.util.Collection;
  229.68 +import java.util.Collections;
  229.69 +import java.util.EnumMap;
  229.70 +import java.util.EnumSet;
  229.71 +import java.util.HashMap;
  229.72 +import java.util.HashSet;
  229.73 +import java.util.Iterator;
  229.74 +import java.util.LinkedHashMap;
  229.75 +import java.util.LinkedList;
  229.76 +import java.util.List;
  229.77 +import java.util.Map;
  229.78 +import java.util.Map.Entry;
  229.79 +import java.util.Set;
  229.80 +import java.util.Stack;
  229.81 +import java.util.concurrent.atomic.AtomicBoolean;
  229.82 +import javax.lang.model.element.Name;
  229.83 +import org.netbeans.api.java.source.CompilationInfo;
  229.84 +import org.netbeans.api.java.source.support.CancellableTreeScanner;
  229.85 +import org.netbeans.modules.java.hints.spiimpl.Utilities;
  229.86 +import org.netbeans.modules.java.hints.providers.spi.HintDescription.AdditionalQueryConstraints;
  229.87 +import org.openide.util.Exceptions;
  229.88 +
  229.89 +/**
  229.90 + *
  229.91 + * @author lahvac
  229.92 + */
  229.93 +public class NFABasedBulkSearch extends BulkSearch {
  229.94 +
  229.95 +    public NFABasedBulkSearch() {
  229.96 +        super(false);
  229.97 +    }
  229.98 +
  229.99 +    @Override
 229.100 +    public Map<String, Collection<TreePath>> match(CompilationInfo info, final AtomicBoolean cancel, TreePath tree, BulkPattern patternIn, Map<String, Long> timeLog) {
 229.101 +        BulkPatternImpl pattern = (BulkPatternImpl) patternIn;
 229.102 +        
 229.103 +        final Map<Res, Collection<TreePath>> occurringPatterns = new HashMap<Res, Collection<TreePath>>();
 229.104 +        final NFA<Input, Res> nfa = pattern.toNFA();
 229.105 +        final Set<String> identifiers = new HashSet<String>();
 229.106 +
 229.107 +        new CollectIdentifiers<Void, TreePath>(identifiers, cancel) {
 229.108 +            private NFA.State active = nfa.getStartingState();
 229.109 +            @Override
 229.110 +            public Void scan(Tree node, TreePath p) {
 229.111 +                if (node == null) {
 229.112 +                    return null;
 229.113 +                }
 229.114 +
 229.115 +                TreePath currentPath = new TreePath(p, node);
 229.116 +                boolean[] goDeeper = new boolean[1];
 229.117 +                final NFA.State newActiveAfterVariable = nfa.transition(active, new Input(Kind.IDENTIFIER, "$", false));
 229.118 +                Input normalizedInput = normalizeInput(node, goDeeper, null);
 229.119 +                boolean ignoreKind = normalizedInput.kind == Kind.IDENTIFIER || normalizedInput.kind == Kind.MEMBER_SELECT;
 229.120 +
 229.121 +                NFA.State newActiveBefore = nfa.transition(active, normalizedInput);
 229.122 +
 229.123 +                if (normalizedInput.name != null && !ignoreKind) {
 229.124 +                    newActiveBefore = nfa.join(newActiveBefore, nfa.transition(active, new Input(normalizedInput.kind, "$", false)));
 229.125 +                }
 229.126 +
 229.127 +                active = newActiveBefore;
 229.128 +
 229.129 +                if (goDeeper[0]) {
 229.130 +                    super.scan(node, currentPath);
 229.131 +                } else {
 229.132 +                    new CollectIdentifiers<Void, Void>(identifiers, cancel).scan(node, null);
 229.133 +                }
 229.134 +                
 229.135 +                if (cancel.get()) return null;
 229.136 +
 229.137 +                NFA.State newActiveAfter = nfa.transition(active, UP);
 229.138 +
 229.139 +                active = nfa.join(newActiveAfter, nfa.transition(newActiveAfterVariable, UP));
 229.140 +
 229.141 +                for (Res r : nfa.getResults(active)) {
 229.142 +                    addOccurrence(r, currentPath);
 229.143 +                }
 229.144 +
 229.145 +                return null;
 229.146 +            }
 229.147 +
 229.148 +            @Override
 229.149 +            public Void scan(Iterable<? extends Tree> nodes, TreePath p) {
 229.150 +                active = nfa.transition(active, new Input(Kind.IDENTIFIER, "(", false));
 229.151 +                try {
 229.152 +                    return super.scan(nodes, p);
 229.153 +                } finally {
 229.154 +                    active = nfa.transition(active, UP);
 229.155 +                }
 229.156 +            }
 229.157 +            
 229.158 +            private void addOccurrence(Res r, TreePath currentPath) {
 229.159 +                Collection<TreePath> occurrences = occurringPatterns.get(r);
 229.160 +                if (occurrences == null) {
 229.161 +                    occurringPatterns.put(r, occurrences = new LinkedList<TreePath>());
 229.162 +                }
 229.163 +                occurrences.add(currentPath);
 229.164 +            }
 229.165 +        }.scan(tree, tree.getParentPath());
 229.166 +
 229.167 +        if (cancel.get()) return null;
 229.168 +        
 229.169 +        Map<String, Collection<TreePath>> result = new HashMap<String, Collection<TreePath>>();
 229.170 +
 229.171 +        for (Entry<Res, Collection<TreePath>> e : occurringPatterns.entrySet()) {
 229.172 +            if (cancel.get()) return null;
 229.173 +            if (!identifiers.containsAll(pattern.getIdentifiers().get(e.getKey().patternIndex))) {
 229.174 +                continue;
 229.175 +            }
 229.176 +
 229.177 +            result.put(e.getKey().pattern, e.getValue());
 229.178 +        }
 229.179 +
 229.180 +        return result;
 229.181 +    }
 229.182 +
 229.183 +    @Override
 229.184 +    public BulkPattern create(Collection<? extends String> code, Collection<? extends Tree> patterns, Collection<? extends AdditionalQueryConstraints> additionalConstraints, final AtomicBoolean cancel) {
 229.185 +        int startState = 0;
 229.186 +        final int[] nextState = new int[] {1};
 229.187 +        final Map<NFA.Key<Input>, NFA.State> transitionTable = new LinkedHashMap<NFA.Key<Input>, NFA.State>();
 229.188 +        Map<Integer, Res> finalStates = new HashMap<Integer, Res>();
 229.189 +        List<Set<? extends String>> identifiers = new LinkedList<Set<? extends String>>();
 229.190 +        List<List<List<String>>> requiredContent = new ArrayList<List<List<String>>>();
 229.191 +        Iterator<? extends String> codeIt = code.iterator();
 229.192 +        int patternIndex = 0;
 229.193 +
 229.194 +        for (final Tree pattern : patterns) {
 229.195 +            final int[] currentState = new int[] {startState};
 229.196 +            final Set<String> patternIdentifiers = new HashSet<String>();
 229.197 +            final List<List<String>> content = new ArrayList<List<String>>();
 229.198 +
 229.199 +            identifiers.add(patternIdentifiers);
 229.200 +            requiredContent.add(content);
 229.201 +
 229.202 +            class Scanner extends CollectIdentifiers<Void, Void> {
 229.203 +                public Scanner() {
 229.204 +                    super(patternIdentifiers, cancel);
 229.205 +                }
 229.206 +                private boolean auxPath;
 229.207 +                private List<String> currentContent;
 229.208 +                {
 229.209 +                    content.add(currentContent = new ArrayList<String>());
 229.210 +                }
 229.211 +                @Override
 229.212 +                public Void scan(Tree t, Void v) {
 229.213 +                    if (t == null) {
 229.214 +                        return null;
 229.215 +                    }
 229.216 +
 229.217 +                    if (Utilities.isMultistatementWildcardTree(t) || multiModifiers(t)) {
 229.218 +                        int target = nextState[0]++;
 229.219 +
 229.220 +                        setBit(transitionTable, NFA.Key.create(currentState[0], new Input(Kind.IDENTIFIER, "$", false)), target);
 229.221 +                        setBit(transitionTable, NFA.Key.create(target, UP), currentState[0]);
 229.222 +
 229.223 +                        content.add(currentContent = new ArrayList<String>());
 229.224 +                        
 229.225 +                        return null;
 229.226 +                    }
 229.227 +
 229.228 +                    if (t.getKind() == Kind.BLOCK) {
 229.229 +                        StatementTree singletonStatement = null;
 229.230 +                        BlockTree bt = (BlockTree) t;
 229.231 +
 229.232 +                        if (!bt.isStatic()) {
 229.233 +                            switch (bt.getStatements().size()) {
 229.234 +                                case 1:
 229.235 +                                    singletonStatement = bt.getStatements().get(0);
 229.236 +                                    break;
 229.237 +                                case 2:
 229.238 +                                    if (Utilities.isMultistatementWildcardTree(bt.getStatements().get(0))) {
 229.239 +                                        singletonStatement = bt.getStatements().get(1);
 229.240 +                                    } else {
 229.241 +                                        if (Utilities.isMultistatementWildcardTree(bt.getStatements().get(1))) {
 229.242 +                                            singletonStatement = bt.getStatements().get(0);
 229.243 +                                        }
 229.244 +                                    }
 229.245 +                                    break;
 229.246 +                                case 3:
 229.247 +                                    if (Utilities.isMultistatementWildcardTree(bt.getStatements().get(0)) && Utilities.isMultistatementWildcardTree(bt.getStatements().get(2))) {
 229.248 +                                        singletonStatement = bt.getStatements().get(1);
 229.249 +                                    }
 229.250 +                                    break;
 229.251 +                            }
 229.252 +                        }
 229.253 +
 229.254 +                        if (singletonStatement != null) {
 229.255 +                            int backup = currentState[0];
 229.256 +
 229.257 +                            boolean oldAuxPath = auxPath;
 229.258 +
 229.259 +                            auxPath = true;
 229.260 +
 229.261 +                            scan(singletonStatement, null);
 229.262 +
 229.263 +                            auxPath = oldAuxPath;
 229.264 +
 229.265 +                            int target = currentState[0];
 229.266 +
 229.267 +                            setBit(transitionTable, NFA.Key.create(backup, new Input(Kind.BLOCK, null, false)), currentState[0] = nextState[0]++);
 229.268 +                            setBit(transitionTable, NFA.Key.create(currentState[0], new Input(Kind.IDENTIFIER, "(", false)), currentState[0] = nextState[0]++);
 229.269 +
 229.270 +                            for (StatementTree st : bt.getStatements()) {
 229.271 +                                scan(st, null);
 229.272 +                            }
 229.273 +
 229.274 +                            setBit(transitionTable, NFA.Key.create(currentState[0], UP), currentState[0] = nextState[0]++);
 229.275 +                            setBit(transitionTable, NFA.Key.create(currentState[0], UP), target);
 229.276 +                            currentState[0] = target;
 229.277 +
 229.278 +                            return null;
 229.279 +                        }
 229.280 +                    }
 229.281 +                    
 229.282 +                    boolean[] goDeeper = new boolean[1];
 229.283 +                    Input[] bypass = new Input[1];
 229.284 +                    Input i = normalizeInput(t, goDeeper, bypass);
 229.285 +
 229.286 +                    if (!TO_IGNORE.contains(i.kind) && !auxPath) {
 229.287 +                        currentContent.add(kind2EncodedString.get(i.kind));
 229.288 +                    }
 229.289 +
 229.290 +                    if (i.name != null && !auxPath) {
 229.291 +                        if (!"$".equals(i.name)) {
 229.292 +                            if (isIdentifierAcceptable(i.name)) {
 229.293 +                                currentContent.add(i.name);
 229.294 +                            }
 229.295 +                            if (Utilities.isPureMemberSelect(t, false)) {
 229.296 +                                content.add(currentContent = new ArrayList<String>());
 229.297 +                            }
 229.298 +                        } else {
 229.299 +                            content.add(currentContent = new ArrayList<String>());
 229.300 +                        }
 229.301 +                    }
 229.302 +
 229.303 +                    int backup = currentState[0];
 229.304 +
 229.305 +                    handleTree(i, goDeeper, t, bypass);
 229.306 +
 229.307 +                    boolean oldAuxPath = auxPath;
 229.308 +
 229.309 +                    auxPath = true;
 229.310 +
 229.311 +                    if (StatementTree.class.isAssignableFrom(t.getKind().asInterface()) && t != pattern) {
 229.312 +                        int target = currentState[0];
 229.313 +
 229.314 +                        setBit(transitionTable, NFA.Key.create(backup, new Input(Kind.BLOCK, null, false)), currentState[0] = nextState[0]++);
 229.315 +                        setBit(transitionTable, NFA.Key.create(currentState[0], new Input(Kind.IDENTIFIER, "(", false)), currentState[0] = nextState[0]++);
 229.316 +                        handleTree(i, goDeeper, t, bypass);
 229.317 +                        setBit(transitionTable, NFA.Key.create(currentState[0], UP), currentState[0] = nextState[0]++);
 229.318 +                        setBit(transitionTable, NFA.Key.create(currentState[0], UP), target);
 229.319 +                        currentState[0] = target;
 229.320 +                    }
 229.321 +
 229.322 +                    auxPath = oldAuxPath;
 229.323 +
 229.324 +                    return null;
 229.325 +                }
 229.326 +
 229.327 +                @Override
 229.328 +                public Void scan(Iterable<? extends Tree> nodes, Void p) {
 229.329 +                    setBit(transitionTable, NFA.Key.create(currentState[0], new Input(Kind.IDENTIFIER, "(", false)), currentState[0] = nextState[0]++);
 229.330 +                    try {
 229.331 +                        return super.scan(nodes, p);
 229.332 +                    } finally {
 229.333 +                        setBit(transitionTable, NFA.Key.create(currentState[0], UP), currentState[0] = nextState[0]++);
 229.334 +                    }
 229.335 +                }
 229.336 +
 229.337 +                private void handleTree(Input i, boolean[] goDeeper, Tree t, Input[] bypass) {
 229.338 +                    int backup = currentState[0];
 229.339 +                    int target = nextState[0]++;
 229.340 +
 229.341 +                    setBit(transitionTable, NFA.Key.create(backup, i), currentState[0] = nextState[0]++);
 229.342 +
 229.343 +                    if (goDeeper[0]) {
 229.344 +                        super.scan(t, null);
 229.345 +                    } else {
 229.346 +                        new CollectIdentifiers<Void, Void>(patternIdentifiers, cancel).scan(t, null);
 229.347 +                        int aux = nextState[0]++;
 229.348 +                        setBit(transitionTable, NFA.Key.create(backup, new Input(Kind.MEMBER_SELECT, i.name, false)), aux);
 229.349 +                        setBit(transitionTable, NFA.Key.create(aux, new Input(Kind.IDENTIFIER, "$", false)), aux = nextState[0]++);
 229.350 +                        setBit(transitionTable, NFA.Key.create(aux, UP), aux = nextState[0]++);
 229.351 +                        setBit(transitionTable, NFA.Key.create(aux, UP), target);
 229.352 +                    }
 229.353 +
 229.354 +                    setBit(transitionTable, NFA.Key.create(currentState[0], UP), target);
 229.355 +                    
 229.356 +                    if (bypass[0] != null) {
 229.357 +                        int intermediate = nextState[0]++;
 229.358 +                        
 229.359 +                        setBit(transitionTable, NFA.Key.create(backup, bypass[0]), intermediate);
 229.360 +                        setBit(transitionTable, NFA.Key.create(intermediate, UP), target);
 229.361 +                    }
 229.362 +                    
 229.363 +                    currentState[0] = target;
 229.364 +                }
 229.365 +            }
 229.366 +
 229.367 +            Scanner s = new Scanner();
 229.368 +
 229.369 +            s.scan(pattern, null);
 229.370 +
 229.371 +            finalStates.put(currentState[0], new Res(codeIt.next(), patternIndex++));
 229.372 +        }
 229.373 +
 229.374 +        if (cancel.get()) return null;
 229.375 +        
 229.376 +        NFA<Input, Res> nfa = NFA.<Input, Res>create(startState, nextState[0], null, transitionTable, finalStates);
 229.377 +
 229.378 +        return new BulkPatternImpl(new LinkedList<String>(code), identifiers, requiredContent, new LinkedList<AdditionalQueryConstraints>(additionalConstraints), nfa);
 229.379 +    }
 229.380 +
 229.381 +    private static void setBit(Map<NFA.Key<Input>, NFA.State> transitionTable, NFA.Key<Input> input, int state) {
 229.382 +        NFA.State target = transitionTable.get(input);
 229.383 +
 229.384 +        if (target == null) {
 229.385 +            transitionTable.put(input, target = NFA.State.create());
 229.386 +        }
 229.387 +
 229.388 +        target.mutableOr(state);
 229.389 +    }
 229.390 +
 229.391 +    private static Input normalizeInput(Tree t, boolean[] goDeeper, Input[] bypass) {
 229.392 +        if (t.getKind() == Kind.IDENTIFIER && ((IdentifierTree) t).getName().toString().startsWith("$")) {
 229.393 +            goDeeper[0] = false;
 229.394 +            return new Input(Kind.IDENTIFIER, "$", false);
 229.395 +        }
 229.396 +
 229.397 +        if (Utilities.getWildcardTreeName(t) != null) {
 229.398 +            goDeeper[0] = false;
 229.399 +            return new Input(Kind.IDENTIFIER, "$", false);
 229.400 +        }
 229.401 +        
 229.402 +        if (t.getKind() == Kind.IDENTIFIER) {
 229.403 +            goDeeper[0] = false;
 229.404 +            String name = ((IdentifierTree) t).getName().toString();
 229.405 +            return new Input(Kind.IDENTIFIER, name, false);
 229.406 +        }
 229.407 +
 229.408 +        if (t.getKind() == Kind.MEMBER_SELECT) {
 229.409 +            String name = ((MemberSelectTree) t).getIdentifier().toString();
 229.410 +            if (name.startsWith("$")) {
 229.411 +                goDeeper[0] = false;//???
 229.412 +                return new Input(Kind.IDENTIFIER, "$", false);
 229.413 +            }
 229.414 +            if (bypass != null && Utilities.isPureMemberSelect(t, true)) {
 229.415 +                bypass[0] = new Input(Kind.IDENTIFIER, name, false);
 229.416 +            }
 229.417 +            goDeeper[0] = true;
 229.418 +            return new Input(Kind.MEMBER_SELECT, name, false);
 229.419 +        }
 229.420 +
 229.421 +        goDeeper[0] = true;
 229.422 +
 229.423 +        String name;
 229.424 +
 229.425 +        switch (t.getKind()) {
 229.426 +            case CLASS: name = ((ClassTree)t).getSimpleName().toString(); break;
 229.427 +            case VARIABLE: name = ((VariableTree)t).getName().toString(); break;
 229.428 +            case METHOD: name = ((MethodTree)t).getName().toString(); break;
 229.429 +            case BOOLEAN_LITERAL: name = ((LiteralTree) t).getValue().toString(); break;
 229.430 +            default: name = null;
 229.431 +        }
 229.432 +
 229.433 +        if (name != null) {
 229.434 +            if (!name.isEmpty() && name.charAt(0) == '$') {
 229.435 +                name = "$";
 229.436 +            }
 229.437 +        }
 229.438 +        return new Input(t.getKind(), name, false);
 229.439 +    }
 229.440 +    
 229.441 +    private boolean multiModifiers(Tree t) {
 229.442 +        if (t.getKind() != Kind.MODIFIERS) return false;
 229.443 +        
 229.444 +        List<AnnotationTree> annotations = new ArrayList<AnnotationTree>(((ModifiersTree) t).getAnnotations());
 229.445 +
 229.446 +        return !annotations.isEmpty() && annotations.get(0).getAnnotationType().getKind() == Kind.IDENTIFIER;
 229.447 +    }
 229.448 +
 229.449 +    @Override
 229.450 +    public boolean matches(CompilationInfo info, AtomicBoolean cancel, TreePath tree, BulkPattern pattern) {
 229.451 +        //XXX: performance
 229.452 +        return !match(info, cancel, tree, pattern).isEmpty();
 229.453 +    }
 229.454 +
 229.455 +    private static final Set<Kind> TO_IGNORE = EnumSet.of(Kind.BLOCK, Kind.IDENTIFIER, Kind.MEMBER_SELECT);
 229.456 +
 229.457 +    @Override
 229.458 +    public void encode(Tree tree, final EncodingContext ctx, AtomicBoolean cancel) {
 229.459 +        final Set<String> identifiers = new HashSet<String>();
 229.460 +        final List<String> content = new ArrayList<String>();
 229.461 +        if (!ctx.isForDuplicates()) {
 229.462 +            new CollectIdentifiers<Void, Void>(identifiers, cancel).scan(tree, null);
 229.463 +            try {
 229.464 +                int size = identifiers.size();
 229.465 +                ctx.getOut().write((size >> 24) & 0xFF);
 229.466 +                ctx.getOut().write((size >> 16) & 0xFF);
 229.467 +                ctx.getOut().write((size >>  8) & 0xFF);
 229.468 +                ctx.getOut().write((size >>  0) & 0xFF);
 229.469 +                for (String ident : identifiers) {
 229.470 +                    ctx.getOut().write(ident.getBytes("UTF-8"));//XXX: might probably contain ';'
 229.471 +                    ctx.getOut().write(';');
 229.472 +                }
 229.473 +            } catch (IOException ex) {
 229.474 +                throw new IllegalStateException(ex);
 229.475 +            }
 229.476 +        }
 229.477 +        if (cancel.get());
 229.478 +        new CollectIdentifiers<Void, Void>(new HashSet<String>(), cancel) {
 229.479 +            private boolean encode = true;
 229.480 +            @Override
 229.481 +            public Void scan(Tree t, Void v) {
 229.482 +                if (t == null) return null;
 229.483 +
 229.484 +                if (t instanceof StatementTree && Utilities.isMultistatementWildcardTree((StatementTree) t)) {
 229.485 +                    return null;
 229.486 +                }
 229.487 +
 229.488 +                boolean[] goDeeper = new boolean[1];
 229.489 +
 229.490 +                Input i = normalizeInput(t, goDeeper, null);
 229.491 +                try {
 229.492 +                    ctx.getOut().write('(');
 229.493 +                    ctx.getOut().write(kind2Encoded.get(i.kind));
 229.494 +                    if (!TO_IGNORE.contains(i.kind)) {
 229.495 +                        content.add(kind2EncodedString.get(i.kind));
 229.496 +                    }
 229.497 +                    if (i.name != null) {
 229.498 +                        if (encode) {
 229.499 +                            ctx.getOut().write('$');
 229.500 +                            ctx.getOut().write(i.name.getBytes("UTF-8"));
 229.501 +                            ctx.getOut().write(';');
 229.502 +                        }
 229.503 +                        if (isIdentifierAcceptable(i.name)) content.add(i.name);
 229.504 +                    }
 229.505 +
 229.506 +                    boolean oldEncode = encode;
 229.507 +
 229.508 +                    encode &= goDeeper[0];
 229.509 +                    super.scan(t, v);
 229.510 +                    encode = oldEncode;
 229.511 +
 229.512 +                    ctx.getOut().write(')');
 229.513 +                } catch (IOException ex) {
 229.514 +                    //XXX
 229.515 +                    Exceptions.printStackTrace(ex);
 229.516 +                }
 229.517 +
 229.518 +                return null;
 229.519 +            }
 229.520 +            @Override
 229.521 +            public Void scan(Iterable<? extends Tree> nodes, Void p) {
 229.522 +                try {
 229.523 +                    ctx.getOut().write('(');
 229.524 +                    ctx.getOut().write(kind2Encoded.get(Kind.IDENTIFIER));
 229.525 +                    ctx.getOut().write('$');
 229.526 +                    ctx.getOut().write('(');
 229.527 +                    ctx.getOut().write(';');
 229.528 +                    super.scan(nodes, p);
 229.529 +                    ctx.getOut().write(')');
 229.530 +                } catch (IOException ex) {
 229.531 +                    //XXX
 229.532 +                    Exceptions.printStackTrace(ex);
 229.533 +                }
 229.534 +                return null;
 229.535 +            }
 229.536 +        }.scan(tree, null);
 229.537 +
 229.538 +        ctx.setIdentifiers(identifiers);
 229.539 +        ctx.setContent(content);
 229.540 +        if (cancel.get());
 229.541 +    }
 229.542 +
 229.543 +    @Override
 229.544 +    public boolean matches(InputStream encoded, AtomicBoolean cancel, BulkPattern patternIn) {
 229.545 +        try {
 229.546 +            return !matchesImpl(encoded, cancel, patternIn, false).isEmpty();
 229.547 +        } catch (IOException ex) {
 229.548 +            Exceptions.printStackTrace(ex);
 229.549 +            return false;
 229.550 +        }
 229.551 +    }
 229.552 +
 229.553 +    @Override
 229.554 +    public Map<String, Integer> matchesWithFrequencies(InputStream encoded, BulkPattern patternIn, AtomicBoolean cancel) {
 229.555 +        try {
 229.556 +            return matchesImpl(encoded, cancel, patternIn, true);
 229.557 +        } catch (IOException ex) {
 229.558 +            Exceptions.printStackTrace(ex);
 229.559 +            return Collections.emptyMap();
 229.560 +        }
 229.561 +    }
 229.562 +
 229.563 +    public Map<String, Integer> matchesImpl(InputStream encoded, AtomicBoolean cancel, BulkPattern patternIn, boolean withFrequencies) throws IOException {
 229.564 +        BulkPatternImpl pattern = (BulkPatternImpl) patternIn;
 229.565 +        final NFA<Input, Res> nfa = pattern.toNFA();
 229.566 +        Stack<NFA.State> skips = new Stack<NFA.State>();
 229.567 +        NFA.State active = nfa.getStartingState();
 229.568 +        int identSize = 0;
 229.569 +
 229.570 +        identSize = encoded.read();
 229.571 +        identSize = (identSize << 8) + encoded.read();
 229.572 +        identSize = (identSize << 8) + encoded.read();
 229.573 +        identSize = (identSize << 8) + encoded.read();
 229.574 +
 229.575 +        Set<String> identifiers = new HashSet<String>(2 * identSize);
 229.576 +
 229.577 +        while (identSize-- > 0) {
 229.578 +            if (cancel.get()) return null;
 229.579 +            int read = encoded.read();
 229.580 +
 229.581 +            ByteArrayOutputStream baos = new ByteArrayOutputStream();
 229.582 +
 229.583 +            //read name:
 229.584 +            while (read != ';') {
 229.585 +                baos.write(read);
 229.586 +                read = encoded.read();
 229.587 +            }
 229.588 +
 229.589 +            identifiers.add(new String(baos.toByteArray(), "UTF-8"));
 229.590 +        }
 229.591 +
 229.592 +        Map<String, Integer> patternsAndFrequencies = new HashMap<String, Integer>();
 229.593 +        int read = encoded.read();
 229.594 +        
 229.595 +        while (read != (-1)) {
 229.596 +            if (cancel.get()) return null;
 229.597 +            if (read == '(') {
 229.598 +                read = encoded.read(); //kind
 229.599 +
 229.600 +                Kind k = encoded2Kind.get((read << 8) + encoded.read());
 229.601 +
 229.602 +                read = encoded.read();
 229.603 +
 229.604 +                String name;
 229.605 +
 229.606 +                if (read == '$') {
 229.607 +                    //XXX:
 229.608 +                    read = encoded.read();
 229.609 +
 229.610 +                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
 229.611 +
 229.612 +                    //read name:
 229.613 +                    while (read != ';') {
 229.614 +                        baos.write(read);
 229.615 +                        read = encoded.read();
 229.616 +                    }
 229.617 +
 229.618 +                    read = encoded.read();
 229.619 +                    name = new String(baos.toByteArray(), "UTF-8");
 229.620 +                } else {
 229.621 +                    name = null;
 229.622 +                }
 229.623 +                
 229.624 +                final NFA.State newActiveAfterVariable = nfa.transition(active, new Input(Kind.IDENTIFIER, "$", false));
 229.625 +                Input normalizedInput = new Input(k, name, false);
 229.626 +                boolean ignoreKind = normalizedInput.kind == Kind.IDENTIFIER || normalizedInput.kind == Kind.MEMBER_SELECT;
 229.627 +
 229.628 +                NFA.State newActive = nfa.transition(active, normalizedInput);
 229.629 +
 229.630 +                if (normalizedInput.name != null && !ignoreKind) {
 229.631 +                    newActive = nfa.join(newActive, nfa.transition(active, new Input(k, "$", false)));
 229.632 +                }
 229.633 +
 229.634 +                active = newActive;
 229.635 +
 229.636 +                skips.push(newActiveAfterVariable);
 229.637 +            } else {
 229.638 +                NFA.State newActiveAfterVariable = skips.pop();
 229.639 +                NFA.State newActive = nfa.transition(active, UP);
 229.640 +                NFA.State s2 = nfa.transition(newActiveAfterVariable, UP);
 229.641 +
 229.642 +                active = nfa.join(newActive, s2);
 229.643 +                
 229.644 +                for (Res res : nfa.getResults(active)) {
 229.645 +                    if (identifiers.containsAll(pattern.getIdentifiers().get(res.patternIndex))) {
 229.646 +                        if (!withFrequencies) {
 229.647 +                            patternsAndFrequencies.put(res.pattern, 1);
 229.648 +                            return patternsAndFrequencies;
 229.649 +                        }
 229.650 +                        
 229.651 +                        Integer freqs = patternsAndFrequencies.get(res.pattern);
 229.652 +
 229.653 +                        if (freqs == null) freqs = 0;
 229.654 +
 229.655 +                        patternsAndFrequencies.put(res.pattern, freqs + 1);
 229.656 +                    }
 229.657 +                }
 229.658 +
 229.659 +                read = encoded.read();
 229.660 +            }
 229.661 +        }
 229.662 +
 229.663 +        return patternsAndFrequencies;
 229.664 +    }
 229.665 +
 229.666 +    private static final Map<Kind, byte[]> kind2Encoded;
 229.667 +    private static final Map<Kind, String> kind2EncodedString;
 229.668 +    private static final Map<Integer, Kind> encoded2Kind;
 229.669 +
 229.670 +    static {
 229.671 +        kind2Encoded = new EnumMap<Kind, byte[]>(Kind.class);
 229.672 +        kind2EncodedString = new EnumMap<Kind, String>(Kind.class);
 229.673 +        encoded2Kind = new HashMap<Integer, Kind>();
 229.674 +
 229.675 +        for (Kind k : Kind.values()) {
 229.676 +            String enc = Integer.toHexString(k.ordinal());
 229.677 +
 229.678 +            if (enc.length() < 2) {
 229.679 +                enc = "0" + enc;
 229.680 +            }
 229.681 +
 229.682 +            try {
 229.683 +                final byte[] bytes = enc.getBytes("UTF-8");
 229.684 +
 229.685 +                assert bytes.length == 2;
 229.686 +
 229.687 +                kind2Encoded.put(k, bytes);
 229.688 +                kind2EncodedString.put(k, enc);
 229.689 +
 229.690 +                encoded2Kind.put((bytes[0] << 8) + bytes[1], k);
 229.691 +            } catch (UnsupportedEncodingException ex) {
 229.692 +                throw new IllegalStateException(ex);
 229.693 +            }
 229.694 +        }
 229.695 +    }
 229.696 +
 229.697 +    public static class BulkPatternImpl extends BulkPattern {
 229.698 +
 229.699 +        private final NFA<Input, Res> nfa;
 229.700 +
 229.701 +        private BulkPatternImpl(List<? extends String> patterns, List<? extends Set<? extends String>> identifiers, List<List<List<String>>> requiredContent, List<AdditionalQueryConstraints> additionalConstraints, NFA<Input, Res> nfa) {
 229.702 +            super(patterns, identifiers, requiredContent, additionalConstraints);
 229.703 +            this.nfa = nfa;
 229.704 +        }
 229.705 +
 229.706 +        NFA<Input, Res> toNFA() {
 229.707 +            return nfa;
 229.708 +        }
 229.709 +        
 229.710 +    }
 229.711 +
 229.712 +    private static final class Res {
 229.713 +        private final String pattern;
 229.714 +        private final int patternIndex;
 229.715 +
 229.716 +        public Res(String pattern, int patternIndex) {
 229.717 +            this.pattern = pattern;
 229.718 +            this.patternIndex = patternIndex;
 229.719 +        }
 229.720 +
 229.721 +    }
 229.722 +
 229.723 +    private static final class Input {
 229.724 +        private final Kind kind;
 229.725 +        private final String name;
 229.726 +        private final boolean end;
 229.727 +
 229.728 +        private Input(Kind kind, String name, boolean end) {
 229.729 +            this.kind = kind;
 229.730 +            this.name = name;
 229.731 +            this.end = end;
 229.732 +        }
 229.733 +
 229.734 +        @Override
 229.735 +        public boolean equals(Object obj) {
 229.736 +            if (obj == null) {
 229.737 +                return false;
 229.738 +            }
 229.739 +            if (getClass() != obj.getClass()) {
 229.740 +                return false;
 229.741 +            }
 229.742 +            final Input other = (Input) obj;
 229.743 +            if (this.kind != other.kind) {
 229.744 +                return false;
 229.745 +            }
 229.746 +            if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
 229.747 +                return false;
 229.748 +            }
 229.749 +            if (this.end != other.end) {
 229.750 +                return false;
 229.751 +            }
 229.752 +            return true;
 229.753 +        }
 229.754 +
 229.755 +        @Override
 229.756 +        public int hashCode() {
 229.757 +            int hash = 7;
 229.758 +            hash = 47 * hash + (this.kind != null ? this.kind.hashCode() : 17);
 229.759 +            hash = 47 * hash + (this.name != null ? this.name.hashCode() : 0);
 229.760 +            hash = 47 * hash + (this.end ? 1 : 0);
 229.761 +            return hash;
 229.762 +        }
 229.763 +
 229.764 +        @Override
 229.765 +        public String toString() {
 229.766 +            return kind + ", " + name + ", " + end;
 229.767 +        }
 229.768 +
 229.769 +    }
 229.770 +
 229.771 +    private static final Input UP = new Input(null, null, true);
 229.772 +
 229.773 +    private static boolean isIdentifierAcceptable(CharSequence content) {
 229.774 +        if (content.length() == 0) return false;
 229.775 +        if (content.charAt(0) == '$' || content.charAt(0) == '<') return false;
 229.776 +        String stringValue = content.toString();
 229.777 +        if (stringValue.contentEquals("java") || "lang".equals(stringValue)) return false;
 229.778 +        return true;
 229.779 +    }
 229.780 +
 229.781 +    private static class CollectIdentifiers<R, P> extends CancellableTreeScanner<R, P> {
 229.782 +
 229.783 +        private final Set<String> identifiers;
 229.784 +
 229.785 +        public CollectIdentifiers(Set<String> identifiers, AtomicBoolean cancel) {
 229.786 +            super(cancel);
 229.787 +            this.identifiers = identifiers;
 229.788 +        }
 229.789 +
 229.790 +        private void addIdentifier(Name ident) {
 229.791 +            if (!isIdentifierAcceptable(ident)) return;
 229.792 +            identifiers.add(ident.toString());
 229.793 +        }
 229.794 +
 229.795 +        @Override
 229.796 +        public R visitMemberSelect(MemberSelectTree node, P p) {
 229.797 +            addIdentifier(node.getIdentifier());
 229.798 +            return super.visitMemberSelect(node, p);
 229.799 +        }
 229.800 +
 229.801 +        @Override
 229.802 +        public R visitIdentifier(IdentifierTree node, P p) {
 229.803 +            addIdentifier(node.getName());
 229.804 +            return super.visitIdentifier(node, p);
 229.805 +        }
 229.806 +
 229.807 +        @Override
 229.808 +        public R visitClass(ClassTree node, P p) {
 229.809 +            if (node.getSimpleName().length() == 0) {
 229.810 +                return scan(Utilities.filterHidden(null, node.getMembers()), p);
 229.811 +            }
 229.812 +            addIdentifier(node.getSimpleName());
 229.813 +            return super.visitClass(node, p);
 229.814 +        }
 229.815 +
 229.816 +        @Override
 229.817 +        public R visitMethod(MethodTree node, P p) {
 229.818 +            addIdentifier(node.getName());
 229.819 +            return super.visitMethod(node, p);
 229.820 +        }
 229.821 +
 229.822 +        @Override
 229.823 +        public R visitVariable(VariableTree node, P p) {
 229.824 +            addIdentifier(node.getName());
 229.825 +            return super.visitVariable(node, p);
 229.826 +        }
 229.827 +
 229.828 +    }
 229.829 +}
   230.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   230.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/pm/PatternCompiler.java	Sun Oct 23 11:50:54 2016 +0200
   230.3 @@ -0,0 +1,72 @@
   230.4 +/*
   230.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   230.6 + *
   230.7 + * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
   230.8 + *
   230.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  230.10 + * Other names may be trademarks of their respective owners.
  230.11 + *
  230.12 + * The contents of this file are subject to the terms of either the GNU
  230.13 + * General Public License Version 2 only ("GPL") or the Common
  230.14 + * Development and Distribution License("CDDL") (collectively, the
  230.15 + * "License"). You may not use this file except in compliance with the
  230.16 + * License. You can obtain a copy of the License at
  230.17 + * http://www.netbeans.org/cddl-gplv2.html
  230.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  230.19 + * specific language governing permissions and limitations under the
  230.20 + * License.  When distributing the software, include this License Header
  230.21 + * Notice in each file and include the License file at
  230.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  230.23 + * particular file as subject to the "Classpath" exception as provided
  230.24 + * by Oracle in the GPL Version 2 section of the License file that
  230.25 + * accompanied this code. If applicable, add the following below the
  230.26 + * License Header, with the fields enclosed by brackets [] replaced by
  230.27 + * your own identifying information:
  230.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  230.29 + *
  230.30 + * If you wish your version of this file to be governed by only the CDDL
  230.31 + * or only the GPL Version 2, indicate your decision by adding
  230.32 + * "[Contributor] elects to include this software in this distribution
  230.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  230.34 + * single choice of license, a recipient has the option to distribute
  230.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  230.36 + * to extend the choice of license to its licensees as provided above.
  230.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  230.38 + * Version 2 license, then the option applies only if the new code is
  230.39 + * made subject to such option by the copyright holder.
  230.40 + *
  230.41 + * Contributor(s):
  230.42 + *
  230.43 + * Portions Copyrighted 2008-2009 Sun Microsystems, Inc.
  230.44 + */
  230.45 +
  230.46 +package org.netbeans.modules.java.hints.spiimpl.pm;
  230.47 +
  230.48 +import com.sun.source.tree.Scope;
  230.49 +import com.sun.source.tree.Tree;
  230.50 +import com.sun.source.util.TreePath;
  230.51 +import java.util.Map;
  230.52 +import javax.lang.model.type.TypeMirror;
  230.53 +import org.netbeans.api.java.source.CompilationInfo;
  230.54 +import org.netbeans.modules.java.hints.spiimpl.Utilities;
  230.55 +import org.netbeans.api.java.source.matching.Pattern;
  230.56 +
  230.57 +/**XXX: cancelability!
  230.58 + *
  230.59 + * @author Jan Lahoda
  230.60 + */
  230.61 +public class PatternCompiler {
  230.62 +
  230.63 +    public static Pattern compile(CompilationInfo info, String pattern, Map<String, TypeMirror> constraints, Iterable<? extends String> imports) {
  230.64 +        Scope scope = Utilities.constructScope(info, constraints, imports);
  230.65 +
  230.66 +        if (scope == null) {
  230.67 +            return null; //TODO: can happen?
  230.68 +        }
  230.69 +
  230.70 +        Tree patternTree = Utilities.parseAndAttribute(info, pattern, scope);
  230.71 +
  230.72 +        return Pattern.createPatternWithFreeVariables(new TreePath(new TreePath(info.getCompilationUnit()), patternTree), constraints);
  230.73 +    }
  230.74 +
  230.75 +}
   231.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   231.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/processor/Bundle.properties	Sun Oct 23 11:50:54 2016 +0200
   231.3 @@ -0,0 +1,3 @@
   231.4 +OpenIDE-Module-Name=Java Hints Annotation Processor
   231.5 +OpenIDE-Module-Display-Category=Java
   231.6 +OpenIDE-Module-Short-Description=Java Hints Annotation Processor
   232.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   232.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/processor/JavaHintsAnnotationProcessor.java	Sun Oct 23 11:50:54 2016 +0200
   232.3 @@ -0,0 +1,635 @@
   232.4 +/*
   232.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   232.6 + *
   232.7 + * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
   232.8 + *
   232.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  232.10 + * Other names may be trademarks of their respective owners.
  232.11 + *
  232.12 + * The contents of this file are subject to the terms of either the GNU
  232.13 + * General Public License Version 2 only ("GPL") or the Common
  232.14 + * Development and Distribution License("CDDL") (collectively, the
  232.15 + * "License"). You may not use this file except in compliance with the
  232.16 + * License. You can obtain a copy of the License at
  232.17 + * http://www.netbeans.org/cddl-gplv2.html
  232.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  232.19 + * specific language governing permissions and limitations under the
  232.20 + * License.  When distributing the software, include this License Header
  232.21 + * Notice in each file and include the License file at
  232.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  232.23 + * particular file as subject to the "Classpath" exception as provided
  232.24 + * by Oracle in the GPL Version 2 section of the License file that
  232.25 + * accompanied this code. If applicable, add the following below the
  232.26 + * License Header, with the fields enclosed by brackets [] replaced by
  232.27 + * your own identifying information:
  232.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  232.29 + *
  232.30 + * If you wish your version of this file to be governed by only the CDDL
  232.31 + * or only the GPL Version 2, indicate your decision by adding
  232.32 + * "[Contributor] elects to include this software in this distribution
  232.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  232.34 + * single choice of license, a recipient has the option to distribute
  232.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  232.36 + * to extend the choice of license to its licensees as provided above.
  232.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  232.38 + * Version 2 license, then the option applies only if the new code is
  232.39 + * made subject to such option by the copyright holder.
  232.40 + *
  232.41 + * Contributor(s):
  232.42 + *
  232.43 + * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
  232.44 + */
  232.45 +
  232.46 +package org.netbeans.modules.java.hints.spiimpl.processor;
  232.47 +
  232.48 +import java.lang.reflect.Array;
  232.49 +import java.util.Map.Entry;
  232.50 +import java.util.*;
  232.51 +import java.util.AbstractMap.SimpleEntry;
  232.52 +import java.util.logging.Logger;
  232.53 +import java.util.regex.Matcher;
  232.54 +import java.util.regex.Pattern;
  232.55 +import javax.annotation.processing.Processor;
  232.56 +import javax.annotation.processing.RoundEnvironment;
  232.57 +import javax.annotation.processing.SupportedAnnotationTypes;
  232.58 +import javax.annotation.processing.SupportedSourceVersion;
  232.59 +import javax.lang.model.SourceVersion;
  232.60 +import javax.lang.model.element.*;
  232.61 +import javax.lang.model.type.DeclaredType;
  232.62 +import javax.lang.model.type.TypeMirror;
  232.63 +import javax.lang.model.util.AbstractAnnotationValueVisitor6;
  232.64 +import javax.lang.model.util.ElementFilter;
  232.65 +import javax.lang.model.util.ElementScanner6;
  232.66 +import javax.lang.model.util.Elements;
  232.67 +import javax.lang.model.util.Types;
  232.68 +import javax.tools.Diagnostic.Kind;
  232.69 +import org.openide.filesystems.annotations.LayerBuilder;
  232.70 +import org.openide.filesystems.annotations.LayerBuilder.File;
  232.71 +import org.openide.filesystems.annotations.LayerGeneratingProcessor;
  232.72 +import org.openide.filesystems.annotations.LayerGenerationException;
  232.73 +import org.openide.util.NbCollections;
  232.74 +import org.openide.util.lookup.ServiceProvider;
  232.75 +
  232.76 +/**Inspired by https://sezpoz.dev.java.net/.
  232.77 + *
  232.78 + * @author lahvac
  232.79 + */
  232.80 +@SupportedSourceVersion(SourceVersion.RELEASE_6)
  232.81 +@SupportedAnnotationTypes("org.netbeans.spi.java.hints.*")
  232.82 +@ServiceProvider(service=Processor.class, position=100)
  232.83 +public class JavaHintsAnnotationProcessor extends LayerGeneratingProcessor {
  232.84 +    
  232.85 +    private static final Logger LOG = Logger.getLogger(JavaHintsAnnotationProcessor.class.getName());
  232.86 +    
  232.87 +    @Override
  232.88 +    protected boolean handleProcess(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) throws LayerGenerationException {
  232.89 +        if (!roundEnv.processingOver()) {
  232.90 +            generateTypeList("org.netbeans.spi.java.hints.Hint", roundEnv);
  232.91 +        }
  232.92 +
  232.93 +        return false;
  232.94 +    }
  232.95 +
  232.96 +    private static final String[] TRIGGERS = new String[] {
  232.97 +        "org.netbeans.spi.java.hints.TriggerTreeKind",
  232.98 +        "org.netbeans.spi.java.hints.TriggerPattern",
  232.99 +        "org.netbeans.spi.java.hints.TriggerPatterns",
 232.100 +    };
 232.101 +
 232.102 +    private static final String[] OPTIONS = new String[] {
 232.103 +        "org.netbeans.spi.java.hints.BooleanOption"
 232.104 +    };
 232.105 +
 232.106 +    private void generateTypeList(String annotationName, RoundEnvironment roundEnv) throws LayerGenerationException {
 232.107 +        TypeElement hint = processingEnv.getElementUtils().getTypeElement(annotationName);
 232.108 +
 232.109 +        if (hint == null) return ;
 232.110 +        
 232.111 +        for (Element annotated : roundEnv.getElementsAnnotatedWith(hint)) {
 232.112 +            if (!verifyHintAnnotationAcceptable(annotated)) continue;
 232.113 +            if (!annotated.getKind().isClass() && !annotated.getKind().isInterface()) {
 232.114 +                if (annotated.getKind() != ElementKind.METHOD) {
 232.115 +                    //the compiler should have already warned about this
 232.116 +                    continue;
 232.117 +                }
 232.118 +
 232.119 +                annotated = annotated.getEnclosingElement();
 232.120 +            } else {
 232.121 +                if (!annotated.getKind().isClass()) {
 232.122 +                    //the compiler should have already warned about this
 232.123 +                    continue;
 232.124 +                }
 232.125 +            }
 232.126 +
 232.127 +            if (!annotated.getKind().isClass()) {
 232.128 +                processingEnv.getMessager().printMessage(Kind.ERROR, "Internal error - cannot find class containing the hint", annotated);
 232.129 +                continue;
 232.130 +            }
 232.131 +
 232.132 +            TypeElement clazz = (TypeElement) annotated;
 232.133 +            String classFolder = "org-netbeans-modules-java-hints/code-hints/" + getFQN(clazz).replace('.', '-') + ".class";
 232.134 +
 232.135 +            {
 232.136 +                LayerBuilder builder = layer(clazz);
 232.137 +                File clazzFolder = builder.folder(classFolder);
 232.138 +                
 232.139 +                for (AnnotationMirror am : clazz.getAnnotationMirrors()) {
 232.140 +                    dumpAnnotation(builder, clazzFolder, clazz, am, true);
 232.141 +                }
 232.142 +                
 232.143 +                clazzFolder.write();
 232.144 +            }
 232.145 +
 232.146 +            for (ExecutableElement ee : ElementFilter.methodsIn(clazz.getEnclosedElements())) {
 232.147 +                if (!ee.getAnnotationMirrors().isEmpty()) {
 232.148 +                    LayerBuilder builder = layer(ee);
 232.149 +                    File methodFolder = builder.folder(classFolder + "/" + ee.getSimpleName() + ".method");
 232.150 +
 232.151 +                    for (AnnotationMirror am : ee.getAnnotationMirrors()) {
 232.152 +                        dumpAnnotation(builder, methodFolder, ee, am, true);
 232.153 +                    }
 232.154 +
 232.155 +                    methodFolder.write();
 232.156 +                }
 232.157 +            }
 232.158 +
 232.159 +            for (VariableElement var : ElementFilter.fieldsIn(clazz.getEnclosedElements())) {
 232.160 +                if (!var.getAnnotationMirrors().isEmpty()) {
 232.161 +                    LayerBuilder builder = layer(var);
 232.162 +                    File fieldFolder = builder.folder(classFolder + "/" + var.getSimpleName() + ".field");
 232.163 +
 232.164 +                    for (AnnotationMirror am : var.getAnnotationMirrors()) {
 232.165 +                        dumpAnnotation(builder, fieldFolder, var, am, true);
 232.166 +                    }
 232.167 +
 232.168 +                    if (var.getConstantValue() instanceof String) {
 232.169 +                        fieldFolder.stringvalue("constantValue", (String) var.getConstantValue());
 232.170 +                    }
 232.171 +
 232.172 +                    fieldFolder.write();
 232.173 +                }
 232.174 +            }
 232.175 +            
 232.176 +            new ElementScanner6<Void, Void>() {
 232.177 +                @Override public Void scan(Element e, Void p) {
 232.178 +                    AnnotationMirror hintMirror = findAnnotation(e.getAnnotationMirrors(), "org.netbeans.spi.java.hints.Hint");
 232.179 +            
 232.180 +                    if (hintMirror != null) {
 232.181 +                        String qualifiedName;
 232.182 +                        switch (e.getKind()) {
 232.183 +                            case METHOD: case CONSTRUCTOR:
 232.184 +                                qualifiedName = e.getEnclosingElement().asType().toString() + "." + e.getSimpleName().toString() + e.asType().toString();
 232.185 +                                break;
 232.186 +                            case FIELD: case ENUM_CONSTANT:
 232.187 +                                qualifiedName = e.getEnclosingElement().asType().toString() + "." + e.getSimpleName().toString();
 232.188 +                                break;
 232.189 +                            case ANNOTATION_TYPE: case CLASS:
 232.190 +                            case ENUM: case INTERFACE:
 232.191 +                            default:
 232.192 +                                qualifiedName = e.asType().toString();
 232.193 +                                break;
 232.194 +                        }
 232.195 +                        
 232.196 +                        try {
 232.197 +                            File keywordsFile = layer(e)
 232.198 +                                               .file("OptionsDialog/Keywords/".concat(qualifiedName))
 232.199 +                                               .stringvalue("location", "Editor")
 232.200 +                                               .bundlevalue("tabTitle", "org.netbeans.modules.options.editor.Bundle", "CTL_Hints_DisplayName");
 232.201 +
 232.202 +                            String displayName = getAttributeValue(hintMirror, "displayName", String.class);
 232.203 +
 232.204 +                            if (displayName != null)
 232.205 +                                keywordsFile = keywordsFile.bundlevalue("keywords-1", displayName);
 232.206 +
 232.207 +                            String description = getAttributeValue(hintMirror, "description", String.class);
 232.208 +
 232.209 +                            if (description != null)
 232.210 +                                keywordsFile = keywordsFile.bundlevalue("keywords-2", description);
 232.211 +
 232.212 +                            int i = 3;
 232.213 +
 232.214 +                            for (String sw : getAttributeValue(hintMirror, "suppressWarnings", String[].class)) {
 232.215 +                                keywordsFile = keywordsFile.stringvalue("keywords-" + i++, sw);
 232.216 +                            }
 232.217 +
 232.218 +                            keywordsFile.write();
 232.219 +                        } catch (LayerGenerationException ex) {
 232.220 +                            JavaHintsAnnotationProcessor.<RuntimeException>rethrowAsRuntime(ex);
 232.221 +                        }
 232.222 +                    }
 232.223 +
 232.224 +                    return super.scan(e, p);
 232.225 +                }
 232.226 +            }.scan(annotated, null);
 232.227 +        }
 232.228 +
 232.229 +        for (String ann : TRIGGERS) {
 232.230 +            TypeElement annRes = processingEnv.getElementUtils().getTypeElement(ann);
 232.231 +
 232.232 +            if (annRes == null) continue;
 232.233 +
 232.234 +            for (ExecutableElement method : ElementFilter.methodsIn(roundEnv.getElementsAnnotatedWith(annRes))) {
 232.235 +                verifyHintMethod(method);
 232.236 +                verifyTriggerAnnotations(method);
 232.237 +            }
 232.238 +        }
 232.239 +
 232.240 +        for (String ann : OPTIONS) {
 232.241 +            TypeElement annRes = processingEnv.getElementUtils().getTypeElement(ann);
 232.242 +
 232.243 +            if (annRes == null) continue;
 232.244 +
 232.245 +            for (VariableElement var : ElementFilter.fieldsIn(roundEnv.getElementsAnnotatedWith(annRes))) {
 232.246 +                verifyOptionField(var);
 232.247 +            }
 232.248 +        }
 232.249 +
 232.250 +    }
 232.251 +
 232.252 +    private void dumpAnnotation(LayerBuilder builder, File folder, Element errElement, AnnotationMirror annotation, boolean topLevel) {
 232.253 +        String fqn = getFQN(((TypeElement) annotation.getAnnotationType().asElement())).replace('.', '-');
 232.254 +        if (topLevel && !fqn.startsWith("org-netbeans-spi-java-hints")) return ;
 232.255 +        final File   annotationFolder = builder.folder(folder.getPath() + "/" + fqn + ".annotation");
 232.256 +
 232.257 +        for (Entry<? extends ExecutableElement, ? extends AnnotationValue> e : annotation.getElementValues().entrySet()) {
 232.258 +            final String attrName = e.getKey().getSimpleName().toString();
 232.259 +            e.getValue().accept(new DumpAnnotationValue(builder, annotationFolder, attrName, errElement, annotation, e.getValue()), null);
 232.260 +        }
 232.261 +
 232.262 +        annotationFolder.write();
 232.263 +    }
 232.264 +
 232.265 +    private String getFQN(TypeElement clazz) {
 232.266 +        return processingEnv.getElementUtils().getBinaryName(clazz).toString();
 232.267 +    }
 232.268 +
 232.269 +    static final String ERR_RETURN_TYPE = "The return type must be either org.netbeans.spi.editor.hints.ErrorDescription or java.util.List<org.netbeans.spi.editor.hints.ErrorDescription>";
 232.270 +    static final String ERR_PARAMETERS = "The method must have exactly one parameter of type org.netbeans.spi.java.hints.HintContext";
 232.271 +    static final String ERR_MUST_BE_STATIC = "The method must be static";
 232.272 +    static final String ERR_OPTION_TYPE = "The option field must be of type java.lang.String";
 232.273 +    static final String ERR_OPTION_MUST_BE_STATIC_FINAL = "The option field must be static final";
 232.274 +    static final String WARN_BUNDLE_KEY_NOT_FOUND = "Bundle key %s not found";
 232.275 +
 232.276 +    private static AnnotationMirror findAnnotation(Iterable<? extends AnnotationMirror> annotations, String annotationFQN) {
 232.277 +        for (AnnotationMirror am : annotations) {
 232.278 +            if (((TypeElement) am.getAnnotationType().asElement()).getQualifiedName().contentEquals(annotationFQN)) {
 232.279 +                return am;
 232.280 +            }
 232.281 +        }
 232.282 +
 232.283 +        return null;
 232.284 +    }
 232.285 +
 232.286 +    private <T> T getAttributeValue(AnnotationMirror annotation, String attribute, Class<T> clazz) {
 232.287 +        if (clazz.isArray()) {
 232.288 +            Iterable<?> attributes = getAttributeValueInternal(annotation, attribute, Iterable.class);
 232.289 +            
 232.290 +            Collection<Object> coll = new ArrayList<Object>();
 232.291 +            Class<?> componentType = clazz.getComponentType();
 232.292 +
 232.293 +            for (Object attr : attributes) {
 232.294 +                if (attr instanceof AnnotationValue) {
 232.295 +                    attr = ((AnnotationValue) attr).getValue();
 232.296 +                }
 232.297 +                
 232.298 +                if (componentType.isAssignableFrom(attr.getClass())) {
 232.299 +                    coll.add(componentType.cast(attr));
 232.300 +                }
 232.301 +            }
 232.302 +
 232.303 +            return clazz.cast(coll.toArray((Object[]) Array.newInstance(clazz.getComponentType(), 0)));
 232.304 +        } else {
 232.305 +            return getAttributeValueInternal(annotation, attribute, clazz);
 232.306 +        }
 232.307 +    }
 232.308 +
 232.309 +    private <T> T getAttributeValueInternal(AnnotationMirror annotation, String attribute, Class<T> clazz) {
 232.310 +        for (Entry<? extends ExecutableElement, ? extends AnnotationValue> e : processingEnv.getElementUtils().getElementValuesWithDefaults(annotation).entrySet()) {
 232.311 +            if (e.getKey().getSimpleName().contentEquals(attribute)) {
 232.312 +                Object value = e.getValue().getValue();
 232.313 +
 232.314 +                if (clazz.isAssignableFrom(value.getClass())) {
 232.315 +                    return clazz.cast(value);
 232.316 +                }
 232.317 +
 232.318 +                return null;
 232.319 +            }
 232.320 +        }
 232.321 +        
 232.322 +        return null;
 232.323 +    }
 232.324 +
 232.325 +    private AnnotationValue getAttributeValueDescription(AnnotationMirror annotation, String attribute) {
 232.326 +        for (Entry<? extends ExecutableElement, ? extends AnnotationValue> e : processingEnv.getElementUtils().getElementValuesWithDefaults(annotation).entrySet()) {
 232.327 +            if (e.getKey().getSimpleName().contentEquals(attribute)) {
 232.328 +                return e.getValue();
 232.329 +            }
 232.330 +        }
 232.331 +
 232.332 +        return null;
 232.333 +    }
 232.334 +    
 232.335 +    private boolean verifyHintAnnotationAcceptable(Element hint) {
 232.336 +        AnnotationMirror hintMirror = findAnnotation(hint.getAnnotationMirrors(), "org.netbeans.spi.java.hints.Hint");
 232.337 +
 232.338 +        if (hintMirror == null) return false;
 232.339 +
 232.340 +        String id = getAttributeValue(hintMirror, "id", String.class);
 232.341 +
 232.342 +        if (id == null || id.isEmpty()) {
 232.343 +            switch (hint.getKind()) {
 232.344 +                case CLASS:
 232.345 +                case METHOD:
 232.346 +                    break; //OK
 232.347 +                default:
 232.348 +                    //compiler should have already warned about this
 232.349 +                    return false;
 232.350 +            }
 232.351 +        }
 232.352 +
 232.353 +        TypeMirror customizerProviderType = getAttributeValue(hintMirror, "customizerProvider", TypeMirror.class);
 232.354 +
 232.355 +        if (customizerProviderType != null) {
 232.356 +            Element customizerProvider = processingEnv.getTypeUtils().asElement(customizerProviderType);
 232.357 +
 232.358 +            if (customizerProvider != null) {
 232.359 +                if (customizerProvider.getKind() != ElementKind.CLASS) {
 232.360 +                    TypeElement customizerProviderInterface = processingEnv.getElementUtils().getTypeElement("org.netbeans.spi.java.hints.CustomizerProvider");
 232.361 +
 232.362 +                    if (customizerProviderInterface != null && !customizerProviderInterface.equals(customizerProvider)) {
 232.363 +                        processingEnv.getMessager().printMessage(Kind.ERROR, "Customizer provider must be a concrete class", hint, hintMirror, getAttributeValueDescription(hintMirror, "customizerProvider"));
 232.364 +                    }
 232.365 +                } else {
 232.366 +                    TypeElement customizerProviderClazz = (TypeElement) customizerProvider;
 232.367 +
 232.368 +                    if (!customizerProviderClazz.getModifiers().contains(Modifier.PUBLIC)) {
 232.369 +                        processingEnv.getMessager().printMessage(Kind.ERROR, "Customizer provider must be public", hint, hintMirror, getAttributeValueDescription(hintMirror, "customizerProvider"));
 232.370 +                    }
 232.371 +
 232.372 +                    if (   customizerProviderClazz.getEnclosingElement().getKind() != ElementKind.PACKAGE
 232.373 +                        && !customizerProviderClazz.getModifiers().contains(Modifier.STATIC)) {
 232.374 +                        processingEnv.getMessager().printMessage(Kind.ERROR, "Customizer provider must be non-static innerclass", hint, hintMirror, getAttributeValueDescription(hintMirror, "customizerProvider"));
 232.375 +                    }
 232.376 +
 232.377 +                    boolean foundDefaultConstructor = false;
 232.378 +
 232.379 +                    for (ExecutableElement ee : ElementFilter.constructorsIn(customizerProviderClazz.getEnclosedElements())) {
 232.380 +                        if (ee.getParameters().isEmpty()) {
 232.381 +                            foundDefaultConstructor = true;
 232.382 +                            if (!ee.getModifiers().contains(Modifier.PUBLIC)) {
 232.383 +                                processingEnv.getMessager().printMessage(Kind.ERROR, "Customizer provider must provide a public default constructor", hint, hintMirror, getAttributeValueDescription(hintMirror, "customizerProvider"));
 232.384 +                            }
 232.385 +                            break;
 232.386 +                        }
 232.387 +                    }
 232.388 +
 232.389 +                    if (!foundDefaultConstructor) {
 232.390 +                        processingEnv.getMessager().printMessage(Kind.ERROR, "Customizer provider must provide a public default constructor", hint, hintMirror, getAttributeValueDescription(hintMirror, "customizerProvider"));
 232.391 +                    }
 232.392 +                }
 232.393 +            }
 232.394 +        }
 232.395 +
 232.396 +        return true;
 232.397 +    }
 232.398 +
 232.399 +    private boolean verifyHintMethod(ExecutableElement method) {
 232.400 +        StringBuilder error = new StringBuilder();
 232.401 +        Elements elements = processingEnv.getElementUtils();
 232.402 +        TypeElement errDesc = elements.getTypeElement("org.netbeans.spi.editor.hints.ErrorDescription");
 232.403 +        TypeElement jlIterable = elements.getTypeElement("java.lang.Iterable");
 232.404 +        TypeElement hintCtx = elements.getTypeElement("org.netbeans.spi.java.hints.HintContext");
 232.405 +
 232.406 +        if (errDesc == null || jlIterable == null || hintCtx == null) {
 232.407 +            return true;
 232.408 +        }
 232.409 +
 232.410 +        Types types = processingEnv.getTypeUtils();
 232.411 +        TypeMirror errDescType = errDesc.asType(); //no type params, no need to erasure
 232.412 +        TypeMirror jlIterableErrDesc = types.getDeclaredType(jlIterable, errDescType);
 232.413 +        TypeMirror ret = method.getReturnType();
 232.414 +
 232.415 +        if (!types.isSameType(ret, errDescType) && !types.isAssignable(ret, jlIterableErrDesc)) {
 232.416 +            error.append(ERR_RETURN_TYPE);
 232.417 +            error.append("\n");
 232.418 +        }
 232.419 +
 232.420 +        if (method.getParameters().size() != 1 || !types.isSameType(method.getParameters().get(0).asType(), hintCtx.asType())) {
 232.421 +            error.append(ERR_PARAMETERS);
 232.422 +            error.append("\n");
 232.423 +        }
 232.424 +
 232.425 +        if (!method.getModifiers().contains(Modifier.STATIC)) {
 232.426 +            error.append(ERR_MUST_BE_STATIC);
 232.427 +            error.append("\n");
 232.428 +        }
 232.429 +
 232.430 +        if (error.length() == 0) {
 232.431 +            return true;
 232.432 +        }
 232.433 +
 232.434 +        if (error.charAt(error.length() - 1) == '\n') {
 232.435 +            error.delete(error.length() - 1, error.length());
 232.436 +        }
 232.437 +
 232.438 +        processingEnv.getMessager().printMessage(Kind.ERROR, error.toString(), method);
 232.439 +
 232.440 +        return false;
 232.441 +    }
 232.442 +
 232.443 +    private static final Pattern VARIABLE_PATTERN = Pattern.compile("\\$[a-zA-Z0-9_]+");
 232.444 +    private boolean verifyTriggerAnnotations(ExecutableElement method) {
 232.445 +        List<AnnotationMirror> patternAnnotations = new ArrayList<AnnotationMirror>();
 232.446 +        AnnotationMirror am = findAnnotation(method.getAnnotationMirrors(), "org.netbeans.spi.java.hints.TriggerPattern");
 232.447 +
 232.448 +        if (am != null) {
 232.449 +            patternAnnotations.add(am);
 232.450 +        }
 232.451 +
 232.452 +        am = findAnnotation(method.getAnnotationMirrors(), "org.netbeans.spi.java.hints.TriggerPatterns");
 232.453 +
 232.454 +        if (am != null) {
 232.455 +            patternAnnotations.addAll(Arrays.asList(getAttributeValue(am, "value", AnnotationMirror[].class)));
 232.456 +        }
 232.457 +
 232.458 +        for (AnnotationMirror patternDescription : patternAnnotations) {
 232.459 +            String pattern = getAttributeValue(patternDescription, "value", String.class);
 232.460 +
 232.461 +            if (pattern == null) continue;
 232.462 +
 232.463 +            Set<String> variables = new HashSet<String>();
 232.464 +            Matcher m = VARIABLE_PATTERN.matcher(pattern);
 232.465 +
 232.466 +            while (m.find()) {
 232.467 +                variables.add(m.group(0));
 232.468 +            }
 232.469 +
 232.470 +            for (AnnotationMirror constraint : getAttributeValue(patternDescription, "constraints", AnnotationMirror[].class)) {
 232.471 +                String variable = getAttributeValue(constraint, "variable", String.class);
 232.472 +                String type = getAttributeValue(constraint, "type", String.class);
 232.473 +
 232.474 +                if (variable == null || type == null) continue;
 232.475 +
 232.476 +                if (!variables.contains(variable)) {
 232.477 +                    processingEnv.getMessager().printMessage(Kind.WARNING, "Variable " + variable + " not used in the pattern", method, constraint, getAttributeValueDescription(constraint, "variable"));
 232.478 +                }
 232.479 +            }
 232.480 +        }
 232.481 +
 232.482 +        return false;
 232.483 +    }
 232.484 +
 232.485 +    private boolean verifyOptionField(VariableElement field) {
 232.486 +        StringBuilder error = new StringBuilder();
 232.487 +        Elements elements = processingEnv.getElementUtils();
 232.488 +        TypeElement jlString = elements.getTypeElement("java.lang.String");
 232.489 +
 232.490 +        if (jlString == null) {
 232.491 +            return true;
 232.492 +        }
 232.493 +
 232.494 +        Types types = processingEnv.getTypeUtils();
 232.495 +        TypeMirror jlStringType = jlString.asType(); //no type params, no need to erasure
 232.496 +
 232.497 +        if (!types.isSameType(field.asType(), jlStringType)) {
 232.498 +            error.append(ERR_RETURN_TYPE);
 232.499 +            error.append("\n");
 232.500 +        }
 232.501 +
 232.502 +        if (!field.getModifiers().contains(Modifier.STATIC) || !field.getModifiers().contains(Modifier.FINAL)) {
 232.503 +            error.append(ERR_OPTION_MUST_BE_STATIC_FINAL);
 232.504 +            error.append("\n");
 232.505 +        }
 232.506 +
 232.507 +        Object key = field.getConstantValue();
 232.508 +
 232.509 +        if (key == null) {
 232.510 +            error.append("Option field not a compile-time constant");
 232.511 +            error.append("\n");
 232.512 +        }
 232.513 +
 232.514 +        if (error.length() == 0) {
 232.515 +            return true;
 232.516 +        }
 232.517 +
 232.518 +        if (error.charAt(error.length() - 1) == '\n') {
 232.519 +            error.delete(error.length() - 1, error.length());
 232.520 +        }
 232.521 +
 232.522 +        processingEnv.getMessager().printMessage(Kind.ERROR, error.toString(), field);
 232.523 +
 232.524 +        return false;
 232.525 +    }
 232.526 +
 232.527 +    private class DumpAnnotationValue extends AbstractAnnotationValueVisitor6<Void, Void> {
 232.528 +
 232.529 +        private final LayerBuilder builder;
 232.530 +        private final File annotationFolder;
 232.531 +        private final String attrName;
 232.532 +        private final Element errElement;
 232.533 +        private final AnnotationMirror errAnnotationMirror;
 232.534 +        private final AnnotationValue errAnnotationValue;
 232.535 +
 232.536 +        public DumpAnnotationValue(LayerBuilder builder, File annotationFolder, String attrName, Element errElement, AnnotationMirror errAnnotationMirror, AnnotationValue errAnnotationValue) {
 232.537 +            this.builder = builder;
 232.538 +            this.annotationFolder = annotationFolder;
 232.539 +            this.attrName = attrName;
 232.540 +            this.errElement = errElement;
 232.541 +            this.errAnnotationMirror = errAnnotationMirror;
 232.542 +            this.errAnnotationValue = errAnnotationValue;
 232.543 +        }
 232.544 +
 232.545 +        public Void visitBoolean(boolean b, Void p) {
 232.546 +            annotationFolder.boolvalue(attrName, b);
 232.547 +            return null;
 232.548 +        }
 232.549 +
 232.550 +        public Void visitByte(byte b, Void p) {
 232.551 +            annotationFolder.bytevalue(attrName, b);
 232.552 +            return null;
 232.553 +        }
 232.554 +
 232.555 +        public Void visitChar(char c, Void p) {
 232.556 +            annotationFolder.charvalue(attrName, c);
 232.557 +            return null;
 232.558 +        }
 232.559 +
 232.560 +        public Void visitDouble(double d, Void p) {
 232.561 +            annotationFolder.doublevalue(attrName, d);
 232.562 +            return null;
 232.563 +        }
 232.564 +
 232.565 +        public Void visitFloat(float f, Void p) {
 232.566 +            annotationFolder.floatvalue(attrName, f);
 232.567 +            return null;
 232.568 +        }
 232.569 +
 232.570 +        public Void visitInt(int i, Void p) {
 232.571 +            annotationFolder.intvalue(attrName, i);
 232.572 +            return null;
 232.573 +        }
 232.574 +
 232.575 +        public Void visitLong(long i, Void p) {
 232.576 +            annotationFolder.longvalue(attrName, i);
 232.577 +            return null;
 232.578 +        }
 232.579 +
 232.580 +        public Void visitShort(short s, Void p) {
 232.581 +            annotationFolder.shortvalue(attrName, s);
 232.582 +            return null;
 232.583 +        }
 232.584 +
 232.585 +        public Void visitString(String s, Void p) {
 232.586 +            if ("displayName".equals(attrName) || "description".equals(attrName) || "tooltip".equals(attrName)) {
 232.587 +                try {
 232.588 +                    annotationFolder.bundlevalue(attrName, s);
 232.589 +                } catch (LayerGenerationException ex) {
 232.590 +                   processingEnv.getMessager().printMessage(Kind.ERROR, ex.getLocalizedMessage(), errElement, errAnnotationMirror, errAnnotationValue);
 232.591 +                }
 232.592 +            } else {
 232.593 +                annotationFolder.stringvalue(attrName, s);
 232.594 +            }
 232.595 +            return null;
 232.596 +        }
 232.597 +
 232.598 +        public Void visitType(TypeMirror t, Void p) {
 232.599 +            annotationFolder.stringvalue(attrName, getFQN(((TypeElement) ((DeclaredType) t).asElement())));
 232.600 +            return null;
 232.601 +        }
 232.602 +
 232.603 +        public Void visitEnumConstant(VariableElement c, Void p) {
 232.604 +            TypeElement owner = (TypeElement) c.getEnclosingElement();
 232.605 +            annotationFolder.stringvalue(attrName, getFQN(owner) + "." + c.getSimpleName());
 232.606 +            return null;
 232.607 +        }
 232.608 +
 232.609 +        public Void visitAnnotation(AnnotationMirror a, Void p) {
 232.610 +            File f = builder.folder(annotationFolder.getPath() + "/" + attrName);
 232.611 +            
 232.612 +            dumpAnnotation(builder, f, errElement, a, false);
 232.613 +
 232.614 +            f.write();
 232.615 +            return null;
 232.616 +        }
 232.617 +
 232.618 +        public Void visitArray(List<? extends AnnotationValue> vals, Void p) {
 232.619 +            File arr = builder.folder(annotationFolder.getPath() + "/" + attrName);
 232.620 +            int c = 0;
 232.621 +
 232.622 +            for (AnnotationValue av : vals) {
 232.623 +                av.accept(new DumpAnnotationValue(builder, arr, "item" + c, errElement, errAnnotationMirror, av), null);
 232.624 +                c++;
 232.625 +            }
 232.626 +
 232.627 +            arr.write();
 232.628 +
 232.629 +            return null;
 232.630 +        }
 232.631 +    }
 232.632 +    
 232.633 +    @SuppressWarnings("unchecked")
 232.634 +    private static <T extends Throwable> void rethrowAsRuntime(Throwable t) throws T {
 232.635 +        throw (T) t;
 232.636 +    }
 232.637 +
 232.638 +}
   233.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   233.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/BooleanOption.java	Sun Oct 23 11:50:54 2016 +0200
   233.3 @@ -0,0 +1,87 @@
   233.4 +/*
   233.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   233.6 + *
   233.7 + * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
   233.8 + *
   233.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  233.10 + * Other names may be trademarks of their respective owners.
  233.11 + *
  233.12 + * The contents of this file are subject to the terms of either the GNU
  233.13 + * General Public License Version 2 only ("GPL") or the Common
  233.14 + * Development and Distribution License("CDDL") (collectively, the
  233.15 + * "License"). You may not use this file except in compliance with the
  233.16 + * License. You can obtain a copy of the License at
  233.17 + * http://www.netbeans.org/cddl-gplv2.html
  233.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  233.19 + * specific language governing permissions and limitations under the
  233.20 + * License.  When distributing the software, include this License Header
  233.21 + * Notice in each file and include the License file at
  233.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  233.23 + * particular file as subject to the "Classpath" exception as provided
  233.24 + * by Oracle in the GPL Version 2 section of the License file that
  233.25 + * accompanied this code. If applicable, add the following below the
  233.26 + * License Header, with the fields enclosed by brackets [] replaced by
  233.27 + * your own identifying information:
  233.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  233.29 + *
  233.30 + * If you wish your version of this file to be governed by only the CDDL
  233.31 + * or only the GPL Version 2, indicate your decision by adding
  233.32 + * "[Contributor] elects to include this software in this distribution
  233.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  233.34 + * single choice of license, a recipient has the option to distribute
  233.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  233.36 + * to extend the choice of license to its licensees as provided above.
  233.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  233.38 + * Version 2 license, then the option applies only if the new code is
  233.39 + * made subject to such option by the copyright holder.
  233.40 + *
  233.41 + * Contributor(s):
  233.42 + *
  233.43 + * Portions Copyrighted 2012 Sun Microsystems, Inc.
  233.44 + */
  233.45 +package org.netbeans.spi.java.hints;
  233.46 +
  233.47 +import java.lang.annotation.ElementType;
  233.48 +import java.lang.annotation.Retention;
  233.49 +import java.lang.annotation.RetentionPolicy;
  233.50 +import java.lang.annotation.Target;
  233.51 +import java.util.prefs.Preferences;
  233.52 +
  233.53 +/**Specify an option that affects the way the hint works.
  233.54 + *
  233.55 + * Only {@code static final String} compile-time constant can be marked with this
  233.56 + * annotation. The value of the constant will be used as the key to the hint's {@link Preferences}.
  233.57 + *
  233.58 + * For hints that consist of a class, all options that are directly enclosed in the class
  233.59 + * will be used in their source order.
  233.60 + *
  233.61 + * For hints that consist of a single method, use {@link UseOptions} to specify which options
  233.62 + * from the enclosing class should be used. The order of the options will be the order in which
  233.63 + * they appear in the source code of the enclosing class.
  233.64 + *
  233.65 + * The customizer will be generated automatically when {@link BooleanOption} is used.
  233.66 + *
  233.67 + * Two keys need to be defined in the corresponding {@code Bundle.properties}:
  233.68 + * {@code LBL_<class-fqn>.<field_name>}, which will be used as the display name of
  233.69 + * the corresponding checkbox in the customizer, and {@code TP_<class-fqn>.<field_name>}
  233.70 + * which will be used as the tooltip of the checkbox.
  233.71 + *
  233.72 + * @author lahvac
  233.73 + */
  233.74 +@Retention(RetentionPolicy.SOURCE)
  233.75 +@Target(ElementType.FIELD)
  233.76 +public @interface BooleanOption {
  233.77 +
  233.78 +    /**The options' display name. Will be used as the display name of the
  233.79 +     * checkbox in the customizer.
  233.80 +     */
  233.81 +    public String displayName();
  233.82 +    /**The tooltip of the checkbox in the customizer.
  233.83 +     */
  233.84 +    public String tooltip();
  233.85 +    
  233.86 +    /**The default value of the option.
  233.87 +     */
  233.88 +    public boolean defaultValue();
  233.89 +    
  233.90 +}
   234.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   234.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/Bundle.properties	Sun Oct 23 11:50:54 2016 +0200
   234.3 @@ -0,0 +1,7 @@
   234.4 +#{0}: hint/suggestion name
   234.5 +FIX_DisableHint=Disable "{0}" Hint
   234.6 +FIX_ConfigureHint=Configure "{0}" Hint
   234.7 +FIX_DisableSuggestion=Disable "{0}" Suggestion
   234.8 +FIX_ConfigureSuggestion=Configure "{0}" Suggestion
   234.9 +#{0}: Key of the warning
  234.10 +LBL_FIX_Suppress_Waning=Suppress Warning - {0}
   235.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   235.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/ConstraintVariableType.java	Sun Oct 23 11:50:54 2016 +0200
   235.3 @@ -0,0 +1,73 @@
   235.4 +/*
   235.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   235.6 + *
   235.7 + * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
   235.8 + *
   235.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  235.10 + * Other names may be trademarks of their respective owners.
  235.11 + *
  235.12 + * The contents of this file are subject to the terms of either the GNU
  235.13 + * General Public License Version 2 only ("GPL") or the Common
  235.14 + * Development and Distribution License("CDDL") (collectively, the
  235.15 + * "License"). You may not use this file except in compliance with the
  235.16 + * License. You can obtain a copy of the License at
  235.17 + * http://www.netbeans.org/cddl-gplv2.html
  235.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  235.19 + * specific language governing permissions and limitations under the
  235.20 + * License.  When distributing the software, include this License Header
  235.21 + * Notice in each file and include the License file at
  235.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  235.23 + * particular file as subject to the "Classpath" exception as provided
  235.24 + * by Oracle in the GPL Version 2 section of the License file that
  235.25 + * accompanied this code. If applicable, add the following below the
  235.26 + * License Header, with the fields enclosed by brackets [] replaced by
  235.27 + * your own identifying information:
  235.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  235.29 + *
  235.30 + * If you wish your version of this file to be governed by only the CDDL
  235.31 + * or only the GPL Version 2, indicate your decision by adding
  235.32 + * "[Contributor] elects to include this software in this distribution
  235.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  235.34 + * single choice of license, a recipient has the option to distribute
  235.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  235.36 + * to extend the choice of license to its licensees as provided above.
  235.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  235.38 + * Version 2 license, then the option applies only if the new code is
  235.39 + * made subject to such option by the copyright holder.
  235.40 + *
  235.41 + * Contributor(s):
  235.42 + *
  235.43 + * Portions Copyrighted 2008-2009 Sun Microsystems, Inc.
  235.44 + */
  235.45 +
  235.46 +package org.netbeans.spi.java.hints;
  235.47 +
  235.48 +import java.lang.annotation.Target;
  235.49 +
  235.50 +/**Specifies a type of a variable. During the matching process, only those
  235.51 + * sections of the source code that have the given type are considered.
  235.52 + *
  235.53 + * @author Jan Lahoda
  235.54 + */
  235.55 +@Target({})
  235.56 +public @interface ConstraintVariableType {
  235.57 +
  235.58 +    /**Variable name, must start with the dollar sign (<code>$</code>).
  235.59 +     * Variable<code>$this</code> is automatically bound to the current class.
  235.60 +     */
  235.61 +    public String variable();
  235.62 +
  235.63 +    /**The required type of the section of source code. The value must be a type
  235.64 +     * per JLS 4.1, i.e. a primitive type (JLS 4.2), or a reference type (JLS 4.3).
  235.65 +     * All elements of the type must be resolvable when written to any Java file,
  235.66 +     * they may not contain e.g. references to type variables, simple names, etc.
  235.67 +     *
  235.68 +     * The type may include any actual type arguments, including wildcard.
  235.69 +     *
  235.70 +     * While matching, the type of the tree that corresponds to the variable in
  235.71 +     * the actual occurrence candidate is accepted if it is assignable into the
  235.72 +     * variable defined by the attribute.
  235.73 +     */
  235.74 +    public String type();
  235.75 +    
  235.76 +}
   236.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   236.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/CustomizerProvider.java	Sun Oct 23 11:50:54 2016 +0200
   236.3 @@ -0,0 +1,66 @@
   236.4 +/*
   236.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   236.6 + *
   236.7 + * Copyright 2010-2012 Oracle and/or its affiliates. All rights reserved.
   236.8 + *
   236.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  236.10 + * Other names may be trademarks of their respective owners.
  236.11 + *
  236.12 + * The contents of this file are subject to the terms of either the GNU
  236.13 + * General Public License Version 2 only ("GPL") or the Common
  236.14 + * Development and Distribution License("CDDL") (collectively, the
  236.15 + * "License"). You may not use this file except in compliance with the
  236.16 + * License. You can obtain a copy of the License at
  236.17 + * http://www.netbeans.org/cddl-gplv2.html
  236.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  236.19 + * specific language governing permissions and limitations under the
  236.20 + * License.  When distributing the software, include this License Header
  236.21 + * Notice in each file and include the License file at
  236.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  236.23 + * particular file as subject to the "Classpath" exception as provided
  236.24 + * by Oracle in the GPL Version 2 section of the License file that
  236.25 + * accompanied this code. If applicable, add the following below the
  236.26 + * License Header, with the fields enclosed by brackets [] replaced by
  236.27 + * your own identifying information:
  236.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  236.29 + *
  236.30 + * If you wish your version of this file to be governed by only the CDDL
  236.31 + * or only the GPL Version 2, indicate your decision by adding
  236.32 + * "[Contributor] elects to include this software in this distribution
  236.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  236.34 + * single choice of license, a recipient has the option to distribute
  236.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  236.36 + * to extend the choice of license to its licensees as provided above.
  236.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  236.38 + * Version 2 license, then the option applies only if the new code is
  236.39 + * made subject to such option by the copyright holder.
  236.40 + *
  236.41 + * Contributor(s):
  236.42 + *
  236.43 + * Portions Copyrighted 2010-2012 Sun Microsystems, Inc.
  236.44 + */
  236.45 +
  236.46 +package org.netbeans.spi.java.hints;
  236.47 +
  236.48 +import java.util.prefs.Preferences;
  236.49 +import javax.swing.JComponent;
  236.50 +import org.netbeans.api.annotations.common.NonNull;
  236.51 +
  236.52 +/**A factory for hint customizer.
  236.53 + *
  236.54 + * @author lahvac
  236.55 + */
  236.56 +public interface CustomizerProvider {
  236.57 +
  236.58 +    /**Create a customizer component. The hint settings are in the given
  236.59 +     * {@link Preferences}. The customizer can write into the provided {@link Preferences}
  236.60 +     * immediately, the values will be persisted or rolled-back automatically
  236.61 +     * based on the user's gesture.
  236.62 +     *
  236.63 +     * @param prefs the hints preferences from which the data to show should be read,
  236.64 +     *              and to which the new settings should be written
  236.65 +     * @return a customizer component
  236.66 +     */
  236.67 +    public @NonNull JComponent getCustomizer(@NonNull Preferences prefs);
  236.68 +
  236.69 +}
   237.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   237.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/Decision.java	Sun Oct 23 11:50:54 2016 +0200
   237.3 @@ -0,0 +1,106 @@
   237.4 +/*
   237.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   237.6 + *
   237.7 + * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
   237.8 + *
   237.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  237.10 + * Other names may be trademarks of their respective owners.
  237.11 + *
  237.12 + * The contents of this file are subject to the terms of either the GNU
  237.13 + * General Public License Version 2 only ("GPL") or the Common
  237.14 + * Development and Distribution License("CDDL") (collectively, the
  237.15 + * "License"). You may not use this file except in compliance with the
  237.16 + * License. You can obtain a copy of the License at
  237.17 + * http://www.netbeans.org/cddl-gplv2.html
  237.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  237.19 + * specific language governing permissions and limitations under the
  237.20 + * License.  When distributing the software, include this License Header
  237.21 + * Notice in each file and include the License file at
  237.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  237.23 + * particular file as subject to the "Classpath" exception as provided
  237.24 + * by Oracle in the GPL Version 2 section of the License file that
  237.25 + * accompanied this code. If applicable, add the following below the
  237.26 + * License Header, with the fields enclosed by brackets [] replaced by
  237.27 + * your own identifying information:
  237.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  237.29 + *
  237.30 + * If you wish your version of this file to be governed by only the CDDL
  237.31 + * or only the GPL Version 2, indicate your decision by adding
  237.32 + * "[Contributor] elects to include this software in this distribution
  237.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  237.34 + * single choice of license, a recipient has the option to distribute
  237.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  237.36 + * to extend the choice of license to its licensees as provided above.
  237.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  237.38 + * Version 2 license, then the option applies only if the new code is
  237.39 + * made subject to such option by the copyright holder.
  237.40 + *
  237.41 + * Contributor(s):
  237.42 + *
  237.43 + * Portions Copyrighted 2013 Sun Microsystems, Inc.
  237.44 + */
  237.45 +package org.netbeans.spi.java.hints;
  237.46 +
  237.47 +import java.util.ArrayList;
  237.48 +import java.util.HashMap;
  237.49 +import java.util.List;
  237.50 +import java.util.Map;
  237.51 +import org.netbeans.api.java.source.CompilationInfo;
  237.52 +import org.netbeans.api.java.source.TreePathHandle;
  237.53 +import org.openide.filesystems.FileObject;
  237.54 +
  237.55 +/**
  237.56 + *
  237.57 + * @author lahvac
  237.58 + */
  237.59 +public abstract class Decision<V, R> {
  237.60 +    
  237.61 +    /*XXX: should not be public*/public final TreePathHandle root;
  237.62 +    private final Map<FileObject, List<V>> file2Facts = new HashMap<FileObject, List<V>>();
  237.63 +
  237.64 +    protected Decision(TreePathHandle root) {
  237.65 +        this.root = root;
  237.66 +    }
  237.67 +    
  237.68 +    protected abstract R makeDecision(Iterable<? extends V> input);
  237.69 +    
  237.70 +    private R previousResult;
  237.71 +    
  237.72 +    /*XXX: should not be public*/public boolean makeDecision() {
  237.73 +        List<V> inputs = new ArrayList<V>();
  237.74 +        
  237.75 +        for (List<V> v : file2Facts.values()) {
  237.76 +            inputs.addAll(v);
  237.77 +        }
  237.78 +        
  237.79 +        R current = makeDecision(inputs);
  237.80 +        
  237.81 +        boolean changed = !(previousResult == null ? current == null : previousResult.equals(current));
  237.82 +        
  237.83 +        previousResult = current;
  237.84 +        
  237.85 +        return changed;
  237.86 +    }
  237.87 +    
  237.88 +    public R getCurrentResult() {
  237.89 +        return previousResult;
  237.90 +    }
  237.91 +    
  237.92 +    public void recordLocalFact(/*XXX: should not require the CompilationInfo!*/CompilationInfo info, V fact) {
  237.93 +        List<V> facts = file2Facts.get(info.getFileObject());
  237.94 +        
  237.95 +        if (facts == null) {
  237.96 +            file2Facts.put(info.getFileObject(), facts = new ArrayList<V>());
  237.97 +        }
  237.98 +        
  237.99 +        facts.add(fact);
 237.100 +    }
 237.101 +    
 237.102 +    public static abstract class Factory<V, R, DecisionImpl extends Decision<V, R>> {
 237.103 +        /*XXX: should not be public*/public final Class<DecisionImpl> decisionClass;
 237.104 +        public Factory(Class<DecisionImpl> decisionClass) {
 237.105 +            this.decisionClass = decisionClass;
 237.106 +        }
 237.107 +        public abstract DecisionImpl create(TreePathHandle handle);
 237.108 +    }
 237.109 +}
   238.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   238.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/ErrorDescriptionFactory.java	Sun Oct 23 11:50:54 2016 +0200
   238.3 @@ -0,0 +1,619 @@
   238.4 +/*
   238.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   238.6 + *
   238.7 + * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
   238.8 + *
   238.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  238.10 + * Other names may be trademarks of their respective owners.
  238.11 + *
  238.12 + * The contents of this file are subject to the terms of either the GNU
  238.13 + * General Public License Version 2 only ("GPL") or the Common
  238.14 + * Development and Distribution License("CDDL") (collectively, the
  238.15 + * "License"). You may not use this file except in compliance with the
  238.16 + * License. You can obtain a copy of the License at
  238.17 + * http://www.netbeans.org/cddl-gplv2.html
  238.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  238.19 + * specific language governing permissions and limitations under the
  238.20 + * License.  When distributing the software, include this License Header
  238.21 + * Notice in each file and include the License file at
  238.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  238.23 + * particular file as subject to the "Classpath" exception as provided
  238.24 + * by Oracle in the GPL Version 2 section of the License file that
  238.25 + * accompanied this code. If applicable, add the following below the
  238.26 + * License Header, with the fields enclosed by brackets [] replaced by
  238.27 + * your own identifying information:
  238.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  238.29 + *
  238.30 + * If you wish your version of this file to be governed by only the CDDL
  238.31 + * or only the GPL Version 2, indicate your decision by adding
  238.32 + * "[Contributor] elects to include this software in this distribution
  238.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  238.34 + * single choice of license, a recipient has the option to distribute
  238.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  238.36 + * to extend the choice of license to its licensees as provided above.
  238.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  238.38 + * Version 2 license, then the option applies only if the new code is
  238.39 + * made subject to such option by the copyright holder.
  238.40 + *
  238.41 + * Contributor(s):
  238.42 + *
  238.43 + * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
  238.44 + */
  238.45 +
  238.46 +package org.netbeans.spi.java.hints;
  238.47 +
  238.48 +import com.sun.source.tree.BlockTree;
  238.49 +import com.sun.source.tree.ClassTree;
  238.50 +import com.sun.source.tree.LiteralTree;
  238.51 +import com.sun.source.tree.MemberSelectTree;
  238.52 +import com.sun.source.tree.MethodInvocationTree;
  238.53 +import com.sun.source.tree.MethodTree;
  238.54 +import com.sun.source.tree.ModifiersTree;
  238.55 +import com.sun.source.tree.StatementTree;
  238.56 +import com.sun.source.tree.Tree;
  238.57 +import com.sun.source.tree.Tree.Kind;
  238.58 +import com.sun.source.tree.VariableTree;
  238.59 +import com.sun.source.util.TreePath;
  238.60 +import java.io.IOException;
  238.61 +import java.util.Arrays;
  238.62 +import java.util.Collection;
  238.63 +import java.util.Collections;
  238.64 +import java.util.EnumSet;
  238.65 +import java.util.LinkedHashSet;
  238.66 +import java.util.LinkedList;
  238.67 +import java.util.List;
  238.68 +import java.util.Set;
  238.69 +import javax.lang.model.SourceVersion;
  238.70 +import javax.lang.model.element.TypeElement;
  238.71 +import javax.swing.SwingUtilities;
  238.72 +import org.netbeans.api.annotations.common.NonNull;
  238.73 +import org.netbeans.api.java.source.CompilationInfo;
  238.74 +import org.netbeans.api.java.source.GeneratorUtilities;
  238.75 +import org.netbeans.api.java.source.JavaSource;
  238.76 +import org.netbeans.api.java.source.JavaSource.Phase;
  238.77 +import org.netbeans.api.java.source.Task;
  238.78 +import org.netbeans.api.java.source.TreePathHandle;
  238.79 +import org.netbeans.api.java.source.WorkingCopy;
  238.80 +import org.netbeans.api.lexer.TokenSequence;
  238.81 +import org.netbeans.api.options.OptionsDisplayer;
  238.82 +import org.netbeans.modules.analysis.api.CodeAnalysis;
  238.83 +import org.netbeans.modules.analysis.spi.Analyzer.WarningDescription;
  238.84 +import org.netbeans.modules.java.hints.providers.spi.HintMetadata;
  238.85 +import org.netbeans.modules.java.hints.providers.spi.HintMetadata.Options;
  238.86 +import org.netbeans.modules.java.hints.spiimpl.Hacks.InspectAndTransformOpener;
  238.87 +import org.netbeans.modules.java.hints.spiimpl.SPIAccessor;
  238.88 +import org.netbeans.modules.java.hints.spiimpl.SyntheticFix;
  238.89 +import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings;
  238.90 +import org.netbeans.spi.editor.hints.ChangeInfo;
  238.91 +import org.netbeans.spi.editor.hints.EnhancedFix;
  238.92 +import org.netbeans.spi.editor.hints.ErrorDescription;
  238.93 +import org.netbeans.spi.editor.hints.Fix;
  238.94 +import org.netbeans.spi.editor.hints.LazyFixList;
  238.95 +import org.openide.filesystems.FileObject;
  238.96 +import org.openide.util.Lookup;
  238.97 +import org.openide.util.NbBundle;
  238.98 +import org.openide.util.NbBundle.Messages;
  238.99 +import org.openide.util.Parameters;
 238.100 +
 238.101 +/**
 238.102 + *
 238.103 + * @author Jan Lahoda
 238.104 + */
 238.105 +public class ErrorDescriptionFactory {
 238.106 +
 238.107 +    private ErrorDescriptionFactory() {
 238.108 +    }
 238.109 +
 238.110 +//    public static ErrorDescription forTree(HintContext context, String text, Fix... fixes) {
 238.111 +//        return forTree(context, context.getContext(), text, fixes);
 238.112 +//    }
 238.113 +
 238.114 +    public static ErrorDescription forTree(HintContext context, TreePath tree, String text, Fix... fixes) {
 238.115 +        return forTree(context, tree.getLeaf(), text, fixes);
 238.116 +    }
 238.117 +    
 238.118 +    public static ErrorDescription forTree(HintContext context, Tree tree, String text, Fix... fixes) {
 238.119 +        int start;
 238.120 +        int end;
 238.121 +
 238.122 +        if (context.getHintMetadata().kind == Hint.Kind.INSPECTION) {
 238.123 +            start = (int) context.getInfo().getTrees().getSourcePositions().getStartPosition(context.getInfo().getCompilationUnit(), tree);
 238.124 +            end = (int) context.getInfo().getTrees().getSourcePositions().getEndPosition(context.getInfo().getCompilationUnit(), tree);
 238.125 +        } else {
 238.126 +            start = end = context.getCaretLocation();
 238.127 +        }
 238.128 +
 238.129 +        if (start != (-1) && end != (-1)) {
 238.130 +            LazyFixList fixesForED = org.netbeans.spi.editor.hints.ErrorDescriptionFactory.lazyListForFixes(resolveDefaultFixes(context, fixes));
 238.131 +            return org.netbeans.spi.editor.hints.ErrorDescriptionFactory.createErrorDescription("text/x-java:" + context.getHintMetadata().id, context.getSeverity(), text, context.getHintMetadata().description, fixesForED, context.getInfo().getFileObject(), start, end);
 238.132 +        }
 238.133 +
 238.134 +        return null;
 238.135 +    }
 238.136 +    
 238.137 +    /**Create a new {@link ErrorDescription}. Severity is automatically inferred from the {@link HintContext},
 238.138 +     * and the {@link ErrorDescription} is created to be consistent with {@link ErrorDescription}s created
 238.139 +     * by the other factory methods in this class.
 238.140 +     * 
 238.141 +     * @param context from which the {@link Severity} and other properties are inferred.
 238.142 +     * @param start start of the warning
 238.143 +     * @param end end of the warning
 238.144 +     * @param text the warning text
 238.145 +     * @param fixes one or more {@link Fix}es to show shown to the user.
 238.146 +     * @return a standard {@link ErrorDescription} for use in Java source
 238.147 +     * @since 1.9
 238.148 +     */
 238.149 +    public static ErrorDescription forSpan(HintContext context, int start, int end, String text, Fix... fixes) {
 238.150 +        if (context.getHintMetadata().kind != Hint.Kind.INSPECTION) {
 238.151 +            start = end = context.getCaretLocation();
 238.152 +        }
 238.153 +
 238.154 +        if (start != (-1) && end != (-1)) {
 238.155 +            LazyFixList fixesForED = org.netbeans.spi.editor.hints.ErrorDescriptionFactory.lazyListForFixes(resolveDefaultFixes(context, fixes));
 238.156 +            return org.netbeans.spi.editor.hints.ErrorDescriptionFactory.createErrorDescription("text/x-java:" + context.getHintMetadata().id, context.getSeverity(), text, context.getHintMetadata().description, fixesForED, context.getInfo().getFileObject(), start, end);
 238.157 +        }
 238.158 +
 238.159 +        return null;
 238.160 +    }
 238.161 +    
 238.162 +    public static ErrorDescription forName(HintContext context, TreePath tree, String text, Fix... fixes) {
 238.163 +        return forName(context, tree.getLeaf(), text, fixes);
 238.164 +    }
 238.165 +
 238.166 +    public static ErrorDescription forName(HintContext context, Tree tree, String text, Fix... fixes) {
 238.167 +        int[] span;
 238.168 +        
 238.169 +        if (context.getHintMetadata().kind == Hint.Kind.INSPECTION) {
 238.170 +            span = computeNameSpan(tree, context);
 238.171 +        } else {
 238.172 +            span = new int[] {context.getCaretLocation(), context.getCaretLocation()};
 238.173 +        }
 238.174 +        
 238.175 +        if (span != null && span[0] != (-1) && span[1] != (-1)) {
 238.176 +            LazyFixList fixesForED = org.netbeans.spi.editor.hints.ErrorDescriptionFactory.lazyListForFixes(resolveDefaultFixes(context, fixes));
 238.177 +            return org.netbeans.spi.editor.hints.ErrorDescriptionFactory.createErrorDescription("text/x-java:" + context.getHintMetadata().id, context.getSeverity(), text, context.getHintMetadata().description, fixesForED, context.getInfo().getFileObject(), span[0], span[1]);
 238.178 +        }
 238.179 +
 238.180 +        return null;
 238.181 +    }
 238.182 +
 238.183 +    private static int[] computeNameSpan(Tree tree, HintContext context) {
 238.184 +        switch (tree.getKind()) {
 238.185 +            case METHOD:
 238.186 +                return context.getInfo().getTreeUtilities().findNameSpan((MethodTree) tree);
 238.187 +            case ANNOTATION_TYPE:
 238.188 +            case CLASS:
 238.189 +            case ENUM:
 238.190 +            case INTERFACE:
 238.191 +                return context.getInfo().getTreeUtilities().findNameSpan((ClassTree) tree);
 238.192 +            case VARIABLE:
 238.193 +                return context.getInfo().getTreeUtilities().findNameSpan((VariableTree) tree);
 238.194 +            case MEMBER_SELECT:
 238.195 +                //XXX:
 238.196 +                MemberSelectTree mst = (MemberSelectTree) tree;
 238.197 +                int[] span = context.getInfo().getTreeUtilities().findNameSpan(mst);
 238.198 +
 238.199 +                if (span == null) {
 238.200 +                    int end = (int) context.getInfo().getTrees().getSourcePositions().getEndPosition(context.getInfo().getCompilationUnit(), tree);
 238.201 +                    span = new int[] {end - mst.getIdentifier().length(), end};
 238.202 +                }
 238.203 +                return span;
 238.204 +            case METHOD_INVOCATION:
 238.205 +                return computeNameSpan(((MethodInvocationTree) tree).getMethodSelect(), context);
 238.206 +            case BLOCK:
 238.207 +                Collection<? extends TreePath> prefix = context.getMultiVariables().get("$$1$");
 238.208 +                
 238.209 +                if (prefix != null) {
 238.210 +                    BlockTree bt = (BlockTree) tree;
 238.211 +                    
 238.212 +                    if (bt.getStatements().size() > prefix.size()) {
 238.213 +                        return computeNameSpan(bt.getStatements().get(prefix.size()), context);
 238.214 +                    }
 238.215 +                }
 238.216 +            default:
 238.217 +                int start = (int) context.getInfo().getTrees().getSourcePositions().getStartPosition(context.getInfo().getCompilationUnit(), tree);
 238.218 +                if (    StatementTree.class.isAssignableFrom(tree.getKind().asInterface())
 238.219 +                    && tree.getKind() != Kind.EXPRESSION_STATEMENT
 238.220 +                    && tree.getKind() != Kind.BLOCK) {
 238.221 +                    TokenSequence<?> ts = context.getInfo().getTokenHierarchy().tokenSequence();
 238.222 +                    ts.move(start);
 238.223 +                    if (ts.moveNext()) {
 238.224 +                        return new int[] {ts.offset(), ts.offset() + ts.token().length()};
 238.225 +                    }
 238.226 +                }
 238.227 +                return new int[] {
 238.228 +                    start,
 238.229 +                    (int) context.getInfo().getTrees().getSourcePositions().getEndPosition(context.getInfo().getCompilationUnit(), tree),
 238.230 +                };
 238.231 +        }
 238.232 +    }
 238.233 +
 238.234 +    static List<Fix> resolveDefaultFixes(HintContext ctx, Fix... provided) {
 238.235 +        List<Fix> auxiliaryFixes = new LinkedList<Fix>();
 238.236 +        HintMetadata hm = SPIAccessor.getINSTANCE().getHintMetadata(ctx);
 238.237 +
 238.238 +        if (hm != null) {
 238.239 +            Set<String> suppressWarningsKeys = new LinkedHashSet<String>();
 238.240 +
 238.241 +            for (String key : hm.suppressWarnings) {
 238.242 +                if (key == null || key.length() == 0) {
 238.243 +                    break;
 238.244 +                }
 238.245 +
 238.246 +                suppressWarningsKeys.add(key);
 238.247 +            }
 238.248 +
 238.249 +
 238.250 +            auxiliaryFixes.add(new DisableConfigure(hm, true, SPIAccessor.getINSTANCE().getHintSettings(ctx)));
 238.251 +            auxiliaryFixes.add(new DisableConfigure(hm, false, null));
 238.252 +
 238.253 +            if (hm.kind == Hint.Kind.INSPECTION) {
 238.254 +                auxiliaryFixes.add(new InspectFix(hm, false));
 238.255 +                if (!hm.options.contains(Options.QUERY)) {
 238.256 +                    auxiliaryFixes.add(new InspectFix(hm, true));
 238.257 +                }
 238.258 +            }
 238.259 +            
 238.260 +            if (!suppressWarningsKeys.isEmpty()) {
 238.261 +                auxiliaryFixes.addAll(createSuppressWarnings(ctx.getInfo(), ctx.getPath(), suppressWarningsKeys.toArray(new String[0])));
 238.262 +            }
 238.263 +
 238.264 +            List<Fix> result = new LinkedList<Fix>();
 238.265 +
 238.266 +            for (Fix f : provided != null ? provided : new Fix[0]) {
 238.267 +                if (f == null) continue;
 238.268 +                
 238.269 +                result.add(org.netbeans.spi.editor.hints.ErrorDescriptionFactory.attachSubfixes(f, auxiliaryFixes));
 238.270 +            }
 238.271 +
 238.272 +            if (result.isEmpty()) {
 238.273 +                result.add(org.netbeans.spi.editor.hints.ErrorDescriptionFactory.attachSubfixes(new TopLevelConfigureFix(hm), auxiliaryFixes));
 238.274 +            }
 238.275 +
 238.276 +            return result;
 238.277 +        }
 238.278 +
 238.279 +        return Arrays.asList(provided);
 238.280 +    }
 238.281 +
 238.282 +    private static class DisableConfigure implements Fix, SyntheticFix {
 238.283 +        private final @NonNull HintMetadata metadata;
 238.284 +        private final boolean disable;
 238.285 +        private final HintsSettings hintsSettings;
 238.286 +
 238.287 +        DisableConfigure(@NonNull HintMetadata metadata, boolean disable, HintsSettings hintsSettings) {
 238.288 +            this.metadata = metadata;
 238.289 +            this.disable = disable;
 238.290 +            this.hintsSettings = hintsSettings;
 238.291 +        }
 238.292 +
 238.293 +        @Override
 238.294 +        public String getText() {
 238.295 +            String displayName = metadata.displayName;
 238.296 +            String key;
 238.297 +            switch (metadata.kind) {
 238.298 +                case INSPECTION:
 238.299 +                    key = disable ? "FIX_DisableHint" : "FIX_ConfigureHint";
 238.300 +                    break;
 238.301 +                case ACTION:
 238.302 +                    key = disable ? "FIX_DisableSuggestion" : "FIX_ConfigureSuggestion";
 238.303 +                    break;
 238.304 +                default:
 238.305 +                    throw new IllegalStateException();
 238.306 +            }
 238.307 +
 238.308 +            return NbBundle.getMessage(ErrorDescriptionFactory.class, key, displayName);
 238.309 +        }
 238.310 +
 238.311 +        @Override
 238.312 +        public ChangeInfo implement() throws Exception {
 238.313 +            if (disable) {
 238.314 +                hintsSettings.setEnabled(metadata, false);
 238.315 +                //XXX: re-run hints task
 238.316 +            } else {
 238.317 +                OptionsDisplayer.getDefault().open("Editor/Hints/text/x-java/" + metadata.id);
 238.318 +            }
 238.319 +
 238.320 +            return null;
 238.321 +        }
 238.322 +
 238.323 +        @Override
 238.324 +        public boolean equals(Object obj) {
 238.325 +            if (obj == null) {
 238.326 +                return false;
 238.327 +            }
 238.328 +            if (this.getClass() != obj.getClass()) {
 238.329 +                return false;
 238.330 +            }
 238.331 +            final DisableConfigure other = (DisableConfigure) obj;
 238.332 +            if (this.metadata != other.metadata && (this.metadata == null || !this.metadata.equals(other.metadata))) {
 238.333 +                return false;
 238.334 +            }
 238.335 +            if (this.disable != other.disable) {
 238.336 +                return false;
 238.337 +            }
 238.338 +            return true;
 238.339 +        }
 238.340 +
 238.341 +        @Override
 238.342 +        public int hashCode() {
 238.343 +            int hash = 7;
 238.344 +            hash = 43 * hash + (this.metadata != null ? this.metadata.hashCode() : 0);
 238.345 +            hash = 43 * hash + (this.disable ? 1 : 0);
 238.346 +            return hash;
 238.347 +        }
 238.348 +
 238.349 +
 238.350 +    }
 238.351 +
 238.352 +    private static final class TopLevelConfigureFix extends DisableConfigure implements EnhancedFix {
 238.353 +
 238.354 +        public TopLevelConfigureFix(@NonNull HintMetadata metadata) {
 238.355 +            super(metadata, false, null);
 238.356 +        }
 238.357 +
 238.358 +        @Override
 238.359 +        public CharSequence getSortText() {
 238.360 +            return "\uFFFFzz";
 238.361 +        }
 238.362 +        
 238.363 +    }
 238.364 +
 238.365 +    private static class InspectFix implements Fix, SyntheticFix {
 238.366 +        private final @NonNull HintMetadata metadata;
 238.367 +        private final boolean transform;
 238.368 +
 238.369 +        InspectFix(@NonNull HintMetadata metadata, boolean transform) {
 238.370 +            this.metadata = metadata;
 238.371 +            this.transform = transform;
 238.372 +        }
 238.373 +
 238.374 +        @Override
 238.375 +        @Messages({
 238.376 +            "DN_InspectAndTransform=Run Inspect&Transform on...",
 238.377 +            "DN_Inspect=Run Inspect on..."
 238.378 +        })
 238.379 +        public String getText() {
 238.380 +            return transform ? Bundle.DN_InspectAndTransform() : Bundle.DN_Inspect();
 238.381 +        }
 238.382 +
 238.383 +        @Override
 238.384 +        public ChangeInfo implement() throws Exception {
 238.385 +            SwingUtilities.invokeLater(new Runnable() {
 238.386 +                @Override
 238.387 +                public void run() {
 238.388 +                    if (transform) {
 238.389 +                        final InspectAndTransformOpener o = Lookup.getDefault().lookup(InspectAndTransformOpener.class);
 238.390 +
 238.391 +                        if (o != null) {
 238.392 +                            o.openIAT(metadata);
 238.393 +                        } else {
 238.394 +                            //warn
 238.395 +                        }
 238.396 +                    } else {
 238.397 +                        CodeAnalysis.open(WarningDescription.create("text/x-java:" + metadata.id, null, null, null));
 238.398 +                    }
 238.399 +                }
 238.400 +            });
 238.401 +            
 238.402 +            return null;
 238.403 +        }
 238.404 +
 238.405 +        @Override
 238.406 +        public boolean equals(Object obj) {
 238.407 +            if (obj == null) {
 238.408 +                return false;
 238.409 +            }
 238.410 +            if (this.getClass() != obj.getClass()) {
 238.411 +                return false;
 238.412 +            }
 238.413 +            final InspectFix other = (InspectFix) obj;
 238.414 +            if (this.metadata != other.metadata && (this.metadata == null || !this.metadata.equals(other.metadata))) {
 238.415 +                return false;
 238.416 +            }
 238.417 +            if (this.transform != other.transform) {
 238.418 +                return false;
 238.419 +            }
 238.420 +            return true;
 238.421 +        }
 238.422 +
 238.423 +        @Override
 238.424 +        public int hashCode() {
 238.425 +            int hash = 7;
 238.426 +            hash = 43 * hash + (this.metadata != null ? this.metadata.hashCode() : 0);
 238.427 +            hash = 43 * hash + (this.transform ? 1 : 0);
 238.428 +            return hash;
 238.429 +        }
 238.430 +
 238.431 +
 238.432 +    }
 238.433 +    
 238.434 +    /** Creates a fix, which when invoked adds @SuppresWarnings(keys) to
 238.435 +     * nearest declaration.
 238.436 +     * @param compilationInfo CompilationInfo to work on
 238.437 +     * @param treePath TreePath to a tree. The method will find nearest outer
 238.438 +     *        declaration. (type, method, field or local variable)
 238.439 +     * @param keys keys to be contained in the SuppresWarnings annotation. E.g.
 238.440 +     *        @SuppresWarnings( "key" ) or @SuppresWarnings( {"key1", "key2", ..., "keyN" } ).
 238.441 +     * @throws IllegalArgumentException if keys are null or empty or id no suitable element
 238.442 +     *         to put the annotation on is found (e.g. if TreePath to CompilationUnit is given")
 238.443 +     */
 238.444 +    static Fix createSuppressWarningsFix(CompilationInfo compilationInfo, TreePath treePath, String... keys ) {
 238.445 +        Parameters.notNull("compilationInfo", compilationInfo);
 238.446 +        Parameters.notNull("treePath", treePath);
 238.447 +        Parameters.notNull("keys", keys);
 238.448 +
 238.449 +        if (keys.length == 0) {
 238.450 +            throw new IllegalArgumentException("key must not be empty"); // NOI18N
 238.451 +        }
 238.452 +
 238.453 +        if (!isSuppressWarningsSupported(compilationInfo)) {
 238.454 +            return null;
 238.455 +        }
 238.456 +
 238.457 +        while (treePath.getLeaf().getKind() != Kind.COMPILATION_UNIT && !DECLARATION.contains(treePath.getLeaf().getKind())) {
 238.458 +            treePath = treePath.getParentPath();
 238.459 +        }
 238.460 +
 238.461 +        if (treePath.getLeaf().getKind() != Kind.COMPILATION_UNIT) {
 238.462 +            return new FixImpl(TreePathHandle.create(treePath, compilationInfo), compilationInfo.getFileObject(), keys);
 238.463 +        } else {
 238.464 +            return null;
 238.465 +        }
 238.466 +    }
 238.467 +
 238.468 +    /** Creates a fix, which when invoked adds @SuppresWarnings(keys) to
 238.469 +     * nearest declaration.
 238.470 +     * @param compilationInfo CompilationInfo to work on
 238.471 +     * @param treePath TreePath to a tree. The method will find nearest outer
 238.472 +     *        declaration. (type, method, field or local variable)
 238.473 +     * @param keys keys to be contained in the SuppresWarnings annotation. E.g.
 238.474 +     *        @SuppresWarnings( "key" ) or @SuppresWarnings( {"key1", "key2", ..., "keyN" } ).
 238.475 +     * @throws IllegalArgumentException if keys are null or empty or id no suitable element
 238.476 +     *         to put the annotation on is found (e.g. if TreePath to CompilationUnit is given")
 238.477 +     */
 238.478 +    static List<Fix> createSuppressWarnings(CompilationInfo compilationInfo, TreePath treePath, String... keys ) {
 238.479 +        Parameters.notNull("compilationInfo", compilationInfo);
 238.480 +        Parameters.notNull("treePath", treePath);
 238.481 +        Parameters.notNull("keys", keys);
 238.482 +
 238.483 +        if (keys.length == 0) {
 238.484 +            throw new IllegalArgumentException("key must not be empty"); // NOI18N
 238.485 +        }
 238.486 +
 238.487 +        Fix f = createSuppressWarningsFix(compilationInfo, treePath, keys);
 238.488 +
 238.489 +        if (f != null) {
 238.490 +            return Collections.<Fix>singletonList(f);
 238.491 +        } else {
 238.492 +            return Collections.emptyList();
 238.493 +        }
 238.494 +    }
 238.495 +
 238.496 +    private static boolean isSuppressWarningsSupported(CompilationInfo info) {
 238.497 +        //cannot suppress if there is no SuppressWarnings annotation in the platform:
 238.498 +        if (info.getElements().getTypeElement("java.lang.SuppressWarnings") == null)
 238.499 +            return false;
 238.500 +
 238.501 +        return info.getSourceVersion().compareTo(SourceVersion.RELEASE_5) >= 0;
 238.502 +    }
 238.503 +
 238.504 +    private static final Set<Kind> DECLARATION = EnumSet.of(Kind.ANNOTATION_TYPE, Kind.CLASS, Kind.ENUM, Kind.INTERFACE, Kind.METHOD, Kind.VARIABLE);
 238.505 +
 238.506 +    private static final class FixImpl implements Fix, SyntheticFix {
 238.507 +
 238.508 +        private String keys[];
 238.509 +        private TreePathHandle handle;
 238.510 +        private FileObject file;
 238.511 +
 238.512 +        public FixImpl(TreePathHandle handle, FileObject file, String... keys) {
 238.513 +            this.keys = keys;
 238.514 +            this.handle = handle;
 238.515 +            this.file = file;
 238.516 +        }
 238.517 +
 238.518 +        public String getText() {
 238.519 +            StringBuilder keyNames = new StringBuilder();
 238.520 +            for (int i = 0; i < keys.length; i++) {
 238.521 +                String string = keys[i];
 238.522 +                keyNames.append(string);
 238.523 +                if ( i < keys.length - 1) {
 238.524 +                    keyNames.append(", "); // NOI18N
 238.525 +                }
 238.526 +            }
 238.527 +
 238.528 +            return NbBundle.getMessage(ErrorDescriptionFactory.class, "LBL_FIX_Suppress_Waning",  keyNames.toString() );  // NOI18N
 238.529 +        }
 238.530 +
 238.531 +        public ChangeInfo implement() throws IOException {
 238.532 +            JavaSource js = JavaSource.forFileObject(file);
 238.533 +
 238.534 +            js.runModificationTask(new Task<WorkingCopy>() {
 238.535 +                public void run(WorkingCopy copy) throws IOException {
 238.536 +                    copy.toPhase(Phase.RESOLVED); //XXX: performance
 238.537 +                    TreePath path = handle.resolve(copy);
 238.538 +
 238.539 +                    while (path != null && path.getLeaf().getKind() != Kind.COMPILATION_UNIT && !DECLARATION.contains(path.getLeaf().getKind())) {
 238.540 +                        path = path.getParentPath();
 238.541 +                    }
 238.542 +
 238.543 +                    if (path.getLeaf().getKind() == Kind.COMPILATION_UNIT) {
 238.544 +                        return ;
 238.545 +                    }
 238.546 +
 238.547 +                    Tree top = path.getLeaf();
 238.548 +                    ModifiersTree modifiers = null;
 238.549 +
 238.550 +                    switch (top.getKind()) {
 238.551 +                        case ANNOTATION_TYPE:
 238.552 +                        case CLASS:
 238.553 +                        case ENUM:
 238.554 +                        case INTERFACE:
 238.555 +                            modifiers = ((ClassTree) top).getModifiers();
 238.556 +                            break;
 238.557 +                        case METHOD:
 238.558 +                            modifiers = ((MethodTree) top).getModifiers();
 238.559 +                            break;
 238.560 +                        case VARIABLE:
 238.561 +                            modifiers = ((VariableTree) top).getModifiers();
 238.562 +                            break;
 238.563 +                        default: assert false : "Unhandled Tree.Kind";  // NOI18N
 238.564 +                    }
 238.565 +
 238.566 +                    if (modifiers == null) {
 238.567 +                        return ;
 238.568 +                    }
 238.569 +
 238.570 +                    TypeElement el = copy.getElements().getTypeElement("java.lang.SuppressWarnings");  // NOI18N
 238.571 +
 238.572 +                    if (el == null) {
 238.573 +                        return ;
 238.574 +                    }
 238.575 +
 238.576 +                    LiteralTree[] keyLiterals = new LiteralTree[keys.length];
 238.577 +
 238.578 +                    for (int i = 0; i < keys.length; i++) {
 238.579 +                        keyLiterals[i] = copy.getTreeMaker().
 238.580 +                                Literal(keys[i]);
 238.581 +                    }
 238.582 +
 238.583 +                    ModifiersTree nueMods = GeneratorUtilities.get(copy).appendToAnnotationValue(modifiers, el, "value", keyLiterals);
 238.584 +
 238.585 +                    copy.rewrite(modifiers, nueMods);
 238.586 +                }
 238.587 +            }).commit();
 238.588 +
 238.589 +            return null;
 238.590 +        }
 238.591 +
 238.592 +        @Override
 238.593 +        public boolean equals(Object obj) {
 238.594 +            if (obj == null) {
 238.595 +                return false;
 238.596 +            }
 238.597 +            if (getClass() != obj.getClass()) {
 238.598 +                return false;
 238.599 +            }
 238.600 +            final FixImpl other = (FixImpl) obj;
 238.601 +            if (!Arrays.deepEquals(this.keys, other.keys)) {
 238.602 +                return false;
 238.603 +            }
 238.604 +            if (this.handle != other.handle && (this.handle == null || !this.handle.equals(other.handle))) {
 238.605 +                return false;
 238.606 +            }
 238.607 +            if (this.file != other.file && (this.file == null || !this.file.equals(other.file))) {
 238.608 +                return false;
 238.609 +            }
 238.610 +            return true;
 238.611 +        }
 238.612 +
 238.613 +        @Override
 238.614 +        public int hashCode() {
 238.615 +            int hash = 5;
 238.616 +            hash = 79 * hash + Arrays.deepHashCode(this.keys);
 238.617 +            hash = 79 * hash + (this.handle != null ? this.handle.hashCode() : 0);
 238.618 +            hash = 79 * hash + (this.file != null ? this.file.hashCode() : 0);
 238.619 +            return hash;
 238.620 +        }
 238.621 +    }
 238.622 +}
   239.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   239.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/Hint.java	Sun Oct 23 11:50:54 2016 +0200
   239.3 @@ -0,0 +1,128 @@
   239.4 +/*
   239.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   239.6 + *
   239.7 + * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
   239.8 + *
   239.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  239.10 + * Other names may be trademarks of their respective owners.
  239.11 + *
  239.12 + * The contents of this file are subject to the terms of either the GNU
  239.13 + * General Public License Version 2 only ("GPL") or the Common
  239.14 + * Development and Distribution License("CDDL") (collectively, the
  239.15 + * "License"). You may not use this file except in compliance with the
  239.16 + * License. You can obtain a copy of the License at
  239.17 + * http://www.netbeans.org/cddl-gplv2.html
  239.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  239.19 + * specific language governing permissions and limitations under the
  239.20 + * License.  When distributing the software, include this License Header
  239.21 + * Notice in each file and include the License file at
  239.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  239.23 + * particular file as subject to the "Classpath" exception as provided
  239.24 + * by Oracle in the GPL Version 2 section of the License file that
  239.25 + * accompanied this code. If applicable, add the following below the
  239.26 + * License Header, with the fields enclosed by brackets [] replaced by
  239.27 + * your own identifying information:
  239.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  239.29 + *
  239.30 + * If you wish your version of this file to be governed by only the CDDL
  239.31 + * or only the GPL Version 2, indicate your decision by adding
  239.32 + * "[Contributor] elects to include this software in this distribution
  239.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  239.34 + * single choice of license, a recipient has the option to distribute
  239.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  239.36 + * to extend the choice of license to its licensees as provided above.
  239.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  239.38 + * Version 2 license, then the option applies only if the new code is
  239.39 + * made subject to such option by the copyright holder.
  239.40 + *
  239.41 + * Contributor(s):
  239.42 + *
  239.43 + * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
  239.44 + */
  239.45 +
  239.46 +package org.netbeans.spi.java.hints;
  239.47 +
  239.48 +import java.lang.annotation.ElementType;
  239.49 +import java.lang.annotation.Retention;
  239.50 +import java.lang.annotation.RetentionPolicy;
  239.51 +import java.lang.annotation.Target;
  239.52 +import org.netbeans.spi.editor.hints.Severity;
  239.53 +
  239.54 +/** Description of a hint.
  239.55 + * When applied to a class, any enclosed method marked with a trigger
  239.56 + * will be considered to be part of this hint. When applied to a method, only this specific
  239.57 + * method will be considered to the part of the hint.
  239.58 + * Currently recognized triggers include {@link TriggerPattern} and {@link TriggerTreeKind}.
  239.59 + * @author lahvac, Petr Hrebejk
  239.60 + */
  239.61 +@Target({ElementType.TYPE, ElementType.METHOD})
  239.62 +@Retention(RetentionPolicy.SOURCE)
  239.63 +public @interface Hint {
  239.64 +    /**Manually specify the hint's id. Use only reorganizing code to keep compatibility with settings
  239.65 +     * from previous version. Id will be generated automatically is not specified.
  239.66 +     */
  239.67 +    public String id() default "";
  239.68 +    /** The hint's display name.
  239.69 +     */
  239.70 +    public String displayName();
  239.71 +    /** The hint's long description.
  239.72 +     */
  239.73 +    public String description();
  239.74 +    /**Category where the hint belongs.
  239.75 +     */
  239.76 +    public String category();
  239.77 +    /**Should the hint be enabled by default?*/
  239.78 +    public boolean enabled() default true;
  239.79 +    /**Default severity of the hint. {@link Severity#HINT} will typically be shown
  239.80 +     * only on the line with the caret.*/
  239.81 +    public Severity severity() default Severity.VERIFIER;
  239.82 +    /**Suppress warnings keys that should automatically suppress the hint.*/
  239.83 +    public String[] suppressWarnings() default {};
  239.84 +    /**A customizer that allows to customize hint's preferences.
  239.85 +     */
  239.86 +    public Class<? extends CustomizerProvider> customizerProvider() default CustomizerProvider.class;
  239.87 +    /**Whether the hint should be considered an {@link Kind#INSPECTION inspection}, i.e. it detects a code smell,
  239.88 +     * or otherwise leads to improving the code, or a {@link Kind#SUGGESTION}, which is simply
  239.89 +     * an offer to do automatically do something for the user.
  239.90 +     */
  239.91 +    public Kind hintKind() default Kind.INSPECTION;
  239.92 +    /**Specify various options for the hint*/
  239.93 +    public Options[] options() default {};
  239.94 +
  239.95 +    /**Whether the hint should be considered a {@link Kind#HINT hint}, e.g. it
  239.96 +     * detects a code smell, or otherwise leads to improving the code, or a {@link Kind#ACTION},
  239.97 +     * which is simply an offer to do automatically do something for the user.
  239.98 +     */
  239.99 +   public enum Kind {
 239.100 +       /**The hint represents a code-smell detector, or alike. It marks code that
 239.101 +        * is not correct (in some sense).
 239.102 +        */
 239.103 +       INSPECTION,
 239.104 +       
 239.105 +       /**The hint represents an offer to the user to automatically alter the code.
 239.106 +        * The transformation is not intended to improve the code, only allow the
 239.107 +        * user to do some kind of code transformation quickly.
 239.108 +        *
 239.109 +        * The only meaningful severity for suggestions if {@link Severity#CURRENT_LINE_WARNING}.
 239.110 +        */
 239.111 +       ACTION;
 239.112 +    }
 239.113 +
 239.114 +   /**Various options to altering the behavior of the hint.
 239.115 +    */
 239.116 +    public enum Options {
 239.117 +        /**The hint does not produce any automatic transformations that could be run
 239.118 +         * inside the Inspect&Refactor dialog.
 239.119 +         */
 239.120 +        QUERY,
 239.121 +        /**The hint cannot be run inside the Inspect&Refactor dialog.
 239.122 +         */
 239.123 +        NO_BATCH,
 239.124 +        /**
 239.125 +         * The hint requires heavyweight processing so it should be run explicitly only by Inspect, Refactor (or similar) 
 239.126 +         * features
 239.127 +         */
 239.128 +        HEAVY;
 239.129 +    }
 239.130 +
 239.131 +}
   240.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   240.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/HintContext.java	Sun Oct 23 11:50:54 2016 +0200
   240.3 @@ -0,0 +1,230 @@
   240.4 +/*
   240.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   240.6 + *
   240.7 + * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
   240.8 + *
   240.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  240.10 + * Other names may be trademarks of their respective owners.
  240.11 + *
  240.12 + * The contents of this file are subject to the terms of either the GNU
  240.13 + * General Public License Version 2 only ("GPL") or the Common
  240.14 + * Development and Distribution License("CDDL") (collectively, the
  240.15 + * "License"). You may not use this file except in compliance with the
  240.16 + * License. You can obtain a copy of the License at
  240.17 + * http://www.netbeans.org/cddl-gplv2.html
  240.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  240.19 + * specific language governing permissions and limitations under the
  240.20 + * License.  When distributing the software, include this License Header
  240.21 + * Notice in each file and include the License file at
  240.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  240.23 + * particular file as subject to the "Classpath" exception as provided
  240.24 + * by Oracle in the GPL Version 2 section of the License file that
  240.25 + * accompanied this code. If applicable, add the following below the
  240.26 + * License Header, with the fields enclosed by brackets [] replaced by
  240.27 + * your own identifying information:
  240.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  240.29 + *
  240.30 + * If you wish your version of this file to be governed by only the CDDL
  240.31 + * or only the GPL Version 2, indicate your decision by adding
  240.32 + * "[Contributor] elects to include this software in this distribution
  240.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  240.34 + * single choice of license, a recipient has the option to distribute
  240.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  240.36 + * to extend the choice of license to its licensees as provided above.
  240.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  240.38 + * Version 2 license, then the option applies only if the new code is
  240.39 + * made subject to such option by the copyright holder.
  240.40 + *
  240.41 + * Contributor(s):
  240.42 + *
  240.43 + * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
  240.44 + */
  240.45 +
  240.46 +package org.netbeans.spi.java.hints;
  240.47 +
  240.48 +import com.sun.source.util.TreePath;
  240.49 +import java.util.ArrayList;
  240.50 +import java.util.Collection;
  240.51 +import java.util.Collections;
  240.52 +import java.util.HashMap;
  240.53 +import java.util.LinkedList;
  240.54 +import java.util.List;
  240.55 +import java.util.Map;
  240.56 +import java.util.concurrent.atomic.AtomicBoolean;
  240.57 +import java.util.prefs.Preferences;
  240.58 +import javax.lang.model.type.TypeMirror;
  240.59 +import org.netbeans.api.java.source.CompilationInfo;
  240.60 +import org.netbeans.api.java.source.TreePathHandle;
  240.61 +import org.netbeans.modules.java.hints.providers.spi.HintMetadata;
  240.62 +import org.netbeans.modules.java.hints.spiimpl.MessageImpl;
  240.63 +import org.netbeans.modules.java.hints.spiimpl.SPIAccessor;
  240.64 +import org.netbeans.modules.java.hints.spiimpl.hints.GlobalProcessingContext;
  240.65 +import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings;
  240.66 +import org.netbeans.spi.editor.hints.Severity;
  240.67 +import org.netbeans.spi.java.hints.Decision.Factory;
  240.68 +import org.netbeans.spi.java.hints.Hint.Kind;
  240.69 +
  240.70 +/**
  240.71 + *
  240.72 + * @author Jan Lahoda
  240.73 + */
  240.74 +public class HintContext {
  240.75 +
  240.76 +    private final CompilationInfo info;
  240.77 +    private final HintsSettings settings;
  240.78 +    private final Preferences preferences;
  240.79 +    private final Severity severity;
  240.80 +    private final HintMetadata metadata;
  240.81 +    private final GlobalProcessingContext globalContext;
  240.82 +    private final TreePath path;
  240.83 +    private final Map<String, TreePath> variables;
  240.84 +    private final Map<String, Collection<? extends TreePath>> multiVariables;
  240.85 +    private final Map<String, String> variableNames;
  240.86 +    private final Collection<? super MessageImpl> messages;
  240.87 +    private final Map<String, TypeMirror> constraints;
  240.88 +    private final boolean bulkMode;
  240.89 +    private final AtomicBoolean cancel;
  240.90 +    private final int caret;
  240.91 +
  240.92 +    private HintContext(CompilationInfo info, HintsSettings settings, HintMetadata metadata, GlobalProcessingContext globalContext, TreePath path, Map<String, TreePath> variables, Map<String, Collection<? extends TreePath>> multiVariables, Map<String, String> variableNames, Map<String, TypeMirror> constraints, Collection<? super MessageImpl> problems, boolean bulkMode, AtomicBoolean cancel, int caret) {
  240.93 +        this.info = info;
  240.94 +        this.settings = settings;
  240.95 +        this.preferences = metadata != null ? settings.getHintPreferences(metadata) : null;
  240.96 +        this.severity = preferences != null ? settings.getSeverity(metadata) : Severity.ERROR;
  240.97 +        this.metadata = metadata;
  240.98 +        this.globalContext = globalContext;
  240.99 +        this.path = path;
 240.100 +
 240.101 +        variables = new HashMap<String, TreePath>(variables);
 240.102 +        variables.put("$_", path);
 240.103 +        
 240.104 +        this.variables = variables;
 240.105 +        this.multiVariables = multiVariables;
 240.106 +        this.variableNames = variableNames;
 240.107 +        this.messages = problems;
 240.108 +        this.constraints = constraints;
 240.109 +        this.bulkMode = bulkMode;
 240.110 +        this.cancel = cancel;
 240.111 +        this.caret = caret;
 240.112 +    }
 240.113 +
 240.114 +    public CompilationInfo getInfo() {
 240.115 +        return info;
 240.116 +    }
 240.117 +
 240.118 +    public Preferences getPreferences() {
 240.119 +        return preferences;
 240.120 +    }
 240.121 +
 240.122 +    public Severity getSeverity() {
 240.123 +        return severity;
 240.124 +    }
 240.125 +
 240.126 +    public TreePath getPath() {
 240.127 +        return path;
 240.128 +    }
 240.129 +
 240.130 +    public Map<String, TreePath> getVariables() {
 240.131 +        return variables;
 240.132 +    }
 240.133 +
 240.134 +    public Map<String, Collection<? extends TreePath>> getMultiVariables() {
 240.135 +        return multiVariables;
 240.136 +    }
 240.137 +
 240.138 +    public Map<String, String> getVariableNames() {
 240.139 +        return variableNames;
 240.140 +    }
 240.141 +
 240.142 +    HintMetadata getHintMetadata() {
 240.143 +        return metadata;
 240.144 +    }
 240.145 +
 240.146 +    //TODO: not sure it should be here:
 240.147 +    public Map<String, TypeMirror> getConstraints() {
 240.148 +        return constraints;
 240.149 +    }
 240.150 +
 240.151 +    /**
 240.152 +     * Will be used only for refactoring(s), will be ignored for hints.
 240.153 +     * 
 240.154 +     * @param kind
 240.155 +     * @param text
 240.156 +     */
 240.157 +    public void reportMessage(MessageKind kind, String text) {
 240.158 +        messages.add(new MessageImpl(kind, text));
 240.159 +    }
 240.160 +
 240.161 +    /**Returns {@code true} if the hint is being run in over many files, {@code false}
 240.162 +     * if only the file opened in the editor is being inspected.
 240.163 +     *
 240.164 +     * @return {@code true} if the hint is being run in over many files.
 240.165 +     */
 240.166 +    public boolean isBulkMode() {
 240.167 +        return bulkMode;
 240.168 +    }
 240.169 +
 240.170 +    /**Returns {@code true} if the computation has been canceled.
 240.171 +     *
 240.172 +     * @return {@code true} if the computation has been canceled.
 240.173 +     */
 240.174 +    public boolean isCanceled() {
 240.175 +        return cancel.get();
 240.176 +    }
 240.177 +
 240.178 +    /**For suggestions, returns the caret location for the editor
 240.179 +     * for which the suggestion is being computed. Returns -1 for hints.
 240.180 +     *
 240.181 +     * @return for suggestions, returns the caret location, -1 otherwise
 240.182 +     */
 240.183 +    public int getCaretLocation() {
 240.184 +        return metadata.kind == Kind.ACTION ? caret : -1;
 240.185 +    }
 240.186 +    
 240.187 +    public <V, R, D extends Decision<V, R>> D findDecision(TreePathHandle forPath, Factory<V, R, D> f) {
 240.188 +        List<Decision<?, ?>> decs = globalContext.decisions.get(forPath);
 240.189 +
 240.190 +        if (decs == null) {
 240.191 +            globalContext.decisions.put(forPath, decs = new ArrayList<Decision<?, ?>>());
 240.192 +        }
 240.193 +
 240.194 +        for (Decision<?, ?> d : decs) {
 240.195 +            if (d.getClass() == f.decisionClass) {
 240.196 +                return f.decisionClass.cast(d);
 240.197 +            }
 240.198 +        }
 240.199 +
 240.200 +        D res = f.create(forPath);
 240.201 +
 240.202 +        decs.add((Decision<?, ?>) res);
 240.203 +
 240.204 +        return res;
 240.205 +    }
 240.206 +
 240.207 +    public Decision<?, ?> decision;
 240.208 +
 240.209 +    public Decision<?, ?> getDecision() {
 240.210 +        return decision;
 240.211 +    }
 240.212 +
 240.213 +    public enum MessageKind {
 240.214 +        WARNING, ERROR;
 240.215 +    }
 240.216 +    
 240.217 +    static {
 240.218 +        SPIAccessor.setINSTANCE(new SPIAccessor() {
 240.219 +            @Override public HintContext createHintContext(CompilationInfo info, HintsSettings settings, HintMetadata metadata, GlobalProcessingContext globalContext, TreePath path, Map<String, TreePath> variables, Map<String, Collection<? extends TreePath>> multiVariables, Map<String, String> variableNames, Map<String, TypeMirror> constraints, Collection<? super MessageImpl> problems, boolean bulkMode, AtomicBoolean cancel, int caret) {
 240.220 +                return new HintContext(info, settings, metadata, globalContext, path, variables, multiVariables, variableNames, constraints, problems, bulkMode, cancel, caret);
 240.221 +            }
 240.222 +            @Override public HintContext createHintContext(CompilationInfo info, HintsSettings settings, HintMetadata metadata, GlobalProcessingContext globalContext, TreePath path, Map<String, TreePath> variables, Map<String, Collection<? extends TreePath>> multiVariables, Map<String, String> variableNames) {
 240.223 +                return new HintContext(info, settings, metadata, globalContext, path, variables, multiVariables, variableNames, Collections.<String, TypeMirror>emptyMap(), new LinkedList<MessageImpl>(), false, new AtomicBoolean(), -1);
 240.224 +            }
 240.225 +            @Override public HintMetadata getHintMetadata(HintContext ctx) {
 240.226 +                return ctx.getHintMetadata();
 240.227 +            }
 240.228 +            @Override public HintsSettings getHintSettings(HintContext ctx) {
 240.229 +                return ctx.settings;
 240.230 +            }
 240.231 +        });
 240.232 +    }
 240.233 +}
   241.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   241.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/HintSeverity.java	Sun Oct 23 11:50:54 2016 +0200
   241.3 @@ -0,0 +1,69 @@
   241.4 +/*
   241.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   241.6 + *
   241.7 + * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
   241.8 + *
   241.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  241.10 + * Other names may be trademarks of their respective owners.
  241.11 + *
  241.12 + * The contents of this file are subject to the terms of either the GNU
  241.13 + * General Public License Version 2 only ("GPL") or the Common
  241.14 + * Development and Distribution License("CDDL") (collectively, the
  241.15 + * "License"). You may not use this file except in compliance with the
  241.16 + * License. You can obtain a copy of the License at
  241.17 + * http://www.netbeans.org/cddl-gplv2.html
  241.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  241.19 + * specific language governing permissions and limitations under the
  241.20 + * License.  When distributing the software, include this License Header
  241.21 + * Notice in each file and include the License file at
  241.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  241.23 + * particular file as subject to the "Classpath" exception as provided
  241.24 + * by Oracle in the GPL Version 2 section of the License file that
  241.25 + * accompanied this code. If applicable, add the following below the
  241.26 + * License Header, with the fields enclosed by brackets [] replaced by
  241.27 + * your own identifying information:
  241.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  241.29 + *
  241.30 + * If you wish your version of this file to be governed by only the CDDL
  241.31 + * or only the GPL Version 2, indicate your decision by adding
  241.32 + * "[Contributor] elects to include this software in this distribution
  241.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  241.34 + * single choice of license, a recipient has the option to distribute
  241.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  241.36 + * to extend the choice of license to its licensees as provided above.
  241.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  241.38 + * Version 2 license, then the option applies only if the new code is
  241.39 + * made subject to such option by the copyright holder.
  241.40 + *
  241.41 + * Contributor(s):
  241.42 + *
  241.43 + * Portions Copyrighted 2011 Sun Microsystems, Inc.
  241.44 + */
  241.45 +package org.netbeans.spi.java.hints;
  241.46 +
  241.47 +import org.netbeans.spi.editor.hints.Severity;
  241.48 +
  241.49 +/** Severity of hint
  241.50 + *  <li><code>ERROR</code>  - will show up as error
  241.51 + *  <li><code>WARNING</code>  - will show up as warning
  241.52 + *  <li><code>CURRENT_LINE_WARNING</code>  - will only show up when the caret is placed in the erroneous element
  241.53 + * @author Petr Hrebejk
  241.54 + */
  241.55 +public enum HintSeverity {
  241.56 +    ERROR,
  241.57 +    WARNING,
  241.58 +    CURRENT_LINE_WARNING;
  241.59 +
  241.60 +    public Severity toEditorSeverity() {
  241.61 +        switch ( this ) {
  241.62 +            case ERROR:
  241.63 +                return Severity.ERROR;
  241.64 +            case WARNING:
  241.65 +                return Severity.VERIFIER;
  241.66 +            case CURRENT_LINE_WARNING:
  241.67 +                return Severity.HINT;
  241.68 +            default:
  241.69 +                return null;
  241.70 +        }
  241.71 +    }
  241.72 +}
   242.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   242.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/IntegerOption.java	Sun Oct 23 11:50:54 2016 +0200
   242.3 @@ -0,0 +1,99 @@
   242.4 +/*
   242.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   242.6 + *
   242.7 + * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
   242.8 + *
   242.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  242.10 + * Other names may be trademarks of their respective owners.
  242.11 + *
  242.12 + * The contents of this file are subject to the terms of either the GNU
  242.13 + * General Public License Version 2 only ("GPL") or the Common
  242.14 + * Development and Distribution License("CDDL") (collectively, the
  242.15 + * "License"). You may not use this file except in compliance with the
  242.16 + * License. You can obtain a copy of the License at
  242.17 + * http://www.netbeans.org/cddl-gplv2.html
  242.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  242.19 + * specific language governing permissions and limitations under the
  242.20 + * License.  When distributing the software, include this License Header
  242.21 + * Notice in each file and include the License file at
  242.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  242.23 + * particular file as subject to the "Classpath" exception as provided
  242.24 + * by Oracle in the GPL Version 2 section of the License file that
  242.25 + * accompanied this code. If applicable, add the following below the
  242.26 + * License Header, with the fields enclosed by brackets [] replaced by
  242.27 + * your own identifying information:
  242.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  242.29 + *
  242.30 + * If you wish your version of this file to be governed by only the CDDL
  242.31 + * or only the GPL Version 2, indicate your decision by adding
  242.32 + * "[Contributor] elects to include this software in this distribution
  242.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  242.34 + * single choice of license, a recipient has the option to distribute
  242.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  242.36 + * to extend the choice of license to its licensees as provided above.
  242.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  242.38 + * Version 2 license, then the option applies only if the new code is
  242.39 + * made subject to such option by the copyright holder.
  242.40 + *
  242.41 + * Contributor(s):
  242.42 + *
  242.43 + * Portions Copyrighted 2013 Sun Microsystems, Inc.
  242.44 + */
  242.45 +package org.netbeans.spi.java.hints;
  242.46 +
  242.47 +import java.lang.annotation.Documented;
  242.48 +import java.lang.annotation.ElementType;
  242.49 +import java.lang.annotation.Retention;
  242.50 +import java.lang.annotation.RetentionPolicy;
  242.51 +import java.lang.annotation.Target;
  242.52 +
  242.53 +/**
  242.54 + *  Declares an int-value option that affects hint processing.
  242.55 + *  If the Hint mixes integer and boolean options, the integer options
  242.56 + *  come first, boolean second in the UI.
  242.57 + * 
  242.58 + *  @author sdedic
  242.59 + */
  242.60 +@Retention(RetentionPolicy.SOURCE)
  242.61 +@Target(ElementType.FIELD)
  242.62 +@Documented
  242.63 +public @interface IntegerOption {
  242.64 +    /**
  242.65 +     * @return Display name of the option
  242.66 +     */
  242.67 +    public String displayName();
  242.68 +    
  242.69 +    /**
  242.70 +     * @return tooltip for mouse hover over the option
  242.71 +     */
  242.72 +    public String tooltip() default "";
  242.73 +    
  242.74 +    /**
  242.75 +     * @return default value for the option
  242.76 +     */
  242.77 +    public int defaultValue() default 0;
  242.78 +    
  242.79 +    /**
  242.80 +     * Minimum value for the option. If Integer.MIN_VALUE (the default),
  242.81 +     * no minimum will be enforced.
  242.82 +     * 
  242.83 +     * @return minimum value.
  242.84 +     */
  242.85 +    public int minValue() default 0;
  242.86 +    
  242.87 +    /**
  242.88 +     * Maximum value for the option. If Integer.MAX_VALUE (the default),
  242.89 +     * no maximum will be enforced. Please do choose a reasonable maximum value,
  242.90 +     * as the UI may size the input box to accommodate all digits of the maximum
  242.91 +     * permitted value, and the input box may seem unreasonably large.
  242.92 +     * 
  242.93 +     * @return maximum value
  242.94 +     */
  242.95 +    public int maxValue() default Integer.MAX_VALUE;
  242.96 +    
  242.97 +    /**
  242.98 +     * If non-zero, a spinner will be created with the specified step. If zero (the default),
  242.99 +     * a plain input will be presented. Negative values are not accepted at the moment and are reserved.
 242.100 +     */
 242.101 +    public int step() default 0;
 242.102 +}
   243.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   243.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/JavaFix.java	Sun Oct 23 11:50:54 2016 +0200
   243.3 @@ -0,0 +1,309 @@
   243.4 +/*
   243.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   243.6 + *
   243.7 + * Copyright 2008-2012 Oracle and/or its affiliates. All rights reserved.
   243.8 + *
   243.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  243.10 + * Other names may be trademarks of their respective owners.
  243.11 + *
  243.12 + * The contents of this file are subject to the terms of either the GNU
  243.13 + * General Public License Version 2 only ("GPL") or the Common
  243.14 + * Development and Distribution License("CDDL") (collectively, the
  243.15 + * "License"). You may not use this file except in compliance with the
  243.16 + * License. You can obtain a copy of the License at
  243.17 + * http://www.netbeans.org/cddl-gplv2.html
  243.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  243.19 + * specific language governing permissions and limitations under the
  243.20 + * License.  When distributing the software, include this License Header
  243.21 + * Notice in each file and include the License file at
  243.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  243.23 + * particular file as subject to the "Classpath" exception as provided
  243.24 + * by Oracle in the GPL Version 2 section of the License file that
  243.25 + * accompanied this code. If applicable, add the following below the
  243.26 + * License Header, with the fields enclosed by brackets [] replaced by
  243.27 + * your own identifying information:
  243.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  243.29 + *
  243.30 + * If you wish your version of this file to be governed by only the CDDL
  243.31 + * or only the GPL Version 2, indicate your decision by adding
  243.32 + * "[Contributor] elects to include this software in this distribution
  243.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  243.34 + * single choice of license, a recipient has the option to distribute
  243.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  243.36 + * to extend the choice of license to its licensees as provided above.
  243.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  243.38 + * Version 2 license, then the option applies only if the new code is
  243.39 + * made subject to such option by the copyright holder.
  243.40 + *
  243.41 + * Contributor(s):
  243.42 + *
  243.43 + * Portions Copyrighted 2008-2012 Sun Microsystems, Inc.
  243.44 + */
  243.45 +
  243.46 +package org.netbeans.spi.java.hints;
  243.47 +
  243.48 +import com.sun.source.util.TreePath;
  243.49 +import java.io.ByteArrayInputStream;
  243.50 +import java.io.ByteArrayOutputStream;
  243.51 +import java.io.IOException;
  243.52 +import java.io.InputStream;
  243.53 +import java.io.OutputStream;
  243.54 +import java.nio.ByteBuffer;
  243.55 +import java.util.Collection;
  243.56 +import java.util.Collections;
  243.57 +import java.util.HashMap;
  243.58 +import java.util.List;
  243.59 +import java.util.Map;
  243.60 +import java.util.logging.Level;
  243.61 +import java.util.logging.Logger;
  243.62 +import javax.lang.model.type.TypeMirror;
  243.63 +import javax.swing.text.BadLocationException;
  243.64 +import javax.swing.text.Document;
  243.65 +import org.netbeans.api.annotations.common.NonNull;
  243.66 +import org.netbeans.api.java.source.CompilationInfo;
  243.67 +import org.netbeans.api.java.source.TreePathHandle;
  243.68 +import org.netbeans.api.java.source.WorkingCopy;
  243.69 +import org.netbeans.api.queries.FileEncodingQuery;
  243.70 +import org.netbeans.modules.java.hints.spiimpl.JavaFixImpl;
  243.71 +import org.netbeans.modules.java.hints.spiimpl.batch.BatchUtilities;
  243.72 +import org.netbeans.modules.refactoring.spi.RefactoringElementImplementation;
  243.73 +import org.netbeans.spi.editor.hints.ChangeInfo;
  243.74 +import org.netbeans.spi.editor.hints.Fix;
  243.75 +import org.openide.filesystems.FileObject;
  243.76 +import org.openide.util.Exceptions;
  243.77 +import org.openide.util.Parameters;
  243.78 +
  243.79 +/**A base class for fixes that modify Java source code. Using this class
  243.80 + * as a base class makes creating the fix somewhat simpler, but also supports
  243.81 + * running the hint in the Inspect&Transform dialog. The fix can be converted
  243.82 + * to {@link Fix} by means of the {@link #toEditorFix() } method.
  243.83 + *
  243.84 + * @see JavaFixUtilities for various predefined fixes.
  243.85 + * @author Jan Lahoda
  243.86 + */
  243.87 +public abstract class JavaFix {
  243.88 +
  243.89 +    private final TreePathHandle handle;
  243.90 +    private final Map<String, String> options;
  243.91 +
  243.92 +    /**Create JavaFix with the given base {@link TreePath}. The base {@link TreePath}
  243.93 +     * will be passed back to the real implementation of the fix.
  243.94 +     *
  243.95 +     * @param info a {@link CompilationInfo} from which the given {@link TreePath} originates
  243.96 +     * @param tp a {@link TreePath} that will be passed back to the
  243.97 +     *           {@link #performRewrite(org.netbeans.spi.java.hints.JavaFix.TransformationContext) } method
  243.98 +     */
  243.99 +    protected JavaFix(@NonNull CompilationInfo info, @NonNull TreePath tp) {
 243.100 +        this(info, tp, Collections.<String, String>emptyMap());
 243.101 +    }
 243.102 +
 243.103 +    JavaFix(CompilationInfo info, TreePath tp, Map<String, String> options) {
 243.104 +        this.handle = TreePathHandle.create(tp, info);
 243.105 +        this.options = Collections.unmodifiableMap(new HashMap<String, String>(options));
 243.106 +    }
 243.107 +
 243.108 +    /**Create JavaFix with the given base {@link TreePathHandle}. The base {@link TreePathHandle}
 243.109 +     * will be resolved and passed back to the real implementation of the fix.
 243.110 +     *
 243.111 +     * @param handle a {@link TreePathHandle} that will be resolved and passed back to the
 243.112 +     *              {@link #performRewrite(org.netbeans.spi.java.hints.JavaFix.TransformationContext) } method
 243.113 +     */
 243.114 +    protected JavaFix(@NonNull TreePathHandle handle) {
 243.115 +        this(handle, Collections.<String, String>emptyMap());
 243.116 +    }
 243.117 +
 243.118 +    JavaFix(TreePathHandle handle, Map<String, String> options) {
 243.119 +        this.handle = handle;
 243.120 +        this.options = Collections.unmodifiableMap(new HashMap<String, String>(options));
 243.121 +    }
 243.122 +
 243.123 +    /**The display text of the fix.
 243.124 +     *
 243.125 +     * @return the display text of the fix.
 243.126 +     */
 243.127 +    protected abstract @NonNull String getText();
 243.128 +
 243.129 +    /**Do the transformations needed to implement the hint's function.
 243.130 +     *
 243.131 +     * @param ctx a context over which the fix should operate
 243.132 +     * @throws Exception if something goes wrong while performing the transformation
 243.133 +     *                   - will be logged by the infrastructure
 243.134 +     */
 243.135 +    protected abstract void performRewrite(@NonNull TransformationContext ctx) throws Exception;
 243.136 +
 243.137 +    /**Convert this {@link JavaFix} into the Editor Hints {@link Fix}.
 243.138 +     *
 243.139 +     * @return a {@link Fix}, that when invoked, will invoke {@link #performRewrite(org.netbeans.spi.java.hints.JavaFix.TransformationContext) }
 243.140 +     * method on this {@link JavaFix}.
 243.141 +     */
 243.142 +    public final Fix toEditorFix() {
 243.143 +        return new JavaFixImpl(this);
 243.144 +    }
 243.145 +
 243.146 +    static {
 243.147 +        JavaFixImpl.Accessor.INSTANCE = new JavaFixImpl.Accessor() {
 243.148 +            @Override
 243.149 +            public String getText(JavaFix jf) {
 243.150 +                return jf.getText();
 243.151 +            }
 243.152 +            @Override
 243.153 +            public ChangeInfo process(JavaFix jf, WorkingCopy wc, boolean canShowUI, Map<FileObject, byte[]> resourceContent, Collection<? super RefactoringElementImplementation> fileChanges) throws Exception {
 243.154 +                TreePath tp = jf.handle.resolve(wc);
 243.155 +
 243.156 +                if (tp == null) {
 243.157 +                    Logger.getLogger(JavaFix.class.getName()).log(Level.SEVERE, "Cannot resolve handle={0}", jf.handle);
 243.158 +                    return null;
 243.159 +                }
 243.160 +
 243.161 +                jf.performRewrite(new TransformationContext(wc, tp, canShowUI, resourceContent, fileChanges));
 243.162 +
 243.163 +                return null;
 243.164 +            }
 243.165 +            @Override
 243.166 +            public FileObject getFile(JavaFix jf) {
 243.167 +                return jf.handle.getFileObject();
 243.168 +            }
 243.169 +            @Override
 243.170 +            public Map<String, String> getOptions(JavaFix jf) {
 243.171 +                return jf.options;
 243.172 +            }
 243.173 +
 243.174 +            @Override
 243.175 +            public Fix rewriteFix(CompilationInfo info, String displayName, TreePath what, String to, Map<String, TreePath> parameters, Map<String, Collection<? extends TreePath>> parametersMulti, Map<String, String> parameterNames, Map<String, TypeMirror> constraints, Map<String, String> options, String... imports) {
 243.176 +                return JavaFixUtilities.rewriteFix(info, displayName, what, to, parameters, parametersMulti, parameterNames, constraints, options, imports);
 243.177 +            }
 243.178 +
 243.179 +            @Override
 243.180 +            public Fix createSuppressWarningsFix(CompilationInfo compilationInfo, TreePath treePath, String... keys) {
 243.181 +                return ErrorDescriptionFactory.createSuppressWarningsFix(compilationInfo, treePath, keys);
 243.182 +            }
 243.183 +
 243.184 +            @Override
 243.185 +            public List<Fix> createSuppressWarnings(CompilationInfo compilationInfo, TreePath treePath, String... keys) {
 243.186 +                return ErrorDescriptionFactory.createSuppressWarnings(compilationInfo, treePath, keys);
 243.187 +            }
 243.188 +
 243.189 +            @Override
 243.190 +            public List<Fix> resolveDefaultFixes(HintContext ctx, Fix... provided) {
 243.191 +                return ErrorDescriptionFactory.resolveDefaultFixes(ctx, provided);
 243.192 +            }
 243.193 +        };
 243.194 +    }
 243.195 +
 243.196 +    /**A context that contains a reference to a {@link WorkingCopy} through which
 243.197 +     * modifications of Java source code can be made.
 243.198 +     *
 243.199 +     */
 243.200 +    public static final class TransformationContext {
 243.201 +        private final WorkingCopy workingCopy;
 243.202 +        private final TreePath path;
 243.203 +        private final boolean canShowUI;
 243.204 +        private final Map<FileObject, byte[]> resourceContentChanges;
 243.205 +        private final Collection<? super RefactoringElementImplementation> fileChanges;
 243.206 +        TransformationContext(WorkingCopy workingCopy, TreePath path, boolean canShowUI, Map<FileObject, byte[]> resourceContentChanges, Collection<? super RefactoringElementImplementation> fileChanges) {
 243.207 +            this.workingCopy = workingCopy;
 243.208 +            this.path = path;
 243.209 +            this.canShowUI = canShowUI;
 243.210 +            this.resourceContentChanges = resourceContentChanges;
 243.211 +            this.fileChanges = fileChanges;
 243.212 +        }
 243.213 +
 243.214 +        boolean isCanShowUI() {
 243.215 +            return canShowUI;
 243.216 +        }
 243.217 +
 243.218 +        /**Returns the {@link TreePath} that was passed to a {@link JavaFix} constructor.
 243.219 +         *
 243.220 +         * @return the {@link TreePath} that was passed to a {@link JavaFix} constructor.
 243.221 +         */
 243.222 +        public @NonNull TreePath getPath() {
 243.223 +            return path;
 243.224 +        }
 243.225 +
 243.226 +        /**A {@link WorkingCopy} over which the transformation should operate.
 243.227 +         * @return {@link WorkingCopy} over which the transformation should operate.
 243.228 +         */
 243.229 +        public @NonNull WorkingCopy getWorkingCopy() {
 243.230 +            return workingCopy;
 243.231 +        }
 243.232 +
 243.233 +        /**Allows access to non-Java resources. The content of this InputStream will
 243.234 +         * include all changes done through {@link #getResourceOutput(org.openide.filesystems.FileObject) }
 243.235 +         * before calling this method.
 243.236 +         *
 243.237 +         * @param file whose content should be returned
 243.238 +         * @return the file's content
 243.239 +         * @throws IOException if something goes wrong while opening the file
 243.240 +         * @throws IllegalArgumentException if {@code file} parameter is null, or
 243.241 +         *                                  if it represents a Java file
 243.242 +         */
 243.243 +        public @NonNull InputStream getResourceContent(@NonNull FileObject file) throws IOException, IllegalArgumentException {
 243.244 +            Parameters.notNull("file", file);
 243.245 +            if ("text/x-java".equals(file.getMIMEType("text/x-java")))
 243.246 +                throw new IllegalArgumentException("Cannot access Java files");
 243.247 +
 243.248 +            byte[] newContent = resourceContentChanges != null ? resourceContentChanges.get(file) : null;
 243.249 +
 243.250 +            if (newContent == null) {
 243.251 +                final Document doc = BatchUtilities.getDocument(file);
 243.252 +
 243.253 +                if (doc != null) {
 243.254 +                    final String[] result = new String[1];
 243.255 +
 243.256 +                    doc.render(new Runnable() {
 243.257 +                        @Override public void run() {
 243.258 +                            try {
 243.259 +                                result[0] = doc.getText(0, doc.getLength());
 243.260 +                            } catch (BadLocationException ex) {
 243.261 +                                Exceptions.printStackTrace(ex);
 243.262 +                            }
 243.263 +                        }
 243.264 +                    });
 243.265 +
 243.266 +                    if (result[0] != null) {
 243.267 +                        ByteBuffer encoded = FileEncodingQuery.getEncoding(file).encode(result[0]);
 243.268 +                        byte[] encodedBytes = new byte[encoded.remaining()];
 243.269 +
 243.270 +                        encoded.get(encodedBytes);
 243.271 +
 243.272 +                        return new ByteArrayInputStream(encodedBytes);
 243.273 +                    }
 243.274 +                }
 243.275 +                
 243.276 +                return file.getInputStream();
 243.277 +            } else {
 243.278 +                return new ByteArrayInputStream(newContent);
 243.279 +            }
 243.280 +        }
 243.281 +
 243.282 +        /**Record a changed version of a file. The changes will be applied altogether with
 243.283 +         * changes to the Java file. In Inspect&Transform, changes done through this
 243.284 +         * method will be part of the preview.
 243.285 +         *
 243.286 +         * @param file whose content should be changed
 243.287 +         * @return an {@link java.io.OutputStream} into which the new content of the file should be written
 243.288 +         * @throws IOException if something goes wrong while opening the file
 243.289 +         * @throws IllegalArgumentException if {@code file} parameter is null, or
 243.290 +         *                                  if it represents a Java file
 243.291 +         */
 243.292 +        public @NonNull OutputStream getResourceOutput(@NonNull final FileObject file) throws IOException {
 243.293 +            Parameters.notNull("file", file);
 243.294 +            if ("text/x-java".equals(file.getMIMEType("text/x-java")))
 243.295 +                throw new IllegalArgumentException("Cannot access Java files");
 243.296 +            if (resourceContentChanges == null) return file.getOutputStream();
 243.297 +
 243.298 +            return new ByteArrayOutputStream() {
 243.299 +                @Override public void close() throws IOException {
 243.300 +                    super.close();
 243.301 +                    resourceContentChanges.put(file, toByteArray());
 243.302 +                }
 243.303 +            };
 243.304 +        }
 243.305 +
 243.306 +        Collection<? super RefactoringElementImplementation> getFileChanges() {
 243.307 +            return fileChanges;
 243.308 +        }
 243.309 +
 243.310 +    }
 243.311 +
 243.312 +}
   244.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   244.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/JavaFixUtilities.java	Sun Oct 23 11:50:54 2016 +0200
   244.3 @@ -0,0 +1,1642 @@
   244.4 +/*
   244.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   244.6 + *
   244.7 + * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
   244.8 + *
   244.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  244.10 + * Other names may be trademarks of their respective owners.
  244.11 + *
  244.12 + * The contents of this file are subject to the terms of either the GNU
  244.13 + * General Public License Version 2 only ("GPL") or the Common
  244.14 + * Development and Distribution License("CDDL") (collectively, the
  244.15 + * "License"). You may not use this file except in compliance with the
  244.16 + * License. You can obtain a copy of the License at
  244.17 + * http://www.netbeans.org/cddl-gplv2.html
  244.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  244.19 + * specific language governing permissions and limitations under the
  244.20 + * License.  When distributing the software, include this License Header
  244.21 + * Notice in each file and include the License file at
  244.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  244.23 + * particular file as subject to the "Classpath" exception as provided
  244.24 + * by Oracle in the GPL Version 2 section of the License file that
  244.25 + * accompanied this code. If applicable, add the following below the
  244.26 + * License Header, with the fields enclosed by brackets [] replaced by
  244.27 + * your own identifying information:
  244.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  244.29 + *
  244.30 + * If you wish your version of this file to be governed by only the CDDL
  244.31 + * or only the GPL Version 2, indicate your decision by adding
  244.32 + * "[Contributor] elects to include this software in this distribution
  244.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  244.34 + * single choice of license, a recipient has the option to distribute
  244.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  244.36 + * to extend the choice of license to its licensees as provided above.
  244.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  244.38 + * Version 2 license, then the option applies only if the new code is
  244.39 + * made subject to such option by the copyright holder.
  244.40 + *
  244.41 + * Contributor(s):
  244.42 + *
  244.43 + * Portions Copyrighted 2012 Sun Microsystems, Inc.
  244.44 + */
  244.45 +package org.netbeans.spi.java.hints;
  244.46 +
  244.47 +import com.sun.javadoc.Doc;
  244.48 +import com.sun.javadoc.Tag;
  244.49 +import com.sun.source.tree.AnnotationTree;
  244.50 +import com.sun.source.tree.AssignmentTree;
  244.51 +import com.sun.source.tree.BinaryTree;
  244.52 +import com.sun.source.tree.BlockTree;
  244.53 +import com.sun.source.tree.CaseTree;
  244.54 +import com.sun.source.tree.CatchTree;
  244.55 +import com.sun.source.tree.ClassTree;
  244.56 +import com.sun.source.tree.CompilationUnitTree;
  244.57 +import com.sun.source.tree.CompoundAssignmentTree;
  244.58 +import com.sun.source.tree.ExpressionStatementTree;
  244.59 +import com.sun.source.tree.ExpressionTree;
  244.60 +import com.sun.source.tree.IdentifierTree;
  244.61 +import com.sun.source.tree.IfTree;
  244.62 +import com.sun.source.tree.LambdaExpressionTree;
  244.63 +import com.sun.source.tree.LiteralTree;
  244.64 +import com.sun.source.tree.MemberSelectTree;
  244.65 +import com.sun.source.tree.MethodInvocationTree;
  244.66 +import com.sun.source.tree.MethodTree;
  244.67 +import com.sun.source.tree.ModifiersTree;
  244.68 +import com.sun.source.tree.NewArrayTree;
  244.69 +import com.sun.source.tree.NewClassTree;
  244.70 +import com.sun.source.tree.ParameterizedTypeTree;
  244.71 +import com.sun.source.tree.ParenthesizedTree;
  244.72 +import com.sun.source.tree.Scope;
  244.73 +import com.sun.source.tree.StatementTree;
  244.74 +import com.sun.source.tree.SwitchTree;
  244.75 +import com.sun.source.tree.Tree;
  244.76 +import com.sun.source.tree.Tree.Kind;
  244.77 +import com.sun.source.tree.TryTree;
  244.78 +import com.sun.source.tree.TypeParameterTree;
  244.79 +import com.sun.source.tree.UnaryTree;
  244.80 +import com.sun.source.tree.UnionTypeTree;
  244.81 +import com.sun.source.tree.VariableTree;
  244.82 +import com.sun.source.util.SourcePositions;
  244.83 +import com.sun.source.util.TreePath;
  244.84 +import com.sun.source.util.TreePathScanner;
  244.85 +import com.sun.source.util.TreeScanner;
  244.86 +import java.io.IOException;
  244.87 +import java.util.ArrayList;
  244.88 +import java.util.Arrays;
  244.89 +import java.util.Collection;
  244.90 +import java.util.Collections;
  244.91 +import java.util.EnumMap;
  244.92 +import java.util.EnumSet;
  244.93 +import java.util.HashMap;
  244.94 +import java.util.IdentityHashMap;
  244.95 +import java.util.Iterator;
  244.96 +import java.util.LinkedList;
  244.97 +import java.util.List;
  244.98 +import java.util.Map;
  244.99 +import java.util.Map.Entry;
 244.100 +import java.util.Set;
 244.101 +import java.util.concurrent.Callable;
 244.102 +import java.util.logging.Level;
 244.103 +import java.util.logging.Logger;
 244.104 +import java.util.regex.Matcher;
 244.105 +import javax.lang.model.element.Element;
 244.106 +import javax.lang.model.element.ElementKind;
 244.107 +import javax.lang.model.element.Modifier;
 244.108 +import javax.lang.model.element.TypeElement;
 244.109 +import javax.lang.model.type.TypeKind;
 244.110 +import javax.lang.model.type.TypeMirror;
 244.111 +import org.netbeans.api.java.classpath.ClassPath;
 244.112 +import org.netbeans.api.java.classpath.ClassPath.PathConversionMode;
 244.113 +import org.netbeans.api.java.queries.SourceForBinaryQuery;
 244.114 +import org.netbeans.api.java.source.ClasspathInfo;
 244.115 +import org.netbeans.api.java.source.ClasspathInfo.PathKind;
 244.116 +import org.netbeans.api.java.source.CompilationInfo;
 244.117 +import org.netbeans.api.java.source.SourceUtils;
 244.118 +import org.netbeans.api.java.source.TreeMaker;
 244.119 +import org.netbeans.api.java.source.TreePathHandle;
 244.120 +import org.netbeans.api.java.source.TypeMirrorHandle;
 244.121 +import org.netbeans.api.java.source.WorkingCopy;
 244.122 +import org.netbeans.api.java.source.matching.Occurrence;
 244.123 +import org.netbeans.api.java.source.matching.Pattern;
 244.124 +import org.netbeans.api.project.FileOwnerQuery;
 244.125 +import org.netbeans.api.project.Project;
 244.126 +import org.netbeans.modules.java.hints.spiimpl.Hacks;
 244.127 +import org.netbeans.modules.java.hints.spiimpl.Utilities;
 244.128 +import org.netbeans.modules.java.hints.spiimpl.ipi.upgrade.ProjectDependencyUpgrader;
 244.129 +import org.netbeans.modules.refactoring.spi.SimpleRefactoringElementImplementation;
 244.130 +import org.netbeans.spi.editor.hints.Fix;
 244.131 +import org.netbeans.spi.java.classpath.support.ClassPathSupport;
 244.132 +import org.netbeans.spi.java.hints.JavaFix.TransformationContext;
 244.133 +import org.openide.filesystems.FileObject;
 244.134 +import org.openide.filesystems.FileUtil;
 244.135 +import org.openide.loaders.DataFolder;
 244.136 +import org.openide.loaders.DataObject;
 244.137 +import org.openide.loaders.DataObjectNotFoundException;
 244.138 +import org.openide.modules.SpecificationVersion;
 244.139 +import org.openide.text.PositionBounds;
 244.140 +import org.openide.util.Exceptions;
 244.141 +import org.openide.util.Lookup;
 244.142 +import org.openide.util.NbBundle.Messages;
 244.143 +import org.openide.util.NbCollections;
 244.144 +
 244.145 +/**Factory methods for various predefined {@link JavaFix} implementations.
 244.146 + *
 244.147 + * @author lahvac
 244.148 + */
 244.149 +public class JavaFixUtilities {
 244.150 +
 244.151 +    /**Prepare a fix that will replace the given tree node ({@code what}) with the
 244.152 +     * given code. Any variables in the {@code to} pattern will be replaced with their
 244.153 +     * values from {@link HintContext#getVariables() }, {@link HintContext#getMultiVariables() }
 244.154 +     * and {@link HintContext#getVariableNames() }.
 244.155 +     *
 244.156 +     * @param ctx basic context for which the fix should be created
 244.157 +     * @param displayName the display name of the fix
 244.158 +     * @param what the tree node that should be replaced
 244.159 +     * @param to the new code that should replaced the {@code what} tree node
 244.160 +     * @return an editor fix that performs the required transformation
 244.161 +     */
 244.162 +    public static Fix rewriteFix(HintContext ctx, String displayName, TreePath what, final String to) {
 244.163 +        return rewriteFix(ctx.getInfo(), displayName, what, to, ctx.getVariables(), ctx.getMultiVariables(), ctx.getVariableNames(), ctx.getConstraints(), Collections.<String, String>emptyMap());
 244.164 +    }
 244.165 +
 244.166 +    static Fix rewriteFix(CompilationInfo info, String displayName, TreePath what, final String to, Map<String, TreePath> parameters, Map<String, Collection<? extends TreePath>> parametersMulti, final Map<String, String> parameterNames, Map<String, TypeMirror> constraints, Map<String, String> options, String... imports) {
 244.167 +        final Map<String, TreePathHandle> params = new HashMap<String, TreePathHandle>();
 244.168 +        final Map<String, Object> extraParamsData = new HashMap<String, Object>();
 244.169 +
 244.170 +        for (Entry<String, TreePath> e : parameters.entrySet()) {
 244.171 +            params.put(e.getKey(), TreePathHandle.create(e.getValue(), info));
 244.172 +            if (e.getValue() instanceof Callable) {
 244.173 +                try {
 244.174 +                    extraParamsData.put(e.getKey(), ((Callable) e.getValue()).call());
 244.175 +                } catch (Exception ex) {
 244.176 +                    Exceptions.printStackTrace(ex);
 244.177 +                }
 244.178 +            }
 244.179 +        }
 244.180 +
 244.181 +        final Map<String, Collection<TreePathHandle>> paramsMulti = new HashMap<String, Collection<TreePathHandle>>();
 244.182 +
 244.183 +        for (Entry<String, Collection<? extends TreePath>> e : parametersMulti.entrySet()) {
 244.184 +            Collection<TreePathHandle> tph = new LinkedList<TreePathHandle>();
 244.185 +
 244.186 +            for (TreePath tp : e.getValue()) {
 244.187 +                tph.add(TreePathHandle.create(tp, info));
 244.188 +            }
 244.189 +
 244.190 +            paramsMulti.put(e.getKey(), tph);
 244.191 +        }
 244.192 +
 244.193 +        final Map<String, TypeMirrorHandle<?>> constraintsHandles = new HashMap<String, TypeMirrorHandle<?>>();
 244.194 +
 244.195 +        for (Entry<String, TypeMirror> c : constraints.entrySet()) {
 244.196 +            constraintsHandles.put(c.getKey(), TypeMirrorHandle.create(c.getValue()));
 244.197 +        }
 244.198 +
 244.199 +        if (displayName == null) {
 244.200 +            displayName = defaultFixDisplayName(info, parameters, to);
 244.201 +        }
 244.202 +
 244.203 +        return new JavaFixRealImpl(info, what, options, displayName, to, params, extraParamsData, paramsMulti, parameterNames, constraintsHandles, Arrays.asList(imports)).toEditorFix();
 244.204 +    }
 244.205 +
 244.206 +    /**Creates a fix that removes the given code corresponding to the given tree
 244.207 +     * node from the source code.
 244.208 +     * 
 244.209 +     * @param ctx basic context for which the fix should be created
 244.210 +     * @param displayName the display name of the fix
 244.211 +     * @param what the tree node that should be removed
 244.212 +     * @return an editor fix that removes the give tree from the source code
 244.213 +     */
 244.214 +    public static Fix removeFromParent(HintContext ctx, String displayName, TreePath what) {
 244.215 +        return new RemoveFromParent(displayName, ctx.getInfo(), what).toEditorFix();
 244.216 +    }
 244.217 +
 244.218 +    private static String defaultFixDisplayName(CompilationInfo info, Map<String, TreePath> variables, String replaceTarget) {
 244.219 +        Map<String, String> stringsForVariables = new HashMap<String, String>();
 244.220 +
 244.221 +        for (Entry<String, TreePath> e : variables.entrySet()) {
 244.222 +            Tree t = e.getValue().getLeaf();
 244.223 +            SourcePositions sp = info.getTrees().getSourcePositions();
 244.224 +            int startPos = (int) sp.getStartPosition(info.getCompilationUnit(), t);
 244.225 +            int endPos = (int) sp.getEndPosition(info.getCompilationUnit(), t);
 244.226 +
 244.227 +            if (startPos >= 0 && endPos >= 0) {
 244.228 +                stringsForVariables.put(e.getKey(), info.getText().substring(startPos, endPos));
 244.229 +            } else {
 244.230 +                stringsForVariables.put(e.getKey(), "");
 244.231 +            }
 244.232 +        }
 244.233 +
 244.234 +        if (!stringsForVariables.containsKey("$this")) {
 244.235 +            //XXX: is this correct?
 244.236 +            stringsForVariables.put("$this", "this");
 244.237 +        }
 244.238 +
 244.239 +        for (Entry<String, String> e : stringsForVariables.entrySet()) {
 244.240 +            String quotedVariable = java.util.regex.Pattern.quote(e.getKey());
 244.241 +            String quotedTarget = Matcher.quoteReplacement(e.getValue());
 244.242 +            replaceTarget = replaceTarget.replaceAll(quotedVariable, quotedTarget);
 244.243 +        }
 244.244 +
 244.245 +        return "Rewrite to " + replaceTarget;
 244.246 +    }
 244.247 +
 244.248 +    private static void checkDependency(CompilationInfo copy, Element e, boolean canShowUI) {
 244.249 +        SpecificationVersion sv = computeSpecVersion(copy, e);
 244.250 +
 244.251 +        while (sv == null && e.getKind() != ElementKind.PACKAGE) {
 244.252 +            e = e.getEnclosingElement();
 244.253 +            sv = computeSpecVersion(copy, e);
 244.254 +        }
 244.255 +
 244.256 +        if (sv == null) {
 244.257 +            return ;
 244.258 +        }
 244.259 +
 244.260 +        Project currentProject = FileOwnerQuery.getOwner(copy.getFileObject());
 244.261 +
 244.262 +        if (currentProject == null) {
 244.263 +            return ;
 244.264 +        }
 244.265 +
 244.266 +        FileObject file = getFile(copy, e);
 244.267 +
 244.268 +        if (file == null) {
 244.269 +            return ;
 244.270 +        }
 244.271 +
 244.272 +        FileObject root = findRootForFile(file, copy.getClasspathInfo());
 244.273 +
 244.274 +        if (root == null) {
 244.275 +            return ;
 244.276 +        }
 244.277 +
 244.278 +        Project referedProject = FileOwnerQuery.getOwner(file);
 244.279 +
 244.280 +        if (referedProject != null && currentProject.getProjectDirectory().equals(referedProject.getProjectDirectory())) {
 244.281 +            return ;
 244.282 +        }
 244.283 +
 244.284 +        for (ProjectDependencyUpgrader pdu : Lookup.getDefault().lookupAll(ProjectDependencyUpgrader.class)) {
 244.285 +            if (pdu.ensureDependency(currentProject, root, sv, canShowUI)) {
 244.286 +                return ;
 244.287 +            }
 244.288 +        }
 244.289 +    }
 244.290 +
 244.291 +    private static java.util.regex.Pattern SPEC_VERSION = java.util.regex.Pattern.compile("[0-9]+(\\.[0-9]+)+");
 244.292 +
 244.293 +    static SpecificationVersion computeSpecVersion(CompilationInfo info, Element el) {
 244.294 +        if (!Utilities.isJavadocSupported(info)) return null;
 244.295 +
 244.296 +        Doc javaDoc = info.getElementUtilities().javaDocFor(el);
 244.297 +
 244.298 +        if (javaDoc == null) return null;
 244.299 +
 244.300 +        for (Tag since : javaDoc.tags("@since")) {
 244.301 +            String text = since.text();
 244.302 +
 244.303 +            Matcher m = SPEC_VERSION.matcher(text);
 244.304 +
 244.305 +            if (!m.find()) {
 244.306 +                continue;
 244.307 +            }
 244.308 +
 244.309 +            return new SpecificationVersion(m.group()/*ver.toString()*/);
 244.310 +        }
 244.311 +
 244.312 +        return null;
 244.313 +    }
 244.314 +
 244.315 +    @SuppressWarnings("deprecation")
 244.316 +    private static FileObject getFile(CompilationInfo copy, Element e) {
 244.317 +        return SourceUtils.getFile(e, copy.getClasspathInfo());
 244.318 +    }
 244.319 +
 244.320 +    private static FileObject findRootForFile(final FileObject file, final ClasspathInfo cpInfo) {
 244.321 +        ClassPath cp = ClassPathSupport.createProxyClassPath(
 244.322 +            new ClassPath[] {
 244.323 +                cpInfo.getClassPath(ClasspathInfo.PathKind.SOURCE),
 244.324 +                cpInfo.getClassPath(ClasspathInfo.PathKind.BOOT),
 244.325 +                cpInfo.getClassPath(ClasspathInfo.PathKind.COMPILE),
 244.326 +            });
 244.327 +
 244.328 +        FileObject root = cp.findOwnerRoot(file);
 244.329 +
 244.330 +        if (root != null) {
 244.331 +            return root;
 244.332 +        }
 244.333 +
 244.334 +        for (ClassPath.Entry e : cp.entries()) {
 244.335 +            FileObject[] sourceRoots = SourceForBinaryQuery.findSourceRoots(e.getURL()).getRoots();
 244.336 +
 244.337 +            if (sourceRoots.length == 0) continue;
 244.338 +
 244.339 +            ClassPath sourcePath = ClassPathSupport.createClassPath(sourceRoots);
 244.340 +
 244.341 +            root = sourcePath.findOwnerRoot(file);
 244.342 +
 244.343 +            if (root != null) {
 244.344 +                return root;
 244.345 +            }
 244.346 +        }
 244.347 +        return null;
 244.348 +    }
 244.349 +
 244.350 +    private static boolean isStaticElement(Element el) {
 244.351 +        if (el == null) return false;
 244.352 +
 244.353 +        if (el.asType() == null || el.asType().getKind() == TypeKind.ERROR) {
 244.354 +            return false;
 244.355 +        }
 244.356 +
 244.357 +        if (el.getModifiers().contains(Modifier.STATIC)) {
 244.358 +            //XXX:
 244.359 +            if (!el.getKind().isClass() && !el.getKind().isInterface()) {
 244.360 +                return false;
 244.361 +            }
 244.362 +
 244.363 +            return true;
 244.364 +        }
 244.365 +
 244.366 +        if (el.getKind().isClass() || el.getKind().isInterface()) {
 244.367 +            return el.getEnclosingElement().getKind() == ElementKind.PACKAGE;
 244.368 +        }
 244.369 +
 244.370 +        return false;
 244.371 +    }
 244.372 +
 244.373 +    private static class JavaFixRealImpl extends JavaFix {
 244.374 +        private final String displayName;
 244.375 +        private final Map<String, TreePathHandle> params;
 244.376 +        private final Map<String, Object> extraParamsData;
 244.377 +        private final Map<String, Collection<TreePathHandle>> paramsMulti;
 244.378 +        private final Map<String, String> parameterNames;
 244.379 +        private final Map<String, TypeMirrorHandle<?>> constraintsHandles;
 244.380 +        private final Iterable<? extends String> imports;
 244.381 +        private final String to;
 244.382 +
 244.383 +        public JavaFixRealImpl(CompilationInfo info, TreePath what, Map<String, String> options, String displayName, String to, Map<String, TreePathHandle> params, Map<String, Object> extraParamsData, Map<String, Collection<TreePathHandle>> paramsMulti, final Map<String, String> parameterNames, Map<String, TypeMirrorHandle<?>> constraintsHandles, Iterable<? extends String> imports) {
 244.384 +            super(info, what, options);
 244.385 +
 244.386 +            this.displayName = displayName;
 244.387 +            this.to = to;
 244.388 +            this.params = params;
 244.389 +            this.extraParamsData = extraParamsData;
 244.390 +            this.paramsMulti = paramsMulti;
 244.391 +            this.parameterNames = parameterNames;
 244.392 +            this.constraintsHandles = constraintsHandles;
 244.393 +            this.imports = imports;
 244.394 +        }
 244.395 +
 244.396 +        @Override
 244.397 +        protected String getText() {
 244.398 +            return displayName;
 244.399 +        }
 244.400 +
 244.401 +        @Override
 244.402 +        protected void performRewrite(TransformationContext ctx) {
 244.403 +            final WorkingCopy wc = ctx.getWorkingCopy();
 244.404 +            TreePath tp = ctx.getPath();
 244.405 +            final Map<String, TreePath> parameters = new HashMap<String, TreePath>();
 244.406 +
 244.407 +            for (Entry<String, TreePathHandle> e : params.entrySet()) {
 244.408 +                TreePath p = e.getValue().resolve(wc);
 244.409 +
 244.410 +                if (p == null) {
 244.411 +                    Logger.getLogger(JavaFix.class.getName()).log(Level.SEVERE, "Cannot resolve handle={0}", e.getValue());
 244.412 +                }
 244.413 +
 244.414 +                parameters.put(e.getKey(), p);
 244.415 +            }
 244.416 +
 244.417 +            final Map<String, Collection<TreePath>> parametersMulti = new HashMap<String, Collection<TreePath>>();
 244.418 +
 244.419 +            for (Entry<String, Collection<TreePathHandle>> e : paramsMulti.entrySet()) {
 244.420 +                Collection<TreePath> tps = new LinkedList<TreePath>();
 244.421 +
 244.422 +                for (TreePathHandle tph : e.getValue()) {
 244.423 +                    TreePath p = tph.resolve(wc);
 244.424 +
 244.425 +                    if (p == null) {
 244.426 +                        Logger.getLogger(JavaFix.class.getName()).log(Level.SEVERE, "Cannot resolve handle={0}", e.getValue());
 244.427 +                    }
 244.428 +
 244.429 +                    tps.add(p);
 244.430 +                }
 244.431 +
 244.432 +                parametersMulti.put(e.getKey(), tps);
 244.433 +            }
 244.434 +
 244.435 +            Map<String, TypeMirror> constraints = new HashMap<String, TypeMirror>();
 244.436 +
 244.437 +            for (Entry<String, TypeMirrorHandle<?>> c : constraintsHandles.entrySet()) {
 244.438 +                constraints.put(c.getKey(), c.getValue().resolve(wc));
 244.439 +            }
 244.440 +
 244.441 +            Scope scope = Utilities.constructScope(wc, constraints, imports);
 244.442 +
 244.443 +            assert scope != null;
 244.444 +
 244.445 +            Tree parsed = Utilities.parseAndAttribute(wc, to, scope);
 244.446 +            
 244.447 +            if (parsed.getKind() == Kind.EXPRESSION_STATEMENT && ExpressionTree.class.isAssignableFrom(tp.getLeaf().getKind().asInterface())) {
 244.448 +                parsed = ((ExpressionStatementTree) parsed).getExpression();
 244.449 +            }
 244.450 +            
 244.451 +            Map<Tree, Tree> rewriteFromTo = new IdentityHashMap<Tree, Tree>();
 244.452 +            Tree original;
 244.453 +
 244.454 +            if (Utilities.isFakeBlock(parsed)) {
 244.455 +                TreePath parent = tp.getParentPath();
 244.456 +                List<? extends StatementTree> statements = ((BlockTree) parsed).getStatements();
 244.457 +                
 244.458 +                if (tp.getLeaf().getKind() == Kind.BLOCK) {
 244.459 +                    BlockTree real = (BlockTree) tp.getLeaf();
 244.460 +                    rewriteFromTo.put(original = real, wc.getTreeMaker().Block(statements, real.isStatic()));
 244.461 +                } else {
 244.462 +                    statements = statements.subList(1, statements.size() - 1);
 244.463 +
 244.464 +                    if (parent.getLeaf().getKind() == Kind.BLOCK) {
 244.465 +                        List<StatementTree> newStatements = new LinkedList<StatementTree>();
 244.466 +
 244.467 +                        for (StatementTree st : ((BlockTree) parent.getLeaf()).getStatements()) {
 244.468 +                            if (st == tp.getLeaf()) {
 244.469 +                                newStatements.addAll(statements);
 244.470 +                            } else {
 244.471 +                                newStatements.add(st);
 244.472 +                            }
 244.473 +                        }
 244.474 +
 244.475 +                        rewriteFromTo.put(original = parent.getLeaf(), wc.getTreeMaker().Block(newStatements, ((BlockTree) parent.getLeaf()).isStatic()));
 244.476 +                    } else {
 244.477 +                        rewriteFromTo.put(original = tp.getLeaf(), wc.getTreeMaker().Block(statements, false));
 244.478 +                    }
 244.479 +                }
 244.480 +            } else if (Utilities.isFakeClass(parsed)) {
 244.481 +                TreePath parent = tp.getParentPath();
 244.482 +                List<? extends Tree> members = ((ClassTree) parsed).getMembers();
 244.483 +
 244.484 +                members = members.subList(1, members.size());
 244.485 +
 244.486 +                assert parent.getLeaf().getKind() == Kind.CLASS;
 244.487 +
 244.488 +                List<Tree> newMembers = new LinkedList<Tree>();
 244.489 +
 244.490 +                ClassTree ct = (ClassTree) parent.getLeaf();
 244.491 +
 244.492 +                for (Tree t : ct.getMembers()) {
 244.493 +                    if (t == tp.getLeaf()) {
 244.494 +                        newMembers.addAll(members);
 244.495 +                    } else {
 244.496 +                        newMembers.add(t);
 244.497 +                    }
 244.498 +                }
 244.499 +
 244.500 +                rewriteFromTo.put(original = parent.getLeaf(), wc.getTreeMaker().Class(ct.getModifiers(), ct.getSimpleName(), ct.getTypeParameters(), ct.getExtendsClause(), ct.getImplementsClause(), newMembers));
 244.501 +            } else if (tp.getLeaf().getKind() == Kind.BLOCK && parametersMulti.containsKey("$$1$") && parsed.getKind() != Kind.BLOCK && StatementTree.class.isAssignableFrom(parsed.getKind().asInterface())) {
 244.502 +                List<StatementTree> newStatements = new LinkedList<StatementTree>();
 244.503 +
 244.504 +                newStatements.add(wc.getTreeMaker().ExpressionStatement(wc.getTreeMaker().Identifier("$$1$")));
 244.505 +                newStatements.add((StatementTree) parsed);
 244.506 +                newStatements.add(wc.getTreeMaker().ExpressionStatement(wc.getTreeMaker().Identifier("$$2$")));
 244.507 +
 244.508 +                parsed = wc.getTreeMaker().Block(newStatements, ((BlockTree) tp.getLeaf()).isStatic());
 244.509 +
 244.510 +                rewriteFromTo.put(original = tp.getLeaf(), parsed);
 244.511 +            } else {
 244.512 +                while (   tp.getParentPath().getLeaf().getKind() == Kind.PARENTHESIZED
 244.513 +                       && tp.getLeaf().getKind() != parsed.getKind()
 244.514 +                       && tp.getParentPath() != null
 244.515 +                       && tp.getParentPath().getParentPath() != null
 244.516 +                       && !requiresParenthesis(parsed, tp.getParentPath().getLeaf(), tp.getParentPath().getParentPath().getLeaf())
 244.517 +                       && requiresParenthesis(tp.getLeaf(), tp.getParentPath().getLeaf(), tp.getParentPath().getParentPath().getLeaf()))
 244.518 +                    tp = tp.getParentPath();
 244.519 +                rewriteFromTo.put(original = tp.getLeaf(), parsed);
 244.520 +            }
 244.521 +
 244.522 +            //prevent generating QualIdents inside import clauses - might be better to solve that inside ImportAnalysis2,
 244.523 +            //but that seems not to be straightforward:
 244.524 +            boolean inImport = parsed.getKind() == Kind.IMPORT;
 244.525 +            boolean inPackage = false;
 244.526 +            TreePath w = tp;
 244.527 +
 244.528 +            while (!inImport && w != null) {
 244.529 +                inImport |= w.getLeaf().getKind() == Kind.IMPORT;
 244.530 +                inPackage |= w.getParentPath() != null && w.getParentPath().getLeaf().getKind() == Kind.COMPILATION_UNIT && ((CompilationUnitTree) w.getParentPath().getLeaf()).getPackageName() == w.getLeaf();
 244.531 +                w = w.getParentPath();
 244.532 +            }
 244.533 +
 244.534 +            final Set<Tree> originalTrees = Collections.newSetFromMap(new IdentityHashMap<Tree, Boolean>());
 244.535 +            
 244.536 +            new TreeScanner<Void, Void>() {
 244.537 +                @Override public Void scan(Tree tree, Void p) {
 244.538 +                    originalTrees.add(tree);
 244.539 +                    return super.scan(tree, p);
 244.540 +                }
 244.541 +            }.scan(original, null);
 244.542 +            
 244.543 +            new ReplaceParameters(wc, ctx.isCanShowUI(), inImport, parameters, extraParamsData, parametersMulti, parameterNames, rewriteFromTo, originalTrees).scan(new TreePath(tp.getParentPath(), rewriteFromTo.get(original)), null);
 244.544 +
 244.545 +            if (inPackage) {
 244.546 +                String newPackage = wc.getTreeUtilities().translate(wc.getCompilationUnit().getPackageName(), new IdentityHashMap<Tree, Tree>(rewriteFromTo))./*XXX: not correct*/toString();
 244.547 +
 244.548 +                ClassPath source = wc.getClasspathInfo().getClassPath(PathKind.SOURCE);
 244.549 +                FileObject ownerRoot = source.findOwnerRoot(wc.getFileObject());
 244.550 +
 244.551 +                if (ownerRoot != null) {
 244.552 +                    ctx.getFileChanges().add(new MoveFile(wc.getFileObject(), ownerRoot, newPackage.replace('.', '/')));
 244.553 +                } else {
 244.554 +                    Logger.getLogger(JavaFix.class.getName()).log(Level.WARNING, "{0} not on its source path ({1})", new Object[] {FileUtil.getFileDisplayName(wc.getFileObject()), source.toString(PathConversionMode.PRINT)});
 244.555 +                }
 244.556 +            }
 244.557 +            
 244.558 +            for (Entry<Tree, Tree> e : rewriteFromTo.entrySet()) {
 244.559 +                wc.rewrite(e.getKey(), e.getValue());
 244.560 +            }
 244.561 +        }
 244.562 +    }
 244.563 +
 244.564 +    private static final Set<Kind> NUMBER_LITERAL_KINDS = EnumSet.of(Kind.FLOAT_LITERAL, Kind.DOUBLE_LITERAL, Kind.INT_LITERAL, Kind.LONG_LITERAL);
 244.565 +
 244.566 +    private static class ReplaceParameters extends TreePathScanner<Number, Void> {
 244.567 +
 244.568 +        private final CompilationInfo info;
 244.569 +        private final TreeMaker make;
 244.570 +        private final boolean canShowUI;
 244.571 +        private final boolean inImport;
 244.572 +        private final Map<String, TreePath> parameters;
 244.573 +        private final Map<String, Object> extraParamsData;
 244.574 +        private final Map<String, Collection<TreePath>> parametersMulti;
 244.575 +        private final Map<String, String> parameterNames;
 244.576 +        private final Map<Tree, Tree> rewriteFromTo;
 244.577 +        private final Set<Tree> originalTrees;
 244.578 +
 244.579 +        public ReplaceParameters(WorkingCopy wc, boolean canShowUI, boolean inImport, Map<String, TreePath> parameters, Map<String, Object> extraParamsData, Map<String, Collection<TreePath>> parametersMulti, Map<String, String> parameterNames, Map<Tree, Tree> rewriteFromTo, Set<Tree> originalTrees) {
 244.580 +            this.parameters = parameters;
 244.581 +            this.info = wc;
 244.582 +            this.make = wc.getTreeMaker();
 244.583 +            this.canShowUI = canShowUI;
 244.584 +            this.inImport = inImport;
 244.585 +            this.extraParamsData = extraParamsData;
 244.586 +            this.parametersMulti = parametersMulti;
 244.587 +            this.parameterNames = parameterNames;
 244.588 +            this.rewriteFromTo = rewriteFromTo;
 244.589 +            this.originalTrees = originalTrees;
 244.590 +        }
 244.591 +
 244.592 +        @Override
 244.593 +        public Number visitIdentifier(IdentifierTree node, Void p) {
 244.594 +            String name = node.getName().toString();
 244.595 +            Tree newNode = handleIdentifier(name, node);
 244.596 +            
 244.597 +            if (newNode != null) {
 244.598 +                rewrite(node, newNode);
 244.599 +                if (NUMBER_LITERAL_KINDS.contains(newNode.getKind())) {
 244.600 +                    return (Number) ((LiteralTree) newNode).getValue();
 244.601 +                }
 244.602 +            }
 244.603 +
 244.604 +            Element e = info.getTrees().getElement(getCurrentPath());
 244.605 +
 244.606 +            if (e != null && isStaticElement(e) && !inImport) {
 244.607 +                rewrite(node, make.QualIdent(e));
 244.608 +            }
 244.609 +
 244.610 +            return super.visitIdentifier(node, p);
 244.611 +        }
 244.612 +
 244.613 +        @Override
 244.614 +        public Number visitTypeParameter(TypeParameterTree node, Void p) {
 244.615 +            String name = node.getName().toString();
 244.616 +            Tree newNode = handleIdentifier(name, node);
 244.617 +            
 244.618 +            if (newNode != null) {
 244.619 +                rewrite(node, newNode);
 244.620 +                if (NUMBER_LITERAL_KINDS.contains(newNode.getKind())) {
 244.621 +                    return (Number) ((LiteralTree) newNode).getValue();
 244.622 +                }
 244.623 +            }
 244.624 +            
 244.625 +            return super.visitTypeParameter(node, p);
 244.626 +        }
 244.627 +        
 244.628 +        private Tree handleIdentifier(String name, Tree node) {
 244.629 +            TreePath tp = parameters.get(name);
 244.630 +
 244.631 +            if (tp != null) {
 244.632 +                if (tp.getLeaf() instanceof Hacks.RenameTree) {
 244.633 +                    Hacks.RenameTree rt = (Hacks.RenameTree) tp.getLeaf();
 244.634 +                    return make.setLabel(rt.originalTree, rt.newName);
 244.635 +                }
 244.636 +                if (!parameterNames.containsKey(name)) {
 244.637 +                    Tree target = tp.getLeaf();
 244.638 +                    if (NUMBER_LITERAL_KINDS.contains(target.getKind())) {
 244.639 +                        return target;
 244.640 +                    }
 244.641 +                    //TODO: might also remove parenthesis, but needs to ensure the diff will still be minimal
 244.642 +//                    while (target.getKind() == Kind.PARENTHESIZED
 244.643 +//                           && !requiresParenthesis(((ParenthesizedTree) target).getExpression(), getCurrentPath().getParentPath().getLeaf())) {
 244.644 +//                        target = ((ParenthesizedTree) target).getExpression();
 244.645 +//                    }
 244.646 +                    if (   getCurrentPath().getParentPath() != null
 244.647 +                        && getCurrentPath().getParentPath().getLeaf().getKind() == Kind.LOGICAL_COMPLEMENT
 244.648 +                        && (   tp.getParentPath() == null
 244.649 +                            || tp.getParentPath().getLeaf().getKind() != Kind.LOGICAL_COMPLEMENT)) {
 244.650 +                        Tree negated = negate((ExpressionTree) tp.getLeaf(), getCurrentPath().getParentPath().getParentPath().getLeaf(), true);
 244.651 +                        
 244.652 +                        if (negated != null) {
 244.653 +                            rewrite(getCurrentPath().getParentPath().getLeaf(), negated);
 244.654 +                        }
 244.655 +                    }
 244.656 +                    if (requiresParenthesis(target, node, getCurrentPath().getParentPath().getLeaf())) {
 244.657 +                        target = make.Parenthesized((ExpressionTree) target);
 244.658 +                    }
 244.659 +                    return target;
 244.660 +                }
 244.661 +            }
 244.662 +
 244.663 +            String variableName = parameterNames.get(name);
 244.664 +
 244.665 +            if (variableName != null) {
 244.666 +                return make.Identifier(variableName);
 244.667 +            }
 244.668 +            
 244.669 +            return null;
 244.670 +        }
 244.671 +
 244.672 +        @Override
 244.673 +        public Number visitMemberSelect(MemberSelectTree node, Void p) {
 244.674 +            Element e = info.getTrees().getElement(getCurrentPath());
 244.675 +
 244.676 +            if (e != null && (e.getKind() != ElementKind.CLASS || ((TypeElement) e).asType().getKind() != TypeKind.ERROR)) {
 244.677 +                //check correct dependency:
 244.678 +                checkDependency(info, e, canShowUI);
 244.679 +
 244.680 +                if (isStaticElement(e) && !inImport) {
 244.681 +                    rewrite(node, make.QualIdent(e));
 244.682 +
 244.683 +                    return null;
 244.684 +                }
 244.685 +            }
 244.686 +            
 244.687 +            MemberSelectTree nue = node;
 244.688 +            String selectedName = node.getIdentifier().toString();
 244.689 +
 244.690 +            if (selectedName.startsWith("$") && parameterNames.get(selectedName) != null) {
 244.691 +                nue = make.MemberSelect(node.getExpression(), parameterNames.get(selectedName));
 244.692 +            }
 244.693 +
 244.694 +            if (nue.getExpression().getKind() == Kind.IDENTIFIER) {
 244.695 +                String name = ((IdentifierTree) nue.getExpression()).getName().toString();
 244.696 +
 244.697 +                if (name.startsWith("$") && parameters.get(name) == null) {
 244.698 +                    //XXX: unbound variable, use identifier instead of member select - may cause problems?
 244.699 +                    rewrite(node, make.Identifier(nue.getIdentifier()));
 244.700 +                    return null;
 244.701 +                }
 244.702 +            }
 244.703 +
 244.704 +            if (nue != node) {
 244.705 +                rewrite(node, nue);
 244.706 +            }
 244.707 +            
 244.708 +            return super.visitMemberSelect(node, p);
 244.709 +        }
 244.710 +
 244.711 +        @Override
 244.712 +        public Number visitVariable(VariableTree node, Void p) {
 244.713 +            String name = node.getName().toString();
 244.714 +
 244.715 +            if (name.startsWith("$")) {
 244.716 +                String nueName = parameterNames.get(name);
 244.717 +
 244.718 +                if (nueName != null) {
 244.719 +                    name = nueName;
 244.720 +                }
 244.721 +            }
 244.722 +            
 244.723 +            VariableTree nue = make.Variable(node.getModifiers(), name, node.getType(), resolveOptionalValue(node.getInitializer()));
 244.724 +
 244.725 +            rewrite(node, nue);
 244.726 +
 244.727 +            return super.visitVariable(nue, p);
 244.728 +        }
 244.729 +
 244.730 +        @Override
 244.731 +        public Number visitIf(IfTree node, Void p) {
 244.732 +            IfTree nue = make.If(node.getCondition(), node.getThenStatement(), resolveOptionalValue(node.getElseStatement()));
 244.733 +            
 244.734 +            rewrite(node, nue);
 244.735 +            
 244.736 +            return super.visitIf(nue, p);
 244.737 +        }
 244.738 +
 244.739 +        @Override
 244.740 +        public Number visitMethod(MethodTree node, Void p) {
 244.741 +            String name = node.getName().toString();
 244.742 +            String newName = name;
 244.743 +
 244.744 +            if (name.startsWith("$")) {
 244.745 +                if (parameterNames.containsKey(name)) {
 244.746 +                    newName = parameterNames.get(name);
 244.747 +                }
 244.748 +            }
 244.749 +
 244.750 +            List<? extends TypeParameterTree> typeParams = resolveMultiParameters(node.getTypeParameters());
 244.751 +            List<? extends VariableTree> params = resolveMultiParameters(node.getParameters());
 244.752 +            List<? extends ExpressionTree> thrown = resolveMultiParameters(node.getThrows());
 244.753 +            
 244.754 +            MethodTree nue = make.Method(node.getModifiers(), newName, node.getReturnType(), typeParams, params, thrown, node.getBody(), (ExpressionTree) node.getDefaultValue());
 244.755 +            
 244.756 +            rewrite(node, nue);
 244.757 +            
 244.758 +            return super.visitMethod(nue, p);
 244.759 +        }
 244.760 +
 244.761 +        @Override
 244.762 +        public Number visitClass(ClassTree node, Void p) {
 244.763 +            String name = node.getSimpleName().toString();
 244.764 +            String newName = name;
 244.765 +
 244.766 +            if (name.startsWith("$")) {
 244.767 +                if (parameterNames.containsKey(name)) {
 244.768 +                    newName = parameterNames.get(name);
 244.769 +                }
 244.770 +            }
 244.771 +
 244.772 +            List<? extends TypeParameterTree> typeParams = resolveMultiParameters(node.getTypeParameters());
 244.773 +            List<? extends Tree> implementsClauses = resolveMultiParameters(node.getImplementsClause());
 244.774 +            List<? extends Tree> members = resolveMultiParameters(Utilities.filterHidden(getCurrentPath(), node.getMembers()));
 244.775 +            Tree extend = resolveOptionalValue(node.getExtendsClause());
 244.776 +            ClassTree nue = make.Class(node.getModifiers(), newName, typeParams, extend, implementsClauses, members);
 244.777 +            
 244.778 +            rewrite(node, nue);
 244.779 +            
 244.780 +            return super.visitClass(nue, p);
 244.781 +        }
 244.782 +
 244.783 +        @Override
 244.784 +        public Number visitExpressionStatement(ExpressionStatementTree node, Void p) {
 244.785 +            CharSequence name = Utilities.getWildcardTreeName(node);
 244.786 +
 244.787 +            if (name != null) {
 244.788 +                TreePath tp = parameters.get(name.toString());
 244.789 +
 244.790 +                if (tp != null) {
 244.791 +                    rewrite(node, tp.getLeaf());
 244.792 +                    return null;
 244.793 +                }
 244.794 +            }
 244.795 +
 244.796 +            return super.visitExpressionStatement(node, p);
 244.797 +        }
 244.798 +
 244.799 +        @Override
 244.800 +        public Number visitLiteral(LiteralTree node, Void p) {
 244.801 +            if (node.getValue() instanceof Number) {
 244.802 +                return (Number) node.getValue();
 244.803 +            }
 244.804 +
 244.805 +            return super.visitLiteral(node, p);
 244.806 +        }
 244.807 +
 244.808 +        @Override
 244.809 +        public Number visitBinary(BinaryTree node, Void p) {
 244.810 +            Number left  = scan(node.getLeftOperand(), p);
 244.811 +            Number right = scan(node.getRightOperand(), p);
 244.812 +
 244.813 +            if (left != null && right != null) {
 244.814 +                Number result = null;
 244.815 +                switch (node.getKind()) {
 244.816 +                    case MULTIPLY:
 244.817 +                            if (left instanceof Double || right instanceof Double) {
 244.818 +                                result = left.doubleValue() * right.doubleValue();
 244.819 +                            } else if (left instanceof Float || right instanceof Float) {
 244.820 +                                result = left.floatValue() * right.floatValue();
 244.821 +                            } else if (left instanceof Long || right instanceof Long) {
 244.822 +                                result = left.longValue() * right.longValue();
 244.823 +                            } else if (left instanceof Integer || right instanceof Integer) {
 244.824 +                                result = left.intValue() * right.intValue();
 244.825 +                            } else {
 244.826 +                                throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
 244.827 +                            }
 244.828 +                            break;
 244.829 +
 244.830 +                    case DIVIDE:
 244.831 +                            if (left instanceof Double || right instanceof Double) {
 244.832 +                                result = left.doubleValue() / right.doubleValue();
 244.833 +                            } else if (left instanceof Float || right instanceof Float) {
 244.834 +                                result = left.floatValue() / right.floatValue();
 244.835 +                            } else if (left instanceof Long || right instanceof Long) {
 244.836 +                                result = left.longValue() / right.longValue();
 244.837 +                            } else if (left instanceof Integer || right instanceof Integer) {
 244.838 +                                result = left.intValue() / right.intValue();
 244.839 +                            } else {
 244.840 +                                throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
 244.841 +                            }
 244.842 +                            break;
 244.843 +
 244.844 +                    case REMAINDER:
 244.845 +                            if (left instanceof Double || right instanceof Double) {
 244.846 +                                result = left.doubleValue() % right.doubleValue();
 244.847 +                            } else if (left instanceof Float || right instanceof Float) {
 244.848 +                                result = left.floatValue() % right.floatValue();
 244.849 +                            } else if (left instanceof Long || right instanceof Long) {
 244.850 +                                result = left.longValue() % right.longValue();
 244.851 +                            } else if (left instanceof Integer || right instanceof Integer) {
 244.852 +                                result = left.intValue() % right.intValue();
 244.853 +                            } else {
 244.854 +                                throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
 244.855 +                            }
 244.856 +                            break;
 244.857 +
 244.858 +                    case PLUS:
 244.859 +                            if (left instanceof Double || right instanceof Double) {
 244.860 +                                result = left.doubleValue() + right.doubleValue();
 244.861 +                            } else if (left instanceof Float || right instanceof Float) {
 244.862 +                                result = left.floatValue() + right.floatValue();
 244.863 +                            } else if (left instanceof Long || right instanceof Long) {
 244.864 +                                result = left.longValue() + right.longValue();
 244.865 +                            } else if (left instanceof Integer || right instanceof Integer) {
 244.866 +                                result = left.intValue() + right.intValue();
 244.867 +                            } else {
 244.868 +                                throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
 244.869 +                            }
 244.870 +                            break;
 244.871 +
 244.872 +                    case MINUS:
 244.873 +                            if (left instanceof Double || right instanceof Double) {
 244.874 +                                result = left.doubleValue() - right.doubleValue();
 244.875 +                            } else if (left instanceof Float || right instanceof Float) {
 244.876 +                                result = left.floatValue() - right.floatValue();
 244.877 +                            } else if (left instanceof Long || right instanceof Long) {
 244.878 +                                result = left.longValue() - right.longValue();
 244.879 +                            } else if (left instanceof Integer || right instanceof Integer) {
 244.880 +                                result = left.intValue() - right.intValue();
 244.881 +                            } else {
 244.882 +                                throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
 244.883 +                            }
 244.884 +                            break;
 244.885 +
 244.886 +                    case LEFT_SHIFT:
 244.887 +                            if (left instanceof Long || right instanceof Long) {
 244.888 +                                result = left.longValue() << right.longValue();
 244.889 +                            } else if (left instanceof Integer || right instanceof Integer) {
 244.890 +                                result = left.intValue() << right.intValue();
 244.891 +                            } else {
 244.892 +                                throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
 244.893 +                            }
 244.894 +                            break;
 244.895 +
 244.896 +                    case RIGHT_SHIFT:
 244.897 +                            if (left instanceof Long || right instanceof Long) {
 244.898 +                                result = left.longValue() >> right.longValue();
 244.899 +                            } else if (left instanceof Integer || right instanceof Integer) {
 244.900 +                                result = left.intValue() >> right.intValue();
 244.901 +                            } else {
 244.902 +                                throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
 244.903 +                            }
 244.904 +                            break;
 244.905 +
 244.906 +                    case UNSIGNED_RIGHT_SHIFT:
 244.907 +                            if (left instanceof Long || right instanceof Long) {
 244.908 +                                result = left.longValue() >>> right.longValue();
 244.909 +                            } else if (left instanceof Integer || right instanceof Integer) {
 244.910 +                                result = left.intValue() >>> right.intValue();
 244.911 +                            } else {
 244.912 +                                throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
 244.913 +                            }
 244.914 +                            break;
 244.915 +
 244.916 +                    case AND:
 244.917 +                            if (left instanceof Long || right instanceof Long) {
 244.918 +                                result = left.longValue() & right.longValue();
 244.919 +                            } else if (left instanceof Integer || right instanceof Integer) {
 244.920 +                                result = left.intValue() & right.intValue();
 244.921 +                            } else {
 244.922 +                                throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
 244.923 +                            }
 244.924 +                            break;
 244.925 +
 244.926 +                    case XOR:
 244.927 +                            if (left instanceof Long || right instanceof Long) {
 244.928 +                                result = left.longValue() ^ right.longValue();
 244.929 +                            } else if (left instanceof Integer || right instanceof Integer) {
 244.930 +                                result = left.intValue() ^ right.intValue();
 244.931 +                            } else {
 244.932 +                                throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
 244.933 +                            }
 244.934 +                            break;
 244.935 +
 244.936 +                    case OR:
 244.937 +                            if (left instanceof Long || right instanceof Long) {
 244.938 +                                result = left.longValue() | right.longValue();
 244.939 +                            } else if (left instanceof Integer || right instanceof Integer) {
 244.940 +                                result = left.intValue() | right.intValue();
 244.941 +                            } else {
 244.942 +                                throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
 244.943 +                            }
 244.944 +                            break;
 244.945 +                }
 244.946 +
 244.947 +                if (result != null) {
 244.948 +                    rewrite(node, make.Literal(result));
 244.949 +
 244.950 +                    return result;
 244.951 +                }
 244.952 +            }
 244.953 +
 244.954 +            return null;
 244.955 +        }
 244.956 +
 244.957 +        @Override
 244.958 +        public Number visitUnary(UnaryTree node, Void p) {
 244.959 +            Number op  = scan(node.getExpression(), p);
 244.960 +
 244.961 +            if (op != null) {
 244.962 +                Number result = null;
 244.963 +                switch (node.getKind()) {
 244.964 +                    case UNARY_MINUS:
 244.965 +                            if (op instanceof Double) {
 244.966 +                                result = -op.doubleValue();
 244.967 +                            } else if (op instanceof Float) {
 244.968 +                                result = -op.floatValue();
 244.969 +                            } else if (op instanceof Long) {
 244.970 +                                result = -op.longValue();
 244.971 +                            } else if (op instanceof Integer) {
 244.972 +                                result = -op.intValue();
 244.973 +                            } else {
 244.974 +                                throw new IllegalStateException("op=" + op.getClass());
 244.975 +                            }
 244.976 +                            break;
 244.977 +                    case UNARY_PLUS:
 244.978 +                        result = op;
 244.979 +                        break;
 244.980 +                }
 244.981 +
 244.982 +                if (result != null) {
 244.983 +                    rewrite(node, make.Literal(result));
 244.984 +
 244.985 +                    return result;
 244.986 +                }
 244.987 +            }
 244.988 +
 244.989 +            return super.visitUnary(node, p);
 244.990 +        }
 244.991 +
 244.992 +        @Override
 244.993 +        public Number visitBlock(BlockTree node, Void p) {
 244.994 +            List<? extends StatementTree> nueStatement = resolveMultiParameters(node.getStatements());
 244.995 +            BlockTree nue = make.Block(nueStatement, node.isStatic());
 244.996 +
 244.997 +            rewrite(node, nue);
 244.998 +
 244.999 +            return super.visitBlock(nue, p);
244.1000 +        }
244.1001 +
244.1002 +        @Override
244.1003 +        public Number visitCase(CaseTree node, Void p) {
244.1004 +            List<? extends StatementTree> statements = (List<? extends StatementTree>) resolveMultiParameters(node.getStatements());
244.1005 +            CaseTree nue = make.Case(node.getExpression(), statements);
244.1006 +
244.1007 +            rewrite(node, nue);
244.1008 +            return super.visitCase(node, p);
244.1009 +        }
244.1010 +
244.1011 +        @Override
244.1012 +        public Number visitMethodInvocation(MethodInvocationTree node, Void p) {
244.1013 +            List<? extends ExpressionTree> typeArgs = (List<? extends ExpressionTree>) resolveMultiParameters(node.getTypeArguments());
244.1014 +            List<? extends ExpressionTree> args = resolveMultiParameters(node.getArguments());
244.1015 +            MethodInvocationTree nue = make.MethodInvocation(typeArgs, node.getMethodSelect(), args);
244.1016 +
244.1017 +            rewrite(node, nue);
244.1018 +
244.1019 +            return super.visitMethodInvocation(nue, p);
244.1020 +        }
244.1021 +
244.1022 +        @Override
244.1023 +        public Number visitNewClass(NewClassTree node, Void p) {
244.1024 +            List<? extends ExpressionTree> typeArgs = (List<? extends ExpressionTree>) resolveMultiParameters(node.getTypeArguments());
244.1025 +            List<? extends ExpressionTree> args = resolveMultiParameters(node.getArguments());
244.1026 +            NewClassTree nue = make.NewClass(node.getEnclosingExpression(), typeArgs, node.getIdentifier(), args, node.getClassBody());
244.1027 +
244.1028 +            rewrite(node, nue);
244.1029 +            return super.visitNewClass(nue, p);
244.1030 +        }
244.1031 +
244.1032 +        @Override
244.1033 +        public Number visitParameterizedType(ParameterizedTypeTree node, Void p) {
244.1034 +            List<? extends ExpressionTree> typeArgs = (List<? extends ExpressionTree>) resolveMultiParameters(node.getTypeArguments());
244.1035 +            ParameterizedTypeTree nue = make.ParameterizedType(node.getType(), typeArgs);
244.1036 +
244.1037 +            rewrite(node, nue);
244.1038 +            return super.visitParameterizedType(node, p);
244.1039 +        }
244.1040 +
244.1041 +        @Override
244.1042 +        public Number visitSwitch(SwitchTree node, Void p) {
244.1043 +            List<? extends CaseTree> cases = (List<? extends CaseTree>) resolveMultiParameters(node.getCases());
244.1044 +            SwitchTree nue = make.Switch(node.getExpression(), cases);
244.1045 +
244.1046 +            rewrite(node, nue);
244.1047 +            return super.visitSwitch(node, p);
244.1048 +        }
244.1049 +
244.1050 +        @Override
244.1051 +        public Number visitTry(TryTree node, Void p) {
244.1052 +            List<? extends Tree> resources = (List<? extends Tree>) resolveMultiParameters(node.getResources());
244.1053 +            List<? extends CatchTree> catches = (List<? extends CatchTree>) resolveMultiParameters(node.getCatches());
244.1054 +            TryTree nue = make.Try(resources, node.getBlock(), catches, node.getFinallyBlock());
244.1055 +
244.1056 +            rewrite(node, nue);
244.1057 +            return super.visitTry(node, p);
244.1058 +        }
244.1059 +
244.1060 +        @Override
244.1061 +        public Number visitModifiers(ModifiersTree node, Void p) {
244.1062 +            List<AnnotationTree> annotations = new ArrayList<AnnotationTree>(node.getAnnotations());
244.1063 +            IdentifierTree ident = !annotations.isEmpty() && annotations.get(0).getAnnotationType().getKind() == Kind.IDENTIFIER ? (IdentifierTree) annotations.get(0).getAnnotationType() : null;
244.1064 +
244.1065 +            if (ident != null) {
244.1066 +                annotations.remove(0);
244.1067 +                
244.1068 +                String name = ident.getName().toString();
244.1069 +                TreePath orig = parameters.get(name);
244.1070 +                ModifiersTree nue;
244.1071 +                
244.1072 +                if (orig != null && orig.getLeaf().getKind() == Kind.MODIFIERS) {
244.1073 +                    ModifiersTree origMods = (ModifiersTree) orig.getLeaf();
244.1074 +                    Object actualContent = extraParamsData.get(name);
244.1075 +                    Set<Modifier> actualFlags = EnumSet.noneOf(Modifier.class);
244.1076 +                    boolean[] actualAnnotationsMask = new boolean[0];
244.1077 +                    
244.1078 +                    if (actualContent instanceof Object[] && ((Object[]) actualContent)[0] instanceof Set) {
244.1079 +                        actualFlags.addAll(NbCollections.checkedSetByFilter((Set) ((Object[]) actualContent)[0], Modifier.class, false));
244.1080 +                    }
244.1081 +                    
244.1082 +                    if (actualContent instanceof Object[] && ((Object[]) actualContent)[1] instanceof boolean[]) {
244.1083 +                        actualAnnotationsMask = (boolean[]) ((Object[]) actualContent)[1];
244.1084 +                    }
244.1085 +                    
244.1086 +                    nue = origMods;
244.1087 +                    
244.1088 +                    for (Modifier m : origMods.getFlags()) {
244.1089 +                        if (actualFlags.contains(m)) continue;
244.1090 +                        nue = make.removeModifiersModifier(nue, m);
244.1091 +                    }
244.1092 +                    
244.1093 +                    for (Modifier m : node.getFlags()) {
244.1094 +                        nue = make.addModifiersModifier(nue, m);
244.1095 +                    }
244.1096 +                    
244.1097 +                    int ai = 0;
244.1098 +                    
244.1099 +                    OUTER: for (AnnotationTree a : origMods.getAnnotations()) {
244.1100 +                        if (actualAnnotationsMask.length <= ai || actualAnnotationsMask[ai++]) continue;
244.1101 +                        for (Iterator<AnnotationTree> it = annotations.iterator(); it.hasNext();) {
244.1102 +                            AnnotationTree toCheck = it.next();
244.1103 +                            Collection<? extends Occurrence> match = org.netbeans.api.java.source.matching.Matcher.create(info).setTreeTopSearch().setSearchRoot(new TreePath(getCurrentPath(), a)).match(Pattern.createSimplePattern(new TreePath(getCurrentPath(), toCheck)));
244.1104 +                            
244.1105 +                            if (!match.isEmpty()) {
244.1106 +                                //should be kept:
244.1107 +                                it.remove();
244.1108 +                                break OUTER;
244.1109 +                            }
244.1110 +                        }
244.1111 +                        
244.1112 +                        nue = make.removeModifiersAnnotation(nue, a);
244.1113 +                    }
244.1114 +                    
244.1115 +                    for (AnnotationTree a : annotations) {
244.1116 +                        nue = make.addModifiersAnnotation(nue, a);
244.1117 +                        scan(a, p);
244.1118 +                    }
244.1119 +                } else {
244.1120 +                    nue = make.removeModifiersAnnotation(node, 0);
244.1121 +                }
244.1122 +                
244.1123 +                rewrite(node, nue);
244.1124 +                
244.1125 +                return null;
244.1126 +            }
244.1127 +            
244.1128 +            return super.visitModifiers(node, p);
244.1129 +        }
244.1130 +
244.1131 +        @Override
244.1132 +        public Number visitNewArray(NewArrayTree node, Void p) {
244.1133 +            List<? extends ExpressionTree> dimensions = (List<? extends ExpressionTree>) resolveMultiParameters(node.getDimensions());
244.1134 +            List<? extends ExpressionTree> initializers = (List<? extends ExpressionTree>) resolveMultiParameters(node.getInitializers());
244.1135 +            NewArrayTree nue = make.NewArray(node.getType(), dimensions, initializers);
244.1136 +
244.1137 +            rewrite(node, nue);
244.1138 +            return super.visitNewArray(node, p);
244.1139 +        }
244.1140 +
244.1141 +        @Override
244.1142 +        public Number visitLambdaExpression(LambdaExpressionTree node, Void p) {
244.1143 +            List<? extends VariableTree> args = resolveMultiParameters(node.getParameters());
244.1144 +            LambdaExpressionTree nue = make.LambdaExpression(args, node.getBody());
244.1145 +
244.1146 +            rewrite(node, nue);
244.1147 +
244.1148 +            return super.visitLambdaExpression(node, p);
244.1149 +        }
244.1150 +
244.1151 +        @Override
244.1152 +        public Number visitAnnotation(AnnotationTree node, Void p) {
244.1153 +            List<? extends ExpressionTree> args = resolveMultiParameters(node.getArguments());
244.1154 +            AnnotationTree nue = make.Annotation(node.getAnnotationType(), args);
244.1155 +
244.1156 +            rewrite(node, nue);
244.1157 +
244.1158 +            return super.visitAnnotation(node, p);
244.1159 +        }
244.1160 +
244.1161 +        private <T extends Tree> List<T> resolveMultiParameters(List<T> list) {
244.1162 +            if (list == null) return null;
244.1163 +            if (!Utilities.containsMultistatementTrees(list)) return list;
244.1164 +
244.1165 +            List<T> result = new LinkedList<T>();
244.1166 +
244.1167 +            for (T t : list) {
244.1168 +                if (Utilities.isMultistatementWildcardTree(t)) {
244.1169 +                    Collection<TreePath> embedded = parametersMulti.get(Utilities.getWildcardTreeName(t).toString());
244.1170 +
244.1171 +                    if (embedded != null) {
244.1172 +                        for (TreePath tp : embedded) {
244.1173 +                            result.add((T) tp.getLeaf());
244.1174 +                        }
244.1175 +                    }
244.1176 +                } else {
244.1177 +                    result.add(t);
244.1178 +                }
244.1179 +            }
244.1180 +
244.1181 +            return result;
244.1182 +        }
244.1183 +        
244.1184 +        private <T extends Tree> T resolveOptionalValue(T in) {
244.1185 +            if (in != null && Utilities.isMultistatementWildcardTree(in)) {
244.1186 +                TreePath out = parameters.get(Utilities.getWildcardTreeName(in).toString());
244.1187 +                if (out != null) return (T) out.getLeaf();
244.1188 +                return null;
244.1189 +            }
244.1190 +            
244.1191 +            return in;
244.1192 +        }
244.1193 +
244.1194 +        private ExpressionTree negate(ExpressionTree original, Tree parent, boolean nullOnPlainNeg) {
244.1195 +            ExpressionTree newTree;
244.1196 +            switch (original.getKind()) {
244.1197 +                case PARENTHESIZED:
244.1198 +                    ExpressionTree expr = ((ParenthesizedTree) original).getExpression();
244.1199 +                    return make.Parenthesized(negate(expr, original, nullOnPlainNeg));
244.1200 +                case LOGICAL_COMPLEMENT:
244.1201 +                    newTree = ((UnaryTree) original).getExpression();
244.1202 +                    while (newTree.getKind() == Kind.PARENTHESIZED && !JavaFixUtilities.requiresParenthesis(((ParenthesizedTree) newTree).getExpression(), original, parent)) {
244.1203 +                        newTree = ((ParenthesizedTree) newTree).getExpression();
244.1204 +                    }
244.1205 +                    break;
244.1206 +                case NOT_EQUAL_TO:
244.1207 +                    newTree = negateBinaryOperator(original, Kind.EQUAL_TO, false);
244.1208 +                    break;
244.1209 +                case EQUAL_TO:
244.1210 +                    newTree = negateBinaryOperator(original, Kind.NOT_EQUAL_TO, false);
244.1211 +                    break;
244.1212 +                case BOOLEAN_LITERAL:
244.1213 +                    newTree = make.Literal(!(Boolean) ((LiteralTree) original).getValue());
244.1214 +                    break;
244.1215 +                case CONDITIONAL_AND:
244.1216 +                    newTree = negateBinaryOperator(original, Kind.CONDITIONAL_OR, true);
244.1217 +                    break;
244.1218 +                case CONDITIONAL_OR:
244.1219 +                    newTree = negateBinaryOperator(original, Kind.CONDITIONAL_AND, true);
244.1220 +                    break;
244.1221 +                case LESS_THAN:
244.1222 +                    newTree = negateBinaryOperator(original, Kind.GREATER_THAN_EQUAL, false);
244.1223 +                    break;
244.1224 +                case LESS_THAN_EQUAL:
244.1225 +                    newTree = negateBinaryOperator(original, Kind.GREATER_THAN, false);
244.1226 +                    break;
244.1227 +                case GREATER_THAN:
244.1228 +                    newTree = negateBinaryOperator(original, Kind.LESS_THAN_EQUAL, false);
244.1229 +                    break;
244.1230 +                case GREATER_THAN_EQUAL:
244.1231 +                    newTree = negateBinaryOperator(original, Kind.LESS_THAN, false);
244.1232 +                    break;
244.1233 +                default:
244.1234 +                    if (nullOnPlainNeg)
244.1235 +                        return null;
244.1236 +                    newTree = make.Unary(Kind.LOGICAL_COMPLEMENT, original);
244.1237 +            }
244.1238 +         
244.1239 +            if (JavaFixUtilities.requiresParenthesis(newTree, original, parent)) {
244.1240 +                newTree = make.Parenthesized(newTree);
244.1241 +            }
244.1242 +            
244.1243 +            return newTree;
244.1244 +        }
244.1245 +        
244.1246 +        private ExpressionTree negateBinaryOperator(Tree original, Kind newKind, boolean negateOperands) {
244.1247 +            BinaryTree bt = (BinaryTree) original;
244.1248 +            BinaryTree nonNegated = make.Binary(newKind,
244.1249 +                                                bt.getLeftOperand(),
244.1250 +                                                bt.getRightOperand());
244.1251 +            if (negateOperands) {
244.1252 +                ExpressionTree lo = negate(bt.getLeftOperand(), nonNegated, false);
244.1253 +                ExpressionTree ro = negate(bt.getRightOperand(), nonNegated, false);
244.1254 +                return make.Binary(newKind,
244.1255 +                                   lo != null ? lo : bt.getLeftOperand(),
244.1256 +                                   ro != null ? ro : bt.getRightOperand());
244.1257 +            }
244.1258 +            return nonNegated;
244.1259 +        }
244.1260 +        
244.1261 +        private void rewrite(Tree from, Tree to) {
244.1262 +            if (originalTrees.contains(from)) return ;
244.1263 +            rewriteFromTo.put(from, to);
244.1264 +        }
244.1265 +    }
244.1266 +
244.1267 +    private static final Map<Kind, Integer> OPERATOR_PRIORITIES;
244.1268 +
244.1269 +    static {
244.1270 +        OPERATOR_PRIORITIES = new EnumMap<Kind, Integer>(Kind.class);
244.1271 +
244.1272 +        OPERATOR_PRIORITIES.put(Kind.IDENTIFIER, 0);
244.1273 +
244.1274 +        for (Kind k : Kind.values()) {
244.1275 +            if (k.asInterface() == LiteralTree.class) {
244.1276 +                OPERATOR_PRIORITIES.put(k, 0);
244.1277 +            }
244.1278 +        }
244.1279 +
244.1280 +        OPERATOR_PRIORITIES.put(Kind.ARRAY_ACCESS, 1);
244.1281 +        OPERATOR_PRIORITIES.put(Kind.METHOD_INVOCATION, 1);
244.1282 +        OPERATOR_PRIORITIES.put(Kind.MEMBER_SELECT, 1);
244.1283 +        OPERATOR_PRIORITIES.put(Kind.POSTFIX_DECREMENT, 1);
244.1284 +        OPERATOR_PRIORITIES.put(Kind.POSTFIX_INCREMENT, 1);
244.1285 +        OPERATOR_PRIORITIES.put(Kind.NEW_ARRAY, 1);
244.1286 +        OPERATOR_PRIORITIES.put(Kind.NEW_CLASS, 1);
244.1287 +
244.1288 +        OPERATOR_PRIORITIES.put(Kind.BITWISE_COMPLEMENT, 2);
244.1289 +        OPERATOR_PRIORITIES.put(Kind.LOGICAL_COMPLEMENT, 2);
244.1290 +        OPERATOR_PRIORITIES.put(Kind.PREFIX_DECREMENT, 2);
244.1291 +        OPERATOR_PRIORITIES.put(Kind.PREFIX_INCREMENT, 2);
244.1292 +        OPERATOR_PRIORITIES.put(Kind.UNARY_MINUS, 2);
244.1293 +        OPERATOR_PRIORITIES.put(Kind.UNARY_PLUS, 2);
244.1294 +
244.1295 +        OPERATOR_PRIORITIES.put(Kind.TYPE_CAST, 3);
244.1296 +
244.1297 +        OPERATOR_PRIORITIES.put(Kind.DIVIDE, 4);
244.1298 +        OPERATOR_PRIORITIES.put(Kind.MULTIPLY, 4);
244.1299 +        OPERATOR_PRIORITIES.put(Kind.REMAINDER, 4);
244.1300 +
244.1301 +        OPERATOR_PRIORITIES.put(Kind.MINUS, 5);
244.1302 +        OPERATOR_PRIORITIES.put(Kind.PLUS, 5);
244.1303 +
244.1304 +        OPERATOR_PRIORITIES.put(Kind.LEFT_SHIFT, 6);
244.1305 +        OPERATOR_PRIORITIES.put(Kind.RIGHT_SHIFT, 6);
244.1306 +        OPERATOR_PRIORITIES.put(Kind.UNSIGNED_RIGHT_SHIFT, 6);
244.1307 +
244.1308 +        OPERATOR_PRIORITIES.put(Kind.INSTANCE_OF, 7);
244.1309 +        OPERATOR_PRIORITIES.put(Kind.GREATER_THAN, 7);
244.1310 +        OPERATOR_PRIORITIES.put(Kind.GREATER_THAN_EQUAL, 7);
244.1311 +        OPERATOR_PRIORITIES.put(Kind.LESS_THAN, 7);
244.1312 +        OPERATOR_PRIORITIES.put(Kind.LESS_THAN_EQUAL, 7);
244.1313 +
244.1314 +        OPERATOR_PRIORITIES.put(Kind.EQUAL_TO, 8);
244.1315 +        OPERATOR_PRIORITIES.put(Kind.NOT_EQUAL_TO, 8);
244.1316 +
244.1317 +        OPERATOR_PRIORITIES.put(Kind.AND, 9);
244.1318 +        OPERATOR_PRIORITIES.put(Kind.OR, 11);
244.1319 +        OPERATOR_PRIORITIES.put(Kind.XOR, 10);
244.1320 +
244.1321 +        OPERATOR_PRIORITIES.put(Kind.CONDITIONAL_AND, 12);
244.1322 +        OPERATOR_PRIORITIES.put(Kind.CONDITIONAL_OR, 13);
244.1323 +
244.1324 +        OPERATOR_PRIORITIES.put(Kind.CONDITIONAL_EXPRESSION, 14);
244.1325 +
244.1326 +        OPERATOR_PRIORITIES.put(Kind.AND_ASSIGNMENT, 15);
244.1327 +        OPERATOR_PRIORITIES.put(Kind.ASSIGNMENT, 15);
244.1328 +        OPERATOR_PRIORITIES.put(Kind.DIVIDE_ASSIGNMENT, 15);
244.1329 +        OPERATOR_PRIORITIES.put(Kind.LEFT_SHIFT_ASSIGNMENT, 15);
244.1330 +        OPERATOR_PRIORITIES.put(Kind.MINUS_ASSIGNMENT, 15);
244.1331 +        OPERATOR_PRIORITIES.put(Kind.MULTIPLY_ASSIGNMENT, 15);
244.1332 +        OPERATOR_PRIORITIES.put(Kind.OR_ASSIGNMENT, 15);
244.1333 +        OPERATOR_PRIORITIES.put(Kind.PLUS_ASSIGNMENT, 15);
244.1334 +        OPERATOR_PRIORITIES.put(Kind.REMAINDER_ASSIGNMENT, 15);
244.1335 +        OPERATOR_PRIORITIES.put(Kind.RIGHT_SHIFT_ASSIGNMENT, 15);
244.1336 +        OPERATOR_PRIORITIES.put(Kind.UNSIGNED_RIGHT_SHIFT_ASSIGNMENT, 15);
244.1337 +        OPERATOR_PRIORITIES.put(Kind.XOR_ASSIGNMENT, 15);
244.1338 +    }
244.1339 +
244.1340 +    /**Checks whether putting {@code inner} tree into {@code outter} tree,
244.1341 +     * when {@code original} is being replaced with {@code inner} requires parentheses.
244.1342 +     *
244.1343 +     * @param inner    the new tree node that will be placed under {@code outter}
244.1344 +     * @param original the tree node that is being replaced with {@code inner}
244.1345 +     * @param outter   the future parent node of {@code inner}
244.1346 +     * @return true if and only if inner needs to be wrapped using {@link TreeMaker#Parenthesized(com.sun.source.tree.ExpressionTree) }
244.1347 +     *              to keep the original meaning.
244.1348 +     */
244.1349 +    public static boolean requiresParenthesis(Tree inner, Tree original, Tree outter) {
244.1350 +        if (!ExpressionTree.class.isAssignableFrom(inner.getKind().asInterface())) return false;
244.1351 +        if (!ExpressionTree.class.isAssignableFrom(outter.getKind().asInterface())) return false;
244.1352 +
244.1353 +        if (outter.getKind() == Kind.PARENTHESIZED || inner.getKind() == Kind.PARENTHESIZED) return false;
244.1354 +
244.1355 +        if (outter.getKind() == Kind.METHOD_INVOCATION) {
244.1356 +            if (((MethodInvocationTree) outter).getArguments().contains(original)) return false;
244.1357 +        }
244.1358 +
244.1359 +        if (outter.getKind() == Kind.NEW_CLASS) {
244.1360 +            if (((NewClassTree) outter).getArguments().contains(original)) return false;
244.1361 +        }
244.1362 +
244.1363 +        Integer innerPriority = OPERATOR_PRIORITIES.get(inner.getKind());
244.1364 +        Integer outterPriority = OPERATOR_PRIORITIES.get(outter.getKind());
244.1365 +
244.1366 +        if (innerPriority == null || outterPriority == null) {
244.1367 +            Logger.getLogger(JavaFix.class.getName()).log(Level.WARNING, "Unknown tree kind(s): {0}/{1}", new Object[] {inner.getKind(), outter.getKind()});
244.1368 +            return true;
244.1369 +        }
244.1370 +
244.1371 +        if (innerPriority > outterPriority) {
244.1372 +            return true;
244.1373 +        }
244.1374 +
244.1375 +        if (innerPriority < outterPriority) {
244.1376 +            return false;
244.1377 +        }
244.1378 +
244.1379 +        //associativity
244.1380 +        if (BinaryTree.class.isAssignableFrom(outter.getKind().asInterface())) {
244.1381 +            BinaryTree ot = (BinaryTree) outter;
244.1382 +
244.1383 +            //TODO: for + it might be possible to skip the parenthesis:
244.1384 +            return ot.getRightOperand() == original;
244.1385 +        }
244.1386 +
244.1387 +        if (CompoundAssignmentTree.class.isAssignableFrom(outter.getKind().asInterface())) {
244.1388 +            CompoundAssignmentTree ot = (CompoundAssignmentTree) outter;
244.1389 +
244.1390 +            return ot.getVariable() == original;
244.1391 +        }
244.1392 +
244.1393 +        if (AssignmentTree.class.isAssignableFrom(outter.getKind().asInterface())) {
244.1394 +            AssignmentTree ot = (AssignmentTree) outter;
244.1395 +
244.1396 +            return ot.getVariable() == original;
244.1397 +        }
244.1398 +
244.1399 +        return false;
244.1400 +    }
244.1401 +
244.1402 +    private static final class RemoveFromParent extends JavaFix {
244.1403 +
244.1404 +        private final String displayName;
244.1405 +
244.1406 +        public RemoveFromParent(String displayName, CompilationInfo info, TreePath toRemove) {
244.1407 +            super(info, toRemove);
244.1408 +            this.displayName = displayName;
244.1409 +        }
244.1410 +
244.1411 +        @Override
244.1412 +        protected String getText() {
244.1413 +            return displayName;
244.1414 +        }
244.1415 +
244.1416 +        @Override
244.1417 +        protected void performRewrite(TransformationContext ctx) {
244.1418 +            WorkingCopy wc = ctx.getWorkingCopy();
244.1419 +            TreePath tp = ctx.getPath();
244.1420 +            
244.1421 +            doRemoveFromParent(wc, tp);
244.1422 +        }
244.1423 +        
244.1424 +        private void doRemoveFromParent(WorkingCopy wc, TreePath what) {
244.1425 +            TreeMaker make = wc.getTreeMaker();
244.1426 +            Tree leaf = what.getLeaf();
244.1427 +            Tree parentLeaf = what.getParentPath().getLeaf();
244.1428 +
244.1429 +            switch (parentLeaf.getKind()) {
244.1430 +                case ANNOTATION:
244.1431 +                    AnnotationTree at = (AnnotationTree) parentLeaf;
244.1432 +                    AnnotationTree newAnnot;
244.1433 +
244.1434 +                    newAnnot = make.removeAnnotationAttrValue(at, (ExpressionTree) leaf);
244.1435 +
244.1436 +                    wc.rewrite(at, newAnnot);
244.1437 +                    break;
244.1438 +                case BLOCK:
244.1439 +                    BlockTree bt = (BlockTree) parentLeaf;
244.1440 +
244.1441 +                    wc.rewrite(bt, make.removeBlockStatement(bt, (StatementTree) leaf));
244.1442 +                    break;
244.1443 +                case CASE:
244.1444 +                    CaseTree caseTree = (CaseTree) parentLeaf;
244.1445 +
244.1446 +                    wc.rewrite(caseTree, make.removeCaseStatement(caseTree, (StatementTree) leaf));
244.1447 +                    break;
244.1448 +                case CLASS:
244.1449 +                    ClassTree classTree = (ClassTree) parentLeaf;
244.1450 +                    ClassTree nueClassTree;
244.1451 +
244.1452 +                    if (classTree.getTypeParameters().contains(leaf)) {
244.1453 +                        nueClassTree = make.removeClassTypeParameter(classTree, (TypeParameterTree) leaf);
244.1454 +                    } else if (classTree.getExtendsClause() == leaf) {
244.1455 +                        nueClassTree = make.Class(classTree.getModifiers(), classTree.getSimpleName(), classTree.getTypeParameters(), null, classTree.getImplementsClause(), classTree.getMembers());
244.1456 +                    } else if (classTree.getImplementsClause().contains(leaf)) {
244.1457 +                        nueClassTree = make.removeClassImplementsClause(classTree, leaf);
244.1458 +                    } else if (classTree.getMembers().contains(leaf)) {
244.1459 +                        nueClassTree = make.removeClassMember(classTree, leaf);
244.1460 +                    } else {
244.1461 +                        throw new UnsupportedOperationException();
244.1462 +                    }
244.1463 +
244.1464 +                    wc.rewrite(classTree, nueClassTree);
244.1465 +                    break;
244.1466 +                case UNION_TYPE:
244.1467 +                    UnionTypeTree disjunct = (UnionTypeTree) parentLeaf;
244.1468 +                    List<? extends Tree> alternatives = new LinkedList<Tree>(disjunct.getTypeAlternatives());
244.1469 +
244.1470 +                    alternatives.remove(leaf);
244.1471 +
244.1472 +                    wc.rewrite(disjunct, make.UnionType(alternatives));
244.1473 +                    break;
244.1474 +                case METHOD:
244.1475 +                    MethodTree mTree = (MethodTree) parentLeaf;
244.1476 +                    MethodTree newMethod;
244.1477 +
244.1478 +                    if (mTree.getTypeParameters().contains(leaf)) {
244.1479 +                        newMethod = make.removeMethodTypeParameter(mTree, (TypeParameterTree) leaf);
244.1480 +                    } else if (mTree.getParameters().contains(leaf)) {
244.1481 +                        newMethod = make.removeMethodParameter(mTree, (VariableTree) leaf);
244.1482 +                    } else if (mTree.getThrows().contains(leaf)) {
244.1483 +                        newMethod = make.removeMethodThrows(mTree, (ExpressionTree) leaf);
244.1484 +                    } else {
244.1485 +                        throw new UnsupportedOperationException();
244.1486 +                    }
244.1487 +
244.1488 +                    wc.rewrite(mTree, newMethod);
244.1489 +                    break;
244.1490 +                case METHOD_INVOCATION:
244.1491 +                    MethodInvocationTree iTree = (MethodInvocationTree) parentLeaf;
244.1492 +                    MethodInvocationTree newInvocation;
244.1493 +
244.1494 +                    if (iTree.getTypeArguments().contains(leaf)) {
244.1495 +                        newInvocation = make.removeMethodInvocationTypeArgument(iTree, (ExpressionTree) leaf);
244.1496 +                    } else if (iTree.getArguments().contains(leaf)) {
244.1497 +                        newInvocation = make.removeMethodInvocationArgument(iTree, (ExpressionTree) leaf);
244.1498 +                    } else {
244.1499 +                        throw new UnsupportedOperationException();
244.1500 +                    }
244.1501 +
244.1502 +                    wc.rewrite(iTree, newInvocation);
244.1503 +                    break;
244.1504 +                case MODIFIERS:
244.1505 +                    ModifiersTree modsTree = (ModifiersTree) parentLeaf;
244.1506 +
244.1507 +                    wc.rewrite(modsTree, make.removeModifiersAnnotation(modsTree, (AnnotationTree) leaf));
244.1508 +                    break;
244.1509 +                case NEW_CLASS:
244.1510 +                    NewClassTree newCTree = (NewClassTree) parentLeaf;
244.1511 +                    NewClassTree newNCT;
244.1512 +
244.1513 +                    if (newCTree.getTypeArguments().contains(leaf)) {
244.1514 +                        newNCT = make.removeNewClassTypeArgument(newCTree, (ExpressionTree) leaf);
244.1515 +                    } else if (newCTree.getArguments().contains(leaf)) {
244.1516 +                        newNCT = make.removeNewClassArgument(newCTree, (ExpressionTree) leaf);
244.1517 +                    } else {
244.1518 +                        throw new UnsupportedOperationException();
244.1519 +                    }
244.1520 +
244.1521 +                    wc.rewrite(newCTree, newNCT);
244.1522 +                    break;
244.1523 +                case PARAMETERIZED_TYPE:
244.1524 +                    ParameterizedTypeTree parTree = (ParameterizedTypeTree) parentLeaf;
244.1525 +
244.1526 +                    wc.rewrite(parTree, make.removeParameterizedTypeTypeArgument(parTree, (ExpressionTree) leaf));
244.1527 +                    break;
244.1528 +                case SWITCH:
244.1529 +                    SwitchTree switchTree = (SwitchTree) parentLeaf;
244.1530 +                    SwitchTree newSwitch;
244.1531 +
244.1532 +                    if (switchTree.getCases().contains(leaf)) {
244.1533 +                        newSwitch = make.removeSwitchCase(switchTree, (CaseTree) leaf);
244.1534 +                    } else {
244.1535 +                        throw new UnsupportedOperationException();
244.1536 +                    }
244.1537 +
244.1538 +                    wc.rewrite(switchTree, newSwitch);
244.1539 +                    break;
244.1540 +                case TRY:
244.1541 +                    TryTree tryTree = (TryTree) parentLeaf;
244.1542 +                    TryTree newTry;
244.1543 +
244.1544 +                    if (tryTree.getResources().contains(leaf)) {
244.1545 +                        LinkedList<Tree> resources = new LinkedList<Tree>(tryTree.getResources());
244.1546 +
244.1547 +                        resources.remove(leaf);
244.1548 +
244.1549 +                        newTry = make.Try(resources, tryTree.getBlock(), tryTree.getCatches(), tryTree.getFinallyBlock());
244.1550 +                    } else if (tryTree.getCatches().contains(leaf)) {
244.1551 +                        newTry = make.removeTryCatch(tryTree, (CatchTree) leaf);
244.1552 +                    } else {
244.1553 +                        throw new UnsupportedOperationException();
244.1554 +                    }
244.1555 +
244.1556 +                    wc.rewrite(tryTree, newTry);
244.1557 +                    break;
244.1558 +                case EXPRESSION_STATEMENT:
244.1559 +                    doRemoveFromParent(wc, what.getParentPath());
244.1560 +                    break;
244.1561 +                default:
244.1562 +                    wc.rewrite(what.getLeaf(), make.Block(Collections.<StatementTree>emptyList(), false));
244.1563 +                    break;
244.1564 +            }
244.1565 +        }
244.1566 +
244.1567 +    }
244.1568 +
244.1569 +    //TODO: from FileMovePlugin
244.1570 +    private static class MoveFile extends SimpleRefactoringElementImplementation {
244.1571 +
244.1572 +        private FileObject toMove;
244.1573 +        private final FileObject sourceRoot;
244.1574 +        private final String targetFolderName;
244.1575 +
244.1576 +        public MoveFile(FileObject toMove, FileObject sourceRoot, String targetFolderName) {
244.1577 +            this.toMove = toMove;
244.1578 +            this.sourceRoot = sourceRoot;
244.1579 +            this.targetFolderName = targetFolderName;
244.1580 +        }
244.1581 +
244.1582 +        @Override
244.1583 +        @Messages({"#{0} - original file name", "TXT_MoveFile=Move {0}"})
244.1584 +        public String getText() {
244.1585 +            return Bundle.TXT_MoveFile(toMove.getNameExt());
244.1586 +        }
244.1587 +
244.1588 +        @Override
244.1589 +        public String getDisplayText() {
244.1590 +            return getText();
244.1591 +        }
244.1592 +
244.1593 +        DataFolder sourceFolder;
244.1594 +        DataObject source;
244.1595 +        @Override
244.1596 +        public void performChange() {
244.1597 +            try {
244.1598 +                FileObject target = FileUtil.createFolder(sourceRoot, targetFolderName);
244.1599 +                DataFolder targetFolder = DataFolder.findFolder(target);
244.1600 +                if (!toMove.isValid()) {
244.1601 +                    String path = FileUtil.getFileDisplayName(toMove);
244.1602 +                    Logger.getLogger(JavaFix.class.getName()).fine("Invalid FileObject " + path + "trying to recreate...");
244.1603 +                    toMove = FileUtil.toFileObject(FileUtil.toFile(toMove));
244.1604 +                    if (toMove==null) {
244.1605 +                        Logger.getLogger(JavaFix.class.getName()).severe("Invalid FileObject " + path + "\n. File not found.");
244.1606 +                        return;
244.1607 +                    }
244.1608 +                }
244.1609 +                source = DataObject.find(toMove);
244.1610 +                sourceFolder = source.getFolder();
244.1611 +                source.move(targetFolder);
244.1612 +            } catch (DataObjectNotFoundException ex) {
244.1613 +                ex.printStackTrace();
244.1614 +            } catch (IOException ex) {
244.1615 +                ex.printStackTrace();
244.1616 +            }
244.1617 +        }
244.1618 +
244.1619 +        @Override
244.1620 +        public void undoChange() {
244.1621 +            try {
244.1622 +                source.move(sourceFolder);
244.1623 +            } catch (DataObjectNotFoundException ex) {
244.1624 +                ex.printStackTrace();
244.1625 +            } catch (IOException ex) {
244.1626 +                ex.printStackTrace();
244.1627 +            }
244.1628 +        }
244.1629 +
244.1630 +        @Override
244.1631 +        public Lookup getLookup() {
244.1632 +            return Lookup.EMPTY;
244.1633 +        }
244.1634 +
244.1635 +        @Override
244.1636 +        public FileObject getParentFile() {
244.1637 +            return toMove;
244.1638 +        }
244.1639 +
244.1640 +        @Override
244.1641 +        public PositionBounds getPosition() {
244.1642 +            return null;
244.1643 +        }
244.1644 +    }
244.1645 +}
   245.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   245.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/MatcherUtilities.java	Sun Oct 23 11:50:54 2016 +0200
   245.3 @@ -0,0 +1,157 @@
   245.4 +/*
   245.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   245.6 + *
   245.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
   245.8 + *
   245.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  245.10 + * Other names may be trademarks of their respective owners.
  245.11 + *
  245.12 + * The contents of this file are subject to the terms of either the GNU
  245.13 + * General Public License Version 2 only ("GPL") or the Common
  245.14 + * Development and Distribution License("CDDL") (collectively, the
  245.15 + * "License"). You may not use this file except in compliance with the
  245.16 + * License. You can obtain a copy of the License at
  245.17 + * http://www.netbeans.org/cddl-gplv2.html
  245.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  245.19 + * specific language governing permissions and limitations under the
  245.20 + * License.  When distributing the software, include this License Header
  245.21 + * Notice in each file and include the License file at
  245.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  245.23 + * particular file as subject to the "Classpath" exception as provided
  245.24 + * by Oracle in the GPL Version 2 section of the License file that
  245.25 + * accompanied this code. If applicable, add the following below the
  245.26 + * License Header, with the fields enclosed by brackets [] replaced by
  245.27 + * your own identifying information:
  245.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  245.29 + *
  245.30 + * If you wish your version of this file to be governed by only the CDDL
  245.31 + * or only the GPL Version 2, indicate your decision by adding
  245.32 + * "[Contributor] elects to include this software in this distribution
  245.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  245.34 + * single choice of license, a recipient has the option to distribute
  245.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  245.36 + * to extend the choice of license to its licensees as provided above.
  245.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  245.38 + * Version 2 license, then the option applies only if the new code is
  245.39 + * made subject to such option by the copyright holder.
  245.40 + *
  245.41 + * Contributor(s):
  245.42 + *
  245.43 + * Portions Copyrighted 2009 Sun Microsystems, Inc.
  245.44 + */
  245.45 +
  245.46 +package org.netbeans.spi.java.hints;
  245.47 +
  245.48 +import com.sun.source.tree.BlockTree;
  245.49 +import com.sun.source.tree.Scope;
  245.50 +import com.sun.source.tree.StatementTree;
  245.51 +import com.sun.source.tree.Tree;
  245.52 +import com.sun.source.util.TreePath;
  245.53 +import java.util.Collection;
  245.54 +import java.util.Collections;
  245.55 +import java.util.HashMap;
  245.56 +import java.util.Iterator;
  245.57 +import java.util.List;
  245.58 +import java.util.Map;
  245.59 +import java.util.concurrent.atomic.AtomicBoolean;
  245.60 +import javax.lang.model.type.TypeMirror;
  245.61 +import org.netbeans.api.annotations.common.NonNull;
  245.62 +import org.netbeans.modules.java.hints.spiimpl.Utilities;
  245.63 +import org.netbeans.modules.java.hints.spiimpl.pm.PatternCompiler;
  245.64 +import org.netbeans.api.java.source.matching.Matcher;
  245.65 +import org.netbeans.api.java.source.matching.Occurrence;
  245.66 +import org.netbeans.api.java.source.matching.Pattern;
  245.67 +
  245.68 +/**XXX: cancelability
  245.69 + * TODO: needed?
  245.70 + *
  245.71 + * @author lahvac
  245.72 + */
  245.73 +public class MatcherUtilities {
  245.74 +
  245.75 +    public static boolean matches(@NonNull HintContext ctx, @NonNull TreePath variable, @NonNull String pattern) {
  245.76 +        return matches(ctx, variable, pattern, null, null, null);
  245.77 +    }
  245.78 +
  245.79 +    public static boolean matches(@NonNull HintContext ctx, @NonNull TreePath variable, @NonNull String pattern, boolean fillInVariablesHack) {
  245.80 +        return matches(ctx, variable, pattern, ctx.getVariables(), ctx.getMultiVariables(), ctx.getVariableNames());
  245.81 +    }
  245.82 +
  245.83 +    public static boolean matches(@NonNull HintContext ctx, @NonNull TreePath variable, @NonNull String pattern, Map<String, TreePath> outVariables, Map<String, Collection<? extends TreePath>> outMultiVariables, Map<String, String> outVariables2Names) {
  245.84 +        Pattern p = PatternCompiler.compile(ctx.getInfo(), pattern, Collections.<String, TypeMirror>emptyMap(), Collections.<String>emptyList());
  245.85 +        Map<String, TreePath> variables = new HashMap<String, TreePath>(ctx.getVariables());
  245.86 +        Map<String, Collection<? extends TreePath>> multiVariables = new HashMap<String, Collection<? extends TreePath>>(ctx.getMultiVariables());
  245.87 +        Map<String, String> variables2Names = new HashMap<String, String>(ctx.getVariableNames());
  245.88 +        Iterable<? extends Occurrence> occurrences = Matcher.create(ctx.getInfo()).setCancel(new AtomicBoolean()).setPresetVariable(variables, multiVariables, variables2Names).setSearchRoot(variable).setTreeTopSearch().match(p);
  245.89 +
  245.90 +        if (occurrences.iterator().hasNext()) {
  245.91 +            Occurrence od = occurrences.iterator().next();
  245.92 +            outVariables(outVariables, od.getVariables(), ctx.getVariables());
  245.93 +            outVariables(outMultiVariables, od.getMultiVariables(), ctx.getMultiVariables());
  245.94 +            outVariables(outVariables2Names, od.getVariables2Names(), ctx.getVariableNames());
  245.95 +
  245.96 +            return true;
  245.97 +        }
  245.98 +
  245.99 +        return false;
 245.100 +    }
 245.101 +
 245.102 +    public static boolean matches(@NonNull HintContext ctx, @NonNull Collection<? extends TreePath> variable, @NonNull String pattern, Map<String, TreePath> outVariables, Map<String, Collection<? extends TreePath>> outMultiVariables, Map<String, String> outVariables2Names) {
 245.103 +        Scope s = Utilities.constructScope(ctx.getInfo(), Collections.<String, TypeMirror>emptyMap());
 245.104 +        Tree  patternTree = Utilities.parseAndAttribute(ctx.getInfo(), pattern, s);
 245.105 +        List<? extends Tree> patternTrees;
 245.106 +
 245.107 +        if (Utilities.isFakeBlock(patternTree)) {
 245.108 +            List<? extends StatementTree> statements = ((BlockTree) patternTree).getStatements();
 245.109 +
 245.110 +            patternTrees = statements.subList(1, statements.size() - 1);
 245.111 +        } else {
 245.112 +            patternTrees = Collections.singletonList(patternTree);
 245.113 +        }
 245.114 +
 245.115 +        if (variable.size() != patternTrees.size()) return false;
 245.116 +        
 245.117 +        Map<String, TreePath> variables = new HashMap<String, TreePath>(ctx.getVariables());
 245.118 +        Map<String, Collection<? extends TreePath>> multiVariables = new HashMap<String, Collection<? extends TreePath>>(ctx.getMultiVariables());
 245.119 +        Map<String, String> variables2Names = new HashMap<String, String>(ctx.getVariableNames());
 245.120 +        Iterator<? extends TreePath> variableIt = variable.iterator();
 245.121 +        Iterator<? extends Tree> patternTreesIt = patternTrees.iterator();
 245.122 +
 245.123 +        while (variableIt.hasNext() && patternTreesIt.hasNext()) {
 245.124 +            TreePath patternTreePath = new TreePath(new TreePath(ctx.getInfo().getCompilationUnit()), patternTreesIt.next());
 245.125 +            Pattern p = Pattern.createPatternWithFreeVariables(patternTreePath, Collections.<String, TypeMirror>emptyMap());
 245.126 +            Iterable<? extends Occurrence> occurrences = Matcher.create(ctx.getInfo()).setCancel(new AtomicBoolean()).setPresetVariable(variables, multiVariables, variables2Names).setSearchRoot(variableIt.next()).setTreeTopSearch().match(p);
 245.127 +
 245.128 +            if (!occurrences.iterator().hasNext()) {
 245.129 +                return false;
 245.130 +            }
 245.131 +
 245.132 +            Occurrence od = occurrences.iterator().next();
 245.133 +
 245.134 +            variables = od.getVariables();
 245.135 +            multiVariables = od.getMultiVariables();
 245.136 +            variables2Names = od.getVariables2Names();
 245.137 +        }
 245.138 +
 245.139 +        if (variableIt.hasNext() == patternTreesIt.hasNext()) {
 245.140 +            outVariables(outVariables, variables, ctx.getVariables());
 245.141 +            outVariables(outMultiVariables, multiVariables, ctx.getMultiVariables());
 245.142 +            outVariables(outVariables2Names, variables2Names, ctx.getVariableNames());
 245.143 +
 245.144 +            return true;
 245.145 +        }
 245.146 +
 245.147 +        return false;
 245.148 +    }
 245.149 +
 245.150 +    private static <T> void outVariables(Map<String, T> outMap, Map<String, T> currentValues, Map<String, T> origValues) {
 245.151 +        if (outMap == null) return;
 245.152 +
 245.153 +        for (String key : origValues.keySet()) {
 245.154 +            currentValues.remove(key);
 245.155 +        }
 245.156 +
 245.157 +        outMap.putAll(currentValues);
 245.158 +    }
 245.159 +
 245.160 +}
   246.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   246.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/TriggerDecision.java	Sun Oct 23 11:50:54 2016 +0200
   246.3 @@ -0,0 +1,59 @@
   246.4 +/*
   246.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   246.6 + *
   246.7 + * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
   246.8 + *
   246.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  246.10 + * Other names may be trademarks of their respective owners.
  246.11 + *
  246.12 + * The contents of this file are subject to the terms of either the GNU
  246.13 + * General Public License Version 2 only ("GPL") or the Common
  246.14 + * Development and Distribution License("CDDL") (collectively, the
  246.15 + * "License"). You may not use this file except in compliance with the
  246.16 + * License. You can obtain a copy of the License at
  246.17 + * http://www.netbeans.org/cddl-gplv2.html
  246.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  246.19 + * specific language governing permissions and limitations under the
  246.20 + * License.  When distributing the software, include this License Header
  246.21 + * Notice in each file and include the License file at
  246.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  246.23 + * particular file as subject to the "Classpath" exception as provided
  246.24 + * by Oracle in the GPL Version 2 section of the License file that
  246.25 + * accompanied this code. If applicable, add the following below the
  246.26 + * License Header, with the fields enclosed by brackets [] replaced by
  246.27 + * your own identifying information:
  246.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  246.29 + *
  246.30 + * If you wish your version of this file to be governed by only the CDDL
  246.31 + * or only the GPL Version 2, indicate your decision by adding
  246.32 + * "[Contributor] elects to include this software in this distribution
  246.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  246.34 + * single choice of license, a recipient has the option to distribute
  246.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  246.36 + * to extend the choice of license to its licensees as provided above.
  246.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  246.38 + * Version 2 license, then the option applies only if the new code is
  246.39 + * made subject to such option by the copyright holder.
  246.40 + *
  246.41 + * Contributor(s):
  246.42 + *
  246.43 + * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
  246.44 + */
  246.45 +
  246.46 +package org.netbeans.spi.java.hints;
  246.47 +
  246.48 +import java.lang.annotation.ElementType;
  246.49 +import java.lang.annotation.Retention;
  246.50 +import java.lang.annotation.RetentionPolicy;
  246.51 +import java.lang.annotation.Target;
  246.52 +
  246.53 +/**
  246.54 + * @author lahvac
  246.55 + */
  246.56 +@Retention(RetentionPolicy.SOURCE)
  246.57 +@Target(ElementType.METHOD)
  246.58 +public @interface TriggerDecision {
  246.59 +
  246.60 +    public Class<? extends Decision<?, ?>> value();
  246.61 +
  246.62 +}
   247.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   247.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/TriggerPattern.java	Sun Oct 23 11:50:54 2016 +0200
   247.3 @@ -0,0 +1,93 @@
   247.4 +/*
   247.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   247.6 + *
   247.7 + * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
   247.8 + *
   247.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  247.10 + * Other names may be trademarks of their respective owners.
  247.11 + *
  247.12 + * The contents of this file are subject to the terms of either the GNU
  247.13 + * General Public License Version 2 only ("GPL") or the Common
  247.14 + * Development and Distribution License("CDDL") (collectively, the
  247.15 + * "License"). You may not use this file except in compliance with the
  247.16 + * License. You can obtain a copy of the License at
  247.17 + * http://www.netbeans.org/cddl-gplv2.html
  247.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  247.19 + * specific language governing permissions and limitations under the
  247.20 + * License.  When distributing the software, include this License Header
  247.21 + * Notice in each file and include the License file at
  247.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  247.23 + * particular file as subject to the "Classpath" exception as provided
  247.24 + * by Oracle in the GPL Version 2 section of the License file that
  247.25 + * accompanied this code. If applicable, add the following below the
  247.26 + * License Header, with the fields enclosed by brackets [] replaced by
  247.27 + * your own identifying information:
  247.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  247.29 + *
  247.30 + * If you wish your version of this file to be governed by only the CDDL
  247.31 + * or only the GPL Version 2, indicate your decision by adding
  247.32 + * "[Contributor] elects to include this software in this distribution
  247.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  247.34 + * single choice of license, a recipient has the option to distribute
  247.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  247.36 + * to extend the choice of license to its licensees as provided above.
  247.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  247.38 + * Version 2 license, then the option applies only if the new code is
  247.39 + * made subject to such option by the copyright holder.
  247.40 + *
  247.41 + * Contributor(s):
  247.42 + *
  247.43 + * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
  247.44 + */
  247.45 +
  247.46 +package org.netbeans.spi.java.hints;
  247.47 +
  247.48 +import java.lang.annotation.ElementType;
  247.49 +import java.lang.annotation.Retention;
  247.50 +import java.lang.annotation.RetentionPolicy;
  247.51 +import java.lang.annotation.Target;
  247.52 +import org.netbeans.spi.editor.hints.ErrorDescription;
  247.53 +
  247.54 +/**Find parts of the source code that satisfy the given pattern, and invoke the method
  247.55 + * that is annotated with this annotation.
  247.56 + *
  247.57 + * The method must be {@code public static}, the return type must either be assignable to
  247.58 + * {@link ErrorDescription} or to {@link Iterable}{@code <? extends }{@link ErrorDescription}{@code >}.
  247.59 + * Its sole parameter must be {@link HintContext}.
  247.60 + *
  247.61 + * @author lahvac
  247.62 + */
  247.63 +@Retention(RetentionPolicy.SOURCE)
  247.64 +@Target(ElementType.METHOD)
  247.65 +public @interface TriggerPattern {
  247.66 +
  247.67 +    /**
  247.68 +     * Pattern to match on.
  247.69 +     * The pattern consists of:
  247.70 +     * <ul>
  247.71 +     *     <li>a single Java expression</li>
  247.72 +     *     <li>a single Java statement</li>
  247.73 +     *     <li>multiple Java statements</li>
  247.74 +     *     <li>a Java field, method or class</li>
  247.75 +     * </ul>
  247.76 +     *
  247.77 +     * Variables (identifiers starting with {@code $}) can be used to replace part of the pattern.
  247.78 +     * During matching, the actual part of the AST that corresponds to the variable in the pattern
  247.79 +     * will be "bound" to the variable. Variables whose names that do not end with a {@code $} ("single" variables)
  247.80 +     * will be bound to exactly one AST node, whereas variables whose names end with a {@code $} ("multi" variables)
  247.81 +     * will be bound to any number of consecutive AST nodes (with the same AST node as a parent).
  247.82 +     *
  247.83 +     * The actual AST nodes that were bound to single variables are available through {@link HintContext#getVariables() },
  247.84 +     * nodes bound to multi variables are available through {@link HintContext#getMultiVariables() }.
  247.85 +     *
  247.86 +     * For variables that represent an expression, a type constraint can be specified using the
  247.87 +     * {@link #constraints() } attribute.
  247.88 +     *
  247.89 +     * All classes should be referred to using FQNs.
  247.90 +     */
  247.91 +    public String value();
  247.92 +    /**Expected types for variables from the {@link #value() pattern}.
  247.93 +     */
  247.94 +    public ConstraintVariableType[] constraints() default {};
  247.95 +
  247.96 +}
   248.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   248.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/TriggerPatterns.java	Sun Oct 23 11:50:54 2016 +0200
   248.3 @@ -0,0 +1,60 @@
   248.4 +/*
   248.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   248.6 + *
   248.7 + * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
   248.8 + *
   248.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  248.10 + * Other names may be trademarks of their respective owners.
  248.11 + *
  248.12 + * The contents of this file are subject to the terms of either the GNU
  248.13 + * General Public License Version 2 only ("GPL") or the Common
  248.14 + * Development and Distribution License("CDDL") (collectively, the
  248.15 + * "License"). You may not use this file except in compliance with the
  248.16 + * License. You can obtain a copy of the License at
  248.17 + * http://www.netbeans.org/cddl-gplv2.html
  248.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  248.19 + * specific language governing permissions and limitations under the
  248.20 + * License.  When distributing the software, include this License Header
  248.21 + * Notice in each file and include the License file at
  248.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  248.23 + * particular file as subject to the "Classpath" exception as provided
  248.24 + * by Oracle in the GPL Version 2 section of the License file that
  248.25 + * accompanied this code. If applicable, add the following below the
  248.26 + * License Header, with the fields enclosed by brackets [] replaced by
  248.27 + * your own identifying information:
  248.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  248.29 + *
  248.30 + * If you wish your version of this file to be governed by only the CDDL
  248.31 + * or only the GPL Version 2, indicate your decision by adding
  248.32 + * "[Contributor] elects to include this software in this distribution
  248.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  248.34 + * single choice of license, a recipient has the option to distribute
  248.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  248.36 + * to extend the choice of license to its licensees as provided above.
  248.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  248.38 + * Version 2 license, then the option applies only if the new code is
  248.39 + * made subject to such option by the copyright holder.
  248.40 + *
  248.41 + * Contributor(s):
  248.42 + *
  248.43 + * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
  248.44 + */
  248.45 +
  248.46 +package org.netbeans.spi.java.hints;
  248.47 +
  248.48 +import java.lang.annotation.ElementType;
  248.49 +import java.lang.annotation.Retention;
  248.50 +import java.lang.annotation.RetentionPolicy;
  248.51 +import java.lang.annotation.Target;
  248.52 +
  248.53 +/**Multiple {@link TriggerPattern}s.
  248.54 + *
  248.55 + * @author lahvac
  248.56 + */
  248.57 +@Retention(RetentionPolicy.SOURCE)
  248.58 +@Target(ElementType.METHOD)
  248.59 +public @interface TriggerPatterns {
  248.60 +
  248.61 +    public TriggerPattern[] value();
  248.62 +    
  248.63 +}
   249.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   249.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/TriggerTreeKind.java	Sun Oct 23 11:50:54 2016 +0200
   249.3 @@ -0,0 +1,66 @@
   249.4 +/*
   249.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   249.6 + *
   249.7 + * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
   249.8 + *
   249.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  249.10 + * Other names may be trademarks of their respective owners.
  249.11 + *
  249.12 + * The contents of this file are subject to the terms of either the GNU
  249.13 + * General Public License Version 2 only ("GPL") or the Common
  249.14 + * Development and Distribution License("CDDL") (collectively, the
  249.15 + * "License"). You may not use this file except in compliance with the
  249.16 + * License. You can obtain a copy of the License at
  249.17 + * http://www.netbeans.org/cddl-gplv2.html
  249.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  249.19 + * specific language governing permissions and limitations under the
  249.20 + * License.  When distributing the software, include this License Header
  249.21 + * Notice in each file and include the License file at
  249.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  249.23 + * particular file as subject to the "Classpath" exception as provided
  249.24 + * by Oracle in the GPL Version 2 section of the License file that
  249.25 + * accompanied this code. If applicable, add the following below the
  249.26 + * License Header, with the fields enclosed by brackets [] replaced by
  249.27 + * your own identifying information:
  249.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  249.29 + *
  249.30 + * If you wish your version of this file to be governed by only the CDDL
  249.31 + * or only the GPL Version 2, indicate your decision by adding
  249.32 + * "[Contributor] elects to include this software in this distribution
  249.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  249.34 + * single choice of license, a recipient has the option to distribute
  249.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  249.36 + * to extend the choice of license to its licensees as provided above.
  249.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  249.38 + * Version 2 license, then the option applies only if the new code is
  249.39 + * made subject to such option by the copyright holder.
  249.40 + *
  249.41 + * Contributor(s):
  249.42 + *
  249.43 + * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
  249.44 + */
  249.45 +
  249.46 +package org.netbeans.spi.java.hints;
  249.47 +
  249.48 +import com.sun.source.tree.Tree.Kind;
  249.49 +import com.sun.source.util.TreePath;
  249.50 +import java.lang.annotation.ElementType;
  249.51 +import java.lang.annotation.Retention;
  249.52 +import java.lang.annotation.RetentionPolicy;
  249.53 +import java.lang.annotation.Target;
  249.54 +
  249.55 +/**Invoke the method for {@link TreePath}s of the given kind.
  249.56 + *
  249.57 + * The method must be {@code public static}, the return type must either be assignable to
  249.58 + * {@link ErrorDescription} or to {@link Iterable}{@code <? extends }{@link ErrorDescription}{@code >}.
  249.59 + * Its sole parameter must be {@link HintContext}.
  249.60 + *
  249.61 + * @author lahvac
  249.62 + */
  249.63 +@Retention(RetentionPolicy.SOURCE)
  249.64 +@Target(ElementType.METHOD)
  249.65 +public @interface TriggerTreeKind {
  249.66 +
  249.67 +    public Kind[] value();
  249.68 +
  249.69 +}
   250.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   250.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/UseOptions.java	Sun Oct 23 11:50:54 2016 +0200
   250.3 @@ -0,0 +1,64 @@
   250.4 +/*
   250.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   250.6 + *
   250.7 + * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
   250.8 + *
   250.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  250.10 + * Other names may be trademarks of their respective owners.
  250.11 + *
  250.12 + * The contents of this file are subject to the terms of either the GNU
  250.13 + * General Public License Version 2 only ("GPL") or the Common
  250.14 + * Development and Distribution License("CDDL") (collectively, the
  250.15 + * "License"). You may not use this file except in compliance with the
  250.16 + * License. You can obtain a copy of the License at
  250.17 + * http://www.netbeans.org/cddl-gplv2.html
  250.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  250.19 + * specific language governing permissions and limitations under the
  250.20 + * License.  When distributing the software, include this License Header
  250.21 + * Notice in each file and include the License file at
  250.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  250.23 + * particular file as subject to the "Classpath" exception as provided
  250.24 + * by Oracle in the GPL Version 2 section of the License file that
  250.25 + * accompanied this code. If applicable, add the following below the
  250.26 + * License Header, with the fields enclosed by brackets [] replaced by
  250.27 + * your own identifying information:
  250.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  250.29 + *
  250.30 + * If you wish your version of this file to be governed by only the CDDL
  250.31 + * or only the GPL Version 2, indicate your decision by adding
  250.32 + * "[Contributor] elects to include this software in this distribution
  250.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  250.34 + * single choice of license, a recipient has the option to distribute
  250.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  250.36 + * to extend the choice of license to its licensees as provided above.
  250.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  250.38 + * Version 2 license, then the option applies only if the new code is
  250.39 + * made subject to such option by the copyright holder.
  250.40 + *
  250.41 + * Contributor(s):
  250.42 + *
  250.43 + * Portions Copyrighted 2012 Sun Microsystems, Inc.
  250.44 + */
  250.45 +package org.netbeans.spi.java.hints;
  250.46 +
  250.47 +import java.lang.annotation.ElementType;
  250.48 +import java.lang.annotation.Retention;
  250.49 +import java.lang.annotation.RetentionPolicy;
  250.50 +import java.lang.annotation.Target;
  250.51 +
  250.52 +/**Specifies which options from the enclosing class should be used for this hint.
  250.53 + *
  250.54 + * Only applies to methods marked with the {@link Hint} annotation.
  250.55 + *
  250.56 + * @author lahvac
  250.57 + */
  250.58 +@Retention(RetentionPolicy.SOURCE)
  250.59 +@Target(ElementType.METHOD)
  250.60 +public @interface UseOptions {
  250.61 +
  250.62 +    /**Keys (values of the compile-time constants) of the options that should be used
  250.63 +     * for this hint method.
  250.64 +     */
  250.65 +    public String[] value();
  250.66 +    
  250.67 +}
   251.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   251.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/support/FixFactory.java	Sun Oct 23 11:50:54 2016 +0200
   251.3 @@ -0,0 +1,171 @@
   251.4 +/*
   251.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   251.6 + *
   251.7 + * Copyright 1997-2012 Oracle and/or its affiliates. All rights reserved.
   251.8 + *
   251.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  251.10 + * Other names may be trademarks of their respective owners.
  251.11 + *
  251.12 + * The contents of this file are subject to the terms of either the GNU
  251.13 + * General Public License Version 2 only ("GPL") or the Common
  251.14 + * Development and Distribution License("CDDL") (collectively, the
  251.15 + * "License"). You may not use this file except in compliance with the
  251.16 + * License. You can obtain a copy of the License at
  251.17 + * http://www.netbeans.org/cddl-gplv2.html
  251.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  251.19 + * specific language governing permissions and limitations under the
  251.20 + * License.  When distributing the software, include this License Header
  251.21 + * Notice in each file and include the License file at
  251.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  251.23 + * particular file as subject to the "Classpath" exception as provided
  251.24 + * by Oracle in the GPL Version 2 section of the License file that
  251.25 + * accompanied this code. If applicable, add the following below the
  251.26 + * License Header, with the fields enclosed by brackets [] replaced by
  251.27 + * your own identifying information:
  251.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  251.29 + *
  251.30 + * Contributor(s):
  251.31 + *
  251.32 + * Portions Copyrighted 2007-2012 Sun Microsystems, Inc.
  251.33 + */
  251.34 +package org.netbeans.spi.java.hints.support;
  251.35 +
  251.36 +import com.sun.source.tree.ModifiersTree;
  251.37 +import com.sun.source.tree.Tree.Kind;
  251.38 +import com.sun.source.util.TreePath;
  251.39 +import java.util.Collections;
  251.40 +import java.util.EnumSet;
  251.41 +import java.util.Set;
  251.42 +import javax.lang.model.element.Modifier;
  251.43 +import org.netbeans.api.java.source.CompilationInfo;
  251.44 +import org.netbeans.api.java.source.TreeMaker;
  251.45 +import org.netbeans.api.java.source.TreePathHandle;
  251.46 +import org.netbeans.api.java.source.WorkingCopy;
  251.47 +import org.netbeans.spi.editor.hints.Fix;
  251.48 +import org.netbeans.spi.java.hints.JavaFix;
  251.49 +import org.openide.util.Parameters;
  251.50 +
  251.51 +/** Factory for creating generally useful fixes. Currently, changes to the modifiers
  251.52 + *  are supported.
  251.53 + *
  251.54 + * @author Dusan Balek
  251.55 + */
  251.56 +public final class FixFactory {
  251.57 +
  251.58 +    private FixFactory() {}
  251.59 +
  251.60 +    /** Creates a fix, which when invoked adds a set of modifiers to the existing ones
  251.61 +     * @param compilationInfo CompilationInfo to work on
  251.62 +     * @param treePath TreePath to a ModifiersTree.
  251.63 +     * @param toAdd set of Modifiers to add
  251.64 +     * @param text text displayed as a fix description
  251.65 +     */
  251.66 +    public static final Fix addModifiersFix(CompilationInfo compilationInfo, TreePath treePath, Set<Modifier> toAdd, String text) {
  251.67 +        Parameters.notNull("compilationInfo", compilationInfo);
  251.68 +        Parameters.notNull("treePath", treePath);
  251.69 +        Parameters.notNull("toAdd", toAdd);
  251.70 +        Parameters.notNull("text", text);
  251.71 +
  251.72 +        return changeModifiersFix(compilationInfo, treePath, toAdd, Collections.<Modifier>emptySet(), text);
  251.73 +    }
  251.74 +
  251.75 +    /** Creates a fix, which when invoked removes a set of modifiers from the existing ones
  251.76 +     * @param compilationInfo CompilationInfo to work on
  251.77 +     * @param treePath TreePath to a ModifiersTree.
  251.78 +     * @param toRemove set of Modifiers to remove
  251.79 +     * @param text text displayed as a fix description
  251.80 +     */
  251.81 +    public static final Fix removeModifiersFix(CompilationInfo compilationInfo, TreePath treePath, Set<Modifier> toRemove, String text) {
  251.82 +        Parameters.notNull("compilationInfo", compilationInfo);
  251.83 +        Parameters.notNull("treePath", treePath);
  251.84 +        Parameters.notNull("toRemove", toRemove);
  251.85 +        Parameters.notNull("text", text);
  251.86 +
  251.87 +        return changeModifiersFix(compilationInfo, treePath, Collections.<Modifier>emptySet(), toRemove, text);
  251.88 +    }
  251.89 +
  251.90 +    /** Creates a fix, which when invoked changes the existing modifiers
  251.91 +     * @param compilationInfo CompilationInfo to work on
  251.92 +     * @param treePath TreePath to a ModifiersTree.
  251.93 +     * @param toAdd set of Modifiers to add
  251.94 +     * @param toRemove set of Modifiers to remove
  251.95 +     * @param text text displayed as a fix description
  251.96 +     */
  251.97 +    public static final Fix changeModifiersFix(CompilationInfo compilationInfo, TreePath treePath, Set<Modifier> toAdd, Set<Modifier> toRemove, String text) {
  251.98 +        Parameters.notNull("compilationInfo", compilationInfo);
  251.99 +        Parameters.notNull("treePath", treePath);
 251.100 +        Parameters.notNull("toAdd", toAdd);
 251.101 +        Parameters.notNull("toRemove", toRemove);
 251.102 +        Parameters.notNull("text", text);
 251.103 +
 251.104 +        if (treePath.getLeaf().getKind() != Kind.MODIFIERS) {
 251.105 +            return null;
 251.106 +        }
 251.107 +        return new ChangeModifiersFixImpl(TreePathHandle.create(treePath, compilationInfo), toAdd, toRemove, text).toEditorFix();
 251.108 +    }
 251.109 +
 251.110 +    private static final class ChangeModifiersFixImpl extends JavaFix {
 251.111 +
 251.112 +        private final TreePathHandle modsHandle;
 251.113 +        private final Set<Modifier> toAdd;
 251.114 +        private final Set<Modifier> toRemove;
 251.115 +        private final String text;
 251.116 +
 251.117 +        public ChangeModifiersFixImpl(TreePathHandle modsHandle, Set<Modifier> toAdd, Set<Modifier> toRemove, String text) {
 251.118 +            super(modsHandle);
 251.119 +            this.modsHandle = modsHandle;
 251.120 +            this.toAdd = toAdd;
 251.121 +            this.toRemove = toRemove;
 251.122 +            this.text = text;
 251.123 +        }
 251.124 +
 251.125 +        public String getText() {
 251.126 +            return text;
 251.127 +        }
 251.128 +
 251.129 +        @Override
 251.130 +        protected void performRewrite(TransformationContext ctx) {
 251.131 +            WorkingCopy wc = ctx.getWorkingCopy();
 251.132 +            TreePath path = ctx.getPath();
 251.133 +            TreeMaker make = wc.getTreeMaker();
 251.134 +            ModifiersTree newMods = (ModifiersTree) path.getLeaf();
 251.135 +            for (Modifier a : toAdd) {
 251.136 +                newMods = make.addModifiersModifier(newMods, a);
 251.137 +            }
 251.138 +            for (Modifier r : toRemove) {
 251.139 +                newMods = make.removeModifiersModifier(newMods, r);
 251.140 +            }
 251.141 +            wc.rewrite(path.getLeaf(), newMods);
 251.142 +        }
 251.143 +
 251.144 +        @Override
 251.145 +        public boolean equals(Object obj) {
 251.146 +            if (obj == null) {
 251.147 +                return false;
 251.148 +            }
 251.149 +            if (getClass() != obj.getClass()) {
 251.150 +                return false;
 251.151 +            }
 251.152 +            final ChangeModifiersFixImpl other = (ChangeModifiersFixImpl) obj;
 251.153 +            if (this.modsHandle != other.modsHandle && (this.modsHandle == null || !this.modsHandle.equals(other.modsHandle))) {
 251.154 +                return false;
 251.155 +            }
 251.156 +            if (this.toAdd != other.toAdd && (this.toAdd == null || !this.toAdd.equals(other.toAdd))) {
 251.157 +                return false;
 251.158 +            }
 251.159 +            if (this.toRemove != other.toRemove && (this.toRemove == null || !this.toRemove.equals(other.toRemove))) {
 251.160 +                return false;
 251.161 +            }
 251.162 +            return true;
 251.163 +        }
 251.164 +
 251.165 +        @Override
 251.166 +        public int hashCode() {
 251.167 +            int hash = 5;
 251.168 +            hash = 71 * hash + (this.modsHandle != null ? this.modsHandle.hashCode() : 0);
 251.169 +            hash = 71 * hash + (this.toAdd != null ? this.toAdd.hashCode() : 0);
 251.170 +            hash = 71 * hash + (this.toRemove != null ? this.toRemove.hashCode() : 0);
 251.171 +            return hash;
 251.172 +        }
 251.173 +    }
 251.174 +}
   252.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   252.2 +++ b/sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/support/TransformationSupport.java	Sun Oct 23 11:50:54 2016 +0200
   252.3 @@ -0,0 +1,311 @@
   252.4 +/*
   252.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   252.6 + *
   252.7 + * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
   252.8 + *
   252.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  252.10 + * Other names may be trademarks of their respective owners.
  252.11 + *
  252.12 + * The contents of this file are subject to the terms of either the GNU
  252.13 + * General Public License Version 2 only ("GPL") or the Common
  252.14 + * Development and Distribution License("CDDL") (collectively, the
  252.15 + * "License"). You may not use this file except in compliance with the
  252.16 + * License. You can obtain a copy of the License at
  252.17 + * http://www.netbeans.org/cddl-gplv2.html
  252.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  252.19 + * specific language governing permissions and limitations under the
  252.20 + * License.  When distributing the software, include this License Header
  252.21 + * Notice in each file and include the License file at
  252.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  252.23 + * particular file as subject to the "Classpath" exception as provided
  252.24 + * by Oracle in the GPL Version 2 section of the License file that
  252.25 + * accompanied this code. If applicable, add the following below the
  252.26 + * License Header, with the fields enclosed by brackets [] replaced by
  252.27 + * your own identifying information:
  252.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  252.29 + *
  252.30 + * If you wish your version of this file to be governed by only the CDDL
  252.31 + * or only the GPL Version 2, indicate your decision by adding
  252.32 + * "[Contributor] elects to include this software in this distribution
  252.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  252.34 + * single choice of license, a recipient has the option to distribute
  252.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  252.36 + * to extend the choice of license to its licensees as provided above.
  252.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  252.38 + * Version 2 license, then the option applies only if the new code is
  252.39 + * made subject to such option by the copyright holder.
  252.40 + *
  252.41 + * Contributor(s):
  252.42 + *
  252.43 + * Portions Copyrighted 2012 Sun Microsystems, Inc.
  252.44 + */
  252.45 +package org.netbeans.spi.java.hints.support;
  252.46 +
  252.47 +import com.sun.source.util.TreePath;
  252.48 +import java.util.*;
  252.49 +import java.util.Map.Entry;
  252.50 +import java.util.concurrent.atomic.AtomicBoolean;
  252.51 +import javax.lang.model.type.TypeMirror;
  252.52 +import org.netbeans.api.annotations.common.NonNull;
  252.53 +import org.netbeans.api.java.source.CompilationInfo;
  252.54 +import org.netbeans.api.java.source.ModificationResult;
  252.55 +import org.netbeans.api.java.source.TypeMirrorHandle;
  252.56 +import org.netbeans.api.java.source.WorkingCopy;
  252.57 +import org.netbeans.api.java.source.matching.Matcher;
  252.58 +import org.netbeans.api.java.source.matching.Occurrence;
  252.59 +import org.netbeans.api.java.source.matching.Pattern;
  252.60 +import org.netbeans.api.project.Project;
  252.61 +import org.netbeans.modules.java.hints.jackpot.spi.PatternConvertor;
  252.62 +import org.netbeans.modules.java.hints.providers.spi.HintDescription;
  252.63 +import org.netbeans.modules.java.hints.providers.spi.HintDescriptionFactory;
  252.64 +import org.netbeans.modules.java.hints.providers.spi.Trigger;
  252.65 +import org.netbeans.modules.java.hints.spiimpl.JavaFixImpl;
  252.66 +import org.netbeans.modules.java.hints.spiimpl.MessageImpl;
  252.67 +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch;
  252.68 +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.BatchResult;
  252.69 +import org.netbeans.modules.java.hints.spiimpl.batch.BatchUtilities;
  252.70 +import org.netbeans.modules.java.hints.spiimpl.batch.ProgressHandleWrapper;
  252.71 +import org.netbeans.modules.java.hints.spiimpl.batch.Scopes;
  252.72 +import org.netbeans.modules.java.hints.spiimpl.hints.HintsInvoker;
  252.73 +import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings;
  252.74 +import org.netbeans.modules.java.hints.spiimpl.pm.PatternCompiler;
  252.75 +import org.netbeans.modules.refactoring.spi.RefactoringElementImplementation;
  252.76 +import org.netbeans.spi.editor.hints.*;
  252.77 +import org.netbeans.spi.java.hints.HintContext;
  252.78 +import org.netbeans.spi.java.hints.JavaFix;
  252.79 +import org.openide.util.Exceptions;
  252.80 +
  252.81 +/**
  252.82 + * Static utility classes for processing jackpot patterns.
  252.83 + * <a href="https://bitbucket.org/jlahoda/jackpot30/wiki/RulesLanguage">Rules Language</a>
  252.84 + * @author Jan Becicka
  252.85 + * @since 1.1
  252.86 + */
  252.87 +public final class TransformationSupport {
  252.88 +
  252.89 +    private String jackpotPattern;
  252.90 +    private Transformer transformer;
  252.91 +    private AtomicBoolean cancel = new AtomicBoolean();
  252.92 +
  252.93 +    private TransformationSupport(String jackpotPattern, Transformer transformer) {
  252.94 +        this.jackpotPattern = jackpotPattern;
  252.95 +        this.transformer = transformer;
  252.96 +    }
  252.97 +    
  252.98 +    /**
  252.99 +     * Creates new TransformationSupport representing given jackpotPattern.
 252.100 +     * @param jackpotPattern
 252.101 +     * @return
 252.102 +     */
 252.103 +    public static @NonNull TransformationSupport create(@NonNull String jackpotPattern) {
 252.104 +        return new TransformationSupport(jackpotPattern, null);
 252.105 +    }
 252.106 +
 252.107 +    /**
 252.108 +     * Creates new TransformationSupport representing given jackpotPattern with custom Transformer.
 252.109 +     * @param inputJackpotPattern
 252.110 +     * @param t
 252.111 +     * @see Transformer
 252.112 +     * @return
 252.113 +     */
 252.114 +    public static @NonNull TransformationSupport create(@NonNull String inputJackpotPattern, @NonNull Transformer t) {
 252.115 +        return new TransformationSupport(inputJackpotPattern, t);
 252.116 +    }
 252.117 +
 252.118 +    /**
 252.119 +     * Option to cancel query.
 252.120 +     * @param cancel
 252.121 +     * @return
 252.122 +     */
 252.123 +    public @NonNull TransformationSupport setCancel(@NonNull AtomicBoolean cancel) {
 252.124 +        this.cancel = cancel;
 252.125 +        return this;
 252.126 +    }
 252.127 +
 252.128 +
 252.129 +    /**
 252.130 +     * Run current transformation on all projects and collect results.
 252.131 +     * @return collection of {@link ModificationResult}
 252.132 +     */
 252.133 +    public @NonNull Collection<? extends ModificationResult> processAllProjects() {
 252.134 +        if (transformer!=null) {
 252.135 +            return performTransformation(jackpotPattern, transformer, cancel);
 252.136 +        } else {
 252.137 +            return performTransformation(jackpotPattern, cancel);
 252.138 +        }
 252.139 +    }
 252.140 +
 252.141 +    
 252.142 +    /**
 252.143 +     * Process current transformation on given treePath and performs rewrite on
 252.144 +     * workingCopy.
 252.145 +     * @param workingCopy
 252.146 +     * @param treePath 
 252.147 +     */
 252.148 +    public void transformTreePath(@NonNull WorkingCopy workingCopy, @NonNull TreePath treePath) {
 252.149 +        if (transformer!=null) {
 252.150 +            throw new UnsupportedOperationException("Not implemented yet");
 252.151 +        } else {
 252.152 +            performTransformation(workingCopy, treePath, jackpotPattern, cancel);
 252.153 +        }
 252.154 +    }
 252.155 +
 252.156 +
 252.157 +    /**
 252.158 +     * Transformer callback which is called for each occurrence during processing 
 252.159 +     * of {@link #performTransformation(java.lang.String, org.netbeans.spi.java.hints.support.JackpotSupport.Transformer, java.util.concurrent.atomic.AtomicBoolean)    
 252.160 +     */
 252.161 +    public interface Transformer {
 252.162 +
 252.163 +        /**
 252.164 +         * Implement custom transformation of occurrence here.
 252.165 +         * @param copy
 252.166 +         * @param occurrence
 252.167 +         */
 252.168 +        public void transform(WorkingCopy copy, Occurrence occurrence);
 252.169 +
 252.170 +    }
 252.171 +    
 252.172 +    
 252.173 +    
 252.174 +    /**
 252.175 +     * Performs transformation described by jackpotPattern on given workingCopy.
 252.176 +     * @param workingCopy
 252.177 +     * @param jackpotPattern
 252.178 +     * @param cancel
 252.179 +     */
 252.180 +    private static void performTransformation(WorkingCopy workingCopy, TreePath on, String jackpotPattern, AtomicBoolean cancel) {
 252.181 +        Iterable<? extends HintDescription> hints = PatternConvertor.create(jackpotPattern);
 252.182 +        HintsInvoker inv = new HintsInvoker(HintsSettings.getSettingsFor(workingCopy.getFileObject()), cancel);
 252.183 +        Map<HintDescription, List<ErrorDescription>> computeHints = inv.computeHints(workingCopy, on, false, hints, new ArrayList<MessageImpl>());
 252.184 +        
 252.185 +        if (computeHints == null || cancel.get()) return ;
 252.186 +        
 252.187 +        List<ErrorDescription> errs = new ArrayList<ErrorDescription>();
 252.188 +        for (Entry<HintDescription, List<ErrorDescription>> entry: computeHints.entrySet()) {
 252.189 +            errs.addAll(entry.getValue());
 252.190 +        }
 252.191 +        List<MessageImpl> problems = new LinkedList<MessageImpl>();
 252.192 +
 252.193 +        try {
 252.194 +            if (BatchUtilities.applyFixes(workingCopy, Collections.<Project, Set<String>>emptyMap(), errs, null, new ArrayList<RefactoringElementImplementation>(), problems)) {
 252.195 +                throw new IllegalStateException();
 252.196 +            }
 252.197 +        } catch (IllegalStateException ex) {
 252.198 +            Exceptions.printStackTrace(ex);
 252.199 +        } catch (Exception ex) {
 252.200 +            Exceptions.printStackTrace(ex);
 252.201 +        }
 252.202 +
 252.203 +        if (!problems.isEmpty()) {
 252.204 +            throw new IllegalStateException(problems.get(0).text);
 252.205 +        }
 252.206 +    }
 252.207 +    
 252.208 +    /**
 252.209 +     * Performs jackpotPattern transformation in all open projects.
 252.210 +     * @param jackpotPattern
 252.211 +     * @param cancel
 252.212 +     * @return
 252.213 +     */
 252.214 +    private static  Collection<? extends ModificationResult> performTransformation(String jackpotPattern, AtomicBoolean cancel) {
 252.215 +        Collection<MessageImpl> problems = new LinkedList<MessageImpl>();
 252.216 +        BatchResult batchResult = BatchSearch.findOccurrences(PatternConvertor.create(jackpotPattern), Scopes.allOpenedProjectsScope());
 252.217 +        return BatchUtilities.applyFixes(batchResult, new ProgressHandleWrapper(1, 1), cancel, problems);
 252.218 +    }
 252.219 +    
 252.220 +    /**
 252.221 +     * Performs transformation defined by transformer on all occurrences, which matches inputJackpotPattern.
 252.222 +     * @param inputJackpotPattern
 252.223 +     * @param transformer
 252.224 +     * @return collection of ModificationResults.
 252.225 +     */
 252.226 +    private static Collection<? extends ModificationResult> performTransformation(final String inputJackpotPattern, final Transformer transformer, AtomicBoolean cancel) {
 252.227 +        List<HintDescription> descriptions = new ArrayList<HintDescription>();
 252.228 +
 252.229 +        for (HintDescription hd : PatternConvertor.create(inputJackpotPattern)) {
 252.230 +            final String triggerPattern = ((Trigger.PatternDescription) hd.getTrigger()).getPattern();
 252.231 +            descriptions.add(HintDescriptionFactory.create().setTrigger(hd.getTrigger()).setWorker(new HintDescription.Worker() {
 252.232 +                @Override public Collection<? extends ErrorDescription> createErrors(HintContext ctx) {
 252.233 +                    final Map<String, TypeMirrorHandle<?>> constraintsHandles = new HashMap<String, TypeMirrorHandle<?>>();
 252.234 +
 252.235 +                    for (Map.Entry<String, TypeMirror> c : ctx.getConstraints().entrySet()) {
 252.236 +                        constraintsHandles.put(c.getKey(), TypeMirrorHandle.create(c.getValue()));
 252.237 +                    }
 252.238 +
 252.239 +                    Fix fix = new JavaFix(ctx.getInfo(), ctx.getPath()) {
 252.240 +                        @Override protected String getText() {
 252.241 +                            return "";
 252.242 +                        }
 252.243 +                        @Override protected void performRewrite(JavaFix.TransformationContext ctx) {
 252.244 +                            WorkingCopy wc = ctx.getWorkingCopy();
 252.245 +                            Map<String, TypeMirror> constraints = new HashMap<String, TypeMirror>();
 252.246 +
 252.247 +                            for (Map.Entry<String, TypeMirrorHandle<?>> c : constraintsHandles.entrySet()) {
 252.248 +                                constraints.put(c.getKey(), c.getValue().resolve(wc));
 252.249 +                            }
 252.250 +
 252.251 +                            Pattern pattern = PatternCompiler.compile(wc, triggerPattern, constraints, Collections.<String>emptyList());
 252.252 +                            Collection<? extends Occurrence> occurrence = Matcher.create(wc).setTreeTopSearch().setSearchRoot(ctx.getPath()).match(pattern);
 252.253 +
 252.254 +                            assert occurrence.size() == 1;
 252.255 +
 252.256 +                            transformer.transform(wc, occurrence.iterator().next());
 252.257 +                        }
 252.258 +                    }.toEditorFix();
 252.259 +                    
 252.260 +                    return Collections.singletonList(ErrorDescriptionFactory.createErrorDescription(Severity.WARNING, "", Collections.singletonList(fix), ctx.getInfo().getFileObject(), 0, 0));
 252.261 +                }
 252.262 +            }).produce());
 252.263 +
 252.264 +        }
 252.265 +        
 252.266 +        BatchSearch.BatchResult batchResult = BatchSearch.findOccurrences(descriptions, Scopes.allOpenedProjectsScope());
 252.267 +        return BatchUtilities.applyFixes(batchResult, new ProgressHandleWrapper(1, 1), cancel, new ArrayList<MessageImpl>());
 252.268 +    }
 252.269 +    
 252.270 +    /**
 252.271 +     * Performs transformation described by transformationJackpotPattern on all occurences described by inputJackpotPattern.
 252.272 +     * @param inputJackpotPattern
 252.273 +     * @param transformationJackpotPattern
 252.274 +     * @param cancel 
 252.275 +     * @return
 252.276 +     */
 252.277 +    private static Collection<? extends ModificationResult> performTransformation(String inputJackpotPattern, final String transformationJackpotPattern, AtomicBoolean cancel) {
 252.278 +        return performTransformation(inputJackpotPattern, new Transformer() {
 252.279 +
 252.280 +            @Override
 252.281 +            public void transform(WorkingCopy copy, Occurrence occurrence) {
 252.282 +                try {
 252.283 +                    Fix toFix = TransformationSupport.rewriteFix(copy, "whatever", occurrence.getOccurrenceRoot(), transformationJackpotPattern, occurrence.getVariables(), occurrence.getMultiVariables(), occurrence.getVariables2Names(), Collections.<String, TypeMirror>emptyMap(), Collections.<String, String>emptyMap());
 252.284 +                    TransformationSupport.process(((JavaFixImpl) toFix).jf, copy, false, null, new ArrayList<RefactoringElementImplementation>());
 252.285 +                } catch (Exception ex) {
 252.286 +                    Exceptions.printStackTrace(ex);
 252.287 +                }
 252.288 +            }
 252.289 +        }, cancel);
 252.290 +    }
 252.291 +
 252.292 +    private static ChangeInfo process(JavaFix jf, WorkingCopy wc, boolean canShowUI, Map<org.openide.filesystems.FileObject, byte[]> resourceContent, Collection<? super RefactoringElementImplementation> fileChanges) throws Exception {
 252.293 +        return JavaFixImpl.Accessor.INSTANCE.process(jf, wc, canShowUI, resourceContent, fileChanges);
 252.294 +    }
 252.295 +
 252.296 +    /**
 252.297 +     * 
 252.298 +     * @param info
 252.299 +     * @param displayName
 252.300 +     * @param what
 252.301 +     * @param to
 252.302 +     * @param parameters
 252.303 +     * @param parametersMulti
 252.304 +     * @param parameterNames
 252.305 +     * @param constraints
 252.306 +     * @param options
 252.307 +     * @param imports
 252.308 +     * @return
 252.309 +     */
 252.310 +    private static Fix rewriteFix(CompilationInfo info, String displayName, TreePath what, final String to, Map<String, TreePath> parameters, Map<String, Collection<? extends TreePath>> parametersMulti, final Map<String, String> parameterNames, Map<String, TypeMirror> constraints, Map<String, String> options, String... imports) {
 252.311 +        return JavaFixImpl.Accessor.INSTANCE.rewriteFix(info, displayName, what, to, parameters, parametersMulti, parameterNames, constraints, options, imports);
 252.312 +    }
 252.313 +    
 252.314 +}
   253.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   253.2 +++ b/sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/providers/code/CodeHintProviderImplTest.java	Sun Oct 23 11:50:54 2016 +0200
   253.3 @@ -0,0 +1,114 @@
   253.4 +/*
   253.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   253.6 + *
   253.7 + * Copyright 2009-2010 Oracle and/or its affiliates. All rights reserved.
   253.8 + *
   253.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  253.10 + * Other names may be trademarks of their respective owners.
  253.11 + *
  253.12 + * The contents of this file are subject to the terms of either the GNU
  253.13 + * General Public License Version 2 only ("GPL") or the Common
  253.14 + * Development and Distribution License("CDDL") (collectively, the
  253.15 + * "License"). You may not use this file except in compliance with the
  253.16 + * License. You can obtain a copy of the License at
  253.17 + * http://www.netbeans.org/cddl-gplv2.html
  253.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  253.19 + * specific language governing permissions and limitations under the
  253.20 + * License.  When distributing the software, include this License Header
  253.21 + * Notice in each file and include the License file at
  253.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  253.23 + * particular file as subject to the "Classpath" exception as provided
  253.24 + * by Oracle in the GPL Version 2 section of the License file that
  253.25 + * accompanied this code. If applicable, add the following below the
  253.26 + * License Header, with the fields enclosed by brackets [] replaced by
  253.27 + * your own identifying information:
  253.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  253.29 + *
  253.30 + * If you wish your version of this file to be governed by only the CDDL
  253.31 + * or only the GPL Version 2, indicate your decision by adding
  253.32 + * "[Contributor] elects to include this software in this distribution
  253.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  253.34 + * single choice of license, a recipient has the option to distribute
  253.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  253.36 + * to extend the choice of license to its licensees as provided above.
  253.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  253.38 + * Version 2 license, then the option applies only if the new code is
  253.39 + * made subject to such option by the copyright holder.
  253.40 + *
  253.41 + * Contributor(s):
  253.42 + *
  253.43 + * Portions Copyrighted 2009-2010 Sun Microsystems, Inc.
  253.44 + */
  253.45 +
  253.46 +package org.netbeans.modules.java.hints.providers.code;
  253.47 +
  253.48 +import com.sun.source.tree.Tree.Kind;
  253.49 +import java.util.Arrays;
  253.50 +import java.util.Collection;
  253.51 +import java.util.HashSet;
  253.52 +import java.util.Map;
  253.53 +import java.util.Set;
  253.54 +import org.junit.Test;
  253.55 +import org.netbeans.spi.java.hints.ConstraintVariableType;
  253.56 +import org.netbeans.spi.java.hints.Hint;
  253.57 +import org.netbeans.spi.java.hints.TriggerPattern;
  253.58 +import org.netbeans.spi.java.hints.TriggerTreeKind;
  253.59 +import org.netbeans.spi.java.hints.HintContext;
  253.60 +import static org.junit.Assert.*;
  253.61 +import org.netbeans.modules.java.hints.providers.code.CodeHintProviderImpl.WorkerImpl;
  253.62 +import org.netbeans.modules.java.hints.spiimpl.SPIAccessor;
  253.63 +import org.netbeans.modules.java.hints.providers.spi.HintDescription;
  253.64 +import org.netbeans.modules.java.hints.providers.spi.HintMetadata;
  253.65 +import org.netbeans.spi.editor.hints.ErrorDescription;
  253.66 +
  253.67 +/**
  253.68 + *
  253.69 + * @author lahvac
  253.70 + */
  253.71 +@Hint(displayName="foo", description="bar", id="hintPattern", category="general")
  253.72 +public class CodeHintProviderImplTest {
  253.73 +
  253.74 +    public CodeHintProviderImplTest() {
  253.75 +    }
  253.76 +
  253.77 +    @Test
  253.78 +    public void testComputeHints() throws Exception {
  253.79 +        Map<HintMetadata, ? extends Collection<? extends HintDescription>> hints = new CodeHintProviderImpl().computeHints();
  253.80 +
  253.81 +        Set<String> golden = new HashSet<String>(Arrays.asList(
  253.82 +            "$1.toURL():public static org.netbeans.spi.editor.hints.ErrorDescription org.netbeans.modules.java.hints.providers.code.CodeHintProviderImplTest.hintPattern1(org.netbeans.spi.java.hints.HintContext)",
  253.83 +            "[METHOD_INVOCATION]:public static org.netbeans.spi.editor.hints.ErrorDescription org.netbeans.modules.java.hints.providers.code.CodeHintProviderImplTest.hintPattern2(org.netbeans.spi.java.hints.HintContext)"
  253.84 +        ));
  253.85 +
  253.86 +        for (Collection<? extends HintDescription> hds : hints.values()) {
  253.87 +            for (HintDescription d : hds) {
  253.88 +                golden.remove(toString(d));
  253.89 +            }
  253.90 +        }
  253.91 +
  253.92 +        assertTrue(golden.toString(), golden.isEmpty());
  253.93 +    }
  253.94 +
  253.95 +    private static String toString(HintDescription hd) throws Exception {
  253.96 +        StringBuilder sb = new StringBuilder();
  253.97 +
  253.98 +        sb.append(hd.getTrigger());
  253.99 +        sb.append(":");
 253.100 +        
 253.101 +        //TODO: constraints
 253.102 +        sb.append(((WorkerImpl) hd.getWorker()).getMethod().toGenericString());
 253.103 +
 253.104 +        return sb.toString();
 253.105 +    }
 253.106 +
 253.107 +    @TriggerPattern(value="$1.toURL()", constraints=@ConstraintVariableType(variable="$1", type="java.io.File"))
 253.108 +    public static ErrorDescription hintPattern1(HintContext ctx) {
 253.109 +        return null;
 253.110 +    }
 253.111 +
 253.112 +    @TriggerTreeKind(Kind.METHOD_INVOCATION)
 253.113 +    public static ErrorDescription hintPattern2(HintContext ctx) {
 253.114 +        return null;
 253.115 +    }
 253.116 +
 253.117 +}
 253.118 \ No newline at end of file
   254.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   254.2 +++ b/sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/providers/code/FSWrapperTest.java	Sun Oct 23 11:50:54 2016 +0200
   254.3 @@ -0,0 +1,221 @@
   254.4 +/*
   254.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   254.6 + *
   254.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
   254.8 + *
   254.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  254.10 + * Other names may be trademarks of their respective owners.
  254.11 + *
  254.12 + * The contents of this file are subject to the terms of either the GNU
  254.13 + * General Public License Version 2 only ("GPL") or the Common
  254.14 + * Development and Distribution License("CDDL") (collectively, the
  254.15 + * "License"). You may not use this file except in compliance with the
  254.16 + * License. You can obtain a copy of the License at
  254.17 + * http://www.netbeans.org/cddl-gplv2.html
  254.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  254.19 + * specific language governing permissions and limitations under the
  254.20 + * License.  When distributing the software, include this License Header
  254.21 + * Notice in each file and include the License file at
  254.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  254.23 + * particular file as subject to the "Classpath" exception as provided
  254.24 + * by Oracle in the GPL Version 2 section of the License file that
  254.25 + * accompanied this code. If applicable, add the following below the
  254.26 + * License Header, with the fields enclosed by brackets [] replaced by
  254.27 + * your own identifying information:
  254.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  254.29 + *
  254.30 + * If you wish your version of this file to be governed by only the CDDL
  254.31 + * or only the GPL Version 2, indicate your decision by adding
  254.32 + * "[Contributor] elects to include this software in this distribution
  254.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  254.34 + * single choice of license, a recipient has the option to distribute
  254.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  254.36 + * to extend the choice of license to its licensees as provided above.
  254.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  254.38 + * Version 2 license, then the option applies only if the new code is
  254.39 + * made subject to such option by the copyright holder.
  254.40 + *
  254.41 + * Contributor(s):
  254.42 + *
  254.43 + * Portions Copyrighted 2010 Sun Microsystems, Inc.
  254.44 + */
  254.45 +
  254.46 +package org.netbeans.modules.java.hints.providers.code;
  254.47 +
  254.48 +import java.lang.annotation.Annotation;
  254.49 +import java.lang.reflect.AnnotatedElement;
  254.50 +import java.lang.reflect.Array;
  254.51 +import java.lang.reflect.Method;
  254.52 +import java.util.ArrayList;
  254.53 +import java.util.LinkedList;
  254.54 +import java.util.List;
  254.55 +import java.util.Map;
  254.56 +import java.util.prefs.Preferences;
  254.57 +import javax.sound.sampled.LineListener;
  254.58 +import javax.swing.JComponent;
  254.59 +import javax.swing.JPanel;
  254.60 +import static org.junit.Assert.assertEquals;
  254.61 +import static org.junit.Assert.assertNotNull;
  254.62 +import static org.junit.Assert.fail;
  254.63 +import org.junit.Test;
  254.64 +import org.netbeans.modules.java.hints.providers.code.FSWrapper.AnnotatableWrapper;
  254.65 +import org.netbeans.modules.java.hints.providers.code.FSWrapper.ClassWrapper;
  254.66 +import org.netbeans.modules.java.hints.providers.code.FSWrapper.MethodWrapper;
  254.67 +import org.netbeans.spi.java.hints.CustomizerProvider;
  254.68 +import org.netbeans.spi.java.hints.Hint;
  254.69 +import org.netbeans.spi.java.hints.HintContext;
  254.70 +import org.netbeans.spi.java.hints.TestAnnotations.TestAnnotation1;
  254.71 +import org.netbeans.spi.java.hints.TestAnnotations.TestAnnotation2;
  254.72 +import org.netbeans.spi.java.hints.TestAnnotations.TestAnnotation3;
  254.73 +import org.netbeans.spi.java.hints.TestAnnotations.TestEnum;
  254.74 +
  254.75 +/**
  254.76 + *
  254.77 + * @author lahvac
  254.78 + */
  254.79 +public class FSWrapperTest {
  254.80 +
  254.81 +    public FSWrapperTest() {
  254.82 +    }
  254.83 +
  254.84 +    @Test
  254.85 +    public void testWrappedClasses() throws Exception {
  254.86 +        Class[] classes = new Class[] {TestClass.class};
  254.87 +        Iterable<? extends ClassWrapper> wrapped = FSWrapper.listClasses();
  254.88 +
  254.89 +        OUTER: for (Class<?> c : classes) {
  254.90 +            for (ClassWrapper w : wrapped) {
  254.91 +                if (w.getName().equals(c.getName())) {
  254.92 +                    checkClassWrapper(c, w);
  254.93 +                    continue OUTER;
  254.94 +                }
  254.95 +            }
  254.96 +
  254.97 +            fail(c.getName());
  254.98 +        }
  254.99 +    }
 254.100 +
 254.101 +    private static void checkClassWrapper(Class<?> c, ClassWrapper cw) throws Exception {
 254.102 +        checkAnnotations(c, cw);
 254.103 +
 254.104 +        OUTER: for (Method m : c.getDeclaredMethods()) {
 254.105 +            if (m.getAnnotations().length == 0) continue;
 254.106 +            
 254.107 +            for (MethodWrapper wrapped : cw.getMethods()) {
 254.108 +                if (wrapped.getName().equals(m.getName())) {
 254.109 +                    assertEquals(m, FSWrapper.resolveMethod(wrapped.getClazz().getName(), wrapped.getName()));
 254.110 +                    checkAnnotations(m, wrapped);
 254.111 +                    continue OUTER;
 254.112 +                }
 254.113 +            }
 254.114 +            
 254.115 +            fail(m.getName());
 254.116 +        }
 254.117 +    }
 254.118 +
 254.119 +    private static void checkAnnotations(AnnotatedElement el, AnnotatableWrapper aw) throws Exception {
 254.120 +        for (Annotation ann : el.getAnnotations()) {
 254.121 +            Annotation wrapper = aw.getAnnotation(ann.annotationType());
 254.122 +
 254.123 +            assertNotNull(ann.annotationType().getName(), wrapper);
 254.124 +
 254.125 +            checkAnnotation(ann, wrapper);
 254.126 +        }
 254.127 +    }
 254.128 +
 254.129 +    private static void checkAnnotation(Annotation real, Annotation wrapped) throws Exception {
 254.130 +        for (Method m : real.annotationType().getDeclaredMethods()) {
 254.131 +            Object realValue = m.invoke(real);
 254.132 +            Object wrappedValue = m.invoke(wrapped);
 254.133 +
 254.134 +            checkValue(realValue, wrappedValue);
 254.135 +        }
 254.136 +    }
 254.137 +
 254.138 +    private static void checkValue(Object o1, Object o2) throws Exception {
 254.139 +        assertEquals(o1.getClass().isAnnotation(), o2.getClass().isAnnotation());
 254.140 +        if (o1.getClass().isAnnotation()) {
 254.141 +            assertEquals(((Annotation) o1).annotationType(), ((Annotation) o2).annotationType());
 254.142 +        } else {
 254.143 +            assertEquals(o1.getClass(), o2.getClass());
 254.144 +        }
 254.145 +
 254.146 +        if (o1.getClass().isArray()) {
 254.147 +            assertEquals(Array.getLength(o1), Array.getLength(o2));
 254.148 +
 254.149 +            for (int c = 0; c < Array.getLength(o1); c++) {
 254.150 +                checkValue(Array.get(o1, c), Array.get(o2, c));
 254.151 +            }
 254.152 +        } else if (o1.getClass().isAnnotation()) {
 254.153 +            checkAnnotation((Annotation) o1, (Annotation) o2);
 254.154 +        } else {
 254.155 +            assertEquals(o1, o2);
 254.156 +        }
 254.157 +    }
 254.158 +
 254.159 +    @Hint(displayName="foo", description="bar", category="")
 254.160 +    @TestAnnotation1(
 254.161 +        b1=true,
 254.162 +        b3=true,
 254.163 +        i1=42,
 254.164 +        i3=84,
 254.165 +        s1="a42",
 254.166 +        s3="a84",
 254.167 +        a1=@TestAnnotation2(a1=@TestAnnotation3(as1={"u1a2", "u1b2"}, as3="u1c2")),
 254.168 +//        a3=@TestAnnotation2(a1=@TestAnnotation3(as1={"u1a2", "u1b2"}, as3="u1c2")),
 254.169 +        c1=String.class,
 254.170 +        c3=String.class,
 254.171 +        e1=TestEnum.C,
 254.172 +        e3=TestEnum.D,
 254.173 +        ab1={false, true},
 254.174 +        ab3={false, true, false},
 254.175 +        ai1={84, 42},
 254.176 +        ai3={84, 42, 84},
 254.177 +        as1={"c42", "c84"},
 254.178 +        as3={"c42", "c84", "c42"},
 254.179 +        aa1={@TestAnnotation2(a1=@TestAnnotation3(as1={"u3a2", "u3b2"}, as3="u3c2")), @TestAnnotation2(a1=@TestAnnotation3(as1={"u4a2", "u4b2"}, as3="u4c2"))},
 254.180 +//        aa3={@TestAnnotation2(a1=@TestAnnotation3(as1={"u5a2", "u5b2"}, as3="u5c2")), @TestAnnotation2(a1=@TestAnnotation3(as1={"u6a2", "u6b2"}, as3="u6c2"))},
 254.181 +        ac1={List.class, Integer.class},
 254.182 +        ac3={LineListener.class, LinkedList.class},
 254.183 +        ae1={TestEnum.C, TestEnum.D},
 254.184 +        ae3={TestEnum.D, TestEnum.C}
 254.185 +    )
 254.186 +    public static class TestClass {
 254.187 +        @TestAnnotation1(
 254.188 +            b1=false,
 254.189 +            b2=true,
 254.190 +            i1=43,
 254.191 +            i2=85,
 254.192 +            s1="w42",
 254.193 +            s2="w84",
 254.194 +            a1=@TestAnnotation2(a1=@TestAnnotation3(as1={"u7a2", "u7b2"}, as3="u7c2")),
 254.195 +//            a2=@TestAnnotation2(a1=@TestAnnotation3(as1={"u8a2", "u8b2"}, as3="u8c2")),
 254.196 +            c1=String.class,
 254.197 +            c2=String.class,
 254.198 +            e1=TestEnum.C,
 254.199 +            e3=TestEnum.D,
 254.200 +            ab1={false, true},
 254.201 +            ab2={false, true, false},
 254.202 +            ai1={85, 43},
 254.203 +            ai2={85, 43, 85},
 254.204 +            as1={"d42", "d84"},
 254.205 +            as2={"e42", "e84", "e42"},
 254.206 +            aa1={@TestAnnotation2(a1=@TestAnnotation3(as1={"u9a2", "u9b2"}, as3="u9c2")), @TestAnnotation2(a1=@TestAnnotation3(as1={"uaa2", "u4b2"}, as3="uac2"))},
 254.207 +//            aa2={@TestAnnotation2(a1=@TestAnnotation3(as1={"uba2", "ubb2"}, as3="ubc2")), @TestAnnotation2(a1=@TestAnnotation3(as1={"uca2", "ucb2"}, as3="ucc2"))},
 254.208 +            ac1={ArrayList.class, Float.class},
 254.209 +            ac2={StringBuilder.class, Map.class},
 254.210 +            ae1={TestEnum.C, TestEnum.D},
 254.211 +            ae3={TestEnum.D, TestEnum.C}
 254.212 +        )
 254.213 +        public static void test(HintContext ctx) {
 254.214 +            
 254.215 +        }
 254.216 +    }
 254.217 +
 254.218 +    public static class CustomizerImpl implements CustomizerProvider {
 254.219 +        @Override public JComponent getCustomizer(Preferences prefs) {
 254.220 +            return new JPanel();
 254.221 +        }
 254.222 +    }
 254.223 +
 254.224 +}
   255.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   255.2 +++ b/sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/providers/code/TestAnnotations.java	Sun Oct 23 11:50:54 2016 +0200
   255.3 @@ -0,0 +1,109 @@
   255.4 +/*
   255.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   255.6 + *
   255.7 + * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
   255.8 + *
   255.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  255.10 + * Other names may be trademarks of their respective owners.
  255.11 + *
  255.12 + * The contents of this file are subject to the terms of either the GNU
  255.13 + * General Public License Version 2 only ("GPL") or the Common
  255.14 + * Development and Distribution License("CDDL") (collectively, the
  255.15 + * "License"). You may not use this file except in compliance with the
  255.16 + * License. You can obtain a copy of the License at
  255.17 + * http://www.netbeans.org/cddl-gplv2.html
  255.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  255.19 + * specific language governing permissions and limitations under the
  255.20 + * License.  When distributing the software, include this License Header
  255.21 + * Notice in each file and include the License file at
  255.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  255.23 + * particular file as subject to the "Classpath" exception as provided
  255.24 + * by Oracle in the GPL Version 2 section of the License file that
  255.25 + * accompanied this code. If applicable, add the following below the
  255.26 + * License Header, with the fields enclosed by brackets [] replaced by
  255.27 + * your own identifying information:
  255.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  255.29 + *
  255.30 + * If you wish your version of this file to be governed by only the CDDL
  255.31 + * or only the GPL Version 2, indicate your decision by adding
  255.32 + * "[Contributor] elects to include this software in this distribution
  255.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  255.34 + * single choice of license, a recipient has the option to distribute
  255.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  255.36 + * to extend the choice of license to its licensees as provided above.
  255.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  255.38 + * Version 2 license, then the option applies only if the new code is
  255.39 + * made subject to such option by the copyright holder.
  255.40 + *
  255.41 + * Contributor(s):
  255.42 + *
  255.43 + * Portions Copyrighted 2012 Sun Microsystems, Inc.
  255.44 + */
  255.45 +//placed in this package intentionally: the JavaHintsAnnotationProcessor ignores all annotations outside this package
  255.46 +package org.netbeans.spi.java.hints;
  255.47 +
  255.48 +import java.lang.annotation.Retention;
  255.49 +import java.lang.annotation.RetentionPolicy;
  255.50 +
  255.51 +/**
  255.52 + *
  255.53 + * @author lahvac
  255.54 + */
  255.55 +public class TestAnnotations {
  255.56 +    
  255.57 +    @Retention(RetentionPolicy.RUNTIME)
  255.58 +    public @interface TestAnnotation1 {
  255.59 +        public boolean b1();
  255.60 +        public boolean b2() default false;
  255.61 +        public boolean b3() default false;
  255.62 +        public int     i1();
  255.63 +        public int     i2() default 1;
  255.64 +        public int     i3() default 1;
  255.65 +        public String  s1();
  255.66 +        public String  s2() default "";
  255.67 +        public String  s3() default "";
  255.68 +        public TestAnnotation2 a1();
  255.69 +//        public TestAnnotation2 a2() default @TestAnnotation2(a1=@TestAnnotation3(as1={"a", "b"}, as3="c"));
  255.70 +//        public TestAnnotation2 a3() default @TestAnnotation2(a1=@TestAnnotation3(as1={"a2", "b2"}, as3="c2"));
  255.71 +        public Class   c1();
  255.72 +        public Class   c2() default Void.class;
  255.73 +        public Class   c3() default Void.class;
  255.74 +        public TestEnum e1();
  255.75 +//        public TestEnum e2() default TestEnum.A;
  255.76 +        public TestEnum e3()/* default TestEnum.A*/;
  255.77 +        public boolean[] ab1();
  255.78 +        public boolean[] ab2() default false;
  255.79 +        public boolean[] ab3() default false;
  255.80 +        public int[]     ai1();
  255.81 +        public int[]     ai2() default 1;
  255.82 +        public int[]     ai3() default 1;
  255.83 +        public String[]  as1();
  255.84 +        public String[]  as2() default "";
  255.85 +        public String[]  as3() default "";
  255.86 +        public TestAnnotation2[] aa1();
  255.87 +//        public TestAnnotation2[] aa2() default @TestAnnotation2(a1=@TestAnnotation3(as1={"a", "b"}, as3="c"));
  255.88 +//        public TestAnnotation2[] aa3() default @TestAnnotation2(a1=@TestAnnotation3(as1={"a2", "b2"}, as3="c2"));
  255.89 +        public Class[]   ac1();
  255.90 +        public Class[]   ac2() default Void.class;
  255.91 +        public Class[]   ac3() default Void.class;
  255.92 +        public TestEnum[] ae1();
  255.93 +//        public TestEnum[] ae2() default TestEnum.A;
  255.94 +        public TestEnum[] ae3()/* default TestEnum.A*/;
  255.95 +    }
  255.96 +
  255.97 +    public @interface TestAnnotation2 {
  255.98 +        public TestAnnotation3 a1();
  255.99 +//        public TestAnnotation3 a2() default @TestAnnotation3(as1={"d", "e"}, as3="f");
 255.100 +//        public TestAnnotation3 a3() default @TestAnnotation3(as1={"g", "h"}, as3="i");
 255.101 +    }
 255.102 +
 255.103 +    public @interface TestAnnotation3 {
 255.104 +        public String[] as1();
 255.105 +        public String[] as2() default {""};
 255.106 +        public String[] as3() default {""};
 255.107 +    }
 255.108 +
 255.109 +    public enum TestEnum {
 255.110 +        A, B, C, D;
 255.111 +    }
 255.112 +}
   256.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   256.2 +++ b/sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/TestBase.java	Sun Oct 23 11:50:54 2016 +0200
   256.3 @@ -0,0 +1,124 @@
   256.4 +/*
   256.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   256.6 + *
   256.7 + * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
   256.8 + *
   256.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  256.10 + * Other names may be trademarks of their respective owners.
  256.11 + *
  256.12 + * The contents of this file are subject to the terms of either the GNU
  256.13 + * General Public License Version 2 only ("GPL") or the Common
  256.14 + * Development and Distribution License("CDDL") (collectively, the
  256.15 + * "License"). You may not use this file except in compliance with the
  256.16 + * License. You can obtain a copy of the License at
  256.17 + * http://www.netbeans.org/cddl-gplv2.html
  256.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  256.19 + * specific language governing permissions and limitations under the
  256.20 + * License.  When distributing the software, include this License Header
  256.21 + * Notice in each file and include the License file at
  256.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  256.23 + * particular file as subject to the "Classpath" exception as provided
  256.24 + * by Oracle in the GPL Version 2 section of the License file that
  256.25 + * accompanied this code. If applicable, add the following below the
  256.26 + * License Header, with the fields enclosed by brackets [] replaced by
  256.27 + * your own identifying information:
  256.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  256.29 + *
  256.30 + * If you wish your version of this file to be governed by only the CDDL
  256.31 + * or only the GPL Version 2, indicate your decision by adding
  256.32 + * "[Contributor] elects to include this software in this distribution
  256.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  256.34 + * single choice of license, a recipient has the option to distribute
  256.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  256.36 + * to extend the choice of license to its licensees as provided above.
  256.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  256.38 + * Version 2 license, then the option applies only if the new code is
  256.39 + * made subject to such option by the copyright holder.
  256.40 + *
  256.41 + * Contributor(s):
  256.42 + *
  256.43 + * Portions Copyrighted 2008-2009 Sun Microsystems, Inc.
  256.44 + */
  256.45 +
  256.46 +package org.netbeans.modules.java.hints.spiimpl;
  256.47 +
  256.48 +import java.io.File;
  256.49 +import javax.swing.text.Document;
  256.50 +import org.netbeans.api.java.lexer.JavaTokenId;
  256.51 +import org.netbeans.api.java.source.CompilationInfo;
  256.52 +import org.netbeans.api.java.source.JavaSource;
  256.53 +import org.netbeans.api.java.source.JavaSource.Phase;
  256.54 +import org.netbeans.api.java.source.SourceUtilsTestUtil;
  256.55 +import org.netbeans.api.java.source.TestUtilities;
  256.56 +import org.netbeans.api.lexer.Language;
  256.57 +import org.netbeans.junit.NbTestCase;
  256.58 +import org.netbeans.modules.java.source.TreeLoader;
  256.59 +import org.openide.cookies.EditorCookie;
  256.60 +import org.openide.filesystems.FileObject;
  256.61 +import org.openide.filesystems.FileUtil;
  256.62 +import org.openide.loaders.DataObject;
  256.63 +
  256.64 +/**
  256.65 + *
  256.66 + * @author Jan Lahoda
  256.67 + */
  256.68 +public class TestBase extends NbTestCase {
  256.69 +
  256.70 +    public TestBase(String name) {
  256.71 +        super(name);
  256.72 +    }
  256.73 +
  256.74 +    @Override
  256.75 +    protected void setUp() throws Exception {
  256.76 +        super.setUp();
  256.77 +        SourceUtilsTestUtil.prepareTest(new String[0], new Object[0]);
  256.78 +        TreeLoader.DISABLE_CONFINEMENT_TEST = true;
  256.79 +        clearWorkDir();
  256.80 +
  256.81 +        FileUtil.refreshFor(File.listRoots());
  256.82 +    }
  256.83 +
  256.84 +    private int workDirPart = 0;
  256.85 +    
  256.86 +    protected void prepareTest(String fileName, String code) throws Exception {
  256.87 +        FileObject workFO = FileUtil.createFolder(new File(getWorkDir(), String.valueOf(workDirPart++)));
  256.88 +
  256.89 +        assertNotNull(workFO);
  256.90 +
  256.91 +        workFO.refresh();
  256.92 +
  256.93 +        sourceRoot = workFO.createFolder("src");
  256.94 +        FileObject buildRoot  = workFO.createFolder("build");
  256.95 +        FileObject cache = workFO.createFolder("cache");
  256.96 +
  256.97 +        FileObject data = FileUtil.createData(sourceRoot, fileName);
  256.98 +        File dataFile = FileUtil.toFile(data);
  256.99 +
 256.100 +        assertNotNull(dataFile);
 256.101 +
 256.102 +        TestUtilities.copyStringToFile(dataFile, code);
 256.103 +
 256.104 +        SourceUtilsTestUtil.prepareTest(sourceRoot, buildRoot, cache);
 256.105 +
 256.106 +        DataObject od = DataObject.find(data);
 256.107 +        EditorCookie ec = od.getLookup().lookup(EditorCookie.class);
 256.108 +
 256.109 +        assertNotNull(ec);
 256.110 +
 256.111 +        doc = ec.openDocument();
 256.112 +        doc.putProperty(Language.class, JavaTokenId.language());
 256.113 +
 256.114 +        JavaSource js = JavaSource.forFileObject(data);
 256.115 +
 256.116 +        assertNotNull(js);
 256.117 +
 256.118 +        info = SourceUtilsTestUtil.getCompilationInfo(js, Phase.RESOLVED);
 256.119 +
 256.120 +        assertNotNull(info);
 256.121 +    }
 256.122 +
 256.123 +    protected FileObject sourceRoot;
 256.124 +    protected CompilationInfo info;
 256.125 +    protected Document doc;
 256.126 +
 256.127 +}
   257.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   257.2 +++ b/sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/TestCompilerSettings.java	Sun Oct 23 11:50:54 2016 +0200
   257.3 @@ -0,0 +1,60 @@
   257.4 +/*
   257.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   257.6 + *
   257.7 + * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
   257.8 + *
   257.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  257.10 + * Other names may be trademarks of their respective owners.
  257.11 + *
  257.12 + * The contents of this file are subject to the terms of either the GNU
  257.13 + * General Public License Version 2 only ("GPL") or the Common
  257.14 + * Development and Distribution License("CDDL") (collectively, the
  257.15 + * "License"). You may not use this file except in compliance with the
  257.16 + * License. You can obtain a copy of the License at
  257.17 + * http://www.netbeans.org/cddl-gplv2.html
  257.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  257.19 + * specific language governing permissions and limitations under the
  257.20 + * License.  When distributing the software, include this License Header
  257.21 + * Notice in each file and include the License file at
  257.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  257.23 + * particular file as subject to the "Classpath" exception as provided
  257.24 + * by Oracle in the GPL Version 2 section of the License file that
  257.25 + * accompanied this code. If applicable, add the following below the
  257.26 + * License Header, with the fields enclosed by brackets [] replaced by
  257.27 + * your own identifying information:
  257.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  257.29 + *
  257.30 + * If you wish your version of this file to be governed by only the CDDL
  257.31 + * or only the GPL Version 2, indicate your decision by adding
  257.32 + * "[Contributor] elects to include this software in this distribution
  257.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  257.34 + * single choice of license, a recipient has the option to distribute
  257.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  257.36 + * to extend the choice of license to its licensees as provided above.
  257.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  257.38 + * Version 2 license, then the option applies only if the new code is
  257.39 + * made subject to such option by the copyright holder.
  257.40 + *
  257.41 + * Contributor(s):
  257.42 + *
  257.43 + * Portions Copyrighted 2013 Sun Microsystems, Inc.
  257.44 + */
  257.45 +package org.netbeans.modules.java.hints.spiimpl;
  257.46 +
  257.47 +import org.netbeans.modules.java.source.tasklist.CompilerSettings;
  257.48 +import org.openide.filesystems.FileObject;
  257.49 +import org.openide.util.lookup.ServiceProvider;
  257.50 +
  257.51 +/**
  257.52 + *
  257.53 + * @author lahvac
  257.54 + */
  257.55 +@ServiceProvider(service=CompilerSettings.class, position=0, supersedes="org.netbeans.modules.java.hints.StandardJavacWarnings$CompilerSettingsImpl")
  257.56 +public class TestCompilerSettings extends CompilerSettings {
  257.57 +    public static String commandLine;
  257.58 +    @Override
  257.59 +    protected String buildCommandLine(FileObject file) {
  257.60 +        return commandLine;
  257.61 +    }
  257.62 +    
  257.63 +}
   258.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   258.2 +++ b/sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/TestUtilities.java	Sun Oct 23 11:50:54 2016 +0200
   258.3 @@ -0,0 +1,67 @@
   258.4 +/*
   258.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   258.6 + *
   258.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
   258.8 + *
   258.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  258.10 + * Other names may be trademarks of their respective owners.
  258.11 + *
  258.12 + * The contents of this file are subject to the terms of either the GNU
  258.13 + * General Public License Version 2 only ("GPL") or the Common
  258.14 + * Development and Distribution License("CDDL") (collectively, the
  258.15 + * "License"). You may not use this file except in compliance with the
  258.16 + * License. You can obtain a copy of the License at
  258.17 + * http://www.netbeans.org/cddl-gplv2.html
  258.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  258.19 + * specific language governing permissions and limitations under the
  258.20 + * License.  When distributing the software, include this License Header
  258.21 + * Notice in each file and include the License file at
  258.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  258.23 + * particular file as subject to the "Classpath" exception as provided
  258.24 + * by Oracle in the GPL Version 2 section of the License file that
  258.25 + * accompanied this code. If applicable, add the following below the
  258.26 + * License Header, with the fields enclosed by brackets [] replaced by
  258.27 + * your own identifying information:
  258.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  258.29 + *
  258.30 + * Contributor(s):
  258.31 + *
  258.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
  258.33 + */
  258.34 +package org.netbeans.modules.java.hints.spiimpl;
  258.35 +
  258.36 +import junit.framework.Assert;
  258.37 +
  258.38 +/**
  258.39 + *
  258.40 + * @author Jan Lahoda
  258.41 + */
  258.42 +public class TestUtilities {
  258.43 +
  258.44 +    private TestUtilities() {
  258.45 +    }
  258.46 +
  258.47 +    public static String detectOffsets(String source, int[] positionOrSpan) {
  258.48 +        return detectOffsets(source, positionOrSpan, "\\|");
  258.49 +    }
  258.50 +
  258.51 +    public static String detectOffsets(String source, int[] positionOrSpan, String delimiter) {
  258.52 +        //for now, the position/span delimiter is '|', without possibility of escaping:
  258.53 +        String[] split = source.split(delimiter);
  258.54 +        
  258.55 +        Assert.assertTrue("incorrect number of position markers (|)", positionOrSpan.length == split.length - 1);
  258.56 +        
  258.57 +        StringBuilder sb = new StringBuilder();
  258.58 +        int index = 0;
  258.59 +        int offset = 0;
  258.60 +        
  258.61 +        for (String s : split) {
  258.62 +            sb.append(s);
  258.63 +            if (index < positionOrSpan.length)
  258.64 +                positionOrSpan[index++] = (offset += s.length());
  258.65 +        }
  258.66 +        
  258.67 +        return sb.toString();
  258.68 +    }
  258.69 +
  258.70 +}
   259.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   259.2 +++ b/sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/UtilitiesTest.java	Sun Oct 23 11:50:54 2016 +0200
   259.3 @@ -0,0 +1,644 @@
   259.4 +/*
   259.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   259.6 + *
   259.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
   259.8 + *
   259.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  259.10 + * Other names may be trademarks of their respective owners.
  259.11 + *
  259.12 + * The contents of this file are subject to the terms of either the GNU
  259.13 + * General Public License Version 2 only ("GPL") or the Common
  259.14 + * Development and Distribution License("CDDL") (collectively, the
  259.15 + * "License"). You may not use this file except in compliance with the
  259.16 + * License. You can obtain a copy of the License at
  259.17 + * http://www.netbeans.org/cddl-gplv2.html
  259.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  259.19 + * specific language governing permissions and limitations under the
  259.20 + * License.  When distributing the software, include this License Header
  259.21 + * Notice in each file and include the License file at
  259.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  259.23 + * particular file as subject to the "Classpath" exception as provided
  259.24 + * by Oracle in the GPL Version 2 section of the License file that
  259.25 + * accompanied this code. If applicable, add the following below the
  259.26 + * License Header, with the fields enclosed by brackets [] replaced by
  259.27 + * your own identifying information:
  259.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  259.29 + *
  259.30 + * If you wish your version of this file to be governed by only the CDDL
  259.31 + * or only the GPL Version 2, indicate your decision by adding
  259.32 + * "[Contributor] elects to include this software in this distribution
  259.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  259.34 + * single choice of license, a recipient has the option to distribute
  259.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  259.36 + * to extend the choice of license to its licensees as provided above.
  259.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  259.38 + * Version 2 license, then the option applies only if the new code is
  259.39 + * made subject to such option by the copyright holder.
  259.40 + *
  259.41 + * Contributor(s):
  259.42 + *
  259.43 + * Portions Copyrighted 2009-2010 Sun Microsystems, Inc.
  259.44 + */
  259.45 +
  259.46 +package org.netbeans.modules.java.hints.spiimpl;
  259.47 +
  259.48 +import com.sun.source.tree.IfTree;
  259.49 +import com.sun.source.tree.LambdaExpressionTree;
  259.50 +import com.sun.source.tree.MemberSelectTree;
  259.51 +import com.sun.source.tree.ModifiersTree;
  259.52 +import com.sun.source.tree.Scope;
  259.53 +import com.sun.source.tree.Tree;
  259.54 +import com.sun.source.tree.Tree.Kind;
  259.55 +import com.sun.source.tree.VariableTree;
  259.56 +import com.sun.source.util.SourcePositions;
  259.57 +import com.sun.source.util.TreePath;
  259.58 +import com.sun.source.util.TreeScanner;
  259.59 +import com.sun.tools.javac.tree.JCTree;
  259.60 +import java.util.ArrayList;
  259.61 +import java.util.Arrays;
  259.62 +import java.util.Collection;
  259.63 +import java.util.Collections;
  259.64 +import java.util.LinkedList;
  259.65 +import java.util.List;
  259.66 +import javax.lang.model.element.Element;
  259.67 +import javax.lang.model.element.ElementKind;
  259.68 +import javax.lang.model.type.TypeMirror;
  259.69 +import javax.tools.Diagnostic;
  259.70 +import javax.tools.JavaFileObject;
  259.71 +import org.netbeans.api.java.classpath.ClassPath;
  259.72 +import org.netbeans.api.java.source.ClasspathInfo;
  259.73 +import org.netbeans.api.java.source.CompilationController;
  259.74 +import org.netbeans.api.java.source.JavaSource;
  259.75 +import org.netbeans.api.java.source.JavaSource.Phase;
  259.76 +import org.netbeans.api.java.source.Task;
  259.77 +import org.netbeans.junit.RandomlyFails;
  259.78 +import org.netbeans.modules.java.source.pretty.VeryPretty;
  259.79 +import org.netbeans.modules.java.source.save.DiffContext;
  259.80 +
  259.81 +/**
  259.82 + *
  259.83 + * @author lahvac
  259.84 + */
  259.85 +public class UtilitiesTest extends TestBase {
  259.86 +
  259.87 +    public UtilitiesTest(String name) {
  259.88 +        super(name);
  259.89 +    }
  259.90 +
  259.91 +    public void testParseAndAttributeExpressionStatement() throws Exception {
  259.92 +        prepareTest("test/Test.java", "package test; public class Test{}");
  259.93 +
  259.94 +        Scope s = Utilities.constructScope(info, Collections.singletonMap("$1", info.getTreeUtilities().parseType("int", info.getTopLevelElements().get(0))));
  259.95 +        Tree result = Utilities.parseAndAttribute(info, "$1 = 1;", s);
  259.96 +
  259.97 +        assertTrue(result.getKind().name(), result.getKind() == Kind.EXPRESSION_STATEMENT);
  259.98 +    }
  259.99 +
 259.100 +    public void testParseAndAttributeVariable() throws Exception {
 259.101 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.102 +
 259.103 +        Scope s = Utilities.constructScope(info, Collections.singletonMap("$1", info.getTreeUtilities().parseType("int", info.getTopLevelElements().get(0))));
 259.104 +        Tree result = Utilities.parseAndAttribute(info, "int $2 = $1;", s);
 259.105 +
 259.106 +        assertTrue(result.getKind().name(), result.getKind() == Kind.VARIABLE);
 259.107 +    }
 259.108 +
 259.109 +    public void testParseAndAttributeMultipleStatements() throws Exception {
 259.110 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.111 +
 259.112 +        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 259.113 +        Tree result = Utilities.parseAndAttribute(info, "String $2 = $1; int $l = $2.length(); System.err.println($l);", s);
 259.114 +
 259.115 +        assertTrue(result.getKind().name(), result.getKind() == Kind.BLOCK);
 259.116 +
 259.117 +        String golden = "{\n" +
 259.118 +                        "    $$1$;\n" +
 259.119 +                        "    String $2 = $1;\n" +
 259.120 +                        "    int $l = $2.length();\n" +
 259.121 +                        "    System.err.println($l);\n" +
 259.122 +                        "    $$2$;\n" +
 259.123 +                        "}";
 259.124 +        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 259.125 +    }
 259.126 +
 259.127 +    public void testParseAndAttributeMethod() throws Exception {
 259.128 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.129 +
 259.130 +        Scope s = Utilities.constructScope(info, Collections.singletonMap("$1", info.getTreeUtilities().parseType("int", info.getTopLevelElements().get(0))));
 259.131 +        String methodCode = "private int test(int i) { return i; }";
 259.132 +        Tree result = Utilities.parseAndAttribute(info, methodCode, s);
 259.133 +
 259.134 +        assertEquals(Kind.METHOD, result.getKind());
 259.135 +        assertEquals(methodCode.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " ").trim());
 259.136 +    }
 259.137 +
 259.138 +    public void testParseAndAttributeMultipleClassMembers() throws Exception {
 259.139 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.140 +
 259.141 +        Scope s = Utilities.constructScope(info, Collections.singletonMap("$1", info.getTreeUtilities().parseType("int", info.getTopLevelElements().get(0))));
 259.142 +        String code = "private int i; private int getI() { return i; } private void setI(int i) { this.i = i; }";
 259.143 +        Tree result = Utilities.parseAndAttribute(info, code, s);
 259.144 +
 259.145 +        String golden = "class $ {\n" +
 259.146 +                        "    $$1$;\n" +
 259.147 +                        "    private int i;\n" +
 259.148 +                        "    private int getI() {\n" +
 259.149 +                        "        return i;\n" +
 259.150 +                        "    }\n" +
 259.151 +                        "    private void setI(int i) {\n" +
 259.152 +                        "        this.i = i;\n" +
 259.153 +                        "    }\n" +
 259.154 +                        "}";
 259.155 +
 259.156 +        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " ").trim());
 259.157 +    }
 259.158 +
 259.159 +    public void testParseAndAttributeFieldModifiersVariable() throws Exception {
 259.160 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.161 +
 259.162 +        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 259.163 +        String code = "$mods$ java.lang.String $name;";
 259.164 +        Tree result = Utilities.parseAndAttribute(info, code, s);
 259.165 +
 259.166 +        String golden = "$mods$ java.lang.String $name";
 259.167 +
 259.168 +        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " ").trim());
 259.169 +    }
 259.170 +
 259.171 +    public void testParseAndAttributeIfWithParenthetised() throws Exception {
 259.172 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.173 +
 259.174 +        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 259.175 +        String code = "if ($c) { $1$; System.err.println('a'); $2$; }";
 259.176 +        Tree result = Utilities.parseAndAttribute(info, code, s);
 259.177 +
 259.178 +        IfTree it = (IfTree) result;
 259.179 +
 259.180 +        assertEquals(Kind.PARENTHESIZED, it.getCondition().getKind());
 259.181 +
 259.182 +        String golden = "if ($c) { $1$; System.err.println('a'); $2$; }";
 259.183 +
 259.184 +        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " ").trim());
 259.185 +    }
 259.186 +
 259.187 +    public void testParseAndAttributeMultipleStatements2() throws Exception {
 259.188 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.189 +
 259.190 +        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 259.191 +        Tree result = Utilities.parseAndAttribute(info, "$type $name = $map.get($key); if ($name == null) { $map.put($key, $name = $init); }", s);
 259.192 +
 259.193 +        assertTrue(result.getKind().name(), result.getKind() == Kind.BLOCK);
 259.194 +
 259.195 +        String golden = "{" +
 259.196 +                        "    $$1$;" +
 259.197 +                        "    $type $name = $map.get($key);" +
 259.198 +                        "    if ($name == null) {" +
 259.199 +                        "        $map.put($key, $name = $init);" +
 259.200 +                        "    }" +
 259.201 +                        "    $$2$;\n" +
 259.202 +                        "}";
 259.203 +        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 259.204 +    }
 259.205 +
 259.206 +    public void testParseAndAttributeMethodDeclarationWithMultiparameters() throws Exception {
 259.207 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.208 +
 259.209 +        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 259.210 +        Tree result = Utilities.parseAndAttribute(info, "public void t($params$) {}", s);
 259.211 +
 259.212 +        assertTrue(result.getKind().name(), result.getKind() == Kind.METHOD);
 259.213 +
 259.214 +        String golden = " public void t($params$) { }";
 259.215 +        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 259.216 +    }
 259.217 +
 259.218 +    public void testParseAndAttributeMethodModifiersVariable() throws Exception {
 259.219 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.220 +
 259.221 +        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 259.222 +        String code = "$mods$ $type $name() { $r$; }";
 259.223 +        Tree result = Utilities.parseAndAttribute(info, code, s);
 259.224 +
 259.225 +        String golden = "$mods$ $type $name() { $r$; }";
 259.226 +
 259.227 +        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " ").trim());
 259.228 +    }
 259.229 +
 259.230 +    public void testSimpleExpression() throws Exception {
 259.231 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.232 +
 259.233 +        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 259.234 +        Tree result = Utilities.parseAndAttribute(info, "$1.isDirectory()", s);
 259.235 +
 259.236 +        assertTrue(result.getKind().name(), result.getKind() == Kind.METHOD_INVOCATION);
 259.237 +
 259.238 +        String golden = "$1.isDirectory()";
 259.239 +        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 259.240 +    }
 259.241 +    
 259.242 +    public void testARMResourceVariable1() throws Exception {
 259.243 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.244 +
 259.245 +        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 259.246 +        Tree result = Utilities.parseAndAttribute(info, "try ($t$) { $stmts$; } catch $catches$", s);
 259.247 +
 259.248 +        assertTrue(result.getKind().name(), result.getKind() == Kind.TRY);
 259.249 +
 259.250 +        String golden = "try ($t$) { $stmts$; }$catches$";
 259.251 +        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 259.252 +    }
 259.253 +    
 259.254 +    public void testARMResourceVariable2() throws Exception {
 259.255 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.256 +
 259.257 +        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 259.258 +        Tree result = Utilities.parseAndAttribute(info, "try ($t$; $type $name = $init) { $stmts$; } catch $catches$", s);
 259.259 +
 259.260 +        assertTrue(result.getKind().name(), result.getKind() == Kind.TRY);
 259.261 +
 259.262 +        String golden = "try ($t$ final $type $name = $init;) { $stmts$; }$catches$";
 259.263 +        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 259.264 +    }
 259.265 +    
 259.266 +    public void testARMResourceNotVariable() throws Exception {
 259.267 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.268 +
 259.269 +        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 259.270 +        Tree result = Utilities.parseAndAttribute(info, "try ($t $n = $init$) { $stmts$; } catch $catches$", s);
 259.271 +
 259.272 +        assertTrue(result.getKind().name(), result.getKind() == Kind.TRY);
 259.273 +
 259.274 +        String golden = "try (final $t $n = $init$;) { $stmts$; }$catches$";
 259.275 +        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 259.276 +    }
 259.277 +
 259.278 +    public void testParseAndAttributeType() throws Exception {
 259.279 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.280 +
 259.281 +        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 259.282 +        Tree result = Utilities.parseAndAttribute(info, "\njava. util \n.List \n", s);
 259.283 +
 259.284 +        assertTrue(result.getKind().name(), result.getKind() == Kind.MEMBER_SELECT);
 259.285 +
 259.286 +        assertEquals(ElementKind.INTERFACE, info.getTrees().getElement(new TreePath(new TreePath(info.getCompilationUnit()), result)).getKind());
 259.287 +        assertEquals(info.getElements().getTypeElement("java.util.List"), info.getTrees().getElement(new TreePath(new TreePath(info.getCompilationUnit()), result)));
 259.288 +    }
 259.289 +    
 259.290 +    public void testCatchMultiparam() throws Exception {
 259.291 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.292 +
 259.293 +        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 259.294 +        Tree result = Utilities.parseAndAttribute(info, "try {\n }\n catch $catch$ finally {\n }\n", s);
 259.295 +
 259.296 +        assertTrue(result.getKind().name(), result.getKind() == Kind.TRY);
 259.297 +
 259.298 +        String golden = "try {\n }$catch$ finally {\n }";
 259.299 +        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 259.300 +    }
 259.301 +
 259.302 +    public void testCaseMultiparam() throws Exception {
 259.303 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.304 +
 259.305 +        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 259.306 +        Tree result = Utilities.parseAndAttribute(info, "switch ($v) {case $c1$ case 1: ; case $c2$; case 3: ;}", s);
 259.307 +
 259.308 +        assertTrue(result.getKind().name(), result.getKind() == Kind.SWITCH);
 259.309 +
 259.310 +        String golden = "switch ($v) { $c1$ case 1: ; $c2$ case 3: ; }";
 259.311 +        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 259.312 +    }
 259.313 +    
 259.314 +    public void testOrdinaryCatch() throws Exception {
 259.315 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.316 +
 259.317 +        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 259.318 +        Tree result = Utilities.parseAndAttribute(info, "try {\n }\n catch (NullPointerException ex) { } finally {\n }\n", s);
 259.319 +
 259.320 +        assertTrue(result.getKind().name(), result.getKind() == Kind.TRY);
 259.321 +
 259.322 +        String golden = "try {\n } catch (NullPointerException ex) { } finally {\n }";
 259.323 +        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 259.324 +    }
 259.325 +    
 259.326 +    public void testClassPattern() throws Exception {
 259.327 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.328 +
 259.329 +        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 259.330 +        Tree result = Utilities.parseAndAttribute(info, "$mods$ class $name extends java.util.LinkedList { $methods$; }\n", s);
 259.331 +
 259.332 +        assertTrue(result.getKind().name(), result.getKind() == Kind.CLASS);
 259.333 +
 259.334 +        String golden = " $mods$ class $name extends java.util.LinkedList { $name() { super(); } $methods$ }";
 259.335 +        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 259.336 +    }
 259.337 +
 259.338 +    public void testErrorsForPatterns1() throws Exception {
 259.339 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.340 +
 259.341 +        SourcePositions[] positions = new SourcePositions[1];
 259.342 +        Collection<Diagnostic<? extends JavaFileObject>> errors = new LinkedList<Diagnostic<? extends JavaFileObject>>();
 259.343 +        String code = "foo bar";
 259.344 +        Tree result = Utilities.parseAndAttribute(info, code, null, positions, errors);
 259.345 +
 259.346 +        assertDiagnostics(errors, "7-7:compiler.err.expected");
 259.347 +        assertPositions(result, positions[0], code, "foo", "foo bar");
 259.348 +    }
 259.349 +
 259.350 +    @RandomlyFails
 259.351 +    public void testErrorsForPatterns2() throws Exception {
 259.352 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.353 +
 259.354 +        SourcePositions[] positions = new SourcePositions[1];
 259.355 +        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 259.356 +        Collection<Diagnostic<? extends JavaFileObject>> errors = new LinkedList<Diagnostic<? extends JavaFileObject>>();
 259.357 +        String code = "$1.isDirectory()";
 259.358 +        Tree result = Utilities.parseAndAttribute(info, code, s, positions, errors);
 259.359 +
 259.360 +        assertDiagnostics(errors, "0-0:compiler.err.cant.resolve.location");
 259.361 +        assertPositions(result, positions[0], code, "$1", "$1.isDirectory", "$1.isDirectory()");
 259.362 +    }
 259.363 +
 259.364 +    public void testErrorsForPatterns3() throws Exception {
 259.365 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.366 +
 259.367 +        SourcePositions[] positions = new SourcePositions[1];
 259.368 +        Collection<Diagnostic<? extends JavaFileObject>> errors = new LinkedList<Diagnostic<? extends JavaFileObject>>();
 259.369 +        String code = "if ($cond) { foo() } else $else;";
 259.370 +        Tree result = Utilities.parseAndAttribute(info, code, null, positions, errors);
 259.371 +
 259.372 +        assertDiagnostics(errors, "18-18:compiler.err.expected");
 259.373 +        assertPositions(result, positions[0], code, "$cond", "$else", "$else;", "($cond)", "foo", "foo()", "foo() ", "if ($cond) { foo() } else $else;", "{ foo() }");
 259.374 +    }
 259.375 +
 259.376 +    public void testPositionsForCorrectStatement() throws Exception {
 259.377 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.378 +
 259.379 +        SourcePositions[] positions = new SourcePositions[1];
 259.380 +        Collection<Diagnostic<? extends JavaFileObject>> errors = new LinkedList<Diagnostic<? extends JavaFileObject>>();
 259.381 +        String code = "assert true;";
 259.382 +        Tree result = Utilities.parseAndAttribute(info, code, null, positions, errors);
 259.383 +
 259.384 +        assertTrue(errors.isEmpty());
 259.385 +        assertPositions(result, positions[0], code, "assert true;", "true");
 259.386 +    }
 259.387 +
 259.388 +    public void testCasePattern() throws Exception {
 259.389 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.390 +
 259.391 +        SourcePositions[] positions = new SourcePositions[1];
 259.392 +        Collection<Diagnostic<? extends JavaFileObject>> errors = new LinkedList<Diagnostic<? extends JavaFileObject>>();
 259.393 +        String code = "case $expr: foo bar $stmts$;\n";
 259.394 +        Tree result = Utilities.parseAndAttribute(info, code, null, positions, errors);
 259.395 +
 259.396 +        assertTrue(result.getKind().name(), result.getKind() == Kind.CASE);
 259.397 +
 259.398 +        String golden = "case $expr: foo bar; $stmts$; ";
 259.399 +        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 259.400 +        assertDiagnostics(errors, "19-19:compiler.err.expected");
 259.401 +        assertPositions(result, positions[0], code, "$expr", "$stmts$", "$stmts$;", "case $expr: foo bar $stmts$;", "foo", "foo bar ");
 259.402 +    }
 259.403 +
 259.404 +    public void testLambdaPattern() throws Exception {
 259.405 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.406 +
 259.407 +        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 259.408 +        Tree result = Utilities.parseAndAttribute(info, "new $type() {\n $mods$ $resultType $methodName($args$) {\n $statements$;\n }\n }\n", s);
 259.409 +
 259.410 +        assertTrue(result.getKind().name(), result.getKind() == Kind.NEW_CLASS);
 259.411 +
 259.412 +        String golden = "new $type(){ $mods$ $resultType $methodName($args$) { $statements$; } }";
 259.413 +        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 259.414 +
 259.415 +        Collection<Diagnostic<? extends JavaFileObject>> errors = new LinkedList<Diagnostic<? extends JavaFileObject>>();
 259.416 +
 259.417 +        result = Utilities.parseAndAttribute(info, "new $type() {\n $mods$ $resultType $methodName($args$) {\n $statements$;\n }\n }\n", null, errors);
 259.418 +        assertTrue(result.getKind().name(), result.getKind() == Kind.NEW_CLASS);
 259.419 +
 259.420 +        golden = "new $type(){ $mods$ $resultType $methodName($args$) { $statements$; } }";
 259.421 +        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 259.422 +        assertTrue(errors.toString(), errors.isEmpty());
 259.423 +    }
 259.424 +    
 259.425 +    public void testPackagePattern() throws Exception {
 259.426 +        prepareTest("test/a/Test.java", "package test.a; public class Test{}");
 259.427 +
 259.428 +        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 259.429 +        Tree result = Utilities.parseAndAttribute(info, "test.$1", s);
 259.430 +
 259.431 +        assertTrue(result.getKind().name(), result.getKind() == Kind.MEMBER_SELECT);
 259.432 +
 259.433 +        String golden = "test.$1";
 259.434 +        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 259.435 +        
 259.436 +        Element total = info.getTrees().getElement(new TreePath(new TreePath(info.getCompilationUnit()), result));
 259.437 +        
 259.438 +        assertTrue(Utilities.isError(total));
 259.439 +        
 259.440 +        Element testPack = info.getTrees().getElement(new TreePath(new TreePath(info.getCompilationUnit()), ((MemberSelectTree) result).getExpression()));
 259.441 +
 259.442 +        assertFalse(Utilities.isError(testPack));
 259.443 +        assertEquals(info.getElements().getPackageElement("test"), testPack);
 259.444 +    }
 259.445 +
 259.446 +    public void DtestMultiStatementVarWithModifiers() throws Exception {
 259.447 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.448 +
 259.449 +        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 259.450 +        Tree result = Utilities.parseAndAttribute(info, "$mods$ $type $name; $name = $init;", s);
 259.451 +
 259.452 +        assertTrue(result.getKind().name(), result.getKind() == Kind.BLOCK);
 259.453 +
 259.454 +        String golden = "{ $$1$; $mods$$type $name; $name = $init; $$2$; }";
 259.455 +        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 259.456 +    }
 259.457 +    
 259.458 +    public void testAnnotation() throws Exception {
 259.459 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.460 +
 259.461 +        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 259.462 +        Tree result = Utilities.parseAndAttribute(info, "@$annotation($args$)", s);
 259.463 +
 259.464 +        assertTrue(result.getKind().name(), result.getKind() == Kind.ANNOTATION);
 259.465 +
 259.466 +        String golden = "@$annotation(value = $args$)";
 259.467 +        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 259.468 +    }
 259.469 +
 259.470 +    public void testParseAndAttributeMultipleStatementsWithBefore() throws Exception {
 259.471 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.472 +
 259.473 +        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 259.474 +        Tree result = Utilities.parseAndAttribute(info, "$before$; String $2 = $1; int $l = $2.length(); System.err.println($l);", s);
 259.475 +
 259.476 +        assertTrue(result.getKind().name(), result.getKind() == Kind.BLOCK);
 259.477 +
 259.478 +        String golden = "{\n" +
 259.479 +                        "    $before$;\n" +
 259.480 +                        "    String $2 = $1;\n" +
 259.481 +                        "    int $l = $2.length();\n" +
 259.482 +                        "    System.err.println($l);\n" +
 259.483 +                        "    $$2$;\n" +
 259.484 +                        "}";
 259.485 +        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 259.486 +    }
 259.487 +    
 259.488 +    public void testParseAndAttributeMultipleStatementsWithAfter() throws Exception {
 259.489 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.490 +
 259.491 +        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 259.492 +        Tree result = Utilities.parseAndAttribute(info, "String $2 = $1; int $l = $2.length(); System.err.println($l); $after$;", s);
 259.493 +
 259.494 +        assertTrue(result.getKind().name(), result.getKind() == Kind.BLOCK);
 259.495 +
 259.496 +        String golden = "{\n" +
 259.497 +                        "    $$1$;\n" +
 259.498 +                        "    String $2 = $1;\n" +
 259.499 +                        "    int $l = $2.length();\n" +
 259.500 +                        "    System.err.println($l);\n" +
 259.501 +                        "    $after$;\n" +
 259.502 +                        "}";
 259.503 +        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 259.504 +    }
 259.505 +    
 259.506 +    public void testMethodFormalParams() throws Exception {
 259.507 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.508 +
 259.509 +        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 259.510 +        Tree result = Utilities.parseAndAttribute(info, "$mods$ $ret $name($pref$, $type $name, $suff$) throws $throws$ { $body$; }", s);
 259.511 +
 259.512 +        assertTrue(result.getKind().name(), result.getKind() == Kind.METHOD);
 259.513 +
 259.514 +        String golden = " $mods$ $ret $name($pref$, $type $name, $suff$) throws $throws$ { $body$; }";
 259.515 +        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " "));
 259.516 +    }
 259.517 +    
 259.518 +    public void testPartialModifiers() throws Exception {
 259.519 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.520 +
 259.521 +        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 259.522 +        Tree result = Utilities.parseAndAttribute(info, "$mods$ @Deprecated public $type $name;", s);
 259.523 +
 259.524 +        assertTrue(result.getKind().name(), result.getKind() == Kind.VARIABLE);
 259.525 +
 259.526 +        ModifiersTree mods = ((VariableTree) result).getModifiers();
 259.527 +        String golden = "$mods$,@Deprecated(), [public]";
 259.528 +        
 259.529 +        assertEquals(golden.replaceAll("[ \n\r]+", " "), mods.getAnnotations().toString() + ", " + mods.getFlags().toString());
 259.530 +    }
 259.531 +    
 259.532 +    public void testBrokenPlatform226678() throws Exception {
 259.533 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.534 +
 259.535 +        JavaSource.create(ClasspathInfo.create(ClassPath.EMPTY, ClassPath.EMPTY, ClassPath.EMPTY), info.getFileObject()).runUserActionTask(new Task<CompilationController>() {
 259.536 +            @Override public void run(CompilationController parameter) throws Exception {
 259.537 +                parameter.toPhase(Phase.RESOLVED);
 259.538 +                info = parameter;
 259.539 +            }
 259.540 +        }, true);
 259.541 +        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 259.542 +        String methodCode = "private int test(int i) { return i; }";
 259.543 +        Tree result = Utilities.parseAndAttribute(info, methodCode, s);
 259.544 +
 259.545 +        assertEquals(Kind.METHOD, result.getKind());
 259.546 +        assertEquals(methodCode.replaceAll("[ \n\r]+", " "), result.toString().replaceAll("[ \n\r]+", " ").trim());
 259.547 +    }
 259.548 +    
 259.549 +    public void testLambdaExpression1() throws Exception {
 259.550 +        prepareTest("test/Test.java", "package test; public class Test{}");
 259.551 +
 259.552 +        Scope s = Utilities.constructScope(info, Collections.<String, TypeMirror>emptyMap());
 259.553 +        Tree result = Utilities.parseAndAttribute(info, "($args$) -> $expression", s);
 259.554 +
 259.555 +        assertTrue(result.getKind().name(), result.getKind() == Kind.LAMBDA_EXPRESSION);
 259.556 +
 259.557 +        LambdaExpressionTree let = (LambdaExpressionTree) result;
 259.558 +        
 259.559 +        assertEquals(Kind.IDENTIFIER, let.getParameters().get(0).getKind());
 259.560 +        String golden = "($args$)->$expression";
 259.561 +        
 259.562 +        assertEquals(golden.replaceAll("[ \n\r]+", " "), result.toString());
 259.563 +    }
 259.564 +    
 259.565 +    public void testToHumanReadableTime() {
 259.566 +        long time = 202;
 259.567 +        assertEquals(    "5s", Utilities.toHumanReadableTime(time +=           5 * 1000));
 259.568 +        assertEquals(  "3m5s", Utilities.toHumanReadableTime(time +=      3 * 60 * 1000));
 259.569 +        assertEquals("7h3m5s", Utilities.toHumanReadableTime(time += 7 * 60 * 60 * 1000));
 259.570 +    }
 259.571 +
 259.572 +    public void testGeneralization() throws Exception {
 259.573 +        performGeneralizationTest("package test;\n" +
 259.574 +                                  "public class Test {\n" +
 259.575 +                                  "    class Inner {\n" +
 259.576 +                                  "        Inner(int i) {}\n" +
 259.577 +                                  "    }\n" +
 259.578 +                                  "    public static void main(String[] args) {\n" +
 259.579 +                                  "        int i = 1;\n" +
 259.580 +                                  "        Test c = null;\n" +
 259.581 +                                  "        c.new Inner(i++) {};\n" +
 259.582 +                                  "    }\n" +
 259.583 +                                  "}\n",
 259.584 +                                  "package test;\n" +
 259.585 +                                  "public class Test {\n" +
 259.586 +                                  "    class Inner {\n" +
 259.587 +                                  "        Inner(int $0) { super(); }\n" +
 259.588 +                                  "    }\n" +
 259.589 +                                  "    public static void main(String[] $1) {\n" +
 259.590 +                                  "        int $2 = 1;\n" +
 259.591 +                                  "        Test $3 = null;\n" +
 259.592 +                                  "        $4;\n" + //XXX
 259.593 +                                  "    }\n" +
 259.594 +                                  "}\n");
 259.595 +    }
 259.596 +    private void performGeneralizationTest(String code, String generalized) throws Exception {
 259.597 +        prepareTest("test/Test.java", code);
 259.598 +
 259.599 +        Tree generalizedTree = Utilities.generalizePattern(info, new TreePath(info.getCompilationUnit()));
 259.600 +        VeryPretty vp = new VeryPretty(new DiffContext(info));
 259.601 +
 259.602 +        vp.print((JCTree) generalizedTree);
 259.603 +
 259.604 +        String repr = vp.toString();
 259.605 +
 259.606 +        assertEquals(generalized.replaceAll("[ \n\t]+", " "),
 259.607 +                     repr.replaceAll("[ \n\t]+", " "));
 259.608 +    }
 259.609 +
 259.610 +    private void assertDiagnostics(Collection<Diagnostic<? extends JavaFileObject>> errors, String... golden) {
 259.611 +        List<String> actual = new ArrayList<String>(errors.size());
 259.612 +
 259.613 +        for (Diagnostic<? extends JavaFileObject> d : errors) {
 259.614 +            actual.add(d.getStartPosition() + "-" + d.getEndPosition() + ":" + d.getCode());
 259.615 +        }
 259.616 +
 259.617 +        assertEquals(Arrays.asList(golden), actual);
 259.618 +    }
 259.619 +
 259.620 +    private void assertPositions(Tree t, final SourcePositions sp, final String code, String... golden) {
 259.621 +        final List<String> actual = new ArrayList<String>(golden.length);
 259.622 +
 259.623 +        new TreeScanner<Void, Void>() {
 259.624 +            @Override
 259.625 +            public Void scan(Tree node, Void p) {
 259.626 +                if (node != null) {
 259.627 +                    int start = (int) sp.getStartPosition(null, node);
 259.628 +                    int end = (int) sp.getEndPosition(null, node);
 259.629 +
 259.630 +                    if (start >= 0 && end >= 0) {
 259.631 +                        actual.add(code.substring(start, end));
 259.632 +                    }
 259.633 +                }
 259.634 +                return super.scan(node, p);
 259.635 +            }
 259.636 +        }.scan(t, null);
 259.637 +
 259.638 +        Collections.sort(actual);
 259.639 +
 259.640 +        List<String> goldenList = new ArrayList<String>(Arrays.asList(golden));
 259.641 +
 259.642 +        Collections.sort(goldenList);
 259.643 +
 259.644 +        assertEquals(goldenList, actual);
 259.645 +    }
 259.646 +
 259.647 +}
   260.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   260.2 +++ b/sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/batch/BatchSearchTest.java	Sun Oct 23 11:50:54 2016 +0200
   260.3 @@ -0,0 +1,458 @@
   260.4 +/*
   260.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   260.6 + *
   260.7 + * Copyright 2009-2011 Oracle and/or its affiliates. All rights reserved.
   260.8 + *
   260.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  260.10 + * Other names may be trademarks of their respective owners.
  260.11 + *
  260.12 + * The contents of this file are subject to the terms of either the GNU
  260.13 + * General Public License Version 2 only ("GPL") or the Common
  260.14 + * Development and Distribution License("CDDL") (collectively, the
  260.15 + * "License"). You may not use this file except in compliance with the
  260.16 + * License. You can obtain a copy of the License at
  260.17 + * http://www.netbeans.org/cddl-gplv2.html
  260.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  260.19 + * specific language governing permissions and limitations under the
  260.20 + * License.  When distributing the software, include this License Header
  260.21 + * Notice in each file and include the License file at
  260.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  260.23 + * particular file as subject to the "Classpath" exception as provided
  260.24 + * by Oracle in the GPL Version 2 section of the License file that
  260.25 + * accompanied this code. If applicable, add the following below the
  260.26 + * License Header, with the fields enclosed by brackets [] replaced by
  260.27 + * your own identifying information:
  260.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  260.29 + *
  260.30 + * If you wish your version of this file to be governed by only the CDDL
  260.31 + * or only the GPL Version 2, indicate your decision by adding
  260.32 + * "[Contributor] elects to include this software in this distribution
  260.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  260.34 + * single choice of license, a recipient has the option to distribute
  260.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  260.36 + * to extend the choice of license to its licensees as provided above.
  260.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  260.38 + * Version 2 license, then the option applies only if the new code is
  260.39 + * made subject to such option by the copyright holder.
  260.40 + *
  260.41 + * Contributor(s):
  260.42 + *
  260.43 + * Portions Copyrighted 2009-2011 Sun Microsystems, Inc.
  260.44 + */
  260.45 +package org.netbeans.modules.java.hints.spiimpl.batch;
  260.46 +
  260.47 +import org.netbeans.modules.java.hints.spiimpl.batch.TestUtils.File;
  260.48 +import org.netbeans.modules.java.hints.spiimpl.MessageImpl;
  260.49 +import org.netbeans.modules.java.hints.providers.spi.HintDescription;
  260.50 +import java.net.URL;
  260.51 +import java.util.ArrayList;
  260.52 +import java.util.Arrays;
  260.53 +import java.util.Collection;
  260.54 +import java.util.Collections;
  260.55 +import java.util.HashMap;
  260.56 +import java.util.HashSet;
  260.57 +import java.util.Iterator;
  260.58 +import java.util.LinkedList;
  260.59 +import java.util.List;
  260.60 +import java.util.Map;
  260.61 +import java.util.Map.Entry;
  260.62 +import java.util.Set;
  260.63 +import java.util.concurrent.atomic.AtomicBoolean;
  260.64 +import java.util.regex.Pattern;
  260.65 +import junit.framework.TestSuite;
  260.66 +import org.netbeans.api.java.classpath.ClassPath;
  260.67 +import org.netbeans.api.java.classpath.GlobalPathRegistry;
  260.68 +import org.netbeans.api.java.classpath.GlobalPathRegistryEvent;
  260.69 +import org.netbeans.api.java.classpath.GlobalPathRegistryListener;
  260.70 +import org.netbeans.api.java.source.CompilationController;
  260.71 +import org.netbeans.api.java.source.SourceUtilsTestUtil;
  260.72 +import org.netbeans.core.startup.Main;
  260.73 +import org.netbeans.junit.NbTestCase;
  260.74 +import org.netbeans.junit.NbTestSuite;
  260.75 +import org.netbeans.junit.RandomlyFails;
  260.76 +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.BatchResult;
  260.77 +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.Folder;
  260.78 +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.Resource;
  260.79 +import org.netbeans.modules.parsing.impl.indexing.CacheFolder;
  260.80 +import org.netbeans.modules.parsing.impl.indexing.MimeTypes;
  260.81 +import org.netbeans.modules.parsing.impl.indexing.RepositoryUpdater;
  260.82 +import org.netbeans.spi.editor.hints.ErrorDescription;
  260.83 +import org.netbeans.spi.java.classpath.ClassPathProvider;
  260.84 +import org.netbeans.spi.java.classpath.support.ClassPathSupport;
  260.85 +import org.openide.filesystems.FileObject;
  260.86 +import org.openide.filesystems.FileStateInvalidException;
  260.87 +import org.openide.filesystems.FileUtil;
  260.88 +
  260.89 +import org.openide.util.Exceptions;
  260.90 +import org.openide.util.lookup.ServiceProvider;
  260.91 +import static org.netbeans.modules.java.hints.spiimpl.batch.TestUtils.writeFilesAndWaitForScan;
  260.92 +import static org.netbeans.modules.java.hints.spiimpl.batch.TestUtils.prepareHints;
  260.93 +
  260.94 +/**
  260.95 + *
  260.96 + * @author lahvac
  260.97 + */
  260.98 +public class BatchSearchTest extends NbTestCase {
  260.99 +
 260.100 +    public BatchSearchTest(String name) {
 260.101 +        super(name);
 260.102 +    }
 260.103 +
 260.104 +    public static TestSuite suite() {
 260.105 +        TestSuite result = new NbTestSuite();
 260.106 +
 260.107 +        result.addTestSuite(BatchSearchTest.class);
 260.108 +//        result.addTest(new BatchSearchTest("testBatchSearchFolderRemoteIndex"));
 260.109 +
 260.110 +        return result;
 260.111 +    }
 260.112 +
 260.113 +    //XXX: copied from CustomIndexerImplTest:
 260.114 +    @Override
 260.115 +    protected void setUp() throws Exception {
 260.116 +        SourceUtilsTestUtil.prepareTest(new String[0], new Object[0]);
 260.117 +        Main.initializeURLFactory();
 260.118 +        org.netbeans.api.project.ui.OpenProjects.getDefault().getOpenProjects();
 260.119 +        prepareTest();
 260.120 +        MimeTypes.setAllMimeTypes(Collections.singleton("text/x-java"));
 260.121 +        sourceCP = ClassPathSupport.createClassPath(src1, src2);
 260.122 +        GlobalPathRegistry.getDefault().register(ClassPath.SOURCE, new ClassPath[] {sourceCP});
 260.123 +        RepositoryUpdater.getDefault().start(true);
 260.124 +        super.setUp();
 260.125 +    }
 260.126 +
 260.127 +    @Override
 260.128 +    protected void tearDown() throws Exception {
 260.129 +        super.tearDown();
 260.130 +        GlobalPathRegistry.getDefault().unregister(ClassPath.SOURCE, new ClassPath[] {sourceCP});
 260.131 +    }
 260.132 +
 260.133 +    public void testBatchSearch1() throws Exception {
 260.134 +        writeFilesAndWaitForScan(src1,
 260.135 +                                 new File("test/Test1.java", "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); } }"),
 260.136 +                                 new File("test/Test2.java", "package test; public class Test2 { private void test() { new javax.swing.ImageIcon(null); } }"));
 260.137 +        writeFilesAndWaitForScan(src2,
 260.138 +                                 new File("test/Test1.java", "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); } }"),
 260.139 +                                 new File("test/Test2.java", "package test; public class Test2 { private void test() { new javax.swing.ImageIcon(null); } }"));
 260.140 +
 260.141 +        Iterable<? extends HintDescription> hints = prepareHints("$1.isDirectory()");
 260.142 +        BatchResult result = BatchSearch.findOccurrences(hints, Scopes.allOpenedProjectsScope());
 260.143 +        Map<String, Iterable<String>> output = new HashMap<String, Iterable<String>>();
 260.144 +
 260.145 +        for (Entry<FileObject, Collection<? extends Resource>> e : result.getResourcesWithRoots().entrySet()) {
 260.146 +            Collection<String> resourcesRepr = new LinkedList<String>();
 260.147 +
 260.148 +            for (Resource r : e.getValue()) {
 260.149 +                resourcesRepr.add(r.getRelativePath());
 260.150 +            }
 260.151 +
 260.152 +            output.put(e.getKey().getURL().toExternalForm(), resourcesRepr);
 260.153 +        }
 260.154 +
 260.155 +        Map<String, Iterable<String>> golden = new HashMap<String, Iterable<String>>();
 260.156 +
 260.157 +        golden.put(src1.getURL().toExternalForm(), Arrays.asList("test/Test1.java"));
 260.158 +        golden.put(src2.getURL().toExternalForm(), Arrays.asList("test/Test1.java"));
 260.159 +
 260.160 +        assertEquals(golden, output);
 260.161 +    }
 260.162 +
 260.163 +    public void testBatchSearchSpan() throws Exception {
 260.164 +        String code = "package test;\n" +
 260.165 +                      "public class Test {\n" +
 260.166 +                      "    private void m() {\n" +
 260.167 +                      "        a(c.i().getFileObject());\n" +
 260.168 +                      "        if (span != null && span[0] != (-1) && span[1] != (-1));\n" +
 260.169 +                      "        c.i().getFileObject(\"\");\n" +
 260.170 +                      "    }\n" +
 260.171 +                      "}\n";
 260.172 +
 260.173 +        writeFilesAndWaitForScan(src1, new File("test/Test.java", code));
 260.174 +
 260.175 +        Iterable<? extends HintDescription> hints = prepareHints("$0.getFileObject($1)");
 260.176 +        BatchResult result = BatchSearch.findOccurrences(hints, Scopes.allOpenedProjectsScope());
 260.177 +
 260.178 +        assertEquals(1, result.getResources().size());
 260.179 +        Iterator<? extends Resource> resources = result.getResources().iterator().next().iterator();
 260.180 +        Resource r = resources.next();
 260.181 +
 260.182 +        assertFalse(resources.hasNext());
 260.183 +
 260.184 +        Set<String> snipets = new HashSet<String>();
 260.185 +
 260.186 +        for (int[] span : r.getCandidateSpans()) {
 260.187 +            snipets.add(code.substring(span[0], span[1]));
 260.188 +        }
 260.189 +
 260.190 +        Set<String> golden = new HashSet<String>(Arrays.asList("c.i().getFileObject(\"\")"));
 260.191 +        assertEquals(golden, snipets);
 260.192 +    }
 260.193 +
 260.194 +    @RandomlyFails
 260.195 +    public void testBatchSearchNotIndexed() throws Exception {
 260.196 +        writeFilesAndWaitForScan(src1,
 260.197 +                                 new File("test/Test1.java", "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); } }"),
 260.198 +                                 new File("test/Test2.java", "package test; public class Test2 { private void test() { new javax.swing.ImageIcon(null); } }"));
 260.199 +        writeFilesAndWaitForScan(src3,
 260.200 +                                 new File("test/Test1.java", "package test; public class Test1 { private void test() { Test2 f = null; f.isDirectory(); } }"),
 260.201 +                                 new File("test/Test2.java", "package test; public class Test2 { public boolean isDirectory() {return false} }"));
 260.202 +
 260.203 +        Iterable<? extends HintDescription> hints = prepareHints("$1.isDirectory()", "$1", "test.Test2");
 260.204 +        BatchResult result = BatchSearch.findOccurrences(hints, Scopes.specifiedFoldersScope(Folder.convert(src1, src3, empty)));
 260.205 +        Map<String, Iterable<String>> output = new HashMap<String, Iterable<String>>();
 260.206 +
 260.207 +        for (Entry<FileObject, Collection<? extends Resource>> e : result.getResourcesWithRoots().entrySet()) {
 260.208 +            Collection<String> resourcesRepr = new LinkedList<String>();
 260.209 +
 260.210 +            for (Resource r : e.getValue()) {
 260.211 +                resourcesRepr.add(r.getRelativePath());
 260.212 +            }
 260.213 +
 260.214 +            output.put(e.getKey().getURL().toExternalForm(), resourcesRepr);
 260.215 +        }
 260.216 +
 260.217 +        Map<String, Iterable<String>> golden = new HashMap<String, Iterable<String>>();
 260.218 +
 260.219 +        golden.put(src1.getURL().toExternalForm(), Arrays.asList("test/Test1.java"));
 260.220 +        golden.put(src3.getURL().toExternalForm(), Arrays.asList("test/Test1.java"));
 260.221 +
 260.222 +        assertEquals(golden, output);
 260.223 +
 260.224 +        //check verification:
 260.225 +        Map<String, Map<String, Iterable<String>>> verifiedOutput = verifiedSpans(result, false);
 260.226 +        Map<String, Map<String, Iterable<String>>> verifiedGolden = new HashMap<String, Map<String, Iterable<String>>>();
 260.227 +
 260.228 +        verifiedGolden.put(src1.getURL().toExternalForm(), Collections.<String, Iterable<String>>singletonMap("test/Test1.java", Arrays.<String>asList()));
 260.229 +        verifiedGolden.put(src3.getURL().toExternalForm(), Collections.<String, Iterable<String>>singletonMap("test/Test1.java", Arrays.asList("0:75-0:86:verifier:")));
 260.230 +
 260.231 +        assertEquals(verifiedGolden, verifiedOutput);
 260.232 +    }
 260.233 +
 260.234 +    public void testBatchSearchForceIndexingOfProperDirectory() throws Exception {
 260.235 +        FileObject data = FileUtil.createFolder(workdir, "data");
 260.236 +        FileObject dataSrc1 = FileUtil.createFolder(data, "src1");
 260.237 +        FileObject dataSrc2 = FileUtil.createFolder(data, "src2");
 260.238 +        writeFilesAndWaitForScan(dataSrc1,
 260.239 +                                 new File("test/Test1.java", "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); } }"),
 260.240 +                                 new File("test/Test2.java", "package test; public class Test2 { private void test() { new javax.swing.ImageIcon(null); } }"));
 260.241 +        writeFilesAndWaitForScan(dataSrc2,
 260.242 +                                 new File("test/Test1.java", "package test; public class Test1 { private void test() { Test2 f = null; f.isDirectory(); } }"),
 260.243 +                                 new File("test/Test2.java", "package test; public class Test2 { public boolean isDirectory() {return false} }"));
 260.244 +
 260.245 +        ClassPathProviderImpl.setSourceRoots(Arrays.asList(dataSrc1, dataSrc2));
 260.246 +
 260.247 +        Iterable<? extends HintDescription> hints = prepareHints("$1.isDirectory()", "$1", "test.Test2");
 260.248 +        BatchResult result = BatchSearch.findOccurrences(hints, Scopes.specifiedFoldersScope(Folder.convert(data)));
 260.249 +        Map<String, Iterable<String>> output = new HashMap<String, Iterable<String>>();
 260.250 +
 260.251 +        for (Entry<FileObject, Collection<? extends Resource>> e : result.getResourcesWithRoots().entrySet()) {
 260.252 +            Collection<String> resourcesRepr = new HashSet<String>();
 260.253 +
 260.254 +            for (Resource r : e.getValue()) {
 260.255 +                resourcesRepr.add(r.getRelativePath());
 260.256 +            }
 260.257 +
 260.258 +            output.put(e.getKey().getURL().toExternalForm(), resourcesRepr);
 260.259 +        }
 260.260 +
 260.261 +        Map<String, Iterable<String>> golden = new HashMap<String, Iterable<String>>();
 260.262 +
 260.263 +        golden.put(data.getURL().toExternalForm(), new HashSet<String>(Arrays.asList("src1/test/Test1.java", "src2/test/Test1.java")));
 260.264 +
 260.265 +        assertEquals(golden, output);
 260.266 +
 260.267 +        //check verification:
 260.268 +        final Set<FileObject> added = new HashSet<FileObject>();
 260.269 +        final Set<FileObject> removed = new HashSet<FileObject>();
 260.270 +
 260.271 +        GlobalPathRegistry.getDefault().addGlobalPathRegistryListener(new GlobalPathRegistryListener() {
 260.272 +            public void pathsAdded(GlobalPathRegistryEvent event) {
 260.273 +                for (ClassPath cp : event.getChangedPaths()) {
 260.274 +                    added.addAll(Arrays.asList(cp.getRoots()));
 260.275 +                }
 260.276 +            }
 260.277 +            public void pathsRemoved(GlobalPathRegistryEvent event) {
 260.278 +                for (ClassPath cp : event.getChangedPaths()) {
 260.279 +                    removed.addAll(Arrays.asList(cp.getRoots()));
 260.280 +                }
 260.281 +            }
 260.282 +        });
 260.283 +
 260.284 +//        verifiedGolden.put(data.getURL().toExternalForm(), Arrays.asList("0:75-0:86:verifier:TODO: No display name"));
 260.285 +        Map<String, Map<String, Iterable<String>>> verifiedOutput = verifiedSpans(result, false);
 260.286 +        Map<String, Map<String, Iterable<String>>> verifiedGolden = new HashMap<String, Map<String, Iterable<String>>>();
 260.287 +
 260.288 +        Map<String, Iterable<String>> verifiedGoldenPart = new HashMap<String, Iterable<String>>();
 260.289 +
 260.290 +        verifiedGoldenPart.put("src1/test/Test1.java", Arrays.<String>asList());
 260.291 +        verifiedGoldenPart.put("src2/test/Test1.java", Arrays.<String>asList("0:75-0:86:verifier:"));
 260.292 +
 260.293 +        verifiedGolden.put(data.getURL().toExternalForm(), verifiedGoldenPart);
 260.294 +
 260.295 +        assertEquals(verifiedGolden, verifiedOutput);
 260.296 +        assertEquals(new HashSet<FileObject>(Arrays.asList(dataSrc1, dataSrc2)), added);
 260.297 +        assertEquals(new HashSet<FileObject>(Arrays.asList(dataSrc1, dataSrc2)), removed);
 260.298 +    }
 260.299 +
 260.300 +    public void testBatchSearchFolderNoIndex() throws Exception {
 260.301 +        FileObject data = FileUtil.createFolder(workdir, "data");
 260.302 +        FileObject dataSrc1 = FileUtil.createFolder(data, "src1");
 260.303 +        FileObject dataSrc2 = FileUtil.createFolder(data, "src2");
 260.304 +        writeFilesAndWaitForScan(dataSrc1,
 260.305 +                                 new File("test/Test1.java", "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); } }"),
 260.306 +                                 new File("test/Test2.java", "package test; public class Test2 { private void test() { new javax.swing.ImageIcon(null); } }"));
 260.307 +        writeFilesAndWaitForScan(dataSrc2,
 260.308 +                                 new File("test/Test1.java", "package test; public class Test1 { private void test() { Test2 f = null; f.isDirectory(); } }"),
 260.309 +                                 new File("test/Test2.java", "package test; public class Test2 { public boolean isDirectory() {return false} }"));
 260.310 +
 260.311 +        Iterable<? extends HintDescription> hints = prepareHints("$1.isDirectory()");
 260.312 +        BatchResult result = BatchSearch.findOccurrences(hints, Scopes.specifiedFoldersScope(Folder.convert(Collections.singleton(data)))); //XXX: should be a no-index variant!
 260.313 +        Map<String, Iterable<String>> output = toDebugOutput(result);
 260.314 +        Map<String, Iterable<String>> golden = new HashMap<String, Iterable<String>>();
 260.315 +
 260.316 +        golden.put(data.getURL().toExternalForm(), new HashSet<String>(Arrays.asList("src1/test/Test1.java", "src2/test/Test1.java")));
 260.317 +
 260.318 +        assertEquals(golden, output);
 260.319 +    }
 260.320 +
 260.321 +    private FileObject workdir;
 260.322 +    private FileObject src1;
 260.323 +    private FileObject src2;
 260.324 +    private FileObject src3;
 260.325 +    private FileObject empty;
 260.326 +    private ClassPath sourceCP;
 260.327 +
 260.328 +    private void prepareTest() throws Exception {
 260.329 +        workdir = SourceUtilsTestUtil.makeScratchDir(this);
 260.330 +
 260.331 +        src1 = FileUtil.createFolder(workdir, "src1");
 260.332 +        src2 = FileUtil.createFolder(workdir, "src2");
 260.333 +        src3 = FileUtil.createFolder(workdir, "src3");
 260.334 +        empty = FileUtil.createFolder(workdir, "empty");
 260.335 +
 260.336 +        ClassPathProviderImpl.setSourceRoots(Arrays.asList(src1, src2, src3));
 260.337 +
 260.338 +        FileObject cache = FileUtil.createFolder(workdir, "cache");
 260.339 +
 260.340 +        CacheFolder.setCacheFolder(cache);
 260.341 +    }
 260.342 +
 260.343 +    private Map<String, Iterable<String>> toDebugOutput(BatchResult result) throws Exception {
 260.344 +        Map<String, Iterable<String>> output = new HashMap<String, Iterable<String>>();
 260.345 +
 260.346 +        for (Entry<FileObject, Collection<? extends Resource>> e : result.getResourcesWithRoots().entrySet()) {
 260.347 +            Collection<String> resourcesRepr = new HashSet<String>();
 260.348 +
 260.349 +            for (Resource r : e.getValue()) {
 260.350 +                resourcesRepr.add(r.getRelativePath());
 260.351 +            }
 260.352 +
 260.353 +            output.put(e.getKey().getURL().toExternalForm(), resourcesRepr);
 260.354 +        }
 260.355 +
 260.356 +        return output;
 260.357 +    }
 260.358 +
 260.359 +    private Map<String, Map<String, Iterable<String>>> verifiedSpans(BatchResult candidates, boolean doNotRegisterClassPath) throws Exception {
 260.360 +        final Map<String, Map<String, Iterable<String>>> result = new HashMap<String, Map<String, Iterable<String>>>();
 260.361 +        List<MessageImpl> errors = new LinkedList<MessageImpl>();
 260.362 +        BatchSearch.getVerifiedSpans(candidates, new ProgressHandleWrapper(1), new BatchSearch.VerifiedSpansCallBack() {
 260.363 +            public void groupStarted() {}
 260.364 +            public boolean spansVerified(CompilationController wc, Resource r, Collection<? extends ErrorDescription> hints) throws Exception {
 260.365 +                Map<String, Iterable<String>> files = result.get(r.getRoot().getURL().toExternalForm());
 260.366 +
 260.367 +                if (files == null) {
 260.368 +                    result.put(r.getRoot().getURL().toExternalForm(), files = new HashMap<String, Iterable<String>>());
 260.369 +                }
 260.370 +
 260.371 +                Collection<String> currentHints = new LinkedList<String>();
 260.372 +
 260.373 +                for (ErrorDescription ed : hints) {
 260.374 +                    currentHints.add(ed.toString());
 260.375 +                }
 260.376 +
 260.377 +                files.put(r.getRelativePath(), currentHints);
 260.378 +
 260.379 +                return true;
 260.380 +            }
 260.381 +            public void groupFinished() {}
 260.382 +            public void cannotVerifySpan(Resource r) {
 260.383 +                fail("Cannot verify: " +r.getRelativePath());
 260.384 +            }
 260.385 +        }, doNotRegisterClassPath, errors, new AtomicBoolean());
 260.386 +
 260.387 +        return result;
 260.388 +    }
 260.389 +
 260.390 +    @ServiceProvider(service=ClassPathProvider.class)
 260.391 +    public static final class ClassPathProviderImpl implements ClassPathProvider {
 260.392 +
 260.393 +        private static Collection<FileObject> sourceRoots;
 260.394 +
 260.395 +        public synchronized static void setSourceRoots(Collection<FileObject> sourceRoots) {
 260.396 +            ClassPathProviderImpl.sourceRoots = sourceRoots;
 260.397 +        }
 260.398 +
 260.399 +        public synchronized static Collection<FileObject> getSourceRoots() {
 260.400 +            return sourceRoots;
 260.401 +        }
 260.402 +
 260.403 +        public synchronized ClassPath findClassPath(FileObject file, String type) {
 260.404 +            if (ClassPath.BOOT.equals(type)) {
 260.405 +                return ClassPathSupport.createClassPath(getBootClassPath().toArray(new URL[0]));
 260.406 +            }
 260.407 +
 260.408 +            if (ClassPath.COMPILE.equals(type)) {
 260.409 +                return ClassPathSupport.createClassPath(new URL[0]);
 260.410 +            }
 260.411 +
 260.412 +            if (ClassPath.SOURCE.equals(type) && sourceRoots != null) {
 260.413 +                for (FileObject sr : sourceRoots) {
 260.414 +                    if (file.equals(sr) || FileUtil.isParentOf(sr, file)) {
 260.415 +                        return ClassPathSupport.createClassPath(sr);
 260.416 +                    }
 260.417 +                }
 260.418 +            }
 260.419 +
 260.420 +            return null;
 260.421 +        }
 260.422 +
 260.423 +    }
 260.424 +
 260.425 +    //TODO: copied from SourceUtilsTestUtil:
 260.426 +    private static List<URL> bootClassPath;
 260.427 +
 260.428 +    public static synchronized List<URL> getBootClassPath() {
 260.429 +        if (bootClassPath == null) {
 260.430 +            try {
 260.431 +                String cp = System.getProperty("sun.boot.class.path");
 260.432 +                List<URL> urls = new ArrayList<URL>();
 260.433 +                String[] paths = cp.split(Pattern.quote(System.getProperty("path.separator")));
 260.434 +
 260.435 +                for (String path : paths) {
 260.436 +                    java.io.File f = new java.io.File(path);
 260.437 +
 260.438 +                    if (!f.canRead())
 260.439 +                        continue;
 260.440 +
 260.441 +                    FileObject fo = FileUtil.toFileObject(f);
 260.442 +
 260.443 +                    if (FileUtil.isArchiveFile(fo)) {
 260.444 +                        fo = FileUtil.getArchiveRoot(fo);
 260.445 +                    }
 260.446 +
 260.447 +                    if (fo != null) {
 260.448 +                        urls.add(fo.getURL());
 260.449 +                    }
 260.450 +                }
 260.451 +
 260.452 +                bootClassPath = urls;
 260.453 +            } catch (FileStateInvalidException e) {
 260.454 +                Exceptions.printStackTrace(e);
 260.455 +            }
 260.456 +        }
 260.457 +
 260.458 +        return bootClassPath;
 260.459 +    }
 260.460 +
 260.461 +}
   261.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   261.2 +++ b/sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/batch/BatchUtilitiesTest.java	Sun Oct 23 11:50:54 2016 +0200
   261.3 @@ -0,0 +1,222 @@
   261.4 +/*
   261.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   261.6 + *
   261.7 + * Copyright 2009-2011 Oracle and/or its affiliates. All rights reserved.
   261.8 + *
   261.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  261.10 + * Other names may be trademarks of their respective owners.
  261.11 + *
  261.12 + * The contents of this file are subject to the terms of either the GNU
  261.13 + * General Public License Version 2 only ("GPL") or the Common
  261.14 + * Development and Distribution License("CDDL") (collectively, the
  261.15 + * "License"). You may not use this file except in compliance with the
  261.16 + * License. You can obtain a copy of the License at
  261.17 + * http://www.netbeans.org/cddl-gplv2.html
  261.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  261.19 + * specific language governing permissions and limitations under the
  261.20 + * License.  When distributing the software, include this License Header
  261.21 + * Notice in each file and include the License file at
  261.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  261.23 + * particular file as subject to the "Classpath" exception as provided
  261.24 + * by Oracle in the GPL Version 2 section of the License file that
  261.25 + * accompanied this code. If applicable, add the following below the
  261.26 + * License Header, with the fields enclosed by brackets [] replaced by
  261.27 + * your own identifying information:
  261.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  261.29 + *
  261.30 + * If you wish your version of this file to be governed by only the CDDL
  261.31 + * or only the GPL Version 2, indicate your decision by adding
  261.32 + * "[Contributor] elects to include this software in this distribution
  261.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  261.34 + * single choice of license, a recipient has the option to distribute
  261.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  261.36 + * to extend the choice of license to its licensees as provided above.
  261.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  261.38 + * Version 2 license, then the option applies only if the new code is
  261.39 + * made subject to such option by the copyright holder.
  261.40 + *
  261.41 + * Contributor(s):
  261.42 + *
  261.43 + * Portions Copyrighted 2009-2011 Sun Microsystems, Inc.
  261.44 + */
  261.45 +package org.netbeans.modules.java.hints.spiimpl.batch;
  261.46 +
  261.47 +import org.netbeans.modules.java.hints.spiimpl.batch.TestUtils.File;
  261.48 +import org.netbeans.modules.java.hints.spiimpl.MessageImpl;
  261.49 +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearchTest.ClassPathProviderImpl;
  261.50 +import org.netbeans.modules.java.hints.providers.spi.HintDescription;
  261.51 +import java.util.Arrays;
  261.52 +import java.util.Collection;
  261.53 +import java.util.Collections;
  261.54 +import java.util.HashMap;
  261.55 +import java.util.LinkedList;
  261.56 +import java.util.List;
  261.57 +import java.util.Map;
  261.58 +import java.util.concurrent.atomic.AtomicBoolean;
  261.59 +import org.netbeans.api.editor.mimelookup.MimePath;
  261.60 +import org.netbeans.api.java.classpath.ClassPath;
  261.61 +import org.netbeans.api.java.classpath.GlobalPathRegistry;
  261.62 +import org.netbeans.api.java.lexer.JavaTokenId;
  261.63 +import org.netbeans.api.java.source.ModificationResult;
  261.64 +import org.netbeans.api.java.source.SourceUtilsTestUtil;
  261.65 +import org.netbeans.api.java.source.TestUtilities;
  261.66 +import org.netbeans.api.lexer.InputAttributes;
  261.67 +import org.netbeans.api.lexer.Language;
  261.68 +import org.netbeans.api.lexer.LanguagePath;
  261.69 +import org.netbeans.api.lexer.Token;
  261.70 +import org.netbeans.core.startup.Main;
  261.71 +import org.netbeans.junit.NbTestCase;
  261.72 +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.BatchResult;
  261.73 +import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.Folder;
  261.74 +import org.netbeans.modules.java.source.parsing.JavacParser;
  261.75 +import org.netbeans.modules.parsing.impl.indexing.CacheFolder;
  261.76 +import org.netbeans.modules.parsing.impl.indexing.RepositoryUpdater;
  261.77 +import org.netbeans.spi.editor.mimelookup.MimeDataProvider;
  261.78 +import org.netbeans.spi.java.classpath.support.ClassPathSupport;
  261.79 +import org.netbeans.spi.lexer.LanguageEmbedding;
  261.80 +import org.netbeans.spi.lexer.LanguageProvider;
  261.81 +import org.openide.LifecycleManager;
  261.82 +import org.openide.filesystems.FileObject;
  261.83 +import org.openide.filesystems.FileUtil;
  261.84 +
  261.85 +import org.openide.loaders.DataObject;
  261.86 +import org.openide.util.Lookup;
  261.87 +import org.openide.util.lookup.Lookups;
  261.88 +import org.openide.util.lookup.ServiceProvider;
  261.89 +import static org.netbeans.modules.java.hints.spiimpl.batch.TestUtils.writeFilesAndWaitForScan;
  261.90 +import static org.netbeans.modules.java.hints.spiimpl.batch.TestUtils.prepareHints;
  261.91 +import org.netbeans.modules.parsing.impl.indexing.MimeTypes;
  261.92 +
  261.93 +/**
  261.94 + *
  261.95 + * @author lahvac
  261.96 + */
  261.97 +public class BatchUtilitiesTest extends NbTestCase {
  261.98 +
  261.99 +    public BatchUtilitiesTest(String name) {
 261.100 +        super(name);
 261.101 +    }
 261.102 +
 261.103 +    //XXX: copied from CustomIndexerImplTest:
 261.104 +    @Override
 261.105 +    protected void setUp() throws Exception {
 261.106 +        SourceUtilsTestUtil.prepareTest(new String[] {"org/netbeans/modules/java/source/resources/layer.xml", "org/netbeans/lib/java/lexer/layer.xml"}, new Object[0]);
 261.107 +        Main.initializeURLFactory();
 261.108 +        org.netbeans.api.project.ui.OpenProjects.getDefault().getOpenProjects();
 261.109 +        prepareTest();
 261.110 +        MimeTypes.setAllMimeTypes(Collections.singleton("text/x-java"));
 261.111 +        GlobalPathRegistry.getDefault().register(ClassPath.SOURCE, new ClassPath[] {ClassPathSupport.createClassPath(src1, src2)});
 261.112 +        RepositoryUpdater.getDefault().start(true);
 261.113 +        super.setUp();
 261.114 +    }
 261.115 +
 261.116 +    public void testBatchSearchNotIndexed() throws Exception {
 261.117 +        writeFilesAndWaitForScan(src1,
 261.118 +                                 new File("test/Test1.java", "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); } }"),
 261.119 +                                 new File("test/Test2.java", "package test; public class Test2 { private void test() { new javax.swing.ImageIcon(null); } }"));
 261.120 +        writeFilesAndWaitForScan(src3,
 261.121 +                                 new File("test/Test1.java", "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); } }"),
 261.122 +                                 new File("test/Test2.java", "package test; public class Test2 { public boolean isDirectory() {return false} }"));
 261.123 +
 261.124 +        Iterable<? extends HintDescription> hints = prepareHints("$1.isDirectory() => !$1.isFile()", "$1", "java.io.File");
 261.125 +        BatchResult result = BatchSearch.findOccurrences(hints, Scopes.specifiedFoldersScope(Folder.convert(src1, src3, empty)));
 261.126 +        List<MessageImpl> problems = new LinkedList<MessageImpl>();
 261.127 +        Collection<? extends ModificationResult> changes = BatchUtilities.applyFixes(result, new ProgressHandleWrapper(100), new AtomicBoolean(), problems);
 261.128 +
 261.129 +        assertTrue(problems.toString(), problems.isEmpty());
 261.130 +
 261.131 +        Map<FileObject, String> file2New = new HashMap<FileObject, String>();
 261.132 +
 261.133 +        for (ModificationResult mr : changes) {
 261.134 +            for (FileObject file : mr.getModifiedFileObjects()) {
 261.135 +                assertNull(file2New.put(file, mr.getResultingSource(file)));
 261.136 +            }
 261.137 +        }
 261.138 +
 261.139 +        FileObject src1Test1 = src1.getFileObject("test/Test1.java");
 261.140 +        String src1Test1Real = file2New.remove(src1Test1);
 261.141 +        String src1Test1Golden = "package test; public class Test1 { private void test() { java.io.File f = null; !f.isFile(); } }";
 261.142 +
 261.143 +        assertEquals(src1Test1Golden, src1Test1Real);
 261.144 +
 261.145 +        FileObject src3Test1 = src3.getFileObject("test/Test1.java");
 261.146 +        String src3Test1Real = file2New.remove(src3Test1);
 261.147 +        String src3Test1Golden = "package test; public class Test1 { private void test() { java.io.File f = null; !f.isFile(); } }";
 261.148 +
 261.149 +        assertEquals(src3Test1Golden, src3Test1Real);
 261.150 +
 261.151 +        assertTrue(file2New.toString(), file2New.isEmpty());
 261.152 +    }
 261.153 +
 261.154 +//    public void testRemoveUnusedImports() throws Exception {
 261.155 +//        writeFilesAndWaitForScan(src1,
 261.156 +//                                 new File("test/Test1.java", "package test;\n import java.util.List;\n public class Test1 { }"));
 261.157 +//        writeFilesAndWaitForScan(src2,
 261.158 +//                                 new File("test/Test2.java", "package test;\n import java.util.LinkedList;\n public class Test2 { }"));
 261.159 +//
 261.160 +//        FileObject test1 = src1.getFileObject("test/Test1.java");
 261.161 +//        FileObject test2 = src2.getFileObject("test/Test2.java");
 261.162 +//
 261.163 +//        System.err.println(DataObject.find(test1).getClass());
 261.164 +//        BatchUtilities.removeUnusedImports(Arrays.asList(test1, test2));
 261.165 +//
 261.166 +//        LifecycleManager.getDefault().saveAll();
 261.167 +//
 261.168 +//        assertEquals("package test;\n public class Test1 { }", TestUtilities.copyFileToString(FileUtil.toFile(test1)));
 261.169 +//        assertEquals("package test;\n public class Test2 { }", TestUtilities.copyFileToString(FileUtil.toFile(test2)));
 261.170 +//    }
 261.171 +
 261.172 +    private FileObject src1;
 261.173 +    private FileObject src2;
 261.174 +    private FileObject src3;
 261.175 +    private FileObject empty;
 261.176 +
 261.177 +    private void prepareTest() throws Exception {
 261.178 +        FileObject workdir = SourceUtilsTestUtil.makeScratchDir(this);
 261.179 +
 261.180 +        src1 = FileUtil.createFolder(workdir, "src1");
 261.181 +        src2 = FileUtil.createFolder(workdir, "src2");
 261.182 +        src3 = FileUtil.createFolder(workdir, "src3");
 261.183 +        empty = FileUtil.createFolder(workdir, "empty");
 261.184 +
 261.185 +        ClassPathProviderImpl.setSourceRoots(Arrays.asList(src1, src2, src3));
 261.186 +
 261.187 +        FileObject cache = FileUtil.createFolder(workdir, "cache");
 261.188 +
 261.189 +        CacheFolder.setCacheFolder(cache);
 261.190 +    }
 261.191 +
 261.192 +    @ServiceProvider(service=MimeDataProvider.class)
 261.193 +    public static final class JavaLexerProvider implements MimeDataProvider {
 261.194 +
 261.195 +        private Lookup javaLookup = Lookups.fixed(JavaTokenId.language());
 261.196 +
 261.197 +        public Lookup getLookup(MimePath mimePath) {
 261.198 +            if (mimePath.getPath().endsWith(JavacParser.MIME_TYPE)) {
 261.199 +                return javaLookup;
 261.200 +            }
 261.201 +
 261.202 +            return Lookup.EMPTY;
 261.203 +        }
 261.204 +
 261.205 +    }
 261.206 +
 261.207 +    @ServiceProvider(service=LanguageProvider.class)
 261.208 +    public static final class JavaLanguageProvider extends LanguageProvider {
 261.209 +
 261.210 +        @Override
 261.211 +        public Language<?> findLanguage(String mimeType) {
 261.212 +            if ("text/x-java".equals(mimeType)) {
 261.213 +                return JavaTokenId.language();
 261.214 +            }
 261.215 +
 261.216 +            return null;
 261.217 +        }
 261.218 +
 261.219 +        @Override
 261.220 +        public LanguageEmbedding<?> findLanguageEmbedding(Token<?> token, LanguagePath languagePath, InputAttributes inputAttributes) {
 261.221 +            return null;
 261.222 +        }
 261.223 +
 261.224 +    }
 261.225 +}
   262.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   262.2 +++ b/sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/batch/ProgressHandleWrapperTest.java	Sun Oct 23 11:50:54 2016 +0200
   262.3 @@ -0,0 +1,66 @@
   262.4 +/*
   262.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   262.6 + *
   262.7 + * Copyright 2009-2011 Oracle and/or its affiliates. All rights reserved.
   262.8 + *
   262.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  262.10 + * Other names may be trademarks of their respective owners.
  262.11 + *
  262.12 + * The contents of this file are subject to the terms of either the GNU
  262.13 + * General Public License Version 2 only ("GPL") or the Common
  262.14 + * Development and Distribution License("CDDL") (collectively, the
  262.15 + * "License"). You may not use this file except in compliance with the
  262.16 + * License. You can obtain a copy of the License at
  262.17 + * http://www.netbeans.org/cddl-gplv2.html
  262.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  262.19 + * specific language governing permissions and limitations under the
  262.20 + * License.  When distributing the software, include this License Header
  262.21 + * Notice in each file and include the License file at
  262.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  262.23 + * particular file as subject to the "Classpath" exception as provided
  262.24 + * by Oracle in the GPL Version 2 section of the License file that
  262.25 + * accompanied this code. If applicable, add the following below the
  262.26 + * License Header, with the fields enclosed by brackets [] replaced by
  262.27 + * your own identifying information:
  262.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  262.29 + *
  262.30 + * If you wish your version of this file to be governed by only the CDDL
  262.31 + * or only the GPL Version 2, indicate your decision by adding
  262.32 + * "[Contributor] elects to include this software in this distribution
  262.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  262.34 + * single choice of license, a recipient has the option to distribute
  262.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  262.36 + * to extend the choice of license to its licensees as provided above.
  262.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  262.38 + * Version 2 license, then the option applies only if the new code is
  262.39 + * made subject to such option by the copyright holder.
  262.40 + *
  262.41 + * Contributor(s):
  262.42 + *
  262.43 + * Portions Copyrighted 2009-2011 Sun Microsystems, Inc.
  262.44 + */
  262.45 +package org.netbeans.modules.java.hints.spiimpl.batch;
  262.46 +
  262.47 +import org.netbeans.junit.NbTestCase;
  262.48 +
  262.49 +/**
  262.50 + *
  262.51 + * @author lahvac
  262.52 + */
  262.53 +public class ProgressHandleWrapperTest extends NbTestCase {
  262.54 +
  262.55 +    public ProgressHandleWrapperTest(String name) {
  262.56 +        super(name);
  262.57 +    }
  262.58 +
  262.59 +    public void testNoProgress() {
  262.60 +        ProgressHandleWrapper w = new ProgressHandleWrapper(new ProgressHandleWrapper.ProgressHandleAbstraction() {
  262.61 +            public void start(int totalWork) {}
  262.62 +            public void progress(int currentWorkDone) {}
  262.63 +            public void progress(String message) {}
  262.64 +            public void finish() {}
  262.65 +        }, 1);
  262.66 +        
  262.67 +        w.finish();
  262.68 +    }
  262.69 +}
   263.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   263.2 +++ b/sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/batch/TestUtils.java	Sun Oct 23 11:50:54 2016 +0200
   263.3 @@ -0,0 +1,135 @@
   263.4 +/*
   263.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   263.6 + *
   263.7 + * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
   263.8 + *
   263.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  263.10 + * Other names may be trademarks of their respective owners.
  263.11 + *
  263.12 + * The contents of this file are subject to the terms of either the GNU
  263.13 + * General Public License Version 2 only ("GPL") or the Common
  263.14 + * Development and Distribution License("CDDL") (collectively, the
  263.15 + * "License"). You may not use this file except in compliance with the
  263.16 + * License. You can obtain a copy of the License at
  263.17 + * http://www.netbeans.org/cddl-gplv2.html
  263.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  263.19 + * specific language governing permissions and limitations under the
  263.20 + * License.  When distributing the software, include this License Header
  263.21 + * Notice in each file and include the License file at
  263.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  263.23 + * particular file as subject to the "Classpath" exception as provided
  263.24 + * by Oracle in the GPL Version 2 section of the License file that
  263.25 + * accompanied this code. If applicable, add the following below the
  263.26 + * License Header, with the fields enclosed by brackets [] replaced by
  263.27 + * your own identifying information:
  263.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  263.29 + *
  263.30 + * If you wish your version of this file to be governed by only the CDDL
  263.31 + * or only the GPL Version 2, indicate your decision by adding
  263.32 + * "[Contributor] elects to include this software in this distribution
  263.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  263.34 + * single choice of license, a recipient has the option to distribute
  263.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  263.36 + * to extend the choice of license to its licensees as provided above.
  263.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  263.38 + * Version 2 license, then the option applies only if the new code is
  263.39 + * made subject to such option by the copyright holder.
  263.40 + *
  263.41 + * Contributor(s):
  263.42 + *
  263.43 + * Portions Copyrighted 2011 Sun Microsystems, Inc.
  263.44 + */
  263.45 +package org.netbeans.modules.java.hints.spiimpl.batch;
  263.46 +
  263.47 +import java.util.Collection;
  263.48 +import java.util.Collections;
  263.49 +import org.netbeans.spi.java.hints.HintContext;
  263.50 +import org.netbeans.modules.java.hints.providers.spi.HintDescription.Worker;
  263.51 +import org.netbeans.modules.java.hints.providers.spi.Trigger.PatternDescription;
  263.52 +import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
  263.53 +import org.netbeans.spi.editor.hints.ErrorDescription;
  263.54 +import org.netbeans.modules.java.hints.providers.spi.HintDescriptionFactory;
  263.55 +import java.util.HashMap;
  263.56 +import java.util.Map;
  263.57 +import org.netbeans.api.java.source.SourceUtils;
  263.58 +import org.netbeans.api.java.source.TestUtilities;
  263.59 +import org.netbeans.modules.java.hints.providers.spi.HintDescription;
  263.60 +import org.openide.filesystems.FileObject;
  263.61 +import org.openide.filesystems.FileUtil;
  263.62 +
  263.63 +import static org.junit.Assert.*;
  263.64 +import org.netbeans.spi.java.hints.JavaFixUtilities;
  263.65 +
  263.66 +/**
  263.67 + *
  263.68 + * @author lahvac
  263.69 + */
  263.70 +public class TestUtils {
  263.71 +
  263.72 +    public static void writeFiles(FileObject sourceRoot, File... files) throws Exception {
  263.73 +        for (FileObject c : sourceRoot.getChildren()) {
  263.74 +            c.delete();
  263.75 +        }
  263.76 +
  263.77 +        for (File f : files) {
  263.78 +            FileObject fo = FileUtil.createData(sourceRoot, f.filename);
  263.79 +            TestUtilities.copyStringToFile(fo, f.content);
  263.80 +        }
  263.81 +    }
  263.82 +
  263.83 +    public static void writeFilesAndWaitForScan(FileObject sourceRoot, File... files) throws Exception {
  263.84 +        writeFiles(sourceRoot, files);
  263.85 +        SourceUtils.waitScanFinished();
  263.86 +    }
  263.87 +    
  263.88 +    public static final class File {
  263.89 +        public final String filename;
  263.90 +        public final String content;
  263.91 +        public final boolean index;
  263.92 +
  263.93 +        public File(String filename, String content) {
  263.94 +            this(filename, content, true);
  263.95 +        }
  263.96 +
  263.97 +        public File(String filename, String content, boolean index) {
  263.98 +            this.filename = filename;
  263.99 +            this.content = content;
 263.100 +            this.index = index;
 263.101 +        }
 263.102 +    }
 263.103 +
 263.104 +    public static Iterable<? extends HintDescription> prepareHints(String rule, String... constraints) {
 263.105 +        final String[] split = rule.split("=>");
 263.106 +
 263.107 +        Worker w;
 263.108 +
 263.109 +        if (split.length == 2) {
 263.110 +            w = new HintDescription.Worker() {
 263.111 +                @Override public Collection<? extends ErrorDescription> createErrors(HintContext ctx) {
 263.112 +                    return Collections.singletonList(ErrorDescriptionFactory.forName(ctx, ctx.getPath(), "", JavaFixUtilities.rewriteFix(ctx, "", ctx.getPath(), split[1])));
 263.113 +                }
 263.114 +            };
 263.115 +        } else {
 263.116 +            w = new HintDescription.Worker() {
 263.117 +                @Override public Collection<? extends ErrorDescription> createErrors(HintContext ctx) {
 263.118 +                    return Collections.singletonList(ErrorDescriptionFactory.forName(ctx, ctx.getPath(), ""));
 263.119 +                }
 263.120 +            };
 263.121 +        }
 263.122 +
 263.123 +        assertTrue(constraints.length % 2 == 0);
 263.124 +
 263.125 +        Map<String, String> constr = new HashMap<String, String>();
 263.126 +
 263.127 +        for (int i = 0; i < constraints.length; i += 2) {
 263.128 +            constr.put(constraints[i], constraints[i + 1]);
 263.129 +        }
 263.130 +
 263.131 +        HintDescription hd = HintDescriptionFactory.create()
 263.132 +                                                   .setTrigger(PatternDescription.create(split[0], constr))
 263.133 +                                                   .setWorker(w)
 263.134 +                                                   .produce();
 263.135 +
 263.136 +        return Collections.singletonList(hd);
 263.137 +    }
 263.138 +}
   264.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   264.2 +++ b/sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/hints/HintsInvokerTest.java	Sun Oct 23 11:50:54 2016 +0200
   264.3 @@ -0,0 +1,895 @@
   264.4 +/*
   264.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   264.6 + *
   264.7 + * Copyright 2009-2010 Oracle and/or its affiliates. All rights reserved.
   264.8 + *
   264.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  264.10 + * Other names may be trademarks of their respective owners.
  264.11 + *
  264.12 + * The contents of this file are subject to the terms of either the GNU
  264.13 + * General Public License Version 2 only ("GPL") or the Common
  264.14 + * Development and Distribution License("CDDL") (collectively, the
  264.15 + * "License"). You may not use this file except in compliance with the
  264.16 + * License. You can obtain a copy of the License at
  264.17 + * http://www.netbeans.org/cddl-gplv2.html
  264.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  264.19 + * specific language governing permissions and limitations under the
  264.20 + * License.  When distributing the software, include this License Header
  264.21 + * Notice in each file and include the License file at
  264.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  264.23 + * particular file as subject to the "Classpath" exception as provided
  264.24 + * by Oracle in the GPL Version 2 section of the License file that
  264.25 + * accompanied this code. If applicable, add the following below the
  264.26 + * License Header, with the fields enclosed by brackets [] replaced by
  264.27 + * your own identifying information:
  264.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  264.29 + *
  264.30 + * If you wish your version of this file to be governed by only the CDDL
  264.31 + * or only the GPL Version 2, indicate your decision by adding
  264.32 + * "[Contributor] elects to include this software in this distribution
  264.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  264.34 + * single choice of license, a recipient has the option to distribute
  264.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  264.36 + * to extend the choice of license to its licensees as provided above.
  264.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  264.38 + * Version 2 license, then the option applies only if the new code is
  264.39 + * made subject to such option by the copyright holder.
  264.40 + *
  264.41 + * Contributor(s):
  264.42 + *
  264.43 + * Portions Copyrighted 2009-2010 Sun Microsystems, Inc.
  264.44 + */
  264.45 +
  264.46 +package org.netbeans.modules.java.hints.spiimpl.hints;
  264.47 +
  264.48 +import com.sun.source.tree.Tree.Kind;
  264.49 +import com.sun.source.util.TreePath;
  264.50 +import java.util.Arrays;
  264.51 +import java.util.Collection;
  264.52 +import java.util.Collections;
  264.53 +import java.util.EnumSet;
  264.54 +import java.util.HashMap;
  264.55 +import java.util.LinkedList;
  264.56 +import java.util.List;
  264.57 +import java.util.Map;
  264.58 +import java.util.concurrent.atomic.AtomicBoolean;
  264.59 +import javax.swing.text.Document;
  264.60 +import static org.junit.Assert.*;
  264.61 +import org.netbeans.api.java.source.CompilationInfo;
  264.62 +import org.netbeans.modules.java.hints.spiimpl.TestBase;
  264.63 +import org.netbeans.spi.java.hints.HintContext;
  264.64 +import org.netbeans.modules.java.hints.providers.spi.HintDescription;
  264.65 +import org.netbeans.modules.java.hints.providers.spi.HintDescription.Worker;
  264.66 +import org.netbeans.modules.java.hints.providers.spi.HintDescriptionFactory;
  264.67 +import org.netbeans.modules.java.hints.providers.spi.HintMetadata;
  264.68 +import org.netbeans.modules.java.hints.providers.spi.HintMetadata.Options;
  264.69 +import org.netbeans.modules.java.hints.providers.spi.Trigger.Kinds;
  264.70 +import org.netbeans.modules.java.hints.providers.spi.Trigger.PatternDescription;
  264.71 +import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings;
  264.72 +import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
  264.73 +import org.netbeans.spi.editor.hints.ErrorDescription;
  264.74 +import org.netbeans.spi.editor.hints.Fix;
  264.75 +import org.netbeans.spi.java.hints.JavaFixUtilities;
  264.76 +import org.openide.LifecycleManager;
  264.77 +import org.openide.cookies.EditorCookie;
  264.78 +import org.openide.filesystems.FileObject;
  264.79 +import org.openide.loaders.DataObject;
  264.80 +
  264.81 +/**
  264.82 + *
  264.83 + * @author user
  264.84 + */
  264.85 +public class HintsInvokerTest extends TestBase {
  264.86 +
  264.87 +    public HintsInvokerTest(String name) {
  264.88 +        super(name);
  264.89 +    }
  264.90 +
  264.91 +//    public static TestSuite suite() {
  264.92 +//        NbTestSuite r = new NbTestSuite();
  264.93 +//        r.addTest(new HintsInvokerTest("testPatternVariable1"));
  264.94 +//        return r;
  264.95 +//    }
  264.96 +
  264.97 +    public void testPattern1() throws Exception {
  264.98 +        performAnalysisTest("test/Test.java",
  264.99 +                            "|package test;\n" +
 264.100 +                            "import java.io.File;\n" +
 264.101 +                            "public class Test {\n" +
 264.102 +                            "     private void test(File f) {\n" +
 264.103 +                            "         f.toURL();\n" +
 264.104 +                            "     }\n" +
 264.105 +                            "}\n",
 264.106 +                            "4:11-4:16:verifier:HINT");
 264.107 +    }
 264.108 +
 264.109 +    public void testPattern2() throws Exception {
 264.110 +        performAnalysisTest("test/Test.java",
 264.111 +                            "|package test;\n" +
 264.112 +                            "\n" +
 264.113 +                            "public class Test {\n" +
 264.114 +                            "     private void test(java.io.File f) {\n" +
 264.115 +                            "         f.toURL();\n" +
 264.116 +                            "     }\n" +
 264.117 +                            "}\n",
 264.118 +                            "4:11-4:16:verifier:HINT");
 264.119 +    }
 264.120 +
 264.121 +    public void testKind1() throws Exception {
 264.122 +        performAnalysisTest("test/Test.java",
 264.123 +                            "|package test;\n" +
 264.124 +                            "\n" +
 264.125 +                            "public class Test {\n" +
 264.126 +                            "     private void test(java.io.File f) {\n" +
 264.127 +                            "         f.toURL();\n" +
 264.128 +                            "     }\n" +
 264.129 +                            "}\n",
 264.130 +                            "4:11-4:16:verifier:HINT");
 264.131 +    }
 264.132 +
 264.133 +    public void DISABLEDtestPatternVariable1() throws Exception {
 264.134 +        performFixTest("test/Test.java",
 264.135 +                       "|package test;\n" +
 264.136 +                       "\n" +
 264.137 +                       "public class Test {\n" +
 264.138 +                       "     private void test() {\n" +
 264.139 +                       "         {\n" +
 264.140 +                       "             int y;\n" +
 264.141 +                       "             y = 1;\n" +
 264.142 +                       "         }\n" +
 264.143 +                       "         int z;\n" +
 264.144 +                       "         {\n" +
 264.145 +                       "             int y;\n" +
 264.146 +                       "             z = 1;\n" +
 264.147 +                       "         }\n" +
 264.148 +                       "     }\n" +
 264.149 +                       "}\n",
 264.150 +                       "4:9-7:10:verifier:HINT",
 264.151 +                       "FixImpl",
 264.152 +                       "package test; public class Test { private void test() { { int y = 1; } int z; { int y; z = 1; } } } ");
 264.153 +    }
 264.154 +
 264.155 +    public void testPatternAssert1() throws Exception {
 264.156 +        performAnalysisTest("test/Test.java",
 264.157 +                            "|package test;\n" +
 264.158 +                            "\n" +
 264.159 +                            "public class Test {\n" +
 264.160 +                            "     private void test() {\n" +
 264.161 +                            "         assert true : \"\";\n" +
 264.162 +                            "     }\n" +
 264.163 +                            "}\n",
 264.164 +                            "4:9-4:15:verifier:HINT");
 264.165 +    }
 264.166 +
 264.167 +    public void testPatternStatementAndSingleStatementBlockAreSame() throws Exception {
 264.168 +        performAnalysisTest("test/Test.java",
 264.169 +                            "|package test;\n" +
 264.170 +                            "\n" +
 264.171 +                            "public class Test {\n" +
 264.172 +                            "     private int test() {\n" +
 264.173 +                            "         if (true) {\n" +
 264.174 +                            "             return 0;\n" +
 264.175 +                            "         }\n" +
 264.176 +                            "     }\n" +
 264.177 +                            "}\n",
 264.178 +                            "4:9-4:11:verifier:HINT");
 264.179 +    }
 264.180 +
 264.181 +    public void testPatternFalseOccurrence() throws Exception {
 264.182 +        performAnalysisTest("test/Test.java",
 264.183 +                            "|package test;\n" +
 264.184 +                            "\n" +
 264.185 +                            "public class Test {\n" +
 264.186 +                            "     private int test(java.io.File f) {\n" +
 264.187 +                            "         f.toURI().toURL();\n" +
 264.188 +                            "     }\n" +
 264.189 +                            "}\n");
 264.190 +    }
 264.191 +
 264.192 +    public void testStatementVariables1() throws Exception {
 264.193 +        performFixTest("test/Test.java",
 264.194 +                       "|package test;\n" +
 264.195 +                       "\n" +
 264.196 +                       "public class Test {\n" +
 264.197 +                       "     private int test(java.io.File f) {\n" +
 264.198 +                       "         if (true)\n" +
 264.199 +                       "             System.err.println(1);\n" +
 264.200 +                       "         else\n" +
 264.201 +                       "             System.err.println(2);\n" +
 264.202 +                       "     }\n" +
 264.203 +                       "}\n",
 264.204 +                       "4:9-4:11:verifier:HINT",
 264.205 +                       "FixImpl",
 264.206 +                       ("package test;\n" +
 264.207 +                       "\n" +
 264.208 +                       "public class Test {\n" +
 264.209 +                       "     private int test(java.io.File f) {\n" +
 264.210 +                       "         if (false)\n" +
 264.211 +                       "             System.err.println(2);\n" +
 264.212 +                       "         else\n" +
 264.213 +                       "             System.err.println(1);\n" +
 264.214 +                       "     }\n" +
 264.215 +                       "}\n").replaceAll("[ \t\n]+", " "));
 264.216 +    }
 264.217 +
 264.218 +    public void testStatementVariables2() throws Exception {
 264.219 +        performFixTest("test/Test.java",
 264.220 +                       "|package test;\n" +
 264.221 +                       "\n" +
 264.222 +                       "public class Test {\n" +
 264.223 +                       "     private int test(java.io.File f) {\n" +
 264.224 +                       "         if (true)\n" +
 264.225 +                       "             return 1;\n" +
 264.226 +                       "         else\n" +
 264.227 +                       "             return 2;\n" +
 264.228 +                       "     }\n" +
 264.229 +                       "}\n",
 264.230 +                       "4:9-4:11:verifier:HINT",
 264.231 +                       "FixImpl",
 264.232 +                       ("package test;\n" +
 264.233 +                       "\n" +
 264.234 +                       "public class Test {\n" +
 264.235 +                       "     private int test(java.io.File f) {\n" +
 264.236 +                       "         if (false)\n" +
 264.237 +                       "             return 2;\n" +
 264.238 +                       "         else\n" +
 264.239 +                       "             return 1;\n" +
 264.240 +                       "     }\n" +
 264.241 +                       "}\n").replaceAll("[ \t\n]+", " "));
 264.242 +    }
 264.243 +
 264.244 +    public void testMultiStatementVariables1() throws Exception {
 264.245 +        performFixTest("test/Test.java",
 264.246 +                       "|package test;\n" +
 264.247 +                       "\n" +
 264.248 +                       "public class Test {\n" +
 264.249 +                       "     private int test(int j) {\n" +
 264.250 +                       "         j++;\n" +
 264.251 +                       "         j++;\n" +
 264.252 +                       "         int i = 3;\n" +
 264.253 +                       "         j++;\n" +
 264.254 +                       "         j++;\n" +
 264.255 +                       "         return i;\n" +
 264.256 +                       "     }\n" +
 264.257 +                       "}\n",
 264.258 +                       "3:29-10:6:verifier:HINT",
 264.259 +                       "FixImpl",
 264.260 +                       ("package test;\n" +
 264.261 +                       "\n" +
 264.262 +                       "public class Test {\n" +
 264.263 +                       "     private int test(int j) {\n" +
 264.264 +                       "         j++;\n" +
 264.265 +                       "         j++;\n" +
 264.266 +                       "         float i = 3;\n" +
 264.267 +                       "         j++;\n" +
 264.268 +                       "         j++;\n" +
 264.269 +                       "         return i;\n" +
 264.270 +                       "     }\n" +
 264.271 +                       "}\n").replaceAll("[ \t\n]+", " "));
 264.272 +    }
 264.273 +
 264.274 +    public void testMultiStatementVariables2() throws Exception {
 264.275 +        performFixTest("test/Test.java",
 264.276 +                       "|package test;\n" +
 264.277 +                       "\n" +
 264.278 +                       "public class Test {\n" +
 264.279 +                       "     private int test(int j) {\n" +
 264.280 +                       "         int i = 3;\n" +
 264.281 +                       "         return i;\n" +
 264.282 +                       "     }\n" +
 264.283 +                       "}\n",
 264.284 +                       "3:29-6:6:verifier:HINT",
 264.285 +                       "FixImpl",
 264.286 +                       ("package test;\n" +
 264.287 +                       "\n" +
 264.288 +                       "public class Test {\n" +
 264.289 +                       "     private int test(int j) {\n" +
 264.290 +                       "         float i = 3;\n" +
 264.291 +                       "         return i;\n" +
 264.292 +                       "     }\n" +
 264.293 +                       "}\n").replaceAll("[ \t\n]+", " "));
 264.294 +    }
 264.295 +
 264.296 +    public void testMultiStatementVariables3() throws Exception {
 264.297 +        performFixTest("test/Test.java",
 264.298 +                       "|package test;\n" +
 264.299 +                       "\n" +
 264.300 +                       "public class Test {\n" +
 264.301 +                       "     private int test() {\n" +
 264.302 +                       "         System.err.println();\n" +
 264.303 +                       "         System.err.println();\n" +
 264.304 +                       "         int i = 3;\n" +
 264.305 +                       "         System.err.println(i);\n" +
 264.306 +                       "         System.err.println(i);\n" +
 264.307 +                       "         return i;\n" +
 264.308 +                       "     }\n" +
 264.309 +                       "}\n",
 264.310 +                       "3:24-10:6:verifier:HINT",
 264.311 +                       "FixImpl",
 264.312 +                       ("package test;\n" +
 264.313 +                       "\n" +
 264.314 +                       "public class Test {\n" +
 264.315 +                       "     private int test() {\n" +
 264.316 +                       "         System.err.println();\n" +
 264.317 +                       "         System.err.println();\n" +
 264.318 +                       "         float i = 3;\n" +
 264.319 +                       "         System.err.println(i);\n" +
 264.320 +                       "         System.err.println(i);\n" +
 264.321 +                       "         return i;\n" +
 264.322 +                       "     }\n" +
 264.323 +                       "}\n").replaceAll("[ \t\n]+", " "));
 264.324 +    }
 264.325 +
 264.326 +    public void testMultiStatementVariablesAndBlocks() throws Exception {
 264.327 +        performFixTest("test/Test.java",
 264.328 +                       "|package test;\n" +
 264.329 +                       "\n" +
 264.330 +                       "public class Test {\n" +
 264.331 +                       "     private void test() {" +
 264.332 +                       "         if (true)\n" +
 264.333 +                       "             System.err.println();\n" +
 264.334 +                       "     }\n" +
 264.335 +                       "}\n",
 264.336 +                       "3:35-3:37:verifier:HINT",
 264.337 +                       "FixImpl",
 264.338 +                       ("package test;\n" +
 264.339 +                       "\n" +
 264.340 +                       "public class Test {\n" +
 264.341 +                       "     private void test() {" +
 264.342 +                       "         if (false) {\n" +
 264.343 +                       "             System.err.println();\n" +
 264.344 +                       "         }\n" +
 264.345 +                       "     }\n" +
 264.346 +                       "}\n").replaceAll("[ \t\n]+", " "));
 264.347 +    }
 264.348 +
 264.349 +    public void testOneStatement2MultipleBlock() throws Exception {
 264.350 +        performFixTest("test/Test.java",
 264.351 +                       "|package test;\n" +
 264.352 +                       "\n" +
 264.353 +                       "public class Test {\n" +
 264.354 +                       "     private void test() {\n" +
 264.355 +                       "         System.err.println(\"\");\n" +
 264.356 +                       "     }\n" +
 264.357 +                       "}\n",
 264.358 +                       "4:9-4:32:verifier:HINT",
 264.359 +                       "FixImpl",
 264.360 +                       ("package test;\n" +
 264.361 +                       "\n" +
 264.362 +                       "public class Test {\n" +
 264.363 +                       "     private void test() {\n" +
 264.364 +                       "         System.err.println(\"\");\n" +
 264.365 +                       "         System.err.println(\"\");\n" +
 264.366 +                       "     }\n" +
 264.367 +                       "}\n").replaceAll("[ \t\n]+", " "));
 264.368 +    }
 264.369 +
 264.370 +    public void testOneStatement2MultipleStatement() throws Exception {
 264.371 +        performFixTest("test/Test.java",
 264.372 +                       "|package test;\n" +
 264.373 +                       "\n" +
 264.374 +                       "public class Test {\n" +
 264.375 +                       "     private void test() {\n" +
 264.376 +                       "         if (true)\n" +
 264.377 +                       "             System.err.println(\"\");\n" +
 264.378 +                       "     }\n" +
 264.379 +                       "}\n",
 264.380 +                       "5:13-5:36:verifier:HINT",
 264.381 +                       "FixImpl",
 264.382 +                       ("package test;\n" +
 264.383 +                       "\n" +
 264.384 +                       "public class Test {\n" +
 264.385 +                       "     private void test() {\n" +
 264.386 +                       "         if (true) {\n" +
 264.387 +                       "             System.err.println(\"\");\n" +
 264.388 +                       "             System.err.println(\"\");\n" +
 264.389 +                       "         }\n" +
 264.390 +                       "     }\n" +
 264.391 +                       "}\n").replaceAll("[ \t\n]+", " "));
 264.392 +    }
 264.393 +
 264.394 +    public void testMultiple2OneStatement1() throws Exception {
 264.395 +        performFixTest("test/Test.java",
 264.396 +                       "|package test;\n" +
 264.397 +                       "\n" +
 264.398 +                       "public class Test {\n" +
 264.399 +                       "     private void test() {\n" +
 264.400 +                       "         System.err.println(\"\");\n" +
 264.401 +                       "         System.err.println(\"\");\n" +
 264.402 +                       "     }\n" +
 264.403 +                       "}\n",
 264.404 +                       "4:9-4:32:verifier:HINT",
 264.405 +                       "FixImpl",
 264.406 +                       ("package test;\n" +
 264.407 +                       "\n" +
 264.408 +                       "public class Test {\n" +
 264.409 +                       "     private void test() {\n" +
 264.410 +                       "         System.err.println(\"\");\n" +
 264.411 +                       "     }\n" +
 264.412 +                       "}\n").replaceAll("[ \t\n]+", " "));
 264.413 +    }
 264.414 +
 264.415 +    public void testMultiple2OneStatement2() throws Exception {
 264.416 +        performFixTest("test/Test.java",
 264.417 +                       "|package test;\n" +
 264.418 +                       "\n" +
 264.419 +                       "public class Test {\n" +
 264.420 +                       "     private void test() {\n" +
 264.421 +                       "         int i = 0;\n" +
 264.422 +                       "         System.err.println(\"\");\n" +
 264.423 +                       "         System.err.println(\"\");\n" +
 264.424 +                       "         i++;\n" +
 264.425 +                       "     }\n" +
 264.426 +                       "}\n",
 264.427 +                       "5:9-5:32:verifier:HINT",
 264.428 +                       "FixImpl",
 264.429 +                       ("package test;\n" +
 264.430 +                       "\n" +
 264.431 +                       "public class Test {\n" +
 264.432 +                       "     private void test() {\n" +
 264.433 +                       "         int i = 0;\n" +
 264.434 +                       "         System.err.println(\"\");\n" +
 264.435 +                       "         i++;\n" +
 264.436 +                       "     }\n" +
 264.437 +                       "}\n").replaceAll("[ \t\n]+", " "));
 264.438 +    }
 264.439 +
 264.440 +    public void testMemberSelectInsideMemberSelect() throws Exception {
 264.441 +        performFixTest("test/Test.java",
 264.442 +                       "|package test;\n" +
 264.443 +                       "\n" +
 264.444 +                       "public class Test {\n" +
 264.445 +                       "     public Test test;\n" +
 264.446 +                       "     public String name;\n" +
 264.447 +                       "     private void test() {\n" +
 264.448 +                       "         Test t = null;\n" +
 264.449 +                       "         String s = t.test.toString();\n" +
 264.450 +                       "     }\n" +
 264.451 +                       "}\n",
 264.452 +                       "7:22-7:26:verifier:HINT",
 264.453 +                       "FixImpl",
 264.454 +                       ("package test;\n" +
 264.455 +                       "\n" +
 264.456 +                       "public class Test {\n" +
 264.457 +                       "     public Test test;\n" +
 264.458 +                       "     public String name;\n" +
 264.459 +                       "     private void test() {\n" +
 264.460 +                       "         Test t = null;\n" +
 264.461 +                       "         String s = t.getTest().toString();\n" +
 264.462 +                       "     }\n" +
 264.463 +                       "}\n").replaceAll("[ \t\n]+", " "));
 264.464 +    }
 264.465 +
 264.466 +    public void testPackageInfo() throws Exception {
 264.467 +        performAnalysisTest("test/package-info.java",
 264.468 +                            "|package test;\n");
 264.469 +    }
 264.470 +
 264.471 +    public void testSuppressWarnings() throws Exception {
 264.472 +        performAnalysisTest("test/Test.java",
 264.473 +                            "|package test;\n" +
 264.474 +                            "@SuppressWarnings(\"test\")\n" +
 264.475 +                            "public class Test {\n" +
 264.476 +                            "     public Test test;\n" +
 264.477 +                            "     public String name;\n" +
 264.478 +                            "     private void test() {\n" +
 264.479 +                            "         Test t = null;\n" +
 264.480 +                            "         String s = t.test.toString();\n" +
 264.481 +                            "     }\n" +
 264.482 +                            "}\n");
 264.483 +    }
 264.484 +
 264.485 +    public void testRewriteOneToMultipleClassMembers() throws Exception {
 264.486 +        performFixTest("test/Test.java",
 264.487 +                       "|package test;\n" +
 264.488 +                       "\n" +
 264.489 +                       "public class Test {\n" +
 264.490 +                       "     private int i;\n" +
 264.491 +                       "}\n",
 264.492 +                       "3:17-3:18:verifier:HINT",
 264.493 +                       "FixImpl",
 264.494 +                       ("package test;\n" +
 264.495 +                       "\n" +
 264.496 +                       "public class Test {\n" +
 264.497 +                       "     private int i;\n" +
 264.498 +                       "     public int getI() {\n" +
 264.499 +                       "         return i;\n" +
 264.500 +                       "     }\n" +
 264.501 +                       "}\n").replaceAll("[ \t\n]+", " "));
 264.502 +    }
 264.503 +
 264.504 +    public void testImports1() throws Exception {
 264.505 +        performFixTest("test/Test.java",
 264.506 +                       "|package test;\n" +
 264.507 +                       "\n" +
 264.508 +                       "public class Test {\n" +
 264.509 +                       "     private void test() {\n" +
 264.510 +                       "         new java.util.LinkedList();\n" +
 264.511 +                       "     }" +
 264.512 +                       "}\n",
 264.513 +                       "4:9-4:35:verifier:HINT",
 264.514 +                       "FixImpl",
 264.515 +                       ("package test;\n" +
 264.516 +                       "import java.util.ArrayList;\n" +
 264.517 +                       "public class Test {\n" +
 264.518 +                       "     private void test() {\n" +
 264.519 +                       "         new ArrayList();\n" +
 264.520 +                       "     }" +
 264.521 +                       "}\n").replaceAll("[ \t\n]+", " "));
 264.522 +    }
 264.523 +
 264.524 +    public void testImports2() throws Exception {
 264.525 +        performFixTest("test/Test.java",
 264.526 +                       "|package test;\n" +
 264.527 +                       "import java.util.LinkedList;\n" +
 264.528 +                       "public class Test {\n" +
 264.529 +                       "     private void test() {\n" +
 264.530 +                       "         LinkedList l;\n" +
 264.531 +                       "     }" +
 264.532 +                       "}\n",
 264.533 +                       "4:20-4:21:verifier:HINT",
 264.534 +                       "FixImpl",
 264.535 +                       ("package test;\n" +
 264.536 +                       "import java.util.ArrayList;\n" +
 264.537 +                       "import java.util.LinkedList;\n" +
 264.538 +                       "public class Test {\n" +
 264.539 +                       "     private void test() {\n" +
 264.540 +                       "         ArrayList l;\n" +
 264.541 +                       "     }" +
 264.542 +                       "}\n").replaceAll("[ \t\n]+", " "));
 264.543 +    }
 264.544 +
 264.545 +    public void testMultiParameters() throws Exception {
 264.546 +        performFixTest("test/Test.java",
 264.547 +                       "|package test;\n" +
 264.548 +                       "import java.util.Arrays;\n" +
 264.549 +                       "public class Test {\n" +
 264.550 +                       "     { Arrays.asList(\"a\", \"b\", \"c\"); }\n" +
 264.551 +                       "}\n",
 264.552 +                       "3:14-3:20:verifier:HINT",
 264.553 +                       "FixImpl",
 264.554 +                       ("package test;\n" +
 264.555 +                       "import java.util.Arrays;\n" +
 264.556 +                       "public class Test {\n" +
 264.557 +                       "     { Arrays.asList(\"d\", \"a\", \"b\", \"c\"); }\n" +
 264.558 +                       "}\n").replaceAll("[ \t\n]+", " "));
 264.559 +    }
 264.560 +
 264.561 +    public void testTypeParametersMethod() throws Exception {
 264.562 +        performFixTest("test/Test.java",
 264.563 +                       "|package test;\n" +
 264.564 +                       "import java.util.Arrays;\n" +
 264.565 +                       "public class Test {\n" +
 264.566 +                       "     { Arrays.<String>asList(\"a\", \"b\", \"c\"); }\n" +
 264.567 +                       "}\n",
 264.568 +                       "3:22-3:28:verifier:HINT",
 264.569 +                       "FixImpl",
 264.570 +                       ("package test;\n" +
 264.571 +                       "import java.util.Arrays;\n" +
 264.572 +                       "public class Test {\n" +
 264.573 +                       "     { Arrays.<String>asList(\"d\", \"a\", \"b\", \"c\"); }\n" +
 264.574 +                       "}\n").replaceAll("[ \t\n]+", " "));
 264.575 +    }
 264.576 +
 264.577 +    public void testTypeParametersNewClass() throws Exception {
 264.578 +        performFixTest("test/Test.java",
 264.579 +                       "|package test;\n" +
 264.580 +                       "import java.util.Arrays;\n" +
 264.581 +                       "import java.util.HashSet;\n" +
 264.582 +                       "public class Test {\n" +
 264.583 +                       "     { new HashSet<String>(Arrays.<String>asList(\"a\", \"b\", \"c\")); }\n" +
 264.584 +                       "}\n",
 264.585 +                       "4:7-4:64:verifier:HINT",
 264.586 +                       "FixImpl",
 264.587 +                       ("package test;\n" +
 264.588 +                       "import java.util.Arrays;\n" +
 264.589 +                       "import java.util.HashSet;\n" +
 264.590 +                       "public class Test {\n" +
 264.591 +                       "     { new HashSet<String>(Arrays.<String>asList(\"d\", \"a\", \"b\", \"c\")); }\n" +
 264.592 +                       "}\n").replaceAll("[ \t\n]+", " "));
 264.593 +    }
 264.594 +
 264.595 +    public void testChangeFieldType1() throws Exception {
 264.596 +        performFixTest("test/Test.java",
 264.597 +                       "|package test;\n" +
 264.598 +                       "public class Test {\n" +
 264.599 +                       "     private String name = null;\n" +
 264.600 +                       "}\n",
 264.601 +                       "2:20-2:24:verifier:HINT",
 264.602 +                       "FixImpl",
 264.603 +                       ("package test;\n" +
 264.604 +                       "public class Test {\n" +
 264.605 +                       "     private CharSequence name = null;\n" +
 264.606 +                       "}\n").replaceAll("[ \t\n]+", " "));
 264.607 +    }
 264.608 +
 264.609 +    public void testChangeFieldType2() throws Exception {
 264.610 +        performFixTest("test/Test.java",
 264.611 +                       "|package test;\n" +
 264.612 +                       "public class Test {\n" +
 264.613 +                       "     String name = null;\n" +
 264.614 +                       "}\n",
 264.615 +                       "2:12-2:16:verifier:HINT",
 264.616 +                       "FixImpl",
 264.617 +                       ("package test;\n" +
 264.618 +                       "public class Test {\n" +
 264.619 +                       "     CharSequence name = null;\n" +
 264.620 +                       "}\n").replaceAll("[ \t\n]+", " "));
 264.621 +    }
 264.622 +
 264.623 +    public void testChangeFieldType3() throws Exception {
 264.624 +        performFixTest("test/Test.java",
 264.625 +                       "|package test;\n" +
 264.626 +                       "public class Test {\n" +
 264.627 +                       "     private static final String name = \"test\".substring(0, 4);\n" +
 264.628 +                       "}\n",
 264.629 +                       "2:33-2:37:verifier:HINT",
 264.630 +                       "FixImpl",
 264.631 +                       ("package test;\n" +
 264.632 +                       "public class Test {\n" +
 264.633 +                       "     private static final CharSequence name = \"test\".substring(0, 4);\n" +
 264.634 +                       "}\n").replaceAll("[ \t\n]+", " "));
 264.635 +    }
 264.636 +
 264.637 +    public void testIdentifier() throws Exception {
 264.638 +        performFixTest("test/Test.java",
 264.639 +                       "|package test;\n" +
 264.640 +                       "public class Test {\n" +
 264.641 +                       "     private int l;" +
 264.642 +                       "     {System.err.println(l);}\n" +
 264.643 +                       "}\n",
 264.644 +                       "2:44-2:45:verifier:HINT",
 264.645 +                       "FixImpl",
 264.646 +                       ("package test;\n" +
 264.647 +                       "public class Test {\n" +
 264.648 +                       "     private int l;" +
 264.649 +                       "     {System.err.println(2);}\n" +
 264.650 +                       "}\n").replaceAll("[ \t\n]+", " "));
 264.651 +    }
 264.652 +
 264.653 +    public void testLambda() throws Exception {
 264.654 +        performAnalysisTest("test/Test.java",
 264.655 +                       "|package test;\n" +
 264.656 +                       "public class Test {\n" +
 264.657 +                       "     { new java.io.FileFilter() {public boolean accept(java.io.File f) { return true; } } }\n" +
 264.658 +                       "}\n",
 264.659 +                       "2:7-2:89:verifier:HINT");
 264.660 +    }
 264.661 +
 264.662 +    public void testAddCasesToSwitch() throws Exception {
 264.663 +        performFixTest("test/Test.java",
 264.664 +                       "|package test;\n" +
 264.665 +                       "public class Test {\n" +
 264.666 +                       "     {\n" +
 264.667 +                       "         E e = null;\n" +
 264.668 +                       "         switch (e) {\n" +
 264.669 +                       "             case A: System.err.println(1); break;\n" +
 264.670 +                       "             case D: System.err.println(2); break;\n" +
 264.671 +                       "             case E: System.err.println(3); break;\n" +
 264.672 +                       "         }\n" +
 264.673 +                       "     }\n" +
 264.674 +                       "     public enum E {A, B, C, D, E, F;}\n" +
 264.675 +                       "}\n",
 264.676 +                       "4:9-4:15:verifier:HINT",
 264.677 +                       "FixImpl",
 264.678 +                       ("package test;\n" +
 264.679 +                       "public class Test {\n" +
 264.680 +                       "     {\n" +
 264.681 +                       "         E e = null;\n" +
 264.682 +                       "         switch (e) {\n" +
 264.683 +                       "             case A: System.err.println(1); break;\n" +
 264.684 +                       "             case B:case C:\n" +
 264.685 +//                       "             case C:\n" +
 264.686 +                       "             case D: System.err.println(2); break;\n" +
 264.687 +                       "             case E: System.err.println(3); break;\n" +
 264.688 +                       "         }\n" +
 264.689 +                       "     }\n" +
 264.690 +                       "     public enum E {A, B, C, D, E, F;}\n" +
 264.691 +                       "}\n").replaceAll("[ \t\n]+", " "));
 264.692 +    }
 264.693 +
 264.694 +    private static final Map<String, HintDescription> test2Hint;
 264.695 +
 264.696 +    static {
 264.697 +        test2Hint = new HashMap<String, HintDescription>();
 264.698 +        test2Hint.put("testPattern1", HintDescriptionFactory.create().setTrigger(PatternDescription.create("$1.toURL()", Collections.singletonMap("$1", "java.io.File"))).setWorker(new WorkerImpl()).produce());
 264.699 +        test2Hint.put("testPattern2", test2Hint.get("testPattern1"));
 264.700 +        test2Hint.put("testKind1", HintDescriptionFactory.create().setTrigger(new Kinds(EnumSet.of(Kind.METHOD_INVOCATION))).setWorker(new WorkerImpl()).produce());
 264.701 +        test2Hint.put("testPatternVariable1", HintDescriptionFactory.create().setTrigger(PatternDescription.create("{ $1 $2; $2 = $3; }", Collections.<String, String>emptyMap())).setWorker(new WorkerImpl("{ $1 $2 = $3; }")).produce());
 264.702 +        Map<String, String> constraints = new HashMap<String, String>();
 264.703 +
 264.704 +        constraints.put("$1", "boolean");
 264.705 +        constraints.put("$2", "java.lang.Object");
 264.706 +
 264.707 +        test2Hint.put("testPatternAssert1", HintDescriptionFactory.create().setTrigger(PatternDescription.create("assert $1 : $2;", constraints)).setWorker(new WorkerImpl()).produce());
 264.708 +        test2Hint.put("testPatternStatementAndSingleStatementBlockAreSame", HintDescriptionFactory.create().setTrigger(PatternDescription.create("if ($1) return $2;", Collections.<String, String>emptyMap())).setWorker(new WorkerImpl()).produce());
 264.709 +        test2Hint.put("testPatternFalseOccurrence", HintDescriptionFactory.create().setTrigger(PatternDescription.create("$1.toURL()", Collections.singletonMap("$1", "java.io.File"))).setWorker(new WorkerImpl()).produce());
 264.710 +        test2Hint.put("testStatementVariables1", HintDescriptionFactory.create().setTrigger(PatternDescription.create("if ($1) $2; else $3;", constraints)).setWorker(new WorkerImpl("if (!$1) $3; else $2;")).produce());
 264.711 +        test2Hint.put("testStatementVariables2", test2Hint.get("testStatementVariables1"));
 264.712 +        test2Hint.put("testMultiStatementVariables1", HintDescriptionFactory.create().setTrigger(PatternDescription.create("{ $pref$; int $i = 3; $inf$; return $i; }", Collections.<String, String>emptyMap())).setWorker(new WorkerImpl("{ $pref$; float $i = 3; $inf$; return $i; }")).produce());
 264.713 +        test2Hint.put("testMultiStatementVariables2", test2Hint.get("testMultiStatementVariables1"));
 264.714 +        test2Hint.put("testMultiStatementVariables3", test2Hint.get("testMultiStatementVariables1"));
 264.715 +        test2Hint.put("testMultiStatementVariablesAndBlocks", HintDescriptionFactory.create().setTrigger(PatternDescription.create("if ($c) {$s1$; System.err.println(); $s2$; }", Collections.<String, String>emptyMap())).setWorker(new WorkerImpl("if (!$c) {$s1$; System.err.println(); $s2$; }")).produce());
 264.716 +        test2Hint.put("testOneStatement2MultipleBlock", HintDescriptionFactory.create().setTrigger(PatternDescription.create("System.err.println($1);", Collections.<String, String>emptyMap())).setWorker(new WorkerImpl("System.err.println($1); System.err.println($1);")).produce());
 264.717 +        test2Hint.put("testOneStatement2MultipleStatement", test2Hint.get("testOneStatement2MultipleBlock"));
 264.718 +        test2Hint.put("testMultiple2OneStatement1", HintDescriptionFactory.create().setTrigger(PatternDescription.create("System.err.println($1); System.err.println($2);", Collections.<String, String>emptyMap())).setWorker(new WorkerImpl("System.err.println($1);")).produce());
 264.719 +        test2Hint.put("testMultiple2OneStatement2", test2Hint.get("testMultiple2OneStatement1"));
 264.720 +        test2Hint.put("testMemberSelectInsideMemberSelect", HintDescriptionFactory.create().setTrigger(PatternDescription.create("$Test.test", Collections.<String, String>singletonMap("$Test", "test.Test"))).setWorker(new WorkerImpl("$Test.getTest()")).produce());
 264.721 +        test2Hint.put("testPackageInfo", HintDescriptionFactory.create().setTrigger(PatternDescription.create("$Test.test", Collections.<String, String>singletonMap("$Test", "test.Test"))).setWorker(new WorkerImpl("$Test.getTest()")).produce());
 264.722 +        HintMetadata metadata = HintMetadata.Builder.create("no-id").addOptions(Options.NON_GUI).addSuppressWarnings("test").build();
 264.723 +        test2Hint.put("testSuppressWarnings", HintDescriptionFactory.create().setTrigger(PatternDescription.create("$Test.test", Collections.<String, String>singletonMap("$Test", "test.Test"))).setWorker(new WorkerImpl("$Test.getTest()")).setMetadata(metadata).produce());
 264.724 +        test2Hint.put("testRewriteOneToMultipleClassMembers", HintDescriptionFactory.create().setTrigger(PatternDescription.create("private int i;", Collections.<String, String>emptyMap())).setWorker(new WorkerImpl("private int i; public int getI() { return i; }")).produce());
 264.725 +//        test2Hint.put("testImports1", HintDescriptionFactory.create().setTrigger(PatternDescription.create("new LinkedList()", Collections.<String, String>emptyMap(), "import java.util.LinkedList;")).setWorker(new WorkerImpl("new ArrayList()", "import java.util.ArrayList;\n")).produce());
 264.726 +//        test2Hint.put("testImports2", HintDescriptionFactory.create().setTrigger(PatternDescription.create("LinkedList $0;", Collections.<String, String>emptyMap(), "import java.util.LinkedList;")).setWorker(new WorkerImpl("ArrayList $0;", "import java.util.ArrayList;\n")).produce());
 264.727 +        test2Hint.put("testImports1", HintDescriptionFactory.create().setTrigger(PatternDescription.create("new LinkedList()", Collections.<String, String>emptyMap(), "import java.util.LinkedList;")).setWorker(new WorkerImpl("new java.util.ArrayList()")).produce());
 264.728 +        test2Hint.put("testImports2", HintDescriptionFactory.create().setTrigger(PatternDescription.create("LinkedList $0;", Collections.<String, String>emptyMap(), "import java.util.LinkedList;")).setWorker(new WorkerImpl("java.util.ArrayList $0;")).produce());
 264.729 +        test2Hint.put("testMultiParameters", HintDescriptionFactory.create().setTrigger(PatternDescription.create("java.util.Arrays.asList($1$)", Collections.<String,String>emptyMap())).setWorker(new WorkerImpl("java.util.Arrays.asList(\"d\", $1$)")).produce());
 264.730 +        test2Hint.put("testTypeParametersMethod", HintDescriptionFactory.create().setTrigger(PatternDescription.create("java.util.Arrays.<$T>asList($1$)", Collections.<String,String>emptyMap())).setWorker(new WorkerImpl("java.util.Arrays.<$T>asList(\"d\", $1$)")).produce());
 264.731 +        test2Hint.put("testTypeParametersNewClass", HintDescriptionFactory.create().setTrigger(PatternDescription.create("new java.util.HashSet<$T1$>(java.util.Arrays.<$T$>asList($1$))", Collections.<String,String>emptyMap())).setWorker(new WorkerImpl("new java.util.HashSet<$T1$>(java.util.Arrays.<$T$>asList(\"d\", $1$))")).produce());
 264.732 +        test2Hint.put("testChangeFieldType1", HintDescriptionFactory.create().setTrigger(PatternDescription.create("$modifiers$ java.lang.String $name = $initializer;", Collections.<String, String>emptyMap())).setWorker(new WorkerImpl("$modifiers$ java.lang.CharSequence $name = $initializer;")).produce());
 264.733 +        test2Hint.put("testChangeFieldType2", test2Hint.get("testChangeFieldType1"));
 264.734 +        test2Hint.put("testChangeFieldType3", test2Hint.get("testChangeFieldType1"));
 264.735 +        test2Hint.put("testIdentifier", HintDescriptionFactory.create().setTrigger(PatternDescription.create("$i", Collections.<String, String>singletonMap("$i", "int"))).setWorker(new WorkerImpl("2")).produce());
 264.736 +        test2Hint.put("testLambda", HintDescriptionFactory.create().setTrigger(PatternDescription.create("new $type() { $mods$ $retType $name($params$) { $body$; } }", Collections.<String, String>emptyMap())).setWorker(new WorkerImpl()).produce());
 264.737 +        test2Hint.put("testAddCasesToSwitch", HintDescriptionFactory.create().setTrigger(PatternDescription.create("switch ($var) { case $c1$; case D: $stmts$; case $c2$; }", Collections.<String,String>singletonMap("$var", "test.Test.E"))).setWorker(new WorkerImpl("switch ($var) { case $c1$ case B: case C: case D: $stmts$; case $c2$ }")).produce());
 264.738 +    }
 264.739 +
 264.740 +//    @Override
 264.741 +    protected List<ErrorDescription> computeErrors(CompilationInfo info, TreePath path, int pos) {
 264.742 +        HintDescription hd = test2Hint.get(getName());
 264.743 +
 264.744 +        assertNotNull(hd);
 264.745 +
 264.746 +        return new HintsInvoker(HintsSettings.getGlobalSettings(), new AtomicBoolean()).computeHints(info, Collections.singletonList(hd));
 264.747 +    }
 264.748 +
 264.749 +//    @Override
 264.750 +    protected String toDebugString(CompilationInfo info, Fix f) {
 264.751 +        return "FixImpl";
 264.752 +    }
 264.753 +
 264.754 +//    @Override
 264.755 +//    public void testIssue105979() throws Exception {}
 264.756 +//
 264.757 +//    @Override
 264.758 +//    public void testIssue108246() throws Exception {}
 264.759 +//
 264.760 +//    @Override
 264.761 +//    public void testIssue113933() throws Exception {}
 264.762 +//
 264.763 +//    @Override
 264.764 +//    public void testNoHintsForSimpleInitialize() throws Exception {}
 264.765 +
 264.766 +    private static final class WorkerImpl implements Worker {
 264.767 +
 264.768 +        private final String fix;
 264.769 +
 264.770 +        public WorkerImpl() {
 264.771 +            this(null);
 264.772 +        }
 264.773 +
 264.774 +        public WorkerImpl(String fix) {
 264.775 +            this.fix = fix;
 264.776 +        }
 264.777 +
 264.778 +        public Collection<? extends ErrorDescription> createErrors(HintContext ctx) {
 264.779 +            if (ctx.getInfo().getTreeUtilities().isSynthetic(ctx.getPath())) {
 264.780 +                return null;
 264.781 +            }
 264.782 +
 264.783 +            List<Fix> fixes = new LinkedList<Fix>();
 264.784 +
 264.785 +            if (fix != null) {
 264.786 +                fixes.add(JavaFixUtilities.rewriteFix(ctx, "Rewrite", ctx.getPath(), fix));
 264.787 +            }
 264.788 +            
 264.789 +            return Collections.singletonList(ErrorDescriptionFactory.forName(ctx, ctx.getPath(), "HINT", fixes.toArray(new Fix[0])));
 264.790 +        }
 264.791 +    }
 264.792 +
 264.793 +
 264.794 +    //XXX:copied from TreeRuleTestBase:
 264.795 +
 264.796 +    protected void performAnalysisTest(String fileName, String code, String... golden) throws Exception {
 264.797 +        int[] offset = new int[1];
 264.798 +
 264.799 +        code = org.netbeans.modules.java.hints.spiimpl.TestUtilities.detectOffsets(code, offset);
 264.800 +
 264.801 +        performAnalysisTest(fileName, code, offset[0], golden);
 264.802 +    }
 264.803 +
 264.804 +    protected void performAnalysisTest(String fileName, String code, int pos, String... golden) throws Exception {
 264.805 +        prepareTest(fileName, code);
 264.806 +
 264.807 +        TreePath path = info.getTreeUtilities().pathFor(pos);
 264.808 +
 264.809 +        List<ErrorDescription> errors = computeErrors(info, path, pos);
 264.810 +        List<String> errorsNames = new LinkedList<String>();
 264.811 +
 264.812 +        errors = errors != null ? errors : Collections.<ErrorDescription>emptyList();
 264.813 +
 264.814 +        for (ErrorDescription e : errors) {
 264.815 +            errorsNames.add(e.toString());
 264.816 +        }
 264.817 +
 264.818 +        assertTrue("The warnings provided by the hint do not match expected warnings. Provided warnings: " + errorsNames.toString(), Arrays.equals(golden, errorsNames.toArray(new String[0])));
 264.819 +    }
 264.820 +
 264.821 +    protected String performFixTest(String fileName, String code, String errorDescriptionToString, String fixDebugString, String golden) throws Exception {
 264.822 +        int[] offset = new int[1];
 264.823 +
 264.824 +        code = org.netbeans.modules.java.hints.spiimpl.TestUtilities.detectOffsets(code, offset);
 264.825 +
 264.826 +        return performFixTest(fileName, code, offset[0], errorDescriptionToString, fixDebugString, golden);
 264.827 +    }
 264.828 +
 264.829 +    protected String performFixTest(String fileName, String code, int pos, String errorDescriptionToString, String fixDebugString, String golden) throws Exception {
 264.830 +        return performFixTest(fileName, code, pos, errorDescriptionToString, fixDebugString, fileName, golden);
 264.831 +    }
 264.832 +
 264.833 +    protected String performFixTest(String fileName, String code, String errorDescriptionToString, String fixDebugString, String goldenFileName, String golden) throws Exception {
 264.834 +        int[] offset = new int[1];
 264.835 +
 264.836 +        code = org.netbeans.modules.java.hints.spiimpl.TestUtilities.detectOffsets(code, offset);
 264.837 +
 264.838 +        return performFixTest(fileName, code, offset[0], errorDescriptionToString, fixDebugString, goldenFileName, golden);
 264.839 +    }
 264.840 +
 264.841 +    protected String performFixTest(String fileName, String code, int pos, String errorDescriptionToString, String fixDebugString, String goldenFileName, String golden) throws Exception {
 264.842 +        prepareTest(fileName, code);
 264.843 +
 264.844 +        TreePath path = info.getTreeUtilities().pathFor(pos);
 264.845 +
 264.846 +        List<ErrorDescription> errors = computeErrors(info, path, pos);
 264.847 +
 264.848 +        ErrorDescription toFix = null;
 264.849 +
 264.850 +        for (ErrorDescription d : errors) {
 264.851 +            if (errorDescriptionToString.equals(d.toString())) {
 264.852 +                toFix = d;
 264.853 +                break;
 264.854 +            }
 264.855 +        }
 264.856 +
 264.857 +        assertNotNull("Error: \"" + errorDescriptionToString + "\" not found. All ErrorDescriptions: " + errors.toString(), toFix);
 264.858 +
 264.859 +        assertTrue("Must be computed", toFix.getFixes().isComputed());
 264.860 +
 264.861 +        List<Fix> fixes = toFix.getFixes().getFixes();
 264.862 +        List<String> fixNames = new LinkedList<String>();
 264.863 +        Fix toApply = null;
 264.864 +
 264.865 +        for (Fix f : fixes) {
 264.866 +            if (fixDebugString.equals(toDebugString(info, f))) {
 264.867 +                toApply = f;
 264.868 +            }
 264.869 +
 264.870 +            fixNames.add(toDebugString(info, f));
 264.871 +        }
 264.872 +
 264.873 +        assertNotNull("Cannot find fix to invoke: " + fixNames.toString(), toApply);
 264.874 +
 264.875 +        toApply.implement();
 264.876 +
 264.877 +        FileObject toCheck = sourceRoot.getFileObject(goldenFileName);
 264.878 +
 264.879 +        assertNotNull(toCheck);
 264.880 +
 264.881 +        DataObject toCheckDO = DataObject.find(toCheck);
 264.882 +        EditorCookie ec = toCheckDO.getLookup().lookup(EditorCookie.class);
 264.883 +        Document toCheckDocument = ec.openDocument();
 264.884 +
 264.885 +        String realCode = toCheckDocument.getText(0, toCheckDocument.getLength());
 264.886 +
 264.887 +        //ignore whitespaces:
 264.888 +        realCode = realCode.replaceAll("[ \t\n]+", " ");
 264.889 +
 264.890 +        if (golden != null) {
 264.891 +            assertEquals("The output code does not match the expected code.", golden, realCode);
 264.892 +        }
 264.893 +
 264.894 +        LifecycleManager.getDefault().saveAll();
 264.895 +
 264.896 +        return realCode;
 264.897 +    }
 264.898 +}
 264.899 \ No newline at end of file
   265.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   265.2 +++ b/sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/pm/BulkSearchTestPerformer.java	Sun Oct 23 11:50:54 2016 +0200
   265.3 @@ -0,0 +1,694 @@
   265.4 +/*
   265.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   265.6 + *
   265.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
   265.8 + *
   265.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  265.10 + * Other names may be trademarks of their respective owners.
  265.11 + *
  265.12 + * The contents of this file are subject to the terms of either the GNU
  265.13 + * General Public License Version 2 only ("GPL") or the Common
  265.14 + * Development and Distribution License("CDDL") (collectively, the
  265.15 + * "License"). You may not use this file except in compliance with the
  265.16 + * License. You can obtain a copy of the License at
  265.17 + * http://www.netbeans.org/cddl-gplv2.html
  265.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  265.19 + * specific language governing permissions and limitations under the
  265.20 + * License.  When distributing the software, include this License Header
  265.21 + * Notice in each file and include the License file at
  265.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  265.23 + * particular file as subject to the "Classpath" exception as provided
  265.24 + * by Oracle in the GPL Version 2 section of the License file that
  265.25 + * accompanied this code. If applicable, add the following below the
  265.26 + * License Header, with the fields enclosed by brackets [] replaced by
  265.27 + * your own identifying information:
  265.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  265.29 + *
  265.30 + * If you wish your version of this file to be governed by only the CDDL
  265.31 + * or only the GPL Version 2, indicate your decision by adding
  265.32 + * "[Contributor] elects to include this software in this distribution
  265.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  265.34 + * single choice of license, a recipient has the option to distribute
  265.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  265.36 + * to extend the choice of license to its licensees as provided above.
  265.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  265.38 + * Version 2 license, then the option applies only if the new code is
  265.39 + * made subject to such option by the copyright holder.
  265.40 + *
  265.41 + * Contributor(s):
  265.42 + *
  265.43 + * Portions Copyrighted 2009 Sun Microsystems, Inc.
  265.44 + */
  265.45 +
  265.46 +package org.netbeans.modules.java.hints.spiimpl.pm;
  265.47 +
  265.48 +import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch.BulkPattern;
  265.49 +import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch.EncodingContext;
  265.50 +import com.sun.source.util.TreePath;
  265.51 +import java.io.ByteArrayInputStream;
  265.52 +import java.io.ByteArrayOutputStream;
  265.53 +import java.io.File;
  265.54 +import java.util.Arrays;
  265.55 +import java.util.Collection;
  265.56 +import java.util.Collections;
  265.57 +import java.util.HashMap;
  265.58 +import java.util.HashSet;
  265.59 +import java.util.LinkedList;
  265.60 +import java.util.List;
  265.61 +import java.util.Map;
  265.62 +import java.util.Map.Entry;
  265.63 +import java.util.Set;
  265.64 +import java.util.concurrent.atomic.AtomicBoolean;
  265.65 +import java.util.regex.Pattern;
  265.66 +import javax.swing.text.Document;
  265.67 +import org.netbeans.api.java.lexer.JavaTokenId;
  265.68 +import org.netbeans.api.java.source.CompilationInfo;
  265.69 +import org.netbeans.api.java.source.JavaSource;
  265.70 +import org.netbeans.api.java.source.JavaSource.Phase;
  265.71 +import org.netbeans.api.java.source.SourceUtilsTestUtil;
  265.72 +import org.netbeans.api.java.source.TestUtilities;
  265.73 +import org.netbeans.api.java.source.TreePathHandle;
  265.74 +import org.netbeans.api.lexer.Language;
  265.75 +import org.netbeans.junit.NbTestCase;
  265.76 +import org.netbeans.modules.java.source.TreeLoader;
  265.77 +import org.openide.cookies.EditorCookie;
  265.78 +import org.openide.filesystems.FileObject;
  265.79 +import org.openide.filesystems.FileUtil;
  265.80 +import org.openide.loaders.DataObject;
  265.81 +import static org.junit.Assert.*;
  265.82 +import org.netbeans.junit.RandomlyFails;
  265.83 +
  265.84 +/**
  265.85 + *
  265.86 + * @author lahvac
  265.87 + */
  265.88 +public abstract class BulkSearchTestPerformer extends NbTestCase {
  265.89 +
  265.90 +    public BulkSearchTestPerformer(String name) {
  265.91 +        super(name);
  265.92 +    }
  265.93 +
  265.94 +    @Override
  265.95 +    protected void setUp() throws Exception {
  265.96 +        super.setUp();
  265.97 +        SourceUtilsTestUtil.prepareTest(new String[] {"org/netbeans/modules/java/editor/resources/layer.xml"}, new Object[0]);
  265.98 +        TreeLoader.DISABLE_CONFINEMENT_TEST = true;
  265.99 +    }
 265.100 +
 265.101 +//    public static TestSuite suite() {
 265.102 +//        NbTestSuite s = new NbTestSuite();
 265.103 +//
 265.104 +//        s.addTestSuite(NFABasedBulkSearchTest.class);
 265.105 +//
 265.106 +//        return s;
 265.107 +//    }
 265.108 +
 265.109 +    public void testSimple1() throws Exception {
 265.110 +        performTest("package test; public class Test { private void test() { System.err./**/println(\"\");}}",
 265.111 +                    Collections.singletonMap("System.err.println(\"\")", Arrays.asList("System.err./**/println(\"\")")),
 265.112 +                    Arrays.asList("System.err.println(\"\" + \"\")"));
 265.113 +    }
 265.114 +
 265.115 +    public void testDontCare() throws Exception {
 265.116 +        performTest("package test; public class Test { private void test() { System.err./**/println(\"\" + \"\");}}",
 265.117 +                    Collections.singletonMap("System.err.println($1)", Arrays.asList("System.err./**/println(\"\" + \"\")")),
 265.118 +                    Collections.<String>emptyList());
 265.119 +    }
 265.120 +
 265.121 +    public void testMemberSelectAndIdentifier() throws Exception {
 265.122 +        performTest("package test; public class Test { private static void test() { test();}}",
 265.123 +                    Collections.singletonMap("test.Test.test()", Arrays.asList("test()")),
 265.124 +                    Collections.<String>emptyList());
 265.125 +    }
 265.126 +
 265.127 +    public void testUnpureMemberSelect() throws Exception {
 265.128 +        performTest("package test; public class Test { private static void test() { new StringBuilder().append(\"\");}}",
 265.129 +                    Collections.<String, List<String>>emptyMap(),
 265.130 +                    Arrays.asList("test.append(\"\")"));
 265.131 +    }
 265.132 +
 265.133 +    public void testMemberSelectWithVariables1() throws Exception {
 265.134 +        performTest("package test; public class Test { private static void test() { new StringBuilder().append(\"\");}}",
 265.135 +                    Collections.singletonMap("$0.append(\"\")", Arrays.asList("new StringBuilder().append(\"\")")),
 265.136 +                    Collections.<String>emptyList());
 265.137 +    }
 265.138 +
 265.139 +    public void testMemberSelectWithVariables2() throws Exception {
 265.140 +        performTest("package test; public class Test { private void append(char c) { append(\"\");}}",
 265.141 +                    Collections.singletonMap("$0.append(\"\")", Arrays.asList("append(\"\")")),
 265.142 +                    Collections.<String>emptyList());
 265.143 +    }
 265.144 +
 265.145 +    public void testLocalVariables() throws Exception {
 265.146 +        performTest("package test; public class Test { private void test() { { int y; y = 1; } }}",
 265.147 +                    Collections.singletonMap("{ int $1; $1 = 1; }", Arrays.asList("{ int y; y = 1; }")),
 265.148 +                    Collections.<String>emptyList());
 265.149 +    }
 265.150 +
 265.151 +    public void testAssert() throws Exception {
 265.152 +        performTest("package test; public class Test { private void test() { assert true : \"\"; }}",
 265.153 +                    Collections.singletonMap("assert $1 : $2;", Arrays.asList("assert true : \"\";")),
 265.154 +                    Collections.<String>emptyList());
 265.155 +    }
 265.156 +
 265.157 +    public void testStatementAndSingleBlockStatementAreSame1() throws Exception {
 265.158 +        performTest("package test; public class Test { private void test() { { int y; { y = 1; } } }}",
 265.159 +                    Collections.singletonMap("{ int $1; $1 = 1; }", Arrays.asList("{ int y; { y = 1; } }")),
 265.160 +                    Collections.<String>emptyList());
 265.161 +    }
 265.162 +
 265.163 +    public void testStatementAndSingleBlockStatementAreSame2() throws Exception {
 265.164 +        performTest("package test; public class Test { private void test() { { int y; y = 1; } }}",
 265.165 +                    Collections.singletonMap("{ int $1; { $1 = 1; } }", Arrays.asList("{ int y; y = 1; }")),
 265.166 +                    Collections.<String>emptyList());
 265.167 +    }
 265.168 +
 265.169 +    public void testStatementVariables1() throws Exception {
 265.170 +        performTest("package test; public class Test { public int test1() { if (true) return 1; else return 2; } }",
 265.171 +                    Collections.singletonMap("if ($1) $2; else $3;", Arrays.asList("if (true) return 1; else return 2;")),
 265.172 +                    Collections.<String>emptyList());
 265.173 +    }
 265.174 +
 265.175 +    public void testMultiStatementVariables1() throws Exception {
 265.176 +        performTest("package test; public class Test { public int test1(int i) { System.err.println(i); System.err.println(i); i = 3; System.err.println(i); System.err.println(i); return i; } }",
 265.177 +                    Collections.singletonMap("{ $s1$; i = 3; $s2$; return i; }", Arrays.asList("{ System.err.println(i); System.err.println(i); i = 3; System.err.println(i); System.err.println(i); return i; }")),
 265.178 +                    Collections.<String>emptyList());
 265.179 +    }
 265.180 +
 265.181 +    public void testMultiStatementVariables2() throws Exception {
 265.182 +        performTest("package test; public class Test { public int test1(int i) { i = 3; return i; } }",
 265.183 +                    Collections.singletonMap("{ $s1$; i = 3; $s2$; return i; }", Arrays.asList("{ i = 3; return i; }")),
 265.184 +                    Collections.<String>emptyList());
 265.185 +    }
 265.186 +
 265.187 +    public void testMultiStatementVariablesAndBlocks1() throws Exception {
 265.188 +        performTest("package test; public class Test { public void test1() { if (true) System.err.println(); } }",
 265.189 +                    Collections.singletonMap("if ($c) {$s1$; System.err.println(); $s2$; }", Arrays.asList("if (true) System.err.println();")),
 265.190 +                    Collections.<String>emptyList());
 265.191 +    }
 265.192 +
 265.193 +    public void testMultiStatementVariablesAndBlocks2() throws Exception {
 265.194 +        performTest("package test; public class Test { public void test1() { if (true) System.err.println(); } }",
 265.195 +                    Collections.singletonMap("if ($c) {$s1$; System.err.println(); }", Arrays.asList("if (true) System.err.println();")),
 265.196 +                    Collections.<String>emptyList());
 265.197 +    }
 265.198 +
 265.199 +    public void testMultiStatementVariablesAndBlocks3() throws Exception {
 265.200 +        performTest("package test; public class Test { public void test1() { if (true) System.err.println(); } }",
 265.201 +                    Collections.singletonMap("if ($c) {System.err.println(); $s2$; }", Arrays.asList("if (true) System.err.println();")),
 265.202 +                    Collections.<String>emptyList());
 265.203 +    }
 265.204 +
 265.205 +    public void testMultiStatementVariablesAndBlocks4() throws Exception {
 265.206 +        performTest("package test; public class Test { public void test1() { if (true) System.err.println(); } }",
 265.207 +                    Collections.singletonMap("{ $s1$; System.err.println(); $s2$; }", Arrays.asList("System.err.println();")),
 265.208 +                    Collections.<String>emptyList());
 265.209 +    }
 265.210 +
 265.211 +    public void testTwoPatterns() throws Exception {
 265.212 +        Map<String, List<String>> contained = new HashMap<String, List<String>>();
 265.213 +
 265.214 +        contained.put("if ($a) $ret = $b; else $ret = $c;", Arrays.asList("if (b) q = 2; else q = 3;"));
 265.215 +        contained.put("{ $p$; $T $v; if($a) $v = $b; else $v = $c; $q$; }", Arrays.asList("{ int q; if (b) q = 2; else q = 3; }"));
 265.216 +
 265.217 +        performTest("package test; public class Test { public void test1(boolean b) { int q; if (b) q = 2; else q = 3; } }",
 265.218 +                    contained,
 265.219 +                    Collections.<String>emptyList());
 265.220 +    }
 265.221 +
 265.222 +    public void testEffectiveNewClass() throws Exception {
 265.223 +        performTest("package test; import javax.swing.ImageIcon; public class Test { public void test1(java.awt.Image i) { new ImageIcon(i); new String(i); } }",
 265.224 +                    Collections.singletonMap("new javax.swing.ImageIcon($1)", Arrays.asList("new ImageIcon(i)")),
 265.225 +                    Collections.<String>emptyList());
 265.226 +    }
 265.227 +
 265.228 +    public void testSynchronizedAndMultiStatementVariables() throws Exception {
 265.229 +        performTest("package test; public class Test {public void test() { Object o = null; int i = 0; synchronized (o) {} } }",
 265.230 +                    Collections.singletonMap("synchronized($var) {$stmts$;}", Arrays.asList("synchronized (o) {}")),
 265.231 +                    Collections.<String>emptyList());
 265.232 +    }
 265.233 +
 265.234 +    public void testJackpot30_2() throws Exception {
 265.235 +        String code = "package test;\n" +
 265.236 +                      "public class Test {\n" +
 265.237 +                      "    private void m() {\n" +
 265.238 +                      "        a(c.i().getFileObject());\n" +
 265.239 +                      "        if (span != null && span[0] != (-1) && span[1] != (-1));\n" +
 265.240 +                      "    }\n" +
 265.241 +                      "}\n";
 265.242 +
 265.243 +        performTest(code,
 265.244 +                    Collections.<String, List<String>>emptyMap(),
 265.245 +                    Arrays.asList("$0.getFileObject($1)"));
 265.246 +    }
 265.247 +
 265.248 +    public void testIdentifierInPureMemberSelect() throws Exception {
 265.249 +        String code = "package test;\n" +
 265.250 +                       "public class Test {\n" +
 265.251 +                       "     public Test test;\n" +
 265.252 +                       "     public String name;\n" +
 265.253 +                       "     private void test() {\n" +
 265.254 +                       "         Test t = null;\n" +
 265.255 +                       "         String s = t.test.name;\n" +
 265.256 +                       "     }\n" +
 265.257 +                       "}\n";
 265.258 +
 265.259 +        performTest(code,
 265.260 +                    Collections.singletonMap("$Test.test", Arrays.asList("test", "t.test")),
 265.261 +                    Collections.<String>emptyList());
 265.262 +    }
 265.263 +
 265.264 +    @RandomlyFails
 265.265 +    public void testNoExponentialTimeComplexity() throws Exception {
 265.266 +        try {
 265.267 +        String code = "package test;\n" +
 265.268 +                      "public class Test {\n" +
 265.269 +                      "    private void test() {\n" +
 265.270 +                      "        Object o;\n" +
 265.271 +                      "        if(o == null) {\n" +
 265.272 +                      "            f(\"\");\n" +
 265.273 +                      "        }|\n" +
 265.274 +                      "    }\n" +
 265.275 +                      "}";
 265.276 +        String pattern = "{ $p$; $T $v; if($a) $v = $b; else $v = $c; }";
 265.277 +
 265.278 +        measure(code, "\na(\"\");", 5, pattern); //to load needed classes, etc.
 265.279 +
 265.280 +        int rep = 1;
 265.281 +        long baseline;
 265.282 +
 265.283 +        while (true) {
 265.284 +            baseline = measure(code, "\na(\"\");", rep, pattern);
 265.285 +
 265.286 +            if (baseline >= 2000) {
 265.287 +                break;
 265.288 +            }
 265.289 +
 265.290 +            rep *= 2;
 265.291 +        }
 265.292 +
 265.293 +        long doubleSize = measure(code, "\na(\"\");", 2 * rep, pattern);
 265.294 +
 265.295 +        assertTrue("baseline=" + baseline + ", actual=" + String.valueOf(doubleSize), doubleSize <= 4 * baseline);
 265.296 +        } catch (OutOfMemoryError oome) {
 265.297 +            //OK
 265.298 +        }
 265.299 +    }
 265.300 +
 265.301 +    public void testMultiParameter1() throws Exception {
 265.302 +        performTest("package test; public class Test { { java.util.Arrays.asList(\"a\", \"b\", \"c\"); } }",
 265.303 +                    Collections.singletonMap("java.util.Arrays.asList($params$)", Arrays.asList("java.util.Arrays.asList(\"a\", \"b\", \"c\")")),
 265.304 +                    Collections.<String>emptyList());
 265.305 +    }
 265.306 +
 265.307 +    public void testMultiParameter2() throws Exception {
 265.308 +        performTest("package test; public class Test { { java.util.Arrays.asList(); } }",
 265.309 +                    Collections.singletonMap("java.util.Arrays.asList($params$)", Arrays.asList("java.util.Arrays.asList()")),
 265.310 +                    Collections.<String>emptyList());
 265.311 +    }
 265.312 +
 265.313 +    public void testTypeParameter() throws Exception {
 265.314 +        performTest("package test; public class Test { { java.util.Arrays.<String>asList(); } }",
 265.315 +                    Collections.singletonMap("java.util.Arrays.<$1>asList($params$)", Arrays.asList("java.util.Arrays.<String>asList()")),
 265.316 +                    Collections.<String>emptyList());
 265.317 +    }
 265.318 +
 265.319 +    public void testField1() throws Exception {
 265.320 +        String code = "package test;\n" +
 265.321 +                       "public class Test {\n" +
 265.322 +                       "     String name = null;\n" +
 265.323 +                       "}\n";
 265.324 +
 265.325 +        performTest(code,
 265.326 +                    Collections.singletonMap("$modifiers$ java.lang.String $name = $initializer;", Arrays.asList("String name = null;")),
 265.327 +                    Collections.<String>emptyList());
 265.328 +    }
 265.329 +
 265.330 +    public void testField2() throws Exception {
 265.331 +        String code = "package test;\n" +
 265.332 +                       "public class Test {\n" +
 265.333 +                       "     private String name = null;\n" +
 265.334 +                       "}\n";
 265.335 +
 265.336 +        performTest(code,
 265.337 +                    Collections.singletonMap("$modifiers$ java.lang.String $name = $initializer;", Arrays.asList("private String name = null;")),
 265.338 +                    Collections.<String>emptyList());
 265.339 +    }
 265.340 +
 265.341 +    public void testMemberSelectWithVariable() throws Exception {
 265.342 +        String code = "package test;\n" +
 265.343 +                      "import java.util.Arrays;\n" +
 265.344 +                      "public class Test {" +
 265.345 +                      "     {\n" +
 265.346 +                      "          foo.bar(0, 3, 4);\n" +
 265.347 +                      "     }\n" +
 265.348 +                      "}\n";
 265.349 +
 265.350 +        performTest(code,
 265.351 +                    Collections.singletonMap("$foo.$bar($p1, $p2$)", Arrays.asList("foo.bar(0, 3, 4)")),
 265.352 +                    Collections.<String>emptyList());
 265.353 +    }
 265.354 +
 265.355 +    public void testCheckIdentifiers1() throws Exception {
 265.356 +        String code = "package test;\n" +
 265.357 +                      "import static java.util.Arrays.*;\n" +
 265.358 +                      "public class Test {" +
 265.359 +                      "     {\n" +
 265.360 +                      "          toString(new int[] {0, 3, 4});\n" +
 265.361 +                      "     }\n" +
 265.362 +                      "}\n";
 265.363 +
 265.364 +        performTest(code,
 265.365 +                    Collections.singletonMap("java.util.Arrays.toString($x)", Arrays.asList("toString(new int[] {0, 3, 4})")),
 265.366 +                    Collections.<String>emptyList());
 265.367 +    }
 265.368 +
 265.369 +    public void testCheckIdentifiers2() throws Exception {
 265.370 +        String code = "package test;\n" +
 265.371 +                      "public class Test {" +
 265.372 +                      "     {\n" +
 265.373 +                      "          toString(new int[] {0, 3, 4});\n" +
 265.374 +                      "     }\n" +
 265.375 +                      "}\n";
 265.376 +
 265.377 +        performTest(code,
 265.378 +                    Collections.<String, List<String>>emptyMap(),
 265.379 +                    Collections.singletonList("java.util.Arrays.toString($x)"));
 265.380 +    }
 265.381 +
 265.382 +    public void testCheckIdentifiers3() throws Exception {
 265.383 +        String code = "package test;\n" +
 265.384 +                      "import static java.util.Arrays.*;\n" +
 265.385 +                      "public class Test {" +
 265.386 +                      "     {\n" +
 265.387 +                      "          Foo.toString(new int[] {0, 3, 4});\n" +
 265.388 +                      "     }\n" +
 265.389 +                      "}\n";
 265.390 +
 265.391 +        performTest(code,
 265.392 +                    Collections.<String, List<String>>emptyMap(),
 265.393 +                    Collections.singletonList("java.util.Arrays.toString($x)"));
 265.394 +    }
 265.395 +
 265.396 +    public void testCheckIdentifiers4() throws Exception {
 265.397 +        String code = "package test;\n" +
 265.398 +                      "public class Test {" +
 265.399 +                      "     {\n" +
 265.400 +                      "          java.util.Arrays.toString(new int[] {0, 3, 4});\n" +
 265.401 +                      "     }\n" +
 265.402 +                      "}\n";
 265.403 +
 265.404 +        performTest(code,
 265.405 +                    Collections.singletonMap("Arrays", Arrays.asList("java.util.Arrays")), //could be imported in the input pattern
 265.406 +                    Collections.<String>emptyList());
 265.407 +    }
 265.408 +
 265.409 +    public void testLambdaInput() throws Exception {
 265.410 +        String code = "package test; public class Test {public void test() { new java.io.FilenameFilter() { public boolean accept(java.io.File dir, String name) { return true; } }; } }";
 265.411 +
 265.412 +        performTest(code,
 265.413 +                    Collections.singletonMap("new $type() {public $retType $name($params$) { $body$; } }", Arrays.asList("new java.io.FilenameFilter() { public boolean accept(java.io.File dir, String name) { return true; } }")),
 265.414 +
 265.415 +                    Collections.<String>emptyList());
 265.416 +    }
 265.417 +
 265.418 +    public void testDoubleCheckedLockingWithVariable() throws Exception {
 265.419 +        String dcl =  "if (o == null) {\n" +
 265.420 +                      "              Object o1 = new Object();\n" +
 265.421 +                      "              synchronized (Test.class) {\n" +
 265.422 +                      "                  if (o == null) {\n" +
 265.423 +                      "                      o = o1;\n" +
 265.424 +                      "                  }\n" +
 265.425 +                      "              }\n" +
 265.426 +                      "          }";
 265.427 +        String code = "package test;\n" +
 265.428 +                      "public class Test {\n" +
 265.429 +                      "     private Object o;\n" +
 265.430 +                      "     private void t() {\n" +
 265.431 +                      "          " + dcl + "\n" +
 265.432 +                      "     }\n" +
 265.433 +                      "}\n";
 265.434 +
 265.435 +        performTest(code,
 265.436 +                    Collections.singletonMap("if ($var == null) {$pref$; synchronized ($lock) { if ($var == null) { $init$; } } }", Arrays.asList(dcl)),
 265.437 +                    Collections.<String>emptyList());
 265.438 +    }
 265.439 +
 265.440 +    public void testMethodName1() throws Exception {
 265.441 +        String code = "package test; public class Test {public void test() { clone(); } }";
 265.442 +
 265.443 +        performTest(code,
 265.444 +                    Collections.<String, List<String>>emptyMap(),
 265.445 +                    Collections.<String>singletonList("public void clone() {$stmts$;}"));
 265.446 +    }
 265.447 +
 265.448 +    public void testMethodName2() throws Exception {
 265.449 +        String code = "package test; public class Test {public void test() { clone(); } }";
 265.450 +
 265.451 +        performTest(code,
 265.452 +                    Collections.singletonMap("public void test() {$stmts$;}", Arrays.asList("public void test() { clone(); }")),
 265.453 +                    Collections.<String>emptyList());
 265.454 +    }
 265.455 +    
 265.456 +    public void testBooleanLiterals() throws Exception {
 265.457 +        String code = "package test; public class Test { public void test() { if (false) { System.err.println(\"false\"); } if (true) { System.err.println(\"true\"); } } }";
 265.458 +
 265.459 +        performTest(code,
 265.460 +                    Collections.singletonMap("if (true) $then; else $else$;", Arrays.asList("if (true) { System.err.println(\"true\"); }")),
 265.461 +                    Collections.<String>emptyList());
 265.462 +    }
 265.463 +    
 265.464 +    public void testEfficientMultiMatching() throws Exception {
 265.465 +        String code = "package test; public class Test { private void m() {} }";
 265.466 +
 265.467 +        performTest(code,
 265.468 +                    Collections.<String, List<String>>emptyMap(),
 265.469 +                    Collections.singletonList("$mods$ class $name implements $i$ { }"));
 265.470 +    }
 265.471 +
 265.472 +    private long measure(String baseCode, String toInsert, int repetitions, String pattern) throws Exception {
 265.473 +        int pos = baseCode.indexOf('|');
 265.474 +
 265.475 +        assertTrue(pos != (-1));
 265.476 +
 265.477 +        baseCode = baseCode.replaceAll(Pattern.quote("|"), "");
 265.478 +        
 265.479 +        StringBuilder code = new StringBuilder(baseCode.length() + repetitions * toInsert.length());
 265.480 +
 265.481 +        code.append(baseCode);
 265.482 +        
 265.483 +        while (repetitions-- > 0) {
 265.484 +            code.insert(pos, toInsert);
 265.485 +        }
 265.486 +
 265.487 +        long startTime = System.currentTimeMillis();
 265.488 +
 265.489 +        performTest(code.toString(),
 265.490 +                    Collections.<String, List<String>>emptyMap(),
 265.491 +                    Arrays.asList(pattern));
 265.492 +
 265.493 +        long endTime = System.currentTimeMillis();
 265.494 +
 265.495 +        return endTime - startTime;
 265.496 +    }
 265.497 +
 265.498 +    public void XtestMeasureTime() throws Exception {
 265.499 +        String code = TestUtilities.copyFileToString(new File("/usr/local/home/lahvac/src/nb//outgoing/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionProvider.java"));
 265.500 +        List<String> patterns = new LinkedList<String>();
 265.501 +
 265.502 +        for (int cntr = 0; cntr < 1000; cntr++) {
 265.503 +            patterns.add("System.err.println($1)");
 265.504 +        }
 265.505 +
 265.506 +        performTest(code,
 265.507 +                    Collections.<String, List<String>>emptyMap(),
 265.508 +                    patterns);
 265.509 +    }
 265.510 +
 265.511 +    public void testMatches1() throws Exception {
 265.512 +        performMatchesTest("package test; public class Test { private void test() { f.isDirectory(); } }", Arrays.asList("$1.isDirectory()", "new ImageIcon($1)"), true);
 265.513 +    }
 265.514 +
 265.515 +    public void testSerialization() throws Exception {
 265.516 +        String text = "package test; public class Test { public void test1(boolean b) { int q; if (b) q = 2; else q = 3; } }";
 265.517 +
 265.518 +        prepareTest("test/Test.java", text);
 265.519 +
 265.520 +        ByteArrayOutputStream out = new ByteArrayOutputStream();
 265.521 +        EncodingContext ec = new EncodingContext(out, false);
 265.522 +
 265.523 +        createSearch().encode(info.getCompilationUnit(), ec, new AtomicBoolean());
 265.524 +        
 265.525 +        boolean matches = createSearch().matches(new ByteArrayInputStream(out.toByteArray()), new AtomicBoolean(), createSearch().create(info, new AtomicBoolean(), "{ $p$; $T $v; if($a) $v = $b; else $v = $c; $q$; }"));
 265.526 +
 265.527 +        assertTrue(matches);
 265.528 +    }
 265.529 +
 265.530 +    public void testFrequencies() throws Exception {
 265.531 +        String text = "package test; public class Test { public void test1(boolean b) { java.io.File f = null; f.isDirectory(); f.isDirectory(); new javax.swing.ImageIcon(null); } }";
 265.532 +
 265.533 +        prepareTest("test/Test.java", text);
 265.534 +
 265.535 +        ByteArrayOutputStream out = new ByteArrayOutputStream();
 265.536 +        EncodingContext ec = new EncodingContext(out, false);
 265.537 +
 265.538 +        createSearch().encode(info.getCompilationUnit(), ec, new AtomicBoolean());
 265.539 +        
 265.540 +        Map<String, Integer> actual = createSearch().matchesWithFrequencies(new ByteArrayInputStream(out.toByteArray()), createSearch().create(info, new AtomicBoolean(), "$1.isDirectory()", "new ImageIcon($1)"), new AtomicBoolean());
 265.541 +        Map<String, Integer> golden = new HashMap<String, Integer>();
 265.542 +
 265.543 +        golden.put("$1.isDirectory()", 2);
 265.544 +        golden.put("new ImageIcon($1)", 1);
 265.545 +
 265.546 +        assertEquals(golden, actual);
 265.547 +    }
 265.548 +
 265.549 +    public void testPatternEncodingAndIdentifiers() throws Exception {
 265.550 +        String text = "package test; public class Test { }";
 265.551 +
 265.552 +        prepareTest("test/Test.java", text);
 265.553 +
 265.554 +        BulkPattern bp = createSearch().create(info, new AtomicBoolean(), "$0.isDirectory()");
 265.555 +
 265.556 +        assertEquals(Arrays.asList(new HashSet<String>(Arrays.asList("isDirectory"))), bp.getIdentifiers());
 265.557 +        //TODO: the actual code for kinds differs for NFABased search and REBased search:
 265.558 +//        assertEquals(Arrays.asList(new HashSet<String>(Arrays.asList(Kind.METHOD_INVOCATION.name()))), bp.getKinds());
 265.559 +    }
 265.560 +    
 265.561 +    public void testModifiersMultiVariable() throws Exception {
 265.562 +        String code = "package test;\n" +
 265.563 +                       "public class Test {\n" +
 265.564 +                       "     @Deprecated @Override public Test test;\n" +
 265.565 +                       "}\n";
 265.566 +
 265.567 +        performTest(code,
 265.568 +                    Collections.singletonMap("$mods$ @Deprecated public $type $name = $init$;", Arrays.asList("@Deprecated @Override public Test test;")),
 265.569 +                    Collections.<String>emptyList());
 265.570 +    }
 265.571 +
 265.572 +    protected abstract BulkSearch createSearch();
 265.573 +    
 265.574 +    private void performMatchesTest(String text, List<String> patterns, boolean golden) throws Exception {
 265.575 +        prepareTest("test/Test.java", text);
 265.576 +
 265.577 +        BulkPattern p = createSearch().create(info, new AtomicBoolean(), patterns);
 265.578 +
 265.579 +        boolean result = createSearch().matches(info, new AtomicBoolean(), new TreePath(info.getCompilationUnit()), p);
 265.580 +
 265.581 +        assertEquals(golden, result);
 265.582 +    }
 265.583 +    
 265.584 +    private void performTest(String text, Map<String, List<String>> containedPatterns, Collection<String> notContainedPatterns) throws Exception {
 265.585 +        prepareTest("test/Test.java", text);
 265.586 +
 265.587 +        List<String> patterns = new LinkedList<String>();
 265.588 +
 265.589 +        patterns.addAll(containedPatterns.keySet());
 265.590 +        patterns.addAll(notContainedPatterns);
 265.591 +
 265.592 +        long s1 = System.currentTimeMillis();
 265.593 +        BulkPattern p = createSearch().create(info, new AtomicBoolean(), patterns);
 265.594 +        long e1 = System.currentTimeMillis();
 265.595 +
 265.596 +//        System.err.println("create: " + (e1 - s1));
 265.597 +
 265.598 +        long s2 = System.currentTimeMillis();
 265.599 +        Map<String, Collection<TreePath>> result = createSearch().match(info, new AtomicBoolean(), new TreePath(info.getCompilationUnit()), p);
 265.600 +        long e2 = System.currentTimeMillis();
 265.601 +
 265.602 +//        System.err.println("match: " + (e2 - s2));
 265.603 +
 265.604 +        assertTrue(result.toString(), result.keySet().containsAll(containedPatterns.keySet()));
 265.605 +
 265.606 +        for (Entry<String, Collection<TreePath>> e : result.entrySet()) {
 265.607 +            List<String> actual = new LinkedList<String>();
 265.608 +
 265.609 +            for (TreePath tp : e.getValue()) {
 265.610 +                assertNotNull(TreePathHandle.create(tp, info).resolve(info));
 265.611 +                
 265.612 +                int start = (int) info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), tp.getLeaf());
 265.613 +                int end   = (int) info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), tp.getLeaf());
 265.614 +
 265.615 +                actual.add(info.getText().substring(start, end));
 265.616 +            }
 265.617 +
 265.618 +            assertEquals(e.getKey(), containedPatterns.get(e.getKey()), actual);
 265.619 +        }
 265.620 +
 265.621 +
 265.622 +        Set<String> none = new HashSet<String>(result.keySet());
 265.623 +
 265.624 +        none.retainAll(notContainedPatterns);
 265.625 +
 265.626 +        assertTrue(none.isEmpty());
 265.627 +
 265.628 +        if (!verifyIndexingData())
 265.629 +            return ;
 265.630 +        
 265.631 +        //ensure the returned identifiers/treeKinds are correct:
 265.632 +        ByteArrayOutputStream data = new ByteArrayOutputStream();
 265.633 +        EncodingContext ec = new EncodingContext(data, false);
 265.634 +        
 265.635 +        createSearch().encode(info.getCompilationUnit(), ec, new AtomicBoolean());
 265.636 +
 265.637 +        for (int i = 0; i < containedPatterns.size(); i++) {
 265.638 +            assertTrue("expected: " + p.getIdentifiers().get(i) + ", but exist only: " + ec.getIdentifiers(), ec.getIdentifiers().containsAll(p.getIdentifiers().get(i)));
 265.639 +            
 265.640 +            for (List<String> phrase : p.getRequiredContent().get(i)) {
 265.641 +                assertTrue("expected: " + phrase + ", but exist only: " + ec.getContent() + "(all phrases: " + p.getRequiredContent().get(i) + ")", Collections.indexOfSubList(ec.getContent(), phrase) != (-1));
 265.642 +            }
 265.643 +        }
 265.644 +
 265.645 +        data.close();
 265.646 +        assertEquals(!containedPatterns.isEmpty(), createSearch().matches(new ByteArrayInputStream(data.toByteArray()), new AtomicBoolean(), p));
 265.647 +    }
 265.648 +    
 265.649 +    private void prepareTest(String fileName, String code) throws Exception {
 265.650 +        clearWorkDir();
 265.651 +
 265.652 +        FileUtil.refreshFor(File.listRoots());
 265.653 +
 265.654 +        FileObject workFO = FileUtil.toFileObject(getWorkDir());
 265.655 +
 265.656 +        assertNotNull(workFO);
 265.657 +
 265.658 +        workFO.refresh();
 265.659 +
 265.660 +        sourceRoot = workFO.createFolder("src");
 265.661 +        FileObject buildRoot  = workFO.createFolder("build");
 265.662 +        FileObject cache = workFO.createFolder("cache");
 265.663 +
 265.664 +        FileObject data = FileUtil.createData(sourceRoot, fileName);
 265.665 +        File dataFile = FileUtil.toFile(data);
 265.666 +
 265.667 +        assertNotNull(dataFile);
 265.668 +
 265.669 +        TestUtilities.copyStringToFile(dataFile, code);
 265.670 +
 265.671 +        SourceUtilsTestUtil.prepareTest(sourceRoot, buildRoot, cache);
 265.672 +
 265.673 +        DataObject od = DataObject.find(data);
 265.674 +        EditorCookie ec = od.getLookup().lookup(EditorCookie.class);
 265.675 +
 265.676 +        assertNotNull(ec);
 265.677 +
 265.678 +        doc = ec.openDocument();
 265.679 +        doc.putProperty(Language.class, JavaTokenId.language());
 265.680 +
 265.681 +        JavaSource js = JavaSource.forFileObject(data);
 265.682 +
 265.683 +        assertNotNull(js);
 265.684 +
 265.685 +        info = SourceUtilsTestUtil.getCompilationInfo(js, Phase.RESOLVED);
 265.686 +
 265.687 +        assertNotNull(info);
 265.688 +    }
 265.689 +
 265.690 +    private FileObject sourceRoot;
 265.691 +    private CompilationInfo info;
 265.692 +    private Document doc;
 265.693 +
 265.694 +    protected boolean verifyIndexingData() {
 265.695 +        return true;
 265.696 +    }
 265.697 +}
   266.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   266.2 +++ b/sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/pm/CopyFinderBasedBulkSearchTest.java	Sun Oct 23 11:50:54 2016 +0200
   266.3 @@ -0,0 +1,99 @@
   266.4 +/*
   266.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   266.6 + *
   266.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
   266.8 + *
   266.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  266.10 + * Other names may be trademarks of their respective owners.
  266.11 + *
  266.12 + * The contents of this file are subject to the terms of either the GNU
  266.13 + * General Public License Version 2 only ("GPL") or the Common
  266.14 + * Development and Distribution License("CDDL") (collectively, the
  266.15 + * "License"). You may not use this file except in compliance with the
  266.16 + * License. You can obtain a copy of the License at
  266.17 + * http://www.netbeans.org/cddl-gplv2.html
  266.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  266.19 + * specific language governing permissions and limitations under the
  266.20 + * License.  When distributing the software, include this License Header
  266.21 + * Notice in each file and include the License file at
  266.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  266.23 + * particular file as subject to the "Classpath" exception as provided
  266.24 + * by Oracle in the GPL Version 2 section of the License file that
  266.25 + * accompanied this code. If applicable, add the following below the
  266.26 + * License Header, with the fields enclosed by brackets [] replaced by
  266.27 + * your own identifying information:
  266.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  266.29 + *
  266.30 + * If you wish your version of this file to be governed by only the CDDL
  266.31 + * or only the GPL Version 2, indicate your decision by adding
  266.32 + * "[Contributor] elects to include this software in this distribution
  266.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  266.34 + * single choice of license, a recipient has the option to distribute
  266.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  266.36 + * to extend the choice of license to its licensees as provided above.
  266.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  266.38 + * Version 2 license, then the option applies only if the new code is
  266.39 + * made subject to such option by the copyright holder.
  266.40 + *
  266.41 + * Contributor(s):
  266.42 + *
  266.43 + * Portions Copyrighted 2009 Sun Microsystems, Inc.
  266.44 + */
  266.45 +
  266.46 +package org.netbeans.modules.java.hints.spiimpl.pm;
  266.47 +
  266.48 +/**
  266.49 + *
  266.50 + * @author lahvac
  266.51 + */
  266.52 +public class CopyFinderBasedBulkSearchTest extends BulkSearchTestPerformer {
  266.53 +
  266.54 +    public CopyFinderBasedBulkSearchTest(String name) {
  266.55 +        super(name);
  266.56 +    }
  266.57 +
  266.58 +    @Override
  266.59 +    protected BulkSearch createSearch() {
  266.60 +        return new CopyFinderBasedBulkSearch();
  266.61 +    }
  266.62 +
  266.63 +    @Override
  266.64 +    protected boolean verifyIndexingData() {
  266.65 +        return false;
  266.66 +    }
  266.67 +
  266.68 +    @Override
  266.69 +    public void testSerialization() throws Exception {
  266.70 +        //XXX
  266.71 +    }
  266.72 +
  266.73 +    @Override
  266.74 +    public void testFrequencies() throws Exception {
  266.75 +        //XXX: serialization is a prerequisite
  266.76 +    }
  266.77 +
  266.78 +    @Override
  266.79 +    public void testPatternEncodingAndIdentifiers() throws Exception {
  266.80 +        //XXX
  266.81 +    }
  266.82 +
  266.83 +    @Override
  266.84 +    public void testNoExponentialTimeComplexity() throws Exception {
  266.85 +        //XXX
  266.86 +    }
  266.87 +
  266.88 +    @Override
  266.89 +    public void testCheckIdentifiers2() throws Exception {
  266.90 +        //not critical, only improves performance on vast amounts of sources,
  266.91 +        //and NFA based search is used in such case anyway.
  266.92 +        //XXX
  266.93 +    }
  266.94 +
  266.95 +    @Override
  266.96 +    public void testCheckIdentifiers3() throws Exception {
  266.97 +        //not critical, only improves performance on vast amounts of sources,
  266.98 +        //and NFA based search is used in such case anyway.
  266.99 +        //XXX
 266.100 +    }
 266.101 +
 266.102 +}
 266.103 \ No newline at end of file
   267.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   267.2 +++ b/sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/pm/NFABasedBulkSearchTest.java	Sun Oct 23 11:50:54 2016 +0200
   267.3 @@ -0,0 +1,69 @@
   267.4 +/*
   267.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   267.6 + *
   267.7 + * Copyright 2009-2010 Oracle and/or its affiliates. All rights reserved.
   267.8 + *
   267.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  267.10 + * Other names may be trademarks of their respective owners.
  267.11 + *
  267.12 + * The contents of this file are subject to the terms of either the GNU
  267.13 + * General Public License Version 2 only ("GPL") or the Common
  267.14 + * Development and Distribution License("CDDL") (collectively, the
  267.15 + * "License"). You may not use this file except in compliance with the
  267.16 + * License. You can obtain a copy of the License at
  267.17 + * http://www.netbeans.org/cddl-gplv2.html
  267.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  267.19 + * specific language governing permissions and limitations under the
  267.20 + * License.  When distributing the software, include this License Header
  267.21 + * Notice in each file and include the License file at
  267.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  267.23 + * particular file as subject to the "Classpath" exception as provided
  267.24 + * by Oracle in the GPL Version 2 section of the License file that
  267.25 + * accompanied this code. If applicable, add the following below the
  267.26 + * License Header, with the fields enclosed by brackets [] replaced by
  267.27 + * your own identifying information:
  267.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  267.29 + *
  267.30 + * If you wish your version of this file to be governed by only the CDDL
  267.31 + * or only the GPL Version 2, indicate your decision by adding
  267.32 + * "[Contributor] elects to include this software in this distribution
  267.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  267.34 + * single choice of license, a recipient has the option to distribute
  267.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  267.36 + * to extend the choice of license to its licensees as provided above.
  267.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  267.38 + * Version 2 license, then the option applies only if the new code is
  267.39 + * made subject to such option by the copyright holder.
  267.40 + *
  267.41 + * Contributor(s):
  267.42 + *
  267.43 + * Portions Copyrighted 2009-2010 Sun Microsystems, Inc.
  267.44 + */
  267.45 +
  267.46 +package org.netbeans.modules.java.hints.spiimpl.pm;
  267.47 +
  267.48 +/**
  267.49 + *
  267.50 + * @author lahvac
  267.51 + */
  267.52 +public class NFABasedBulkSearchTest extends BulkSearchTestPerformer {
  267.53 +
  267.54 +    public NFABasedBulkSearchTest(String name) {
  267.55 +        super(name);
  267.56 +    }
  267.57 +
  267.58 +//    public static TestSuite suite() {
  267.59 +//        NbTestSuite r = new NbTestSuite();
  267.60 +//
  267.61 +//        r.addTest(new NFABasedBulkSearchTest("testField1"));
  267.62 +//        r.addTest(new NFABasedBulkSearchTest("testField2"));
  267.63 +//
  267.64 +//        return r;
  267.65 +//    }
  267.66 +
  267.67 +    @Override
  267.68 +    protected BulkSearch createSearch() {
  267.69 +        return new NFABasedBulkSearch();
  267.70 +    }
  267.71 +
  267.72 +}
   268.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   268.2 +++ b/sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/pm/PatternCompilerTest.java	Sun Oct 23 11:50:54 2016 +0200
   268.3 @@ -0,0 +1,203 @@
   268.4 +/*
   268.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   268.6 + *
   268.7 + * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
   268.8 + *
   268.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  268.10 + * Other names may be trademarks of their respective owners.
  268.11 + *
  268.12 + * The contents of this file are subject to the terms of either the GNU
  268.13 + * General Public License Version 2 only ("GPL") or the Common
  268.14 + * Development and Distribution License("CDDL") (collectively, the
  268.15 + * "License"). You may not use this file except in compliance with the
  268.16 + * License. You can obtain a copy of the License at
  268.17 + * http://www.netbeans.org/cddl-gplv2.html
  268.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  268.19 + * specific language governing permissions and limitations under the
  268.20 + * License.  When distributing the software, include this License Header
  268.21 + * Notice in each file and include the License file at
  268.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  268.23 + * particular file as subject to the "Classpath" exception as provided
  268.24 + * by Oracle in the GPL Version 2 section of the License file that
  268.25 + * accompanied this code. If applicable, add the following below the
  268.26 + * License Header, with the fields enclosed by brackets [] replaced by
  268.27 + * your own identifying information:
  268.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  268.29 + *
  268.30 + * If you wish your version of this file to be governed by only the CDDL
  268.31 + * or only the GPL Version 2, indicate your decision by adding
  268.32 + * "[Contributor] elects to include this software in this distribution
  268.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  268.34 + * single choice of license, a recipient has the option to distribute
  268.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  268.36 + * to extend the choice of license to its licensees as provided above.
  268.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  268.38 + * Version 2 license, then the option applies only if the new code is
  268.39 + * made subject to such option by the copyright holder.
  268.40 + *
  268.41 + * Contributor(s):
  268.42 + *
  268.43 + * Portions Copyrighted 2008-2009 Sun Microsystems, Inc.
  268.44 + */
  268.45 +
  268.46 +package org.netbeans.modules.java.hints.spiimpl.pm;
  268.47 +
  268.48 +import com.sun.source.tree.Tree;
  268.49 +import com.sun.source.util.SourcePositions;
  268.50 +import com.sun.source.util.TreePath;
  268.51 +import java.util.Arrays;
  268.52 +import java.util.HashMap;
  268.53 +import java.util.Iterator;
  268.54 +import java.util.Map;
  268.55 +import java.util.Map.Entry;
  268.56 +import java.util.concurrent.atomic.AtomicBoolean;
  268.57 +import org.netbeans.modules.java.hints.spiimpl.TestBase;
  268.58 +import org.netbeans.api.java.source.matching.Matcher;
  268.59 +import org.netbeans.api.java.source.matching.Occurrence;
  268.60 +import org.openide.util.Pair;
  268.61 +
  268.62 +/**
  268.63 + *
  268.64 + * @author Jan Lahoda
  268.65 + */
  268.66 +public class PatternCompilerTest extends TestBase {
  268.67 +
  268.68 +    public PatternCompilerTest(String name) {
  268.69 +        super(name);
  268.70 +    }
  268.71 +
  268.72 +    public void testSimple1() throws Exception {
  268.73 +        performVariablesTest("package test; public class Test {public void test() {int i = |1 + 2|;}}", "$1+$2",
  268.74 +                             Pair.<String, String>of("$1", "1"),
  268.75 +                             Pair.<String, String>of("$2", "2"));
  268.76 +    }
  268.77 +
  268.78 +    public void testTyped1() throws Exception {
  268.79 +        performVariablesTest("package test; public class Test {public void test() {|String.valueOf(\"t\")|;}}", "String.valueOf($1{String})",
  268.80 +                             Pair.<String, String>of("$1", "\"t\""));
  268.81 +    }
  268.82 +
  268.83 +//    public void testTyped2() throws Exception {
  268.84 +//        performVariablesTest("package test; public class Test {public void test() {|String.valueOf(\"t\")|;}}", "$2{java.lang.String}.valueOf($1{String})",
  268.85 +//                             new Pair<String, String>("$1", "\"t\""),
  268.86 +//                             new Pair<String, String>("$2", "String"));
  268.87 +//    }
  268.88 +
  268.89 +    public void testTyped3() throws Exception {
  268.90 +        performVariablesTest("package test; public class Test {public void test(String str) {|str.valueOf(\"t\")|;}}", "String.valueOf($1{String})",
  268.91 +                             Pair.<String, String>of("$1", "\"t\""));
  268.92 +    }
  268.93 +
  268.94 +    public void testTyped4() throws Exception {
  268.95 +        performVariablesTest("package test; public class Test {public void test() {|Integer.bitCount(1)|;}}", "$2{java.lang.String}.valueOf($1{String})",
  268.96 +                             (Pair[]) null);
  268.97 +    }
  268.98 +
  268.99 +    public void testTyped5() throws Exception {
 268.100 +        performVariablesTest("package test; public class Test {public void test() {java.io.File f = null; |f.toURI().toURL()|;}}", "$1{java.io.File}.toURL()",
 268.101 +                             (Pair[]) null);
 268.102 +    }
 268.103 +
 268.104 +    public void testTypedPrimitiveType() throws Exception {
 268.105 +        performVariablesTest("package test; public class Test {public void test(int i) {|test(1)|;}}", "$0{test.Test}.test($1{int})",
 268.106 +                             Pair.<String, String>of("$1", "1"));
 268.107 +    }
 268.108 +
 268.109 +    public void testMemberSelectVSIdentifier() throws Exception {
 268.110 +        performVariablesTest("package test; public class Test {void test1() {} void test2() {|test1()|;}}", "$1{test.Test}.test1()",
 268.111 +                             new Pair[0]);
 268.112 +    }
 268.113 +
 268.114 +    public void testSubClass() throws Exception {
 268.115 +        performVariablesTest("package test; public class Test {void test() {String s = null; |s.toString()|;}}", "$1{java.lang.CharSequence}.toString()",
 268.116 +                             Pair.<String, String>of("$1", "s"));
 268.117 +    }
 268.118 +
 268.119 +    public void testEquality1() throws Exception {
 268.120 +        performVariablesTest("package test; public class Test {void test() {|test()|;}}", "$1{test.Test}.test()",
 268.121 +                             new Pair[0]);
 268.122 +    }
 268.123 +
 268.124 +    public void testEquality2() throws Exception {
 268.125 +        performVariablesTest("package test; public class Test {void test() {String s = null; |String.valueOf(1).charAt(0)|;}}", "$1{java.lang.String}.charAt(0)",
 268.126 +                             Pair.<String, String>of("$1", "String.valueOf(1)"));
 268.127 +    }
 268.128 +
 268.129 +    public void testEquality3() throws Exception {
 268.130 +        performVariablesTest("package test; public class Test {void test() {String s = null; |s.charAt(0)|;}}", "java.lang.String.valueOf(1).charAt(0)",
 268.131 +                             (Pair[]) null);
 268.132 +    }
 268.133 +
 268.134 +    public void testType1() throws Exception {
 268.135 +        performVariablesTest("package test; public class Test {void test() {|String| s;}}", "java.lang.String",
 268.136 +                             new Pair[0]);
 268.137 +    }
 268.138 +
 268.139 +    public void testStatements1() throws Exception {
 268.140 +        performVariablesTest("package test; public class Test {void test() {|assert true : \"\";|}}", "assert $1{boolean} : $2{java.lang.Object};",
 268.141 +                             new Pair[0]);
 268.142 +    }
 268.143 +
 268.144 +    protected void performVariablesTest(String code, String pattern, Pair<String, String>... duplicates) throws Exception {
 268.145 +        String[] split = code.split("\\|");
 268.146 +
 268.147 +        assertEquals(Arrays.toString(split), 3, split.length);
 268.148 +
 268.149 +        int      start = split[0].length();
 268.150 +        int      end   = start + split[1].length();
 268.151 +
 268.152 +        code = split[0] + split[1] + split[2];
 268.153 +
 268.154 +        prepareTest("test/Test.java", code);
 268.155 +
 268.156 +        TreePath tp = info.getTreeUtilities().pathFor((start + end) / 2);
 268.157 +
 268.158 +        while (tp != null) {
 268.159 +            Tree t = tp.getLeaf();
 268.160 +            SourcePositions sp = info.getTrees().getSourcePositions();
 268.161 +
 268.162 +            if (   start == sp.getStartPosition(info.getCompilationUnit(), t)
 268.163 +                && end   == sp.getEndPosition(info.getCompilationUnit(), t)) {
 268.164 +                break;
 268.165 +            }
 268.166 +
 268.167 +            tp = tp.getParentPath();
 268.168 +        }
 268.169 +
 268.170 +        assertNotNull(tp);
 268.171 +
 268.172 +        //XXX:
 268.173 +        Iterator<? extends Occurrence> vars = Matcher.create(info).setCancel(new AtomicBoolean()).setSearchRoot(tp).setTreeTopSearch().match(PatternCompilerUtilities.compile(info, pattern)).iterator();
 268.174 +
 268.175 +        if (duplicates == null) {
 268.176 +            assertFalse(vars.hasNext());
 268.177 +            return ;
 268.178 +        }
 268.179 +
 268.180 +        assertNotNull(vars);
 268.181 +        assertTrue(vars.hasNext());
 268.182 +
 268.183 +        Map<String, String> actual = new HashMap<String, String>();
 268.184 +
 268.185 +        for (Entry<String, TreePath> e : vars.next().getVariables().entrySet()) {
 268.186 +            int[] span = new int[] {
 268.187 +                (int) info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), e.getValue().getLeaf()),
 268.188 +                (int) info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), e.getValue().getLeaf())
 268.189 +            };
 268.190 +
 268.191 +            actual.put(e.getKey(), info.getText().substring(span[0], span[1]));
 268.192 +        }
 268.193 +
 268.194 +        assertFalse(vars.hasNext());
 268.195 +
 268.196 +        for (Pair<String, String> dup : duplicates) {
 268.197 +            String span = actual.remove(dup.first());
 268.198 +
 268.199 +            if (span == null) {
 268.200 +                fail(dup.first());
 268.201 +            }
 268.202 +            assertEquals(dup.first()+ ":" + span, span, dup.second());
 268.203 +        }
 268.204 +    }
 268.205 +
 268.206 +}
   269.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   269.2 +++ b/sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/pm/PatternCompilerUtilities.java	Sun Oct 23 11:50:54 2016 +0200
   269.3 @@ -0,0 +1,88 @@
   269.4 +/*
   269.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   269.6 + *
   269.7 + * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
   269.8 + *
   269.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  269.10 + * Other names may be trademarks of their respective owners.
  269.11 + *
  269.12 + * The contents of this file are subject to the terms of either the GNU
  269.13 + * General Public License Version 2 only ("GPL") or the Common
  269.14 + * Development and Distribution License("CDDL") (collectively, the
  269.15 + * "License"). You may not use this file except in compliance with the
  269.16 + * License. You can obtain a copy of the License at
  269.17 + * http://www.netbeans.org/cddl-gplv2.html
  269.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  269.19 + * specific language governing permissions and limitations under the
  269.20 + * License.  When distributing the software, include this License Header
  269.21 + * Notice in each file and include the License file at
  269.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  269.23 + * particular file as subject to the "Classpath" exception as provided
  269.24 + * by Oracle in the GPL Version 2 section of the License file that
  269.25 + * accompanied this code. If applicable, add the following below the
  269.26 + * License Header, with the fields enclosed by brackets [] replaced by
  269.27 + * your own identifying information:
  269.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  269.29 + *
  269.30 + * If you wish your version of this file to be governed by only the CDDL
  269.31 + * or only the GPL Version 2, indicate your decision by adding
  269.32 + * "[Contributor] elects to include this software in this distribution
  269.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  269.34 + * single choice of license, a recipient has the option to distribute
  269.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  269.36 + * to extend the choice of license to its licensees as provided above.
  269.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  269.38 + * Version 2 license, then the option applies only if the new code is
  269.39 + * made subject to such option by the copyright holder.
  269.40 + *
  269.41 + * Contributor(s):
  269.42 + *
  269.43 + * Portions Copyrighted 2011 Sun Microsystems, Inc.
  269.44 + */
  269.45 +package org.netbeans.modules.java.hints.spiimpl.pm;
  269.46 +
  269.47 +import java.util.Collections;
  269.48 +import java.util.HashMap;
  269.49 +import java.util.Map;
  269.50 +import java.util.regex.Matcher;
  269.51 +import javax.lang.model.type.TypeMirror;
  269.52 +import org.netbeans.api.java.source.CompilationInfo;
  269.53 +import org.netbeans.modules.java.hints.spiimpl.pm.PatternCompiler;
  269.54 +import org.netbeans.api.java.source.matching.Pattern;
  269.55 +import org.netbeans.modules.java.hints.spiimpl.Hacks;
  269.56 +
  269.57 +/**
  269.58 + *
  269.59 + * @author lahvac
  269.60 + */
  269.61 +public class PatternCompilerUtilities {
  269.62 +
  269.63 +    public static Pattern compile(CompilationInfo info, String pattern) {
  269.64 +        Map<String, TypeMirror> constraints = new HashMap<String, TypeMirror>();
  269.65 +        pattern = parseOutTypesFromPattern(info, pattern, constraints);
  269.66 +
  269.67 +        return PatternCompiler.compile(info, pattern, constraints, Collections.<String>emptyList());
  269.68 +    }
  269.69 +
  269.70 +    public static String parseOutTypesFromPattern(CompilationInfo info, String pattern, Map<String, TypeMirror> variablesToTypes) {
  269.71 +        java.util.regex.Pattern p = java.util.regex.Pattern.compile("(\\$[0-9])(\\{([^}]*)\\})?");
  269.72 +        StringBuilder filtered = new StringBuilder();
  269.73 +        Matcher m = p.matcher(pattern);
  269.74 +        int i = 0;
  269.75 +
  269.76 +        while (m.find()) {
  269.77 +            filtered.append(pattern.substring(i, m.start()));
  269.78 +            i = m.end();
  269.79 +
  269.80 +            String var  = m.group(1);
  269.81 +            String type = m.group(3);
  269.82 +
  269.83 +            filtered.append(var);
  269.84 +            variablesToTypes.put(var, type != null ? Hacks.parseFQNType(info, type) : null);
  269.85 +        }
  269.86 +
  269.87 +        filtered.append(pattern.substring(i));
  269.88 +
  269.89 +        return filtered.toString();
  269.90 +    }
  269.91 +}
   270.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   270.2 +++ b/sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/modules/java/hints/spiimpl/processor/JavaHintsAnnotationProcessorTest.java	Sun Oct 23 11:50:54 2016 +0200
   270.3 @@ -0,0 +1,149 @@
   270.4 +/*
   270.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   270.6 + *
   270.7 + * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
   270.8 + *
   270.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  270.10 + * Other names may be trademarks of their respective owners.
  270.11 + *
  270.12 + * The contents of this file are subject to the terms of either the GNU
  270.13 + * General Public License Version 2 only ("GPL") or the Common
  270.14 + * Development and Distribution License("CDDL") (collectively, the
  270.15 + * "License"). You may not use this file except in compliance with the
  270.16 + * License. You can obtain a copy of the License at
  270.17 + * http://www.netbeans.org/cddl-gplv2.html
  270.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  270.19 + * specific language governing permissions and limitations under the
  270.20 + * License.  When distributing the software, include this License Header
  270.21 + * Notice in each file and include the License file at
  270.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  270.23 + * particular file as subject to the "Classpath" exception as provided
  270.24 + * by Oracle in the GPL Version 2 section of the License file that
  270.25 + * accompanied this code. If applicable, add the following below the
  270.26 + * License Header, with the fields enclosed by brackets [] replaced by
  270.27 + * your own identifying information:
  270.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  270.29 + *
  270.30 + * If you wish your version of this file to be governed by only the CDDL
  270.31 + * or only the GPL Version 2, indicate your decision by adding
  270.32 + * "[Contributor] elects to include this software in this distribution
  270.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  270.34 + * single choice of license, a recipient has the option to distribute
  270.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  270.36 + * to extend the choice of license to its licensees as provided above.
  270.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  270.38 + * Version 2 license, then the option applies only if the new code is
  270.39 + * made subject to such option by the copyright holder.
  270.40 + *
  270.41 + * Contributor(s):
  270.42 + *
  270.43 + * Portions Copyrighted 2012 Sun Microsystems, Inc.
  270.44 + */
  270.45 +package org.netbeans.modules.java.hints.spiimpl.processor;
  270.46 +
  270.47 +import java.io.ByteArrayOutputStream;
  270.48 +import java.io.File;
  270.49 +import org.netbeans.junit.NbTestCase;
  270.50 +import org.openide.util.test.AnnotationProcessorTestUtils;
  270.51 +import org.openide.util.test.TestFileUtils;
  270.52 +
  270.53 +/**
  270.54 + *
  270.55 + * @author lahvac
  270.56 + */
  270.57 +public class JavaHintsAnnotationProcessorTest extends NbTestCase {
  270.58 +
  270.59 +    public JavaHintsAnnotationProcessorTest(String name) {
  270.60 +        super(name);
  270.61 +    }
  270.62 +
  270.63 +    public void testErrors1() throws Exception {
  270.64 +        File src = new File(getWorkDir(), "src");
  270.65 +        File dest = new File(getWorkDir(), "classes");
  270.66 +        AnnotationProcessorTestUtils.makeSource(src, "p.H",
  270.67 +                "import org.netbeans.spi.java.hints.*;\n",
  270.68 +                "import org.netbeans.spi.editor.hints.*;\n",
  270.69 +                "@Hint(displayName=\"\", description=\"\", category=\"general\")\n",
  270.70 +                "public class H {\n",
  270.71 +                "    @TriggerPattern(\"$1.$2\")\n",
  270.72 +                "    public static String h1(HintContext ctx) { return null;}\n",
  270.73 +                "    @TriggerPattern(\"$1.$2.$3\")\n",
  270.74 +                "    public static ErrorDescription h2() { return null;}\n",
  270.75 +                "    @TriggerPatterns({@TriggerPattern(\"$1.$2.$3.$4\")})\n",
  270.76 +                "    private ErrorDescription h3(HintContext ctx) { return null;}\n",
  270.77 +                "    @TriggerPattern(value=\"$1.isEmpty()\", constraints=@ConstraintVariableType(variable=\"$unknown\", type=\"java.lang.String\"))\n",
  270.78 +                "    public static ErrorDescription h4(HintContext ctx) { return null;}\n",
  270.79 +                "}\n");
  270.80 +        TestFileUtils.writeFile(new File(src, "p/Bundle.properties"), "");
  270.81 +        ByteArrayOutputStream err = new ByteArrayOutputStream();
  270.82 +        assertFalse(AnnotationProcessorTestUtils.runJavac(src, null, dest, null, err));
  270.83 +        String errors = err.toString();
  270.84 +        assertTrue(errors.contains("error: The return type must be either org.netbeans.spi.editor.hints.ErrorDescription or java.util.List<org.netbeans.spi.editor.hints.ErrorDescription>"));
  270.85 +        assertTrue(errors.contains("error: The method must have exactly one parameter of type org.netbeans.spi.java.hints.HintContext"));
  270.86 +        assertTrue(errors.contains("error: The method must be static"));
  270.87 +        assertTrue(errors.contains("warning: Variable $unknown not used in the pattern"));
  270.88 +    }
  270.89 +
  270.90 +    public void testErrors2() throws Exception {
  270.91 +        File src = new File(getWorkDir(), "src");
  270.92 +        File dest = new File(getWorkDir(), "classes");
  270.93 +        AnnotationProcessorTestUtils.makeSource(src, "p.H",
  270.94 +                "import org.netbeans.spi.java.hints.*;\n",
  270.95 +                "import org.netbeans.spi.editor.hints.*;\n",
  270.96 +                "import java.util.*;\n",
  270.97 +                "@Hint(displayName=\"#DN_p.H\", description=\"#DESC_p.H\", category=\"general\")\n",
  270.98 +                "public class H {\n",
  270.99 +                "    @TriggerPattern(\"$1.$2.$3\")\n",
 270.100 +                "    public static List<ErrorDescription> hint(HintContext ctx) { return null;}\n",
 270.101 +                "}\n");
 270.102 +        TestFileUtils.writeFile(new File(src, "p/Bundle.properties"), "DN_p.H=DN_p.H\nDESC_p.H=DESC_p.H\n");
 270.103 +        ByteArrayOutputStream err = new ByteArrayOutputStream();
 270.104 +        assertTrue(AnnotationProcessorTestUtils.runJavac(src, null, dest, null, err));
 270.105 +    }
 270.106 +
 270.107 +    public void testCustomizerProvider() throws Exception {
 270.108 +        File src = new File(getWorkDir(), "src");
 270.109 +        File dest = new File(getWorkDir(), "classes");
 270.110 +        AnnotationProcessorTestUtils.makeSource(src, "p.H",
 270.111 +                "import org.netbeans.spi.java.hints.*;\n",
 270.112 +                "import org.netbeans.spi.editor.hints.*;\n",
 270.113 +                "import java.util.*;\n",
 270.114 +                "import java.util.prefs.*;\n",
 270.115 +                "import javax.swing.*;\n",
 270.116 +                "@Hint(displayName=\"dn\", description=\"desc\", category=\"general\", customizerProvider=H.Customizer.class)\n",
 270.117 +                "public class H {\n",
 270.118 +                "    @TriggerPattern(\"$1.$2.$3\")\n",
 270.119 +                "    public static List<ErrorDescription> hint(HintContext ctx) { return null;}\n",
 270.120 +                "    static final class Customizer implements CustomizerProvider {\n",
 270.121 +                "        @Override public JComponent getCustomizer(Preferences prefs) {\n",
 270.122 +                "            return new JPanel();\n",
 270.123 +                "        }\n",
 270.124 +                "    }\n",
 270.125 +                "}\n");
 270.126 +        TestFileUtils.writeFile(new File(src, "p/Bundle.properties"), "DN_p.H=DN_p.H\nDESC_p.H=DESC_p.H\n");
 270.127 +        ByteArrayOutputStream err = new ByteArrayOutputStream();
 270.128 +        assertFalse(AnnotationProcessorTestUtils.runJavac(src, null, dest, null, err));
 270.129 +        String errors = err.toString();
 270.130 +        assertTrue(errors.contains("error: Customizer provider must be public"));
 270.131 +        assertTrue(errors.contains("error: Customizer provider must provide a public default constructor"));
 270.132 +    }
 270.133 +
 270.134 +    public void testErrorsMessagesOnMethod() throws Exception {
 270.135 +        File src = new File(getWorkDir(), "src");
 270.136 +        File dest = new File(getWorkDir(), "classes");
 270.137 +        AnnotationProcessorTestUtils.makeSource(src, "p.H",
 270.138 +                "import org.netbeans.spi.java.hints.*;\n",
 270.139 +                "import org.netbeans.spi.editor.hints.*;\n",
 270.140 +                "import org.openide.util.NbBundle.Messages;\n",
 270.141 +                "import java.util.*;\n",
 270.142 +                "public class H {\n",
 270.143 +                "    @Hint(displayName=\"#DN_p.H\", description=\"#DESC_p.H\", category=\"general\")\n",
 270.144 +                "    @TriggerPattern(\"$1.$2.$3\")\n",
 270.145 +                "    @Messages({\"DN_p.H=1\", \"DESC_p.H=2\"})\n",
 270.146 +                "    public static List<ErrorDescription> hint(HintContext ctx) { return null;}\n",
 270.147 +                "}\n");
 270.148 +        ByteArrayOutputStream err = new ByteArrayOutputStream();
 270.149 +        boolean result = AnnotationProcessorTestUtils.runJavac(src, null, dest, null, err);
 270.150 +        assertTrue(err.toString(), result);
 270.151 +    }
 270.152 +}
   271.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   271.2 +++ b/sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/spi/java/hints/JavaFixUtilitiesTest.java	Sun Oct 23 11:50:54 2016 +0200
   271.3 @@ -0,0 +1,1169 @@
   271.4 +/*
   271.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   271.6 + *
   271.7 + * Copyright 2008-2010 Oracle and/or its affiliates. All rights reserved.
   271.8 + *
   271.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  271.10 + * Other names may be trademarks of their respective owners.
  271.11 + *
  271.12 + * The contents of this file are subject to the terms of either the GNU
  271.13 + * General Public License Version 2 only ("GPL") or the Common
  271.14 + * Development and Distribution License("CDDL") (collectively, the
  271.15 + * "License"). You may not use this file except in compliance with the
  271.16 + * License. You can obtain a copy of the License at
  271.17 + * http://www.netbeans.org/cddl-gplv2.html
  271.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  271.19 + * specific language governing permissions and limitations under the
  271.20 + * License.  When distributing the software, include this License Header
  271.21 + * Notice in each file and include the License file at
  271.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  271.23 + * particular file as subject to the "Classpath" exception as provided
  271.24 + * by Oracle in the GPL Version 2 section of the License file that
  271.25 + * accompanied this code. If applicable, add the following below the
  271.26 + * License Header, with the fields enclosed by brackets [] replaced by
  271.27 + * your own identifying information:
  271.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  271.29 + *
  271.30 + * If you wish your version of this file to be governed by only the CDDL
  271.31 + * or only the GPL Version 2, indicate your decision by adding
  271.32 + * "[Contributor] elects to include this software in this distribution
  271.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  271.34 + * single choice of license, a recipient has the option to distribute
  271.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  271.36 + * to extend the choice of license to its licensees as provided above.
  271.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  271.38 + * Version 2 license, then the option applies only if the new code is
  271.39 + * made subject to such option by the copyright holder.
  271.40 + *
  271.41 + * Contributor(s):
  271.42 + *
  271.43 + * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
  271.44 + */
  271.45 +
  271.46 +package org.netbeans.spi.java.hints;
  271.47 +
  271.48 +import org.netbeans.modules.java.hints.providers.spi.HintDescriptionFactory;
  271.49 +import org.netbeans.modules.java.hints.providers.spi.HintDescription;
  271.50 +import com.sun.source.tree.ClassTree;
  271.51 +import com.sun.source.tree.ExpressionTree;
  271.52 +import com.sun.source.tree.VariableTree;
  271.53 +import com.sun.source.util.TreePath;
  271.54 +import java.util.Collection;
  271.55 +import java.util.Collections;
  271.56 +import java.util.HashMap;
  271.57 +import java.util.List;
  271.58 +import java.util.Map;
  271.59 +import java.util.Map.Entry;
  271.60 +import java.util.concurrent.atomic.AtomicBoolean;
  271.61 +import javax.lang.model.element.ExecutableElement;
  271.62 +import javax.lang.model.element.TypeElement;
  271.63 +import javax.lang.model.type.TypeMirror;
  271.64 +import javax.lang.model.util.ElementFilter;
  271.65 +import org.netbeans.modules.java.hints.spiimpl.TestBase;
  271.66 +import org.netbeans.modules.java.hints.spiimpl.hints.HintsInvoker;
  271.67 +import org.netbeans.modules.java.hints.providers.spi.Trigger.PatternDescription;
  271.68 +import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings;
  271.69 +import org.netbeans.modules.java.hints.spiimpl.pm.PatternCompilerUtilities;
  271.70 +import org.netbeans.spi.editor.hints.ErrorDescription;
  271.71 +import org.netbeans.spi.editor.hints.Fix;
  271.72 +import org.openide.LifecycleManager;
  271.73 +import org.openide.modules.SpecificationVersion;
  271.74 +import org.openide.util.MapFormat;
  271.75 +
  271.76 +/**
  271.77 + *
  271.78 + * @author Jan Lahoda
  271.79 + */
  271.80 +public class JavaFixUtilitiesTest extends TestBase {
  271.81 +
  271.82 +    public JavaFixUtilitiesTest(String name) {
  271.83 +        super(name);
  271.84 +    }
  271.85 +
  271.86 +    public void testSimple() throws Exception {
  271.87 +        SpecificationVersion v = computeSpecVersion("/**\n" +
  271.88 +                                                    " * @since 1.5\n" +
  271.89 +                                                    " */\n");
  271.90 +
  271.91 +        assertEquals(0, v.compareTo(new SpecificationVersion("1.5")));
  271.92 +    }
  271.93 +
  271.94 +    public void testSimpleDate() throws Exception {
  271.95 +        SpecificationVersion v = computeSpecVersion("/**\n" +
  271.96 +                                                    " * @since 1.5 (16 May 2005)\n" +
  271.97 +                                                    " */\n");
  271.98 +
  271.99 +        assertEquals(0, v.compareTo(new SpecificationVersion("1.5")));
 271.100 +    }
 271.101 +
 271.102 +    public void testLongText() throws Exception {
 271.103 +        SpecificationVersion v = computeSpecVersion("/**\n" +
 271.104 +                                                    " * @since 1.123.2.1 - branch propsheet_issue_29447\n" +
 271.105 +                                                    " */\n");
 271.106 +
 271.107 +        assertEquals(0, v.compareTo(new SpecificationVersion("1.123.2.1")));
 271.108 +    }
 271.109 +
 271.110 +    public void testModuleName() throws Exception {
 271.111 +        SpecificationVersion v = computeSpecVersion("/**\n" +
 271.112 +                                                    " * @since org.openide.filesystems 7.15\n" +
 271.113 +                                                    " */\n");
 271.114 +
 271.115 +        assertEquals(0, v.compareTo(new SpecificationVersion("7.15")));
 271.116 +    }
 271.117 +
 271.118 +    public void testModuleNameMajor() throws Exception {
 271.119 +        SpecificationVersion v = computeSpecVersion("/**\n" +
 271.120 +                                                    " * @since org.openide/1 4.42\n" +
 271.121 +                                                    " */\n");
 271.122 +
 271.123 +        assertEquals(0, v.compareTo(new SpecificationVersion("4.42")));
 271.124 +    }
 271.125 +
 271.126 +    public void testEnd() throws Exception {
 271.127 +        SpecificationVersion v = computeSpecVersion("/**\n" +
 271.128 +                                                    " * @since 1.5 */\n");
 271.129 +
 271.130 +        assertEquals(0, v.compareTo(new SpecificationVersion("1.5")));
 271.131 +    }
 271.132 +
 271.133 +    public void testOpenAPI() throws Exception {
 271.134 +        SpecificationVersion v = computeSpecVersion("/**\n" +
 271.135 +                                                    " * @since OpenAPI version 2.12" +
 271.136 +                                                    " */\n");
 271.137 +
 271.138 +        assertEquals(0, v.compareTo(new SpecificationVersion("2.12")));
 271.139 +
 271.140 +    }
 271.141 +
 271.142 +    private SpecificationVersion computeSpecVersion(String javadoc) throws Exception {
 271.143 +        prepareTest("test/Test.java",
 271.144 +                    "package test;\n" +
 271.145 +                    "public class Test {\n" +
 271.146 +                    javadoc +
 271.147 +                    "     public void test() {\n" +
 271.148 +                    "     }\n" +
 271.149 +                    "}\n");
 271.150 +
 271.151 +        TypeElement te = info.getElements().getTypeElement("test.Test");
 271.152 +        ExecutableElement method = ElementFilter.methodsIn(te.getEnclosedElements()).iterator().next();
 271.153 +
 271.154 +        return JavaFixUtilities.computeSpecVersion(info, method);
 271.155 +    }
 271.156 +
 271.157 +    public void testArithmetic1() throws Exception {
 271.158 +        performArithmeticTest("1 + 2", "3");
 271.159 +        performArithmeticTest("1f + 2", "3.0F");
 271.160 +        performArithmeticTest("1 + 2f", "3.0F");
 271.161 +        performArithmeticTest("1.0 + 2f", "3.0");
 271.162 +        performArithmeticTest("1 + 2.0", "3.0");
 271.163 +        performArithmeticTest("1L + 2", "3L");
 271.164 +    }
 271.165 +
 271.166 +    public void testArithmetic2() throws Exception {
 271.167 +        performArithmeticTest("1 * 2", "2");
 271.168 +        performArithmeticTest("1f * 2", "2.0F");
 271.169 +        performArithmeticTest("1 * 2f", "2.0F");
 271.170 +        performArithmeticTest("1.0 * 2f", "2.0");
 271.171 +        performArithmeticTest("1 * 2.0", "2.0");
 271.172 +        performArithmeticTest("1L * 2", "2L");
 271.173 +    }
 271.174 +
 271.175 +    public void testArithmetic3() throws Exception {
 271.176 +        performArithmeticTest("4 / 2", "2");
 271.177 +        performArithmeticTest("4f / 2", "2.0F");
 271.178 +        performArithmeticTest("4 / 2f", "2.0F");
 271.179 +        performArithmeticTest("4.0 / 2f", "2.0");
 271.180 +        performArithmeticTest("4 / 2.0", "2.0");
 271.181 +        performArithmeticTest("4L / 2", "2L");
 271.182 +    }
 271.183 +
 271.184 +    public void testArithmetic4() throws Exception {
 271.185 +        performArithmeticTest("5 % 2", "1");
 271.186 +        performArithmeticTest("5f % 2", "1.0F");
 271.187 +        performArithmeticTest("5 % 2f", "1.0F");
 271.188 +        performArithmeticTest("5.0 % 2f", "1.0");
 271.189 +        performArithmeticTest("5 % 2.0", "1.0");
 271.190 +        performArithmeticTest("5L % 2", "1L");
 271.191 +    }
 271.192 +
 271.193 +    public void testArithmetic5() throws Exception {
 271.194 +        performArithmeticTest("5 - 2", "3");
 271.195 +        performArithmeticTest("5f - 2", "3.0F");
 271.196 +        performArithmeticTest("5 - 2f", "3.0F");
 271.197 +        performArithmeticTest("5.0 - 2f", "3.0");
 271.198 +        performArithmeticTest("5 - 2.0", "3.0");
 271.199 +        performArithmeticTest("5L - 2", "3L");
 271.200 +    }
 271.201 +
 271.202 +    public void testArithmetic6() throws Exception {
 271.203 +        performArithmeticTest("5 | 2", "7");
 271.204 +        performArithmeticTest("5L | 2", "7L");
 271.205 +        performArithmeticTest("5 | 2L", "7L");
 271.206 +    }
 271.207 +
 271.208 +    public void testArithmetic7() throws Exception {
 271.209 +        performArithmeticTest("5 & 4", "4");
 271.210 +        performArithmeticTest("5L & 4", "4L");
 271.211 +        performArithmeticTest("5 & 4L", "4L");
 271.212 +    }
 271.213 +
 271.214 +    public void testArithmetic8() throws Exception {
 271.215 +        performArithmeticTest("5 ^ 4", "1");
 271.216 +        performArithmeticTest("5L ^ 4", "1L");
 271.217 +        performArithmeticTest("5 ^ 4L", "1L");
 271.218 +    }
 271.219 +
 271.220 +    public void testArithmetic9() throws Exception {
 271.221 +        performArithmeticTest("5 << 2", "20");
 271.222 +        performArithmeticTest("5L << 2", "20L");
 271.223 +        performArithmeticTest("5 << 2L", "20L");
 271.224 +    }
 271.225 +
 271.226 +    public void testArithmeticA() throws Exception {
 271.227 +        performArithmeticTest("-20 >> 2", "-5");
 271.228 +        performArithmeticTest("-20L >> 2", "-5L");
 271.229 +        performArithmeticTest("-20 >> 2L", "-5L");
 271.230 +    }
 271.231 +
 271.232 +    public void testArithmeticB() throws Exception {
 271.233 +        performArithmeticTest("-20 >>> 2", "1073741819");
 271.234 +    }
 271.235 +
 271.236 +    public void testArithmeticC() throws Exception {
 271.237 +        performArithmeticTest("0 + -20", "-20");
 271.238 +        performArithmeticTest("0 + +20", "20");
 271.239 +    }
 271.240 +
 271.241 +    public void testArithmeticComplex() throws Exception {
 271.242 +        performArithmeticTest("1 + 2 * 4 - 5", "4");
 271.243 +        performArithmeticTest("1f + 2 * 4.0 - 5", "4.0");
 271.244 +        performArithmeticTest("1L + 2 * 4 - 5", "4L");
 271.245 +    }
 271.246 +
 271.247 +    private static final String ARITHMETIC = "public class Test { private Object o = __VAL__; }";
 271.248 +    private void performArithmeticTest(String orig, String nue) throws Exception {
 271.249 +        String code = replace("0");
 271.250 +
 271.251 +        prepareTest("Test.java", code);
 271.252 +        ClassTree clazz = (ClassTree) info.getCompilationUnit().getTypeDecls().get(0);
 271.253 +        VariableTree variable = (VariableTree) clazz.getMembers().get(1);
 271.254 +        ExpressionTree init = variable.getInitializer();
 271.255 +        TreePath tp = new TreePath(new TreePath(new TreePath(new TreePath(info.getCompilationUnit()), clazz), variable), init);
 271.256 +        Fix fix = JavaFixUtilities.rewriteFix(info, "A", tp, orig, Collections.<String, TreePath>emptyMap(), Collections.<String, Collection<? extends TreePath>>emptyMap(), Collections.<String, String>emptyMap(), Collections.<String, TypeMirror>emptyMap(), Collections.<String, String>emptyMap());
 271.257 +        fix.implement();
 271.258 +
 271.259 +        String golden = replace(nue);
 271.260 +        String out = doc.getText(0, doc.getLength());
 271.261 +
 271.262 +        assertEquals(golden, out);
 271.263 +
 271.264 +        LifecycleManager.getDefault().saveAll();
 271.265 +    }
 271.266 +
 271.267 +    private static String replace(String val) {
 271.268 +        MapFormat f = new MapFormat(Collections.singletonMap("VAL", val));
 271.269 +
 271.270 +        f.setLeftBrace("__");
 271.271 +        f.setRightBrace("__");
 271.272 +
 271.273 +        return f.format(ARITHMETIC);
 271.274 +    }
 271.275 +
 271.276 +    public void testRewriteWithParenthesis1() throws Exception {
 271.277 +        performRewriteTest("package test;\n" +
 271.278 +                           "public class Test {\n" +
 271.279 +                           "    int i = new String(\"a\" + \"b\").length();\n" +
 271.280 +                           "}\n",
 271.281 +                           "new String($1)=>$1",
 271.282 +                           "package test;\n" +
 271.283 +                           "public class Test {\n" +
 271.284 +		           "    int i = (\"a\" + \"b\").length();\n" +
 271.285 +		           "}\n");
 271.286 +    }
 271.287 +
 271.288 +    public void testRewriteWithParenthesis2() throws Exception {
 271.289 +        performRewriteTest("package test;\n" +
 271.290 +                           "public class Test {\n" +
 271.291 +                           "    int i = Integer.valueOf(1 + 2) * 3;\n" +
 271.292 +                           "}\n",
 271.293 +                           "Integer.valueOf($1)=>$1",
 271.294 +                           "package test;\n" +
 271.295 +                           "public class Test {\n" +
 271.296 +		           "    int i = (1 + 2) * 3;\n" +
 271.297 +		           "}\n");
 271.298 +    }
 271.299 +
 271.300 +    public void testRewriteWithoutParenthesis1() throws Exception {
 271.301 +        performRewriteTest("package test;\n" +
 271.302 +                           "public class Test {\n" +
 271.303 +                           "    int i = new String(\"a\" + \"b\").length();\n" +
 271.304 +                           "}\n",
 271.305 +                           "new String($1)=>java.lang.String.format(\"%s%s\", $1, \"\")",
 271.306 +                           "package test;\n" +
 271.307 +                           "public class Test {\n" +
 271.308 +		           "    int i = String.format(\"%s%s\", \"a\" + \"b\", \"\").length();\n" +
 271.309 +		           "}\n");
 271.310 +    }
 271.311 +
 271.312 +    public void testRewriteWithoutParenthesis2() throws Exception {
 271.313 +        performRewriteTest("package test;\n" +
 271.314 +                           "public class Test {\n" +
 271.315 +                           "    String s = (\"a\" + \"b\").intern();\n" +
 271.316 +                           "}\n",
 271.317 +                           "($1).intern()=>$1",
 271.318 +                           "package test;\n" +
 271.319 +                           "public class Test {\n" +
 271.320 +		           "    String s = \"a\" + \"b\";\n" +
 271.321 +		           "}\n");
 271.322 +    }
 271.323 +
 271.324 +    public void testRewriteWithoutParenthesis3() throws Exception {
 271.325 +        performRewriteTest("package test;\n" +
 271.326 +                           "public class Test {\n" +
 271.327 +                           "    int i = Integer.valueOf(1 + 2) + 3;\n" +
 271.328 +                           "}\n",
 271.329 +                           "Integer.valueOf($1)=>$1",
 271.330 +                           "package test;\n" +
 271.331 +                           "public class Test {\n" +
 271.332 +		           "    int i = 1 + 2 + 3;\n" +
 271.333 +		           "}\n");
 271.334 +    }
 271.335 +
 271.336 +    public void testRewriteWithoutParenthesis4() throws Exception {
 271.337 +        performRewriteTest("package test;\n" +
 271.338 +                           "public class Test {\n" +
 271.339 +                           "    int i = Integer.valueOf(1 * 2) + 3;\n" +
 271.340 +                           "}\n",
 271.341 +                           "Integer.valueOf($1)=>$1",
 271.342 +                           "package test;\n" +
 271.343 +                           "public class Test {\n" +
 271.344 +		           "    int i = 1 * 2 + 3;\n" +
 271.345 +		           "}\n");
 271.346 +    }
 271.347 +
 271.348 +    public void testRewriteWithoutParenthesis5() throws Exception {
 271.349 +        performRewriteTest("package test;\n" +
 271.350 +                           "public class Test {\n" +
 271.351 +                           "    int i = new Integer(1 * 2).hashCode();\n" +
 271.352 +                           "}\n",
 271.353 +                           "$1.hashCode()=>$1.hashCode()",
 271.354 +                           "package test;\n" +
 271.355 +                           "public class Test {\n" +
 271.356 +		           "    int i = new Integer(1 * 2).hashCode();\n" +
 271.357 +		           "}\n");
 271.358 +    }
 271.359 +
 271.360 +    public void testRewriteWithoutParenthesis6() throws Exception {
 271.361 +        performRewriteTest("package test;\n" +
 271.362 +                           "public class Test {\n" +
 271.363 +                           "    {\n" +
 271.364 +                           "        System.err.println(\"a\" + 1);\n" +
 271.365 +                           "    }\n" +
 271.366 +                           "}\n",
 271.367 +                           "System.err.println($t)=>D.println($t)",
 271.368 +                           "package test;\n" +
 271.369 +                           "public class Test {\n" +
 271.370 +                           "    {\n" +
 271.371 +                           "        D.println(\"a\" + 1);\n" +
 271.372 +                           "    }\n" +
 271.373 +		           "}\n");
 271.374 +    }
 271.375 +
 271.376 +    public void testRewriteWithoutParenthesis7() throws Exception {
 271.377 +        performRewriteTest("package test;\n" +
 271.378 +                           "public class Test {\n" +
 271.379 +                           "    {\n" +
 271.380 +                           "        new String(\"a\" + 1);\n" +
 271.381 +                           "    }\n" +
 271.382 +                           "}\n",
 271.383 +                           "new String($t)=>new D($t)",
 271.384 +                           "package test;\n" +
 271.385 +                           "public class Test {\n" +
 271.386 +                           "    {\n" +
 271.387 +                           "        new D(\"a\" + 1);\n" +
 271.388 +                           "    }\n" +
 271.389 +		           "}\n");
 271.390 +    }
 271.391 +
 271.392 +    public void testTopLevelRewriteWithoutParenthesis1() throws Exception {
 271.393 +        performRewriteTest("package test;\n" +
 271.394 +                           "public class Test {\n" +
 271.395 +                           "    int i = (1 + 2) * 2;\n" +
 271.396 +                           "}\n",
 271.397 +                           "$1 + $2=>3",
 271.398 +                           "package test;\n" +
 271.399 +                           "public class Test {\n" +
 271.400 +		           "    int i = 3 * 2;\n" +
 271.401 +		           "}\n");
 271.402 +    }
 271.403 +
 271.404 +    public void testTopLevelRewriteKeepParenthesis1() throws Exception {
 271.405 +        performRewriteTest("package test;\n" +
 271.406 +                           "public class Test {\n" +
 271.407 +                           "    int i = (1 * 2) + 2;\n" +
 271.408 +                           "}\n",
 271.409 +                           "$1 * $2=>2",
 271.410 +                           "package test;\n" +
 271.411 +                           "public class Test {\n" +
 271.412 +		           "    int i = (2) + 2;\n" +
 271.413 +		           "}\n");
 271.414 +    }
 271.415 +
 271.416 +    public void testTopLevelRewriteKeepParenthesis2() throws Exception {
 271.417 +        performRewriteTest("package test;\n" +
 271.418 +                           "public class Test {\n" +
 271.419 +                           "    { if (1 > 2) ; }\n" +
 271.420 +                           "}\n",
 271.421 +                           "$1 > $2=>false",
 271.422 +                           "package test;\n" +
 271.423 +                           "public class Test {\n" +
 271.424 +                           "    { if (false) ; }\n" +
 271.425 +		           "}\n");
 271.426 +    }
 271.427 +    
 271.428 +    public void testRewriteCatchMultiVariable() throws Exception {
 271.429 +        performRewriteTest("package test;\n" +
 271.430 +                           "public class Test {\n" +
 271.431 +                           "    { try { } catch {NullPointerException ex} { } }\n" +
 271.432 +                           "}\n",
 271.433 +                           "try { } catch $catches$ => try { new Object(); } catch $catches$",
 271.434 +                           "package test;\n" +
 271.435 +                           "public class Test {\n" +
 271.436 +                           //XXX: whitespaces:
 271.437 +                           "    {  try {new Object();\n } catch {NullPointerException ex} { } }\n" +
 271.438 +//                           "    { try {      new Object();\n } catch {NullPointerException ex} { } }\n" +
 271.439 +		           "}\n");
 271.440 +    }
 271.441 +
 271.442 +    public void testRewriteCaseMultiVariable() throws Exception {
 271.443 +        performRewriteTest("package test;\n" +
 271.444 +                           "public class Test {\n" +
 271.445 +                           "    { int i = 0; switch (i) {case 0: System.err.println(1); break; case 1: System.err.println(2); break; case 2: System.err.println(3); break; }\n" +
 271.446 +                           "}\n",
 271.447 +                           "switch ($v) { case $p$ case 2: $stmts$; } => switch ($v) { case $p$ case 3: $stmts$; }",
 271.448 +                           "package test;\n" +
 271.449 +                           "public class Test {\n" +
 271.450 +                           "    { int i = 0; switch (i) {case 0: System.err.println(1); break; case 1: System.err.println(2); break; case 3: System.err.println(3); break; }\n" +
 271.451 +		           "}\n");
 271.452 +    }
 271.453 +
 271.454 +    public void testRewriteMemberSelectVariable() throws Exception {
 271.455 +        performRewriteTest("package test;\n" +
 271.456 +                           "public class Test {\n" +
 271.457 +                           "    { java.io.File f = null; boolean b = f.isDirectory(); }\n" +
 271.458 +                           "}\n",
 271.459 +                           "$file.$m() => foo.Bar.$m($file)",
 271.460 +                           "package test;\n" +
 271.461 +                           "public class Test {\n" +
 271.462 +                           "    { java.io.File f = null; boolean b = foo.Bar.isDirectory(f); }\n" +
 271.463 +		           "}\n");
 271.464 +    }
 271.465 +    
 271.466 +    public void testRewriteIdent2IdentMemberSelectPattern() throws Exception {
 271.467 +        performRewriteTest("package test;\n" +
 271.468 +                           "public class Test {\n" +
 271.469 +                           "    private boolean b; private void t() { boolean c = b; }\n" +
 271.470 +                           "}\n",
 271.471 +                           "$0{test.Test}.b => !$0.b",
 271.472 +                           "package test;\n" +
 271.473 +                           "public class Test {\n" +
 271.474 +                           "    private boolean b; private void t() { boolean c = !b; }\n" +
 271.475 +		           "}\n");
 271.476 +    }
 271.477 +
 271.478 +    public void testCarefulRewriteInImports() throws Exception {
 271.479 +        performRewriteTest("package test;\n" +
 271.480 +                           "import javax.swing.text.AbstractDocument;\n" +
 271.481 +                           "public class Test {\n" +
 271.482 +                           "}\n",
 271.483 +                           "javax.swing.text.AbstractDocument => javax.swing.text.Document",
 271.484 +                           "package test;\n" +
 271.485 +                           "import javax.swing.text.Document;\n" +
 271.486 +                           "public class Test {\n" +
 271.487 +		           "}\n");
 271.488 +    }
 271.489 +
 271.490 +    public void testRemoveFromParent1() throws Exception {
 271.491 +        performRemoveFromParentTest("package test;\n" +
 271.492 +                                    "public class Test {\n" +
 271.493 +                                    "    private int I;" +
 271.494 +                                    "}\n",
 271.495 +                                    "$mods$ int $f;",
 271.496 +                                    "package test;\n" +
 271.497 +                                    "public class Test {\n" +
 271.498 +                                    "}\n");
 271.499 +    }
 271.500 +
 271.501 +    public void testRemoveFromParent2() throws Exception {
 271.502 +        performRemoveFromParentTest("package test;\n" +
 271.503 +                                    "public class Test extends java.util.ArrayList {\n" +
 271.504 +                                    "}\n",
 271.505 +                                    "java.util.ArrayList",
 271.506 +                                    "package test;\n" +
 271.507 +                                    "public class Test {\n" +
 271.508 +                                    "}\n");
 271.509 +    }
 271.510 +    
 271.511 +    public void testRemoveFromParentExpressionStatement206116() throws Exception {
 271.512 +        performRemoveFromParentTest("package test;\n" +
 271.513 +                           "import java.io.InputStream;\n" +
 271.514 +                           "public class Test {\n" +
 271.515 +                           "    private void t() throws Exception {\n" +
 271.516 +                           "        System.err.println();\n" +
 271.517 +                           "        System.err.println(\"a\");\n" +
 271.518 +                           "    }\n" +
 271.519 +                           "}\n",
 271.520 +                           "System.err.println()",
 271.521 +                           "package test;\n" +
 271.522 +                           "import java.io.InputStream;\n" +
 271.523 +                           "public class Test {\n" +
 271.524 +                           "    private void t() throws Exception {\n" +
 271.525 +                           "        System.err.println(\"a\");\n" +
 271.526 +                           "    }\n" +
 271.527 +		           "}\n");
 271.528 +    }
 271.529 +
 271.530 +    public void testUnresolvableTarget() throws Exception {
 271.531 +        performRewriteTest("package test;\n" +
 271.532 +                           "public class Test extends java.util.ArrayList {\n" +
 271.533 +                           "}\n",
 271.534 +                           "java.util.ArrayList => Test",
 271.535 +                           "package test;\n" +
 271.536 +                           "public class Test extends Test {\n" +
 271.537 +                           "}\n");
 271.538 +    }
 271.539 +
 271.540 +    public void testTryWithResourceTarget() throws Exception {
 271.541 +        performRewriteTest("package test;\n" +
 271.542 +                           "import java.io.InputStream;\n" +
 271.543 +                           "public class Test {\n" +
 271.544 +                           "    private void t() throws Exception {\n" +
 271.545 +                           "        InputStream in = null;\n" +
 271.546 +                           "        try {\n" +
 271.547 +                           "        } finally {\n" +
 271.548 +                           "            in.close()\n" +
 271.549 +                           "        }\n" +
 271.550 +                           "    }\n" +
 271.551 +                           "}\n",
 271.552 +                           "$type $var = $init; try {} finally {$var.close();} => try ($type $var = $init) {} finally {$var.close();}",
 271.553 +                           "package test;\n" +
 271.554 +                           "import java.io.InputStream;\n" +
 271.555 +                           "public class Test {\n" +
 271.556 +                           "    private void t() throws Exception {\n" +
 271.557 +//                           "        try (InputStream in = null) {\n" +
 271.558 +                           //XXX:
 271.559 +                           "        try (final InputStream in = null) {\n" +
 271.560 +                           "        } finally {\n" +
 271.561 +                           "            in.close()\n" +
 271.562 +                           "        }\n" +
 271.563 +                           "    }\n" +
 271.564 +		           "}\n");
 271.565 +    }
 271.566 +
 271.567 +    public void testSingle2MultipleStatements() throws Exception {
 271.568 +        performRewriteTest("package test;\n" +
 271.569 +                           "import java.io.InputStream;\n" +
 271.570 +                           "public class Test {\n" +
 271.571 +                           "    private void t() throws Exception {\n" +
 271.572 +                           "        int i = 0;\n" +
 271.573 +                           "    }\n" +
 271.574 +                           "}\n",
 271.575 +                           "$type $var = $init; => $type $var; $var = $init;",
 271.576 +                           "package test;\n" +
 271.577 +                           "import java.io.InputStream;\n" +
 271.578 +                           "public class Test {\n" +
 271.579 +                           "    private void t() throws Exception {\n" +
 271.580 +                           "        int i;\n" +
 271.581 +                           "        i = 0;\n" +
 271.582 +                           "    }\n" +
 271.583 +		           "}\n");
 271.584 +    }
 271.585 +    
 271.586 +    public void testSingle2MultipleStatements2() throws Exception {
 271.587 +        performRewriteTest("package test;\n" +
 271.588 +                           "import java.io.InputStream;\n" +
 271.589 +                           "public class Test {\n" +
 271.590 +                           "    private void t() throws Exception {\n" +
 271.591 +                           "        while (true)\n" +
 271.592 +                           "            if (true) {\n" +
 271.593 +                           "                System.err.println();\n" +
 271.594 +                           "            }\n" +
 271.595 +                           "    }\n" +
 271.596 +                           "}\n",
 271.597 +                           "if (true) $then; => if (true) $then; System.err.println();",
 271.598 +                           "package test;\n" +
 271.599 +                           "import java.io.InputStream;\n" +
 271.600 +                           "public class Test {\n" +
 271.601 +                           "    private void t() throws Exception {\n" +
 271.602 +                           "        while (true) {\n" +
 271.603 +                           "            if (true) {\n" +
 271.604 +                           "                System.err.println();\n" +
 271.605 +                           "            }\n" +
 271.606 +                           "            System.err.println();\n" +
 271.607 +                           "        }\n" +
 271.608 +                           "    }\n" +
 271.609 +		           "}\n");
 271.610 +    }
 271.611 +    
 271.612 +    public void testMultipleStatementsWrapComments1() throws Exception {
 271.613 +        performRewriteTest("package test;\n" +
 271.614 +                           "import java.io.InputStream;\n" +
 271.615 +                           "public class Test {\n" +
 271.616 +                           "    private void t() throws Exception {\n" +
 271.617 +                           "        if (1 == 1) {\n" +
 271.618 +                           "            System.err.println();\n" +
 271.619 +                           "            System.err.println(\"a\");\n" +
 271.620 +                           "            \n" +
 271.621 +                           "            \n" +
 271.622 +                           "            //C\n" +
 271.623 +                           "            System.err.println(\"b\");\n" +
 271.624 +                           "        }\n" +
 271.625 +                           "    }\n" +
 271.626 +                           "}\n",
 271.627 +                           "if ($cond) { System.err.println(); $stmts$;} => while ($cond) { $stmts$;}",
 271.628 +                           "package test;\n" +
 271.629 +                           "import java.io.InputStream;\n" +
 271.630 +                           "public class Test {\n" +
 271.631 +                           "    private void t() throws Exception {\n" +
 271.632 +                           "        while (1 == 1) {\n" +
 271.633 +                           "            System.err.println(\"a\");\n" +
 271.634 +                           "            \n" +
 271.635 +                           "            \n" +
 271.636 +                           "            //C\n" +
 271.637 +                           "            System.err.println(\"b\");\n" +
 271.638 +                           "        }\n" +
 271.639 +                           "    }\n" +
 271.640 +		           "}\n");
 271.641 +    }
 271.642 +    
 271.643 +    public void testMultipleStatementsWrapComments2() throws Exception {
 271.644 +        performRewriteTest("package test;\n" +
 271.645 +                           "import java.io.InputStream;\n" +
 271.646 +                           "public class Test {\n" +
 271.647 +                           "    private void t() throws Exception {\n" +
 271.648 +                           "        if (1 == 1) {\n" +
 271.649 +                           "            System.err.println();\n" +
 271.650 +                           "            System.err.println(\"a\");\n" +
 271.651 +                           "            \n" +
 271.652 +                           "            \n" +
 271.653 +                           "            //C\n" +
 271.654 +                           "            System.err.println(\"b\");\n" +
 271.655 +                           "        }\n" +
 271.656 +                           "    }\n" +
 271.657 +                           "}\n",
 271.658 +                           "if ($cond) { $stmts$;} => while ($cond) { $stmts$;}",
 271.659 +                           "package test;\n" +
 271.660 +                           "import java.io.InputStream;\n" +
 271.661 +                           "public class Test {\n" +
 271.662 +                           "    private void t() throws Exception {\n" +
 271.663 +                           "        while (1 == 1) {\n" +
 271.664 +                           "            System.err.println();\n" +
 271.665 +                           "            System.err.println(\"a\");\n" +
 271.666 +                           "            \n" +
 271.667 +                           "            \n" +
 271.668 +                           "            //C\n" +
 271.669 +                           "            System.err.println(\"b\");\n" +
 271.670 +                           "        }\n" +
 271.671 +                           "    }\n" +
 271.672 +		           "}\n");
 271.673 +    }
 271.674 +    
 271.675 +    public void testReplaceTypeParameters1() throws Exception {
 271.676 +        performRewriteTest("package test;\n" +
 271.677 +                           "import java.io.InputStream;\n" +
 271.678 +                           "public class Test {\n" +
 271.679 +                           "    private <A, B> void t() {\n" +
 271.680 +                           "    }\n" +
 271.681 +                           "}\n",
 271.682 +                           "$mods$ <$O, $T> $ret $name() { $body$; } => $mods$ <$T, $O> $ret $name() { $body$; }",
 271.683 +                           "package test;\n" +
 271.684 +                           "import java.io.InputStream;\n" +
 271.685 +                           "public class Test {\n" +
 271.686 +                           "    private <B, A> void t() {\n" +
 271.687 +                           "    }\n" +
 271.688 +		           "}\n");
 271.689 +    }
 271.690 +    
 271.691 +    public void testReplaceTypeParameters2() throws Exception {
 271.692 +        performRewriteTest("package test;\n" +
 271.693 +                           "import java.io.InputStream;\n" +
 271.694 +                           "public class Test {\n" +
 271.695 +                           "    private <A, B> void t() {\n" +
 271.696 +                           "    }\n" +
 271.697 +                           "}\n",
 271.698 +                           "$mods$ <$T$> $ret $name() { $body$; } => $mods$ <C, $T$> $ret $name() { $body$; }",
 271.699 +                           "package test;\n" +
 271.700 +                           "import java.io.InputStream;\n" +
 271.701 +                           "public class Test {\n" +
 271.702 +                           "    private <C, A, B> void t() {\n" +
 271.703 +                           "    }\n" +
 271.704 +		           "}\n");
 271.705 +    }
 271.706 +    
 271.707 +    public void testAdd2Modifiers() throws Exception {
 271.708 +        performRewriteTest("package test;\n" +
 271.709 +                           "import java.io.InputStream;\n" +
 271.710 +                           "public class Test {\n" +
 271.711 +                           "    void t() {\n" +
 271.712 +                           "    }\n" +
 271.713 +                           "}\n",
 271.714 +                           "$mods$ $ret $name() { $body$; } => $mods$ @java.lang.Deprecated private $ret $name() { $body$; }",
 271.715 +                           "package test;\n" +
 271.716 +                           "import java.io.InputStream;\n" +
 271.717 +                           "public class Test {\n" +
 271.718 +                           "    @Deprecated\n" +
 271.719 +                           "    private void t() {\n" +
 271.720 +                           "    }\n" +
 271.721 +		           "}\n");
 271.722 +    }
 271.723 +    
 271.724 +    public void testReplaceInModifiers() throws Exception {
 271.725 +        performRewriteTest("package test;\n" +
 271.726 +                           "import java.io.InputStream;\n" +
 271.727 +                           "public class Test {\n" +
 271.728 +                           "    public @Override void t() {\n" +
 271.729 +                           "    }\n" +
 271.730 +                           "}\n",
 271.731 +                           "$mods$ public @Override $ret $name() { $body$; } => $mods$ private @Deprecated $ret $name() { $body$; }",
 271.732 +                           "package test;\n" +
 271.733 +                           "import java.io.InputStream;\n" +
 271.734 +                           "public class Test {\n" +
 271.735 +                           "    private @Deprecated void t() {\n" +
 271.736 +                           "    }\n" +
 271.737 +		           "}\n");
 271.738 +    }
 271.739 +    
 271.740 +    public void testKeepInModifiers() throws Exception {
 271.741 +        performRewriteTest("package test;\n" +
 271.742 +                           "import java.io.InputStream;\n" +
 271.743 +                           "public class Test {\n" +
 271.744 +                           "    public @Override void t() {\n" +
 271.745 +                           "    }\n" +
 271.746 +                           "}\n",
 271.747 +                           "$mods$ public @Override $ret $name() { $body$; } => $mods$ public @Override $ret $name() { $body$; }",
 271.748 +                           "package test;\n" +
 271.749 +                           "import java.io.InputStream;\n" +
 271.750 +                           "public class Test {\n" +
 271.751 +                           "    public @Override void t() {\n" +
 271.752 +                           "    }\n" +
 271.753 +		           "}\n");
 271.754 +    }
 271.755 +    
 271.756 +    public void testRemoveInModifiers() throws Exception {
 271.757 +        performRewriteTest("package test;\n" +
 271.758 +                           "import java.io.InputStream;\n" +
 271.759 +                           "public class Test {\n" +
 271.760 +                           "    public static @Deprecated @Override void t() {\n" +
 271.761 +                           "    }\n" +
 271.762 +                           "}\n",
 271.763 +                           "$mods$ public @Override $ret $name() { $body$; } => $mods$ $ret $name() { $body$; }",
 271.764 +                           "package test;\n" +
 271.765 +                           "import java.io.InputStream;\n" +
 271.766 +                           "public class Test {\n" +
 271.767 +                           "    static @Deprecated void t() {\n" +
 271.768 +                           "    }\n" +
 271.769 +		           "}\n");
 271.770 +    }
 271.771 +    
 271.772 +    public void testRewriteMethodParametersWildcard() throws Exception {
 271.773 +        performRewriteTest("package test;\n" +
 271.774 +                           "import java.io.InputStream;\n" +
 271.775 +                           "public class Test {\n" +
 271.776 +                           "    public static void t() {\n" +
 271.777 +                           "    }\n" +
 271.778 +                           "}\n",
 271.779 +                           "$mods$ void $name($args$) { $body$; } => $mods$ int $name($args$) { $body$; }",
 271.780 +                           "package test;\n" +
 271.781 +                           "import java.io.InputStream;\n" +
 271.782 +                           "public class Test {\n" +
 271.783 +                           "    public static int t() {\n" +
 271.784 +                           "    }\n" +
 271.785 +		           "}\n");
 271.786 +    }
 271.787 +    
 271.788 +    public void testRewriteClass() throws Exception {
 271.789 +        performRewriteTest("package test;\n" +
 271.790 +                           "public class Test {\n" +
 271.791 +                           "}\n",
 271.792 +                           "$mods$ class $name<$tp$> extends $e$ implements $i$ { $members$; } => $mods$ @java.lang.Deprecated class $name<$tp$> extends $e$ implements $i$ { $members$; }",
 271.793 +                           "package test;\n" +
 271.794 +                           "@Deprecated\n" +
 271.795 +                           "public class Test {\n" +
 271.796 +		           "}\n");
 271.797 +    }
 271.798 +    
 271.799 +    public void testOptionalVariableInitializer1() throws Exception {
 271.800 +        performRewriteTest("package test;\n" +
 271.801 +                           "public class Test {\n" +
 271.802 +                           "    private int I;\n" +
 271.803 +                           "}\n",
 271.804 +                           "$mods$ int $name = $init$; => $mods$ long $name = $init$;",
 271.805 +                           "package test;\n" +
 271.806 +                           "public class Test {\n" +
 271.807 +                           "    private long I;\n" +
 271.808 +		           "}\n");
 271.809 +    }
 271.810 +    
 271.811 +    public void testOptionalVariableInitializer2() throws Exception {
 271.812 +        performRewriteTest("package test;\n" +
 271.813 +                           "public class Test {\n" +
 271.814 +                           "    private int I = 1;\n" +
 271.815 +                           "}\n",
 271.816 +                           "$mods$ int $name = $init$; => $mods$ long $name = $init$;",
 271.817 +                           "package test;\n" +
 271.818 +                           "public class Test {\n" +
 271.819 +                           "    private long I = 1;\n" +
 271.820 +		           "}\n");
 271.821 +    }
 271.822 +    
 271.823 +    public void testOptionalElse1() throws Exception {
 271.824 +        performRewriteTest("package test;\n" +
 271.825 +                           "public class Test {\n" +
 271.826 +                           "    {\n" +
 271.827 +                           "        if (true) System.err.println(\"a\");\n" +
 271.828 +                           "    }\n" +
 271.829 +                           "}\n",
 271.830 +                           "if (true) $then else $else$; => if (false) $then else $else$;",
 271.831 +                           "package test;\n" +
 271.832 +                           "public class Test {\n" +
 271.833 +                           "    {\n" +
 271.834 +                           "        if (false) System.err.println(\"a\");\n" +
 271.835 +                           "    }\n" +
 271.836 +		           "}\n");
 271.837 +    }
 271.838 +    
 271.839 +    public void testOptionalElse2() throws Exception {
 271.840 +        performRewriteTest("package test;\n" +
 271.841 +                           "public class Test {\n" +
 271.842 +                           "    {\n" +
 271.843 +                           "        if (true) System.err.println(\"a\");\n" +
 271.844 +                           "        else System.err.println(\"b\");\n" +
 271.845 +                           "    }\n" +
 271.846 +                           "}\n",
 271.847 +                           "if (true) $then else $else$; => if (false) $then else $else$;",
 271.848 +                           "package test;\n" +
 271.849 +                           "public class Test {\n" +
 271.850 +                           "    {\n" +
 271.851 +                           "        if (false) System.err.println(\"a\");\n" +
 271.852 +                           "        else System.err.println(\"b\");\n" +
 271.853 +                           "    }\n" +
 271.854 +		           "}\n");
 271.855 +    }
 271.856 +    
 271.857 +    public void testMultiNewArray() throws Exception {
 271.858 +        performRewriteTest("package test;\n" +
 271.859 +                           "public class Test {\n" +
 271.860 +                           "    private static void t(Object... obj) {\n" +
 271.861 +                           "        Test.t(1);\n" +
 271.862 +                           "    }\n" +
 271.863 +                           "}\n",
 271.864 +                           "test.Test.t($args$) => test.Test.t(new Object[] {$args$})",
 271.865 +                           "package test;\n" +
 271.866 +                           "public class Test {\n" +
 271.867 +                           "    private static void t(Object... obj) {\n" +
 271.868 +                           "        Test.t(new Object[]{1});\n" +
 271.869 +                           "    }\n" +
 271.870 +		           "}\n");
 271.871 +    }
 271.872 +
 271.873 +    public void testFakeBlock2FakeBlock191283() throws Exception {
 271.874 +        performRewriteTest("package test;\n" +
 271.875 +                           "import java.io.InputStream;\n" +
 271.876 +                           "public class Test {\n" +
 271.877 +                           "    private void t() throws Exception {\n" +
 271.878 +                           "        System.err.println(1);\n" +
 271.879 +                           "        lock();\n" +
 271.880 +                           "        System.err.println(2);\n" +
 271.881 +                           "        unlock();\n" +
 271.882 +                           "        System.err.println(3);\n" +
 271.883 +                           "    }\n" +
 271.884 +                           "    private static void lock() {}\n" +
 271.885 +                           "    private static void unlock() {}\n" +
 271.886 +                           "}\n",
 271.887 +                           "test.Test.lock(); $i$; test.Test.unlock(); => lock(); try { $i$; } finally { unlock(); }",
 271.888 +                           "package test;\n" +
 271.889 +                           "import java.io.InputStream;\n" +
 271.890 +                           "public class Test {\n" +
 271.891 +                           "    private void t() throws Exception {\n" +
 271.892 +                           "        System.err.println(1);\n" +
 271.893 +                           "        lock();\n" +
 271.894 +                           "        try {\n" +
 271.895 +                           "            System.err.println(2);\n" +
 271.896 +                           "        } finally {\n" +
 271.897 +                           "            unlock();\n" +
 271.898 +                           "        }\n" +
 271.899 +                           "        System.err.println(3);\n" +
 271.900 +                           "    }\n" +
 271.901 +                           "    private static void lock() {}\n" +
 271.902 +                           "    private static void unlock() {}\n" +
 271.903 +		           "}\n");
 271.904 +    }
 271.905 +    
 271.906 +    public void testOptimizeNegExpression() throws Exception {
 271.907 +        performRewriteTest("package test;\n" +
 271.908 +                           "public class Test {\n" +
 271.909 +                           "    private static void t(int i) {\n" +
 271.910 +                           "        if (i == 0) {\n" +
 271.911 +                           "            System.err.println(1);\n" +
 271.912 +                           "        } else {\n" +
 271.913 +                           "            System.err.println(2);\n" +
 271.914 +                           "        }\n" +
 271.915 +                           "    }\n" +
 271.916 +                           "}\n",
 271.917 +                           "if ($cond) $then; else $else; => if (!$cond) $else; else $then;",
 271.918 +                           "package test;\n" +
 271.919 +                           "public class Test {\n" +
 271.920 +                           "    private static void t(int i) {\n" +
 271.921 +                           "        if (i != 0) {\n" +
 271.922 +                           "            System.err.println(2);\n" +
 271.923 +                           "        } else {\n" +
 271.924 +                           "            System.err.println(1);\n" +
 271.925 +                           "        }\n" +
 271.926 +                           "    }\n" +
 271.927 +		           "}\n");
 271.928 +    }
 271.929 +    
 271.930 +    public void testDontOptimizeNegExpression() throws Exception {
 271.931 +        performRewriteTest("package test;\n" +
 271.932 +                           "public class Test {\n" +
 271.933 +                           "    private static void t(int i) {\n" +
 271.934 +                           "        if (!(i == 0)) {\n" +
 271.935 +                           "            System.err.println(1);\n" +
 271.936 +                           "        } else {\n" +
 271.937 +                           "            System.err.println(2);\n" +
 271.938 +                           "        }\n" +
 271.939 +                           "    }\n" +
 271.940 +                           "}\n",
 271.941 +                           "if (!$cond) $then; else $else; => if (!$cond) $else; else $then;",
 271.942 +                           "package test;\n" +
 271.943 +                           "public class Test {\n" +
 271.944 +                           "    private static void t(int i) {\n" +
 271.945 +                           "        if (!(i == 0)) {\n" +
 271.946 +                           "            System.err.println(2);\n" +
 271.947 +                           "        } else {\n" +
 271.948 +                           "            System.err.println(1);\n" +
 271.949 +                           "        }\n" +
 271.950 +                           "    }\n" +
 271.951 +		           "}\n");
 271.952 +    }
 271.953 +    
 271.954 +    public void testCannotOptimizeNegExpression() throws Exception {
 271.955 +        performRewriteTest("package test;\n" +
 271.956 +                           "public class Test {\n" +
 271.957 +                           "    private static void t(String str) {\n" +
 271.958 +                           "        if (str.isEmpty()) {\n" +
 271.959 +                           "            System.err.println(1);\n" +
 271.960 +                           "        } else {\n" +
 271.961 +                           "            System.err.println(2);\n" +
 271.962 +                           "        }\n" +
 271.963 +                           "    }\n" +
 271.964 +                           "}\n",
 271.965 +                           "if ($cond) $then; else $else; => if (!$cond) $else; else $then;",
 271.966 +                           "package test;\n" +
 271.967 +                           "public class Test {\n" +
 271.968 +                           "    private static void t(String str) {\n" +
 271.969 +                           "        if (!str.isEmpty()) {\n" +
 271.970 +                           "            System.err.println(2);\n" +
 271.971 +                           "        } else {\n" +
 271.972 +                           "            System.err.println(1);\n" +
 271.973 +                           "        }\n" +
 271.974 +                           "    }\n" +
 271.975 +		           "}\n");
 271.976 +    }
 271.977 +    
 271.978 +    public void testOptimizeNegExpressionNeg() throws Exception {
 271.979 +        performOptimizeNegExpressionTest("!s.isEmpty()", "s.isEmpty()");
 271.980 +    }
 271.981 +    
 271.982 +    public void testOptimizeNegExpressionParens() throws Exception {
 271.983 +        performOptimizeNegExpressionTest("!(a.length == 0)", "a.length == 0");
 271.984 +    }
 271.985 +    
 271.986 +    public void testOptimizeNegExpressionEquals() throws Exception {
 271.987 +        performOptimizeNegExpressionTest("i == 0", "i != 0");
 271.988 +    }
 271.989 +    
 271.990 +    public void testOptimizeNegExpressionNotEquals() throws Exception {
 271.991 +        performOptimizeNegExpressionTest("i != 0", "i == 0");
 271.992 +    }
 271.993 +    
 271.994 +    public void testOptimizeNegExpressionTrue() throws Exception {
 271.995 +        performOptimizeNegExpressionTest("true", "false");
 271.996 +    }
 271.997 +    
 271.998 +    public void testOptimizeNegExpressionFalse() throws Exception {
 271.999 +        performOptimizeNegExpressionTest("false", "true");
271.1000 +    }
271.1001 +    
271.1002 +    public void testOptimizeNegExpressionDeMorganAnd() throws Exception {
271.1003 +        performOptimizeNegExpressionTest("a.length != 0 && true", "a.length == 0 || false");
271.1004 +    }
271.1005 +    
271.1006 +    public void testOptimizeNegExpressionDeMorganOr() throws Exception {
271.1007 +        performOptimizeNegExpressionTest("args.length != 0 || false", "args.length == 0 && true");
271.1008 +    }
271.1009 +    
271.1010 +    public void testOptimizeNegExpressionLess() throws Exception {
271.1011 +        performOptimizeNegExpressionTest("i < 0", "i >= 0");
271.1012 +    }
271.1013 +    
271.1014 +    public void testOptimizeNegExpressionLessEq() throws Exception {
271.1015 +        performOptimizeNegExpressionTest("i <= 0", "i > 0");
271.1016 +    }
271.1017 +    
271.1018 +    public void testOptimizeNegExpressionGreater() throws Exception {
271.1019 +        performOptimizeNegExpressionTest("i > 0", "i <= 0");
271.1020 +    }
271.1021 +    
271.1022 +    public void testOptimizeNegExpressionGreaterEq() throws Exception {
271.1023 +        performOptimizeNegExpressionTest("i >= 0", "i < 0");
271.1024 +    }
271.1025 +    
271.1026 +    public void testOptimizeNegExpressionAnd() throws Exception {
271.1027 +        performOptimizeNegExpressionTest("b1 && b2", "!b1 || !b2");
271.1028 +    }
271.1029 +    
271.1030 +    public void test229785a() throws Exception {
271.1031 +        performOptimizeNegExpressionTest("(a[0] == null && a[1] != null) || (a[0] != null && !a[0].equals(a[1]))", "(a[0] != null || a[1] == null) && (a[0] == null || a[0].equals(a[1]))");
271.1032 +    }
271.1033 +    
271.1034 +    public void test229785b() throws Exception {
271.1035 +        performOptimizeNegExpressionTest("a[0] == null && a[1] != null || a[0] != null && !a[0].equals(a[1])", "(a[0] != null || a[1] == null) && (a[0] == null || a[0].equals(a[1]))");
271.1036 +    }
271.1037 +    
271.1038 +    private void performOptimizeNegExpressionTest(String origExpr, String newExpr) throws Exception {
271.1039 +        performRewriteTest("package test;\n" +
271.1040 +                           "public class Test {\n" +
271.1041 +                           "    private static void t(String s, int i, boolean b1, boolean b2, String... a) {\n" +
271.1042 +                           "        if (" + origExpr + ") {\n" +
271.1043 +                           "            System.err.println(1);\n" +
271.1044 +                           "        } else {\n" +
271.1045 +                           "            System.err.println(2);\n" +
271.1046 +                           "        }\n" +
271.1047 +                           "    }\n" +
271.1048 +                           "}\n",
271.1049 +                           "if ($cond) $then; else $else; => if (!$cond) $else; else $then;",
271.1050 +                           "package test;\n" +
271.1051 +                           "public class Test {\n" +
271.1052 +                           "    private static void t(String s, int i, boolean b1, boolean b2, String... a) {\n" +
271.1053 +                           "        if (" + newExpr + ") {\n" +
271.1054 +                           "            System.err.println(2);\n" +
271.1055 +                           "        } else {\n" +
271.1056 +                           "            System.err.println(1);\n" +
271.1057 +                           "        }\n" +
271.1058 +                           "    }\n" +
271.1059 +		           "}\n");
271.1060 +    }
271.1061 +    
271.1062 +    public void testExpression2ExpressionStatementTolerance227429() throws Exception {
271.1063 +        performRewriteTest("package test;\n" +
271.1064 +                           "public class Test {\n" +
271.1065 +                           "    private static void t() {\n" +
271.1066 +                           "        System.err.println(1);\n" +
271.1067 +                           "    }\n" +
271.1068 +                           "}\n",
271.1069 +                           "java.lang.System.err.println($args$) => java.lang.System.out.println($args$);",
271.1070 +                           "package test;\n" +
271.1071 +                           "public class Test {\n" +
271.1072 +                           "    private static void t() {\n" +
271.1073 +                           "        System.out.println(1);\n" +
271.1074 +                           "    }\n" +
271.1075 +		           "}\n");
271.1076 +    }
271.1077 +    
271.1078 +    public void testSplitIfOr() throws Exception {
271.1079 +        performRewriteTest("package test;\n" +
271.1080 +                           "public class Test {\n" +
271.1081 +                           "    private static void t(int i) {\n" +
271.1082 +                           "        if (i == 0 || i == 1) {\n" +
271.1083 +                           "            System.err.println();\n" +
271.1084 +                           "        }\n" +
271.1085 +                           "    }\n" +
271.1086 +                           "}\n",
271.1087 +                           "if ($cond1 || $cond2) $then; => if ($cond1) $then; else if ($cond2) $then;",
271.1088 +                           "package test;\n" +
271.1089 +                           "public class Test {\n" +
271.1090 +                           "    private static void t(int i) {\n" +
271.1091 +                           "        if (i == 0) {\n" +
271.1092 +                           "            System.err.println();\n" +
271.1093 +                           "        } else if (i == 1) {\n" +
271.1094 +                           "            System.err.println();\n" +
271.1095 +                           "        }\n" +
271.1096 +                           "    }\n" +
271.1097 +		           "}\n");
271.1098 +    }
271.1099 +    
271.1100 +    public void testLambdaExpr2Block() throws Exception {
271.1101 +        performRewriteTest("package test;\n" +
271.1102 +                           "import java.util.*;\n" +
271.1103 +                           "public class Test {\n" +
271.1104 +                           "    public void main(List<String> list) {\n" +
271.1105 +                           "        Collections.sort(list, (l, r) -> l.compareTo(r));\n" +
271.1106 +                           "    }\n" +
271.1107 +                           "}\n",
271.1108 +                           "($args$) -> $expr => ($args$) -> { return $expr; }",
271.1109 +                           "package test;\n" +
271.1110 +                           "import java.util.*;\n" +
271.1111 +                           "public class Test {\n" +
271.1112 +                           "    public void main(List<String> list) {\n" +
271.1113 +                           "        Collections.sort(list, (l, r) -> {\n" +
271.1114 +                           "            return l.compareTo(r);\n" +
271.1115 +                           "        });\n" +
271.1116 +                           "    }\n" +
271.1117 +		           "}\n");
271.1118 +    }
271.1119 +    
271.1120 +    public void performRewriteTest(String code, String rule, String golden) throws Exception {
271.1121 +	prepareTest("test/Test.java", code);
271.1122 +
271.1123 +        final String[] split = rule.split("=>");
271.1124 +        assertEquals(2, split.length);
271.1125 +        Map<String, TypeMirror> variablesToTypesTM = new HashMap<String, TypeMirror>();
271.1126 +        String plainRule = PatternCompilerUtilities.parseOutTypesFromPattern(info, split[0], variablesToTypesTM);
271.1127 +        Map<String, String> variablesToTypes = new HashMap<String, String>();
271.1128 +        for (Entry<String, TypeMirror> e : variablesToTypesTM.entrySet()) {
271.1129 +            if (e.getValue() == null) continue;
271.1130 +            variablesToTypes.put(e.getKey(), e.getValue().toString());
271.1131 +        }
271.1132 +        HintDescription hd = HintDescriptionFactory.create()
271.1133 +                                                   .setTrigger(PatternDescription.create(plainRule, variablesToTypes))
271.1134 +                                                   .setWorker(new HintDescription.Worker() {
271.1135 +            @Override public Collection<? extends ErrorDescription> createErrors(HintContext ctx) {
271.1136 +                return Collections.singletonList(ErrorDescriptionFactory.forName(ctx, ctx.getPath(), "", JavaFixUtilities.rewriteFix(ctx, "", ctx.getPath(), split[1])));
271.1137 +            }
271.1138 +        }).produce();
271.1139 +
271.1140 +        List<ErrorDescription> computeHints = new HintsInvoker(HintsSettings.getGlobalSettings(), new AtomicBoolean()).computeHints(info, Collections.singleton(hd));
271.1141 +
271.1142 +        assertEquals(computeHints.toString(), 1, computeHints.size());
271.1143 +
271.1144 +        Fix fix = computeHints.get(0).getFixes().getFixes().get(0);
271.1145 +
271.1146 +	fix.implement();
271.1147 +
271.1148 +        assertEquals(golden, doc.getText(0, doc.getLength()));
271.1149 +    }
271.1150 +
271.1151 +    public void performRemoveFromParentTest(String code, String rule, String golden) throws Exception {
271.1152 +	prepareTest("test/Test.java", code);
271.1153 +
271.1154 +        HintDescription hd = HintDescriptionFactory.create()
271.1155 +                                                   .setTrigger(PatternDescription.create(rule, Collections.<String, String>emptyMap()))
271.1156 +                                                   .setWorker(new HintDescription.Worker() {
271.1157 +            @Override public Collection<? extends ErrorDescription> createErrors(HintContext ctx) {
271.1158 +                return Collections.singletonList(ErrorDescriptionFactory.forName(ctx, ctx.getPath(), "", JavaFixUtilities.removeFromParent(ctx, "", ctx.getPath())));
271.1159 +            }
271.1160 +        }).produce();
271.1161 +
271.1162 +        List<ErrorDescription> computeHints = new HintsInvoker(HintsSettings.getGlobalSettings(), new AtomicBoolean()).computeHints(info, Collections.singleton(hd));
271.1163 +
271.1164 +        assertEquals(computeHints.toString(), 1, computeHints.size());
271.1165 +
271.1166 +        Fix fix = computeHints.get(0).getFixes().getFixes().get(0);
271.1167 +
271.1168 +	fix.implement();
271.1169 +
271.1170 +        assertEquals(golden, doc.getText(0, doc.getLength()));
271.1171 +    }
271.1172 +}
   272.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   272.2 +++ b/sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/spi/java/hints/MatcherUtilitiesTest.java	Sun Oct 23 11:50:54 2016 +0200
   272.3 @@ -0,0 +1,113 @@
   272.4 +/*
   272.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   272.6 + *
   272.7 + * Copyright 2009-2010 Oracle and/or its affiliates. All rights reserved.
   272.8 + *
   272.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  272.10 + * Other names may be trademarks of their respective owners.
  272.11 + *
  272.12 + * The contents of this file are subject to the terms of either the GNU
  272.13 + * General Public License Version 2 only ("GPL") or the Common
  272.14 + * Development and Distribution License("CDDL") (collectively, the
  272.15 + * "License"). You may not use this file except in compliance with the
  272.16 + * License. You can obtain a copy of the License at
  272.17 + * http://www.netbeans.org/cddl-gplv2.html
  272.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  272.19 + * specific language governing permissions and limitations under the
  272.20 + * License.  When distributing the software, include this License Header
  272.21 + * Notice in each file and include the License file at
  272.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  272.23 + * particular file as subject to the "Classpath" exception as provided
  272.24 + * by Oracle in the GPL Version 2 section of the License file that
  272.25 + * accompanied this code. If applicable, add the following below the
  272.26 + * License Header, with the fields enclosed by brackets [] replaced by
  272.27 + * your own identifying information:
  272.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  272.29 + *
  272.30 + * If you wish your version of this file to be governed by only the CDDL
  272.31 + * or only the GPL Version 2, indicate your decision by adding
  272.32 + * "[Contributor] elects to include this software in this distribution
  272.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  272.34 + * single choice of license, a recipient has the option to distribute
  272.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  272.36 + * to extend the choice of license to its licensees as provided above.
  272.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  272.38 + * Version 2 license, then the option applies only if the new code is
  272.39 + * made subject to such option by the copyright holder.
  272.40 + *
  272.41 + * Contributor(s):
  272.42 + *
  272.43 + * Portions Copyrighted 2009-2010 Sun Microsystems, Inc.
  272.44 + */
  272.45 +
  272.46 +package org.netbeans.spi.java.hints;
  272.47 +
  272.48 +import com.sun.source.util.TreePath;
  272.49 +import java.util.Collection;
  272.50 +import java.util.Collections;
  272.51 +import java.util.HashMap;
  272.52 +import java.util.Map;
  272.53 +import java.util.regex.Pattern;
  272.54 +import org.netbeans.modules.java.hints.spiimpl.SPIAccessor;
  272.55 +import org.netbeans.modules.java.hints.spiimpl.TestBase;
  272.56 +import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings;
  272.57 +
  272.58 +/**
  272.59 + *
  272.60 + * @author lahvac
  272.61 + */
  272.62 +public class MatcherUtilitiesTest extends TestBase {
  272.63 +
  272.64 +    public MatcherUtilitiesTest(String name) {
  272.65 +        super(name);
  272.66 +    }
  272.67 +
  272.68 +    public void testParentMatches1() throws Exception {
  272.69 +        String code = "package test; public class Test { private int test() { int i = 0; i = test(|); } }";
  272.70 +        int pos = code.indexOf("|");
  272.71 +
  272.72 +        code = code.replaceAll(Pattern.quote("|"), "");
  272.73 +
  272.74 +        prepareTest("test/Test.java", code);
  272.75 +
  272.76 +        TreePath tp = info.getTreeUtilities().pathFor(pos);
  272.77 +        HintContext ctx = SPIAccessor.getINSTANCE().createHintContext(info, HintsSettings.getGlobalSettings(), null, null, tp, Collections.<String, TreePath>emptyMap(), Collections.<String, Collection<? extends TreePath>>emptyMap(), Collections.<String, String>emptyMap());
  272.78 +
  272.79 +        assertTrue(MatcherUtilities.matches(ctx, ctx.getPath().getParentPath(), "$0 = $_"));
  272.80 +    }
  272.81 +
  272.82 +    public void testParentMatches2() throws Exception {
  272.83 +        String code = "package test; public class Test { private int test() { int i = test(|); } }";
  272.84 +        int pos = code.indexOf("|");
  272.85 +
  272.86 +        code = code.replaceAll(Pattern.quote("|"), "");
  272.87 +
  272.88 +        prepareTest("test/Test.java", code);
  272.89 +
  272.90 +        TreePath tp = info.getTreeUtilities().pathFor(pos);
  272.91 +        HintContext ctx = SPIAccessor.getINSTANCE().createHintContext(info, HintsSettings.getGlobalSettings(), null, null, tp, Collections.<String, TreePath>emptyMap(), Collections.<String, Collection<? extends TreePath>>emptyMap(), Collections.<String, String>emptyMap());
  272.92 +
  272.93 +        assertTrue(MatcherUtilities.matches(ctx, ctx.getPath().getParentPath(), "$1 $0 = $_;"));
  272.94 +    }
  272.95 +
  272.96 +    public void testOutVariables1() throws Exception {
  272.97 +        String code = "package test; public class Test { private int test() { int i = test(|); } }";
  272.98 +        int pos = code.indexOf("|");
  272.99 +
 272.100 +        code = code.replaceAll(Pattern.quote("|"), "");
 272.101 +
 272.102 +        prepareTest("test/Test.java", code);
 272.103 +
 272.104 +        TreePath tp = info.getTreeUtilities().pathFor(pos);
 272.105 +        HintContext ctx = SPIAccessor.getINSTANCE().createHintContext(info, HintsSettings.getGlobalSettings(), null, null, tp, Collections.<String, TreePath>emptyMap(), Collections.<String, Collection<? extends TreePath>>emptyMap(), Collections.<String, String>emptyMap());
 272.106 +
 272.107 +        Map<String, TreePath> outVariables = new HashMap<String, TreePath>();
 272.108 +        Map<String, Collection<? extends TreePath>> outMultiVariables = new HashMap<String, Collection<? extends TreePath>>();
 272.109 +        Map<String, String> outVariables2Names = new HashMap<String, String>();
 272.110 +
 272.111 +        assertTrue(MatcherUtilities.matches(ctx, ctx.getPath().getParentPath(), "$1 $0 = $_;", outVariables, outMultiVariables, outVariables2Names));
 272.112 +        assertEquals("int", outVariables.get("$1").getLeaf().toString());
 272.113 +        assertEquals("i", outVariables2Names.get("$0"));
 272.114 +    }
 272.115 +
 272.116 +}
 272.117 \ No newline at end of file
   273.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   273.2 +++ b/sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/spi/java/hints/TestUtils.java	Sun Oct 23 11:50:54 2016 +0200
   273.3 @@ -0,0 +1,69 @@
   273.4 +/*
   273.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   273.6 + *
   273.7 + * Copyright 2015 Oracle and/or its affiliates. All rights reserved.
   273.8 + *
   273.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  273.10 + * Other names may be trademarks of their respective owners.
  273.11 + *
  273.12 + * The contents of this file are subject to the terms of either the GNU
  273.13 + * General Public License Version 2 only ("GPL") or the Common
  273.14 + * Development and Distribution License("CDDL") (collectively, the
  273.15 + * "License"). You may not use this file except in compliance with the
  273.16 + * License. You can obtain a copy of the License at
  273.17 + * http://www.netbeans.org/cddl-gplv2.html
  273.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  273.19 + * specific language governing permissions and limitations under the
  273.20 + * License.  When distributing the software, include this License Header
  273.21 + * Notice in each file and include the License file at
  273.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  273.23 + * particular file as subject to the "Classpath" exception as provided
  273.24 + * by Oracle in the GPL Version 2 section of the License file that
  273.25 + * accompanied this code. If applicable, add the following below the
  273.26 + * License Header, with the fields enclosed by brackets [] replaced by
  273.27 + * your own identifying information:
  273.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  273.29 + *
  273.30 + * If you wish your version of this file to be governed by only the CDDL
  273.31 + * or only the GPL Version 2, indicate your decision by adding
  273.32 + * "[Contributor] elects to include this software in this distribution
  273.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  273.34 + * single choice of license, a recipient has the option to distribute
  273.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  273.36 + * to extend the choice of license to its licensees as provided above.
  273.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  273.38 + * Version 2 license, then the option applies only if the new code is
  273.39 + * made subject to such option by the copyright holder.
  273.40 + *
  273.41 + * Contributor(s):
  273.42 + *
  273.43 + * Portions Copyrighted 2015 Sun Microsystems, Inc.
  273.44 + */
  273.45 +package org.netbeans.spi.java.hints;
  273.46 +
  273.47 +import org.netbeans.api.editor.mimelookup.MimePath;
  273.48 +import org.netbeans.modules.editor.impl.DocumentFactoryImpl;
  273.49 +import org.netbeans.spi.editor.mimelookup.MimeDataProvider;
  273.50 +import org.openide.util.Lookup;
  273.51 +import org.openide.util.lookup.Lookups;
  273.52 +import org.openide.util.lookup.ServiceProvider;
  273.53 +
  273.54 +/**
  273.55 + *
  273.56 + * @author lahvac
  273.57 + */
  273.58 +public class TestUtils {
  273.59 +
  273.60 +    @ServiceProvider(service = MimeDataProvider.class)
  273.61 +    public static final class MimeDataProviderImpl implements MimeDataProvider {
  273.62 +
  273.63 +        private final Lookup l = Lookups.singleton(new DocumentFactoryImpl());
  273.64 +
  273.65 +        @Override
  273.66 +        public Lookup getLookup(MimePath mimePath) {
  273.67 +            return "text/x-java".equals(mimePath.getPath()) ? l : Lookup.EMPTY;
  273.68 +        }
  273.69 +
  273.70 +    }
  273.71 +
  273.72 +}
   274.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   274.2 +++ b/sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/spi/java/hints/matching/CopyFinderTest.java	Sun Oct 23 11:50:54 2016 +0200
   274.3 @@ -0,0 +1,1612 @@
   274.4 +/*
   274.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   274.6 + *
   274.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
   274.8 + *
   274.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  274.10 + * Other names may be trademarks of their respective owners.
  274.11 + *
  274.12 + * The contents of this file are subject to the terms of either the GNU
  274.13 + * General Public License Version 2 only ("GPL") or the Common
  274.14 + * Development and Distribution License("CDDL") (collectively, the
  274.15 + * "License"). You may not use this file except in compliance with the
  274.16 + * License. You can obtain a copy of the License at
  274.17 + * http://www.netbeans.org/cddl-gplv2.html
  274.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  274.19 + * specific language governing permissions and limitations under the
  274.20 + * License.  When distributing the software, include this License Header
  274.21 + * Notice in each file and include the License file at
  274.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  274.23 + * particular file as subject to the "Classpath" exception as provided
  274.24 + * by Oracle in the GPL Version 2 section of the License file that
  274.25 + * accompanied this code. If applicable, add the following below the
  274.26 + * License Header, with the fields enclosed by brackets [] replaced by
  274.27 + * your own identifying information:
  274.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  274.29 + *
  274.30 + * Contributor(s):
  274.31 + *
  274.32 + * Portions Copyrighted 2007-2010 Sun Microsystems, Inc.
  274.33 + */
  274.34 +package org.netbeans.spi.java.hints.matching;
  274.35 +
  274.36 +import com.sun.source.tree.BlockTree;
  274.37 +import com.sun.source.tree.StatementTree;
  274.38 +import com.sun.source.tree.Tree;
  274.39 +import com.sun.source.tree.VariableTree;
  274.40 +import com.sun.source.util.SourcePositions;
  274.41 +import com.sun.source.util.TreePath;
  274.42 +import com.sun.source.util.TreePathScanner;
  274.43 +import java.io.File;
  274.44 +import java.util.Arrays;
  274.45 +import java.util.Collection;
  274.46 +import java.util.Collections;
  274.47 +import java.util.EnumSet;
  274.48 +import java.util.HashMap;
  274.49 +import java.util.HashSet;
  274.50 +import java.util.LinkedList;
  274.51 +import java.util.List;
  274.52 +import java.util.Map;
  274.53 +import java.util.Map.Entry;
  274.54 +import java.util.Set;
  274.55 +import java.util.concurrent.atomic.AtomicBoolean;
  274.56 +import javax.lang.model.element.VariableElement;
  274.57 +import javax.lang.model.type.TypeMirror;
  274.58 +import javax.swing.text.Document;
  274.59 +import org.netbeans.api.java.lexer.JavaTokenId;
  274.60 +import org.netbeans.api.java.source.CompilationInfo;
  274.61 +import org.netbeans.api.java.source.JavaSource;
  274.62 +import org.netbeans.api.java.source.JavaSource.Phase;
  274.63 +import org.netbeans.api.java.source.SourceUtilsTestUtil;
  274.64 +import org.netbeans.api.java.source.TestUtilities;
  274.65 +import org.netbeans.api.java.source.TreePathHandle;
  274.66 +import org.netbeans.api.java.source.matching.MatchingTestAccessor;
  274.67 +import org.netbeans.api.java.source.matching.Pattern;
  274.68 +import org.netbeans.api.lexer.Language;
  274.69 +import org.netbeans.junit.NbTestCase;
  274.70 +import org.netbeans.modules.java.hints.introduce.IntroduceMethodFix;
  274.71 +import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch;
  274.72 +import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch.BulkPattern;
  274.73 +import org.netbeans.modules.java.hints.spiimpl.pm.PatternCompiler;
  274.74 +import org.netbeans.modules.java.hints.spiimpl.pm.PatternCompilerUtilities;
  274.75 +import org.netbeans.modules.java.source.matching.CopyFinder;
  274.76 +import org.netbeans.modules.java.source.matching.CopyFinder.Cancel;
  274.77 +import org.netbeans.modules.java.source.matching.CopyFinder.Options;
  274.78 +import org.netbeans.modules.java.source.matching.CopyFinder.VariableAssignments;
  274.79 +import org.openide.cookies.EditorCookie;
  274.80 +import org.openide.filesystems.FileObject;
  274.81 +import org.openide.filesystems.FileUtil;
  274.82 +import org.openide.loaders.DataObject;
  274.83 +
  274.84 +/**
  274.85 + *
  274.86 + * @author Jan Lahoda
  274.87 + */
  274.88 +public class CopyFinderTest extends NbTestCase {
  274.89 +
  274.90 +    public CopyFinderTest(String testName) {
  274.91 +        super(testName);
  274.92 +    }
  274.93 +
  274.94 +//    public static TestSuite suite() {
  274.95 +//        NbTestSuite nb = new NbTestSuite();
  274.96 +//
  274.97 +//        nb.addTest(new CopyFinderTest("testCorrectSite3"));
  274.98 +//
  274.99 +//        return nb;
 274.100 +//    }
 274.101 +
 274.102 +    @Override
 274.103 +    protected void setUp() throws Exception {
 274.104 +        SourceUtilsTestUtil.prepareTest(new String[0], new Object[0]);
 274.105 +        super.setUp();
 274.106 +    }
 274.107 +
 274.108 +    public void testSimple1() throws Exception {
 274.109 +        performTest("package test; public class Test {public void test() {int i = 0; y = i + i; y = i + i;}}", 90 - 22, 95 - 22, 101 - 22, 106 - 22);
 274.110 +    }
 274.111 +
 274.112 +//    public void testSimple2() throws Exception {
 274.113 +//        performTest("package test; public class Test {public void test() {int i = 0; y = i + i; y = i + i + i;}}", 90 - 22, 95 - 22, 101 - 22, 106 - 22);
 274.114 +//    }
 274.115 +
 274.116 +    public void testSimple3() throws Exception {
 274.117 +        performTest("package test; public class Test {public void test() {int i = System.currentTimeMillis(); y = System.currentTimeMillis();}}", 83 - 22, 109 - 22, 115 - 22, 141 - 22);
 274.118 +    }
 274.119 +
 274.120 +    public void testSimple4() throws Exception {
 274.121 +        performTest("package test; import java.util.ArrayList; public class Test {public void test() {Object o = new ArrayList<String>();o = new ArrayList<String>();}}", 114 - 22, 137- 22, 142 - 22, 165 - 22);
 274.122 +    }
 274.123 +
 274.124 +    public void testSimple5() throws Exception {
 274.125 +        performTest("package test; public class Test {public void test() {Object o = null; String s = (String) o; s = (String) o; s = (String) null; o = (Object) o;}}", 103 - 22, 113 - 22, 119 - 22, 129 - 22);
 274.126 +    }
 274.127 +
 274.128 +    public void testSimple6() throws Exception {
 274.129 +        performTest("package test; public class Test {public void test() {int i = 0; y = i + i; y = i + i;} public void test2() {int i = 0; y = i + i; y = i + i;}}", 90 - 22, 95 - 22, 101 - 22, 106 - 22);
 274.130 +    }
 274.131 +
 274.132 +    public void testSimple7() throws Exception {
 274.133 +        performTest("package test; public class Test {public void test() {int i = 0; y = i != 0 ? i + i : i * i; y = i != 0 ? i + i : i * i; y = i != 1 ? i + i : i * i; y = i == 0 ? i + i : i * i; y = i != 0 ? i * i : i * i; y = i != 0 ? i + i : i + i; y = i != 0 ? i + i : i * 1;}}", 90 - 22, 112 - 22, 118 - 22, 140 - 22);
 274.134 +    }
 274.135 +
 274.136 +    public void testSimple8() throws Exception {
 274.137 +        performTest("package test; public class Test {public void test() {int i = 0; int y = -i; y = -i; y = +i; y = +y;}}", 94 - 22, 96 - 22, 102 - 22, 104 - 22);
 274.138 +    }
 274.139 +
 274.140 +    public void testSimple9() throws Exception {
 274.141 +        performTest("package test; public class Test {public void test() {int i = 0; int y = i *= 9; y = i *= 9; y = i /= 9; y = i *= 8; y = y *= 9;}}", 94 - 22, 100 - 22, 106 - 22, 112 - 22);
 274.142 +    }
 274.143 +
 274.144 +    public void testSimple10() throws Exception {
 274.145 +        performTest("package test; public class Test {public void test() {int[] i = null; int y = i[1]; y = i[1]; y = i[y]; y = i[0];}}", 99 - 22, 103 - 22, 109 - 22, 113 - 22);
 274.146 +    }
 274.147 +
 274.148 +    public void testSimple11() throws Exception {
 274.149 +        performTest("package test; public class Test {public void test() {int[] i = new int[0]; i = new int[0]; i = new int[1];}}", 85 - 22, 95 - 22, 101 - 22, 111 - 22);
 274.150 +    }
 274.151 +
 274.152 +    public void testSimple12() throws Exception {
 274.153 +        performTest("package test; public class Test {public void test() {int[] i = new int[1]; i = new int[1]; i = new int[0];}}", 85 - 22, 95 - 22, 101 - 22, 111 - 22);
 274.154 +    }
 274.155 +
 274.156 +    public void testSimple13() throws Exception {
 274.157 +        performTest("package test; public class Test {public void test() {int i = 0; int y = (i); y = (i); y = i;}}", 94 - 22, 97 - 22, 103 - 22, 106 - 22);
 274.158 +    }
 274.159 +
 274.160 +    public void testSimple14() throws Exception {
 274.161 +        performTest("package test; public class Test {public void test() {Object o = null; boolean b = o instanceof String; b = o instanceof String; b = o instanceof Object;}}", 104 - 22, 123 - 22, 129 - 22, 148 - 22);
 274.162 +    }
 274.163 +
 274.164 +    public void testSimple15() throws Exception {
 274.165 +        performTest("package test; public class Test {private int x = 1; private int y = 1; public void test() {int x = 1; int y = 1;}}", 90 - 22, 91 - 22, 71 - 22, 72 - 22, 121 - 22, 122 - 22, 132 - 22, 133 - 22);
 274.166 +    }
 274.167 +
 274.168 +    public void testSimple16() throws Exception {
 274.169 +        performTest("package test; public class Test {public void test(int i) {int y = \"\".length(); test(\"\".length());} }", 88 - 22, 99 - 22, 106 - 22, 117 - 22);
 274.170 +    }
 274.171 +
 274.172 +    public void testSimple17() throws Exception {
 274.173 +        performTest("package test; public class Test {public void test2() {int a = test(test(test(1))); a = test(test(test(1))); a = test(test(test(1)));} public int test(int i) {return 0;} }", 94 - 22, 101 - 22, 119 - 22, 126 - 22, 144 - 22, 151 - 22);
 274.174 +    }
 274.175 +
 274.176 +    public void testMemberSelectAndIdentifierAreSame() throws Exception {
 274.177 +        performTest("package test; import static java.lang.String.*; public class Test {public void test1() {|String.valueOf(2)|; |valueOf(2)|;} }");
 274.178 +    }
 274.179 +
 274.180 +    public void testVariables1() throws Exception {
 274.181 +        performVariablesTest("package test; import static java.lang.String.*; public class Test {public void test1() {String.valueOf(2+4);} }",
 274.182 +                             "java.lang.String.valueOf($1)",
 274.183 +                             new Pair[] {new Pair<String, int[]>("$1", new int[] {134 - 31, 137 - 31})},
 274.184 +                             new Pair[0]);
 274.185 +    }
 274.186 +
 274.187 +    public void testAssert1() throws Exception {
 274.188 +        performTest("package test; public class Test {public void test() {int i = 0; |assert i == 1;| |assert i == 1;|}}");
 274.189 +    }
 274.190 +
 274.191 +    public void testReturn1() throws Exception {
 274.192 +        performTest("package test; public class Test {public int test1() {|return 1;|} public int test2() {|return 1;|}}");
 274.193 +    }
 274.194 +
 274.195 +    public void testIf1() throws Exception {
 274.196 +        performTest("package test; public class Test {public void test() { int i = 0; int j; |if (i == 0) {j = 1;} else {j = 2;}| |if (i == 0) {j = 1;} else {j = 2;}| } }");
 274.197 +    }
 274.198 +
 274.199 +    public void testExpressionStatement1() throws Exception {
 274.200 +        performTest("package test; public class Test {public void test() { int i = 0; |i = 1;| |i = 1;| } }");
 274.201 +    }
 274.202 +
 274.203 +    public void testBlock1() throws Exception {
 274.204 +        performTest("package test; public class Test {public void test() { int i = 0; |{i = 1;}| |{i = 1;}| } }");
 274.205 +    }
 274.206 +
 274.207 +    public void testSynchronized1() throws Exception {
 274.208 +        performTest("package test; public class Test {public void test() { Object o = null; int i = 0; |synchronized (o) {i = 1;}| |synchronized (o) {i = 1;}| } }");
 274.209 +    }
 274.210 +
 274.211 +//    public void testEnhancedForLoop() throws Exception {
 274.212 +//        performTest("package test; public class Test {public void test(Iterable<String> i) { |for (String s : i) { System.err.println(); }| |for (String s : i) { System.err.println(); }| }");
 274.213 +//    }
 274.214 +
 274.215 +//    public void testConstants() throws Exception {
 274.216 +//        performTest("package test; public class Test {public static final int A = 3; public void test() { int i = |3|; i = |test.Test.A|; } }");
 274.217 +//    }
 274.218 +
 274.219 +    public void testOverridingImplementing1() throws Exception {
 274.220 +        performVariablesTest("package test; public class Test implements Runnable { { this.run(); } public void run() { } } }",
 274.221 +                             "$0{java.lang.Runnable}.run()",
 274.222 +                             new Pair[] {new Pair<String, int[]>("$0", new int[] {56, 60})},
 274.223 +                             new Pair[0]);
 274.224 +    }
 274.225 +
 274.226 +    public void testMemberSelectCCE() throws Exception {
 274.227 +        //should not throw a CCE
 274.228 +        //(selected regions are not duplicates)
 274.229 +        performTest("package test; public class Test {public static class T extends Test { public void test() { |Test.test|(); |System.err.println|(); } } }", false);
 274.230 +    }
 274.231 +
 274.232 +    public void testLocalVariable() throws Exception {
 274.233 +        performVariablesTest("package test; public class Test {public void test1() { { int y; y = 1; } int z; { int y; z = 1; } } }",
 274.234 +                             "{ int $1; $1 = 1; }",
 274.235 +                             new Pair[0],
 274.236 +                             new Pair[] {new Pair<String, String>("$1", "y")});
 274.237 +    }
 274.238 +
 274.239 +    public void testStatementAndSingleBlockStatementAreSame1() throws Exception {
 274.240 +        performVariablesTest("package test; public class Test {public void test1() { { int x; { x = 1; } } } }",
 274.241 +                             "{ int $1; $1 = 1; }",
 274.242 +                             new Pair[0],
 274.243 +                             new Pair[] {new Pair<String, String>("$1", "x")});
 274.244 +    }
 274.245 +
 274.246 +    public void testStatementAndSingleBlockStatementAreSame2() throws Exception {
 274.247 +        performVariablesTest("package test; public class Test {public void test1() { { int x; x = 1; } } }",
 274.248 +                             "{ int $1; { $1 = 1; } }",
 274.249 +                             new Pair[0],
 274.250 +                             new Pair[] {new Pair<String, String>("$1", "x")});
 274.251 +    }
 274.252 +
 274.253 +    public void testStatementVariables() throws Exception {
 274.254 +        performVariablesTest("package test; public class Test {public int test1() { if (true) return 1; else return 2; } }",
 274.255 +                             "if ($1) $2; else $3;",
 274.256 +                             new Pair[] {
 274.257 +                                  new Pair<String, int[]>("$1", new int[] {89 - 31, 93 - 31}),
 274.258 +                                  new Pair<String, int[]>("$2", new int[] {95 - 31, 104 - 31}),
 274.259 +                                  new Pair<String, int[]>("$3", new int[] {110 - 31, 119 - 31})
 274.260 +                             },
 274.261 +                             new Pair[0]);
 274.262 +    }
 274.263 +
 274.264 +    public void testThrowStatement() throws Exception {
 274.265 +        performVariablesTest("package test; public class Test {public void test() { throw new NullPointerException(); throw new IllegalStateException();} }",
 274.266 +                             "throw new NullPointerException()",
 274.267 +                             new Pair[0],
 274.268 +                             new Pair[0]);
 274.269 +    }
 274.270 +
 274.271 +    public void testMultiStatementVariables1() throws Exception {
 274.272 +        performVariablesTest("package test; public class Test { public int test1() { System.err.println(); System.err.println(); int i = 3; System.err.println(i); System.err.println(i); return i; } }",
 274.273 +                             "{ $s1$; int $i = 3; $s2$; return $i; }",
 274.274 +                             new Pair[0],
 274.275 +                             new Pair[] {
 274.276 +                                  new Pair<String, int[]>("$s1$", new int[] {55, 76, 77, 98}),
 274.277 +                                  new Pair<String, int[]>("$s2$", new int[] {110, 132, 133, 155})
 274.278 +                             },
 274.279 +                             new Pair[] {new Pair<String, String>("$i", "i")});
 274.280 +    }
 274.281 +
 274.282 +    public void testMultiStatementVariables2() throws Exception {
 274.283 +        performVariablesTest("package test; public class Test { public int test1() { int i = 3; return i; } }",
 274.284 +                             "{ $s1$; int $i = 3; $s2$; return $i; }",
 274.285 +                             new Pair[0],
 274.286 +                             new Pair[] {
 274.287 +                                  new Pair<String, int[]>("$s1$", new int[] {}),
 274.288 +                                  new Pair<String, int[]>("$s2$", new int[] {}),
 274.289 +                             },
 274.290 +                             new Pair[] {new Pair<String, String>("$i", "i")});
 274.291 +    }
 274.292 +
 274.293 +    public void testMultiStatementVariablesAndBlocks1() throws Exception {
 274.294 +        performVariablesTest("package test; public class Test { public void test1() { if (true) System.err.println(); } }",
 274.295 +                             "if ($c) {$s1$; System.err.println(); $s2$; }",
 274.296 +                             new Pair[] {new Pair<String, int[]>("$c", new int[] {60, 64})},
 274.297 +                             new Pair[] {
 274.298 +                                  new Pair<String, int[]>("$s1$", new int[] {}),
 274.299 +                                  new Pair<String, int[]>("$s2$", new int[] {}),
 274.300 +                             },
 274.301 +                             new Pair[0]);
 274.302 +    }
 274.303 +
 274.304 +    public void testMultiStatementVariablesAndBlocks2() throws Exception {
 274.305 +        performVariablesTest("package test; public class Test { public void test1() { if (true) System.err.println(); } }",
 274.306 +                             "if ($c) {$s1$; System.err.println(); }",
 274.307 +                             new Pair[] {new Pair<String, int[]>("$c", new int[] {60, 64})},
 274.308 +                             new Pair[] {
 274.309 +                                  new Pair<String, int[]>("$s1$", new int[] {}),
 274.310 +                             },
 274.311 +                             new Pair[0]);
 274.312 +    }
 274.313 +
 274.314 +    public void testMultiStatementVariablesAndBlocks3() throws Exception {
 274.315 +        performVariablesTest("package test; public class Test { public void test1() { if (true) System.err.println(); } }",
 274.316 +                             "if ($c) {System.err.println(); $s2$; }",
 274.317 +                             new Pair[] {new Pair<String, int[]>("$c", new int[] {60, 64})},
 274.318 +                             new Pair[] {
 274.319 +                                  new Pair<String, int[]>("$s2$", new int[] {}),
 274.320 +                             },
 274.321 +                             new Pair[0]);
 274.322 +    }
 274.323 +
 274.324 +    public void testMultiStatementVariablesAndBlocks4() throws Exception {
 274.325 +        performVariablesTest("package test; public class Test { public void test1() { if (true) System.err.println(); } }",
 274.326 +                             "if ($c) { $s$; }",
 274.327 +                             new Pair[] {new Pair<String, int[]>("$c", new int[] {60, 64})},
 274.328 +                             new Pair[] {
 274.329 +                                  new Pair<String, int[]>("$s$", new int[] {66, 87}),
 274.330 +                             },
 274.331 +                             new Pair[0]);
 274.332 +    }
 274.333 +
 274.334 +    public void testVariableVerification() throws Exception {
 274.335 +        performVariablesTest("package test; public class Test { public void test1(String[] a, String[] b) { for (int c = 0; c < a.length; c++) { String s = b[c]; System.err.println(s); } } }",
 274.336 +                             "for(int $i = 0; $i < $array.length; $i++) { $T $var = $array[$i]; $stmts$; }",
 274.337 +                             new Pair[0],
 274.338 +                             new Pair[0],
 274.339 +                             new Pair[0],
 274.340 +                             true);
 274.341 +    }
 274.342 +
 274.343 +    public void testFor() throws Exception {
 274.344 +        performVariablesTest("package test; public class Test { public void test1(String[] a) { for (int c = 0; c < a.length; c++) { String s = a[c]; System.err.println(s); } } }",
 274.345 +                             "for(int $i = 0; $i < $array.length; $i++) { $T $var = $array[$i]; $stmts$; }",
 274.346 +                             new Pair[] {
 274.347 +                                  new Pair<String, int[]>("$array", new int[] {117 - 31, 118 - 31}),
 274.348 +                                  new Pair<String, int[]>("$T", new int[] {134 - 31, 140 - 31}),
 274.349 +                             },
 274.350 +                             new Pair[] {
 274.351 +                                  new Pair<String, int[]>("$stmts$", new int[] {151 - 31, 173 - 31}),
 274.352 +                             },
 274.353 +                             new Pair[] {
 274.354 +                                  new Pair<String, String>("$i", "c"),
 274.355 +                                  new Pair<String, String>("$var", "s"),
 274.356 +                             });
 274.357 +    }
 274.358 +
 274.359 +    public void testEnhancedFor() throws Exception {
 274.360 +        performVariablesTest("package test; public class Test { public void test1(String[] a) { for (String s : a) { System.err.println(s); } } }",
 274.361 +                             "for($T $var : $array) { $stmts$; }",
 274.362 +                             new Pair[] {
 274.363 +                                  new Pair<String, int[]>("$array", new int[] {113 - 31, 114 - 31}),
 274.364 +                                  new Pair<String, int[]>("$T", new int[] {102 - 31, 108 - 31}),
 274.365 +                             },
 274.366 +                             new Pair[] {
 274.367 +                                  new Pair<String, int[]>("$stmts$", new int[] {118 - 31, 140 - 31}),
 274.368 +                             },
 274.369 +                             new Pair[] {
 274.370 +                                  new Pair<String, String>("$var", "s"),
 274.371 +                             });
 274.372 +    }
 274.373 +
 274.374 +    public void testWhile() throws Exception {
 274.375 +        performVariablesTest("package test; public class Test { public void test1(String[] a) { int c = 0; while  (c < a.length) { String s = a[c]; System.err.println(s); c++; } } }",
 274.376 +                             "while ($i < $array.length) { $T $var = $array[$i]; $stmts$; $i++; }",
 274.377 +                             new Pair[] {
 274.378 +                                  new Pair<String, int[]>("$array", new int[] {120 - 31, 121 - 31}),
 274.379 +                                  new Pair<String, int[]>("$T", new int[] {132 - 31, 138 - 31}),
 274.380 +                                  new Pair<String, int[]>("$i", new int[] {116 - 31, 117 - 31}),
 274.381 +                             },
 274.382 +                             new Pair[] {
 274.383 +                                  new Pair<String, int[]>("$stmts$", new int[] {149 - 31, 171 - 31}),
 274.384 +                             },
 274.385 +                             new Pair[] {
 274.386 +                                  new Pair<String, String>("$var", "s"),
 274.387 +                             });
 274.388 +    }
 274.389 +
 274.390 +    public void testDoWhile() throws Exception {
 274.391 +        performVariablesTest("package test; public class Test { public void test1(String[] a) { int c = 0; do { String s = a[c]; System.err.println(s); c++; } while  (c < a.length); } }",
 274.392 +                             "do { $T $var = $array[$i]; $stmts$; $i++; } while ($i < $array.length);",
 274.393 +                             new Pair[] {
 274.394 +                                  new Pair<String, int[]>("$array", new int[] {124 - 31, 125 - 31}),
 274.395 +                                  new Pair<String, int[]>("$T", new int[] {113 - 31, 119 - 31}),
 274.396 +                                  new Pair<String, int[]>("$i", new int[] {126 - 31, 127 - 31}),
 274.397 +                             },
 274.398 +                             new Pair[] {
 274.399 +                                  new Pair<String, int[]>("$stmts$", new int[] {130 - 31, 152 - 31}),
 274.400 +                             },
 274.401 +                             new Pair[] {
 274.402 +                                  new Pair<String, String>("$var", "s"),
 274.403 +                             });
 274.404 +    }
 274.405 +
 274.406 +    public void testArrayType() throws Exception {
 274.407 +        performVariablesTest("package test; public class Test { public void test1() { int[][] a; } }",
 274.408 +                             "$T[]",
 274.409 +                             new Pair[] {
 274.410 +                                  new Pair<String, int[]>("$T", new int[] {87 - 31, /*92*//*XXX:*/94 - 31}),
 274.411 +                             },
 274.412 +                             new Pair[0],
 274.413 +                             new Pair[0]);
 274.414 +    }
 274.415 +
 274.416 +    public void testSemiMatchPackage() throws Exception {
 274.417 +        performVariablesTest("package test; import javax.lang.model.type.TypeMirror; public class Test { }",
 274.418 +                             "$T{java.lang.Object}.type",
 274.419 +                             new Pair[0],
 274.420 +                             new Pair[0],
 274.421 +                             new Pair[0],
 274.422 +                             true);
 274.423 +    }
 274.424 +
 274.425 +    public void testNullType() throws Exception {
 274.426 +        performVariablesTest("package javax.lang.model.type; public class Test { }",
 274.427 +                             "$T{java.lang.Object}.type",
 274.428 +                             new Pair[0],
 274.429 +                             new Pair[0],
 274.430 +                             new Pair[0],
 274.431 +                             true);
 274.432 +    }
 274.433 +
 274.434 +    public void testTryCatch() throws Exception {
 274.435 +        performVariablesTest("package test; import java.io.*; public class Test { public void test() { InputStream ins = null; try { ins = new FileInputStream(\"\"); } catch (IOException e) { e.printStackTrace(); } finally {ins.close();} } }",
 274.436 +                             "try {$stmts$;} catch (java.io.IOException $e) {$e.printStackTrace();} finally {$finally$;}",
 274.437 +                             new Pair[] {
 274.438 +                                   new Pair<String, int[]>("$e", new int[] {176 - 31 - 2, 189 - 31 - 2}),
 274.439 +                             },
 274.440 +                             new Pair[] {
 274.441 +                                  new Pair<String, int[]>("$stmts$", new int[] {134 - 31, 166 - 31 - 2}),
 274.442 +                                  new Pair<String, int[]>("$finally$", new int[] {225 - 31 - 2, 237 - 31 - 2}),
 274.443 +                             },
 274.444 +                             new Pair[] {
 274.445 +                                  new Pair<String, String>("$e", "e"),
 274.446 +                             });
 274.447 +    }
 274.448 +
 274.449 +    public void testMultiParameters1() throws Exception {
 274.450 +        performVariablesTest("package test; public class Test { { java.util.Arrays.asList(\"a\", \"b\", \"c\"); }",
 274.451 +                             "java.util.Arrays.asList($1$)",
 274.452 +                             new Pair[] {
 274.453 +                             },
 274.454 +                             new Pair[] {
 274.455 +                                new Pair<String, int[]>("$1$", new int[] {60, 63, 65, 68, 70, 73}),
 274.456 +                             },
 274.457 +                             new Pair[] {
 274.458 +                             });
 274.459 +    }
 274.460 +
 274.461 +    public void testMultiParameters2() throws Exception {
 274.462 +        performVariablesTest("package test; public class Test { { java.util.Arrays.asList(new String(\"a\"), \"b\", \"c\"); }",
 274.463 +                             "java.util.Arrays.asList(new String(\"a\"), $1$)",
 274.464 +                             new Pair[] {
 274.465 +                             },
 274.466 +                             new Pair[] {
 274.467 +                                new Pair<String, int[]>("$1$", new int[] {77, 80, 82, 85}),
 274.468 +                             },
 274.469 +                             new Pair[] {
 274.470 +                             });
 274.471 +    }
 274.472 +
 274.473 +    public void testMultiParameters3() throws Exception {
 274.474 +        performVariablesTest("package test; public class Test { { java.util.Arrays.asList(); }",
 274.475 +                             "java.util.Arrays.asList($1$)",
 274.476 +                             new Pair[] {
 274.477 +                             },
 274.478 +                             new Pair[] {
 274.479 +                                new Pair<String, int[]>("$1$", new int[] {}),
 274.480 +                             },
 274.481 +                             new Pair[] {
 274.482 +                             });
 274.483 +    }
 274.484 +
 274.485 +    public void testTypeParameters() throws Exception {
 274.486 +        performVariablesTest("package test; public class Test { { java.util.Arrays.<String>asList(\"a\", \"b\"); }",
 274.487 +                             "java.util.Arrays.<$1>asList($1$)",
 274.488 +                             new Pair[] {
 274.489 +                                   new Pair<String, int[]>("$1", new int[] {85 - 31, 91 - 31}),
 274.490 +                             },
 274.491 +                             new Pair[] {
 274.492 +                             },
 274.493 +                             new Pair[] {
 274.494 +                             });
 274.495 +    }
 274.496 +
 274.497 +    public void testModifiers() throws Exception {
 274.498 +        performVariablesTest("package test; public class Test { private String s; }",
 274.499 +                             "$mods$ java.lang.String $name;",
 274.500 +                             new Pair[] {
 274.501 +                                 new Pair<String, int[]>("$name", new int[] {65 - 31, 82 - 31}),
 274.502 +                                 new Pair<String, int[]>("$mods$", new int[] {65 - 31, 72 - 31}), //XXX: shouldn't this be a multi-variable?
 274.503 +                             },
 274.504 +                             new Pair[] {
 274.505 +                             },
 274.506 +                             new Pair[] {
 274.507 +                                  new Pair<String, String>("$name", "s"),
 274.508 +                             });
 274.509 +    }
 274.510 +
 274.511 +    public void testVariableIsFullPattern1() throws Exception {
 274.512 +        performVariablesTest("package test; public class Test { private int a; {System.err.println(a);} }",
 274.513 +                             "$0{int}",
 274.514 +                             new Pair[] {
 274.515 +                                 new Pair<String, int[]>("$0", new int[] {100 - 31, 101 - 31}),
 274.516 +                             },
 274.517 +                             new Pair[] {
 274.518 +                             },
 274.519 +                             new Pair[] {
 274.520 +                             });
 274.521 +    }
 274.522 +
 274.523 +    public void testVariableIsFullPattern2() throws Exception {
 274.524 +        performVariablesTest("package test; public class Test { private int a; {System.err.println(a);} }",
 274.525 +                             "$0{int}",
 274.526 +                             new Pair[] {
 274.527 +                                 new Pair<String, int[]>("$0", new int[] {100 - 31, 101 - 31}),
 274.528 +                             },
 274.529 +                             new Pair[] {
 274.530 +                             },
 274.531 +                             new Pair[] {
 274.532 +                             },
 274.533 +                             false,
 274.534 +                             true);
 274.535 +    }
 274.536 +
 274.537 +    public void testNoCCEForVariableName() throws Exception {
 274.538 +        performVariablesTest("package test; public class Test { { int[] arr = null; int a; arr[a] = 0;} }",
 274.539 +                             "int $a; $a = 0;",
 274.540 +                             new Pair[] {
 274.541 +                             },
 274.542 +                             new Pair[] {
 274.543 +                             },
 274.544 +                             new Pair[] {
 274.545 +                             },
 274.546 +                             true,
 274.547 +                             true);
 274.548 +    }
 274.549 +
 274.550 +    public void testVerifySameTrees1() throws Exception {
 274.551 +        performVariablesTest("package test; public class Test { { if (true) { System.err.println(); } else { System.err.println(); System.err.println(); } } }",
 274.552 +                             "if ($c) $s; else $s;",
 274.553 +                             new Pair[] {
 274.554 +                             },
 274.555 +                             new Pair[] {
 274.556 +                             },
 274.557 +                             new Pair[] {
 274.558 +                             },
 274.559 +                             true,
 274.560 +                             true);
 274.561 +    }
 274.562 +
 274.563 +    public void testVerifySameTreesMultiVariables1() throws Exception {
 274.564 +        performVariablesTest("package test; public class Test { { if (true) { System.err.println(); System.err.println(); } else { System.err.println(); System.err.println(); System.err.println(); } } }",
 274.565 +                             "if ($c) { $s$;} else { $s$; }",
 274.566 +                             new Pair[] {
 274.567 +                             },
 274.568 +                             new Pair[] {
 274.569 +                             },
 274.570 +                             new Pair[] {
 274.571 +                             },
 274.572 +                             true,
 274.573 +                             true);
 274.574 +    }
 274.575 +
 274.576 +    public void testVerifySameTreesMultiVariables2() throws Exception {
 274.577 +        performVariablesTest("package test; public class Test { { if (true) { System.err.println(1); System.err.println(); } else System.err.println(1); } }",
 274.578 +                             "if ($c) { System.err.println(1); $s2$; } else { System.err.println(1); $s2$; }",
 274.579 +                             new Pair[] {
 274.580 +                             },
 274.581 +                             new Pair[] {
 274.582 +                             },
 274.583 +                             new Pair[] {
 274.584 +                             },
 274.585 +                             true,
 274.586 +                             true);
 274.587 +    }
 274.588 +
 274.589 +    public void testVerifySameTreesMultiVariables3() throws Exception {
 274.590 +        performVariablesTest("package test; public class Test { { if (true) { System.err.println(); System.err.println(1); } else System.err.println(1); } }",
 274.591 +                             "if ($c) { $s1$; System.err.println(1); } else { $s1$; System.err.println(1); }",
 274.592 +                             new Pair[] {
 274.593 +                             },
 274.594 +                             new Pair[] {
 274.595 +                             },
 274.596 +                             new Pair[] {
 274.597 +                             },
 274.598 +                             true,
 274.599 +                             true);
 274.600 +    }
 274.601 +
 274.602 +    public void XtestVerifySameTreesMultiVariables4() throws Exception {
 274.603 +        performVariablesTest("package test; public class Test { { if (true) { System.err.println(); System.err.println(1); System.err.println(); } else System.err.println(1); } }",
 274.604 +                             "if ($c) { $s1$; System.err.println(1); $s2$; } else { $s1$; System.err.println(1); $s2$; }",
 274.605 +                             new Pair[] {
 274.606 +                             },
 274.607 +                             new Pair[] {
 274.608 +                             },
 274.609 +                             new Pair[] {
 274.610 +                             },
 274.611 +                             true,
 274.612 +                             true);
 274.613 +    }
 274.614 +
 274.615 +    public void testVerifySameTreesMultiVariables5() throws Exception {
 274.616 +        performVariablesTest("package test; public class Test { { if (true) { System.err.println(1); } else System.err.println(2); } }",
 274.617 +                             "if ($c) { $s$; } else { $s$; }",
 274.618 +                             new Pair[] {
 274.619 +                             },
 274.620 +                             new Pair[] {
 274.621 +                             },
 274.622 +                             new Pair[] {
 274.623 +                             },
 274.624 +                             true,
 274.625 +                             true);
 274.626 +    }
 274.627 +
 274.628 +    public void testSimpleRemapping1() throws Exception {
 274.629 +        performRemappingTest("package test;\n" +
 274.630 +                             "public class Test {\n" +
 274.631 +                             "    void t1() {\n" +
 274.632 +                             "        int i = 0;\n" +
 274.633 +                             "        |System.err.println(i);|\n" +
 274.634 +                             "    }\n" +
 274.635 +                             "    void t2() {\n" +
 274.636 +                             "        int a = 0;\n" +
 274.637 +                             "        |System.err.println(a);|\n" +
 274.638 +                             "    }\n" +
 274.639 +                             "}\n",
 274.640 +                             "i",
 274.641 +                             Options.ALLOW_REMAP_VARIABLE_TO_EXPRESSION);
 274.642 +    }
 274.643 +
 274.644 +    public void testSimpleRemapping2() throws Exception {
 274.645 +        performRemappingTest("package test;\n" +
 274.646 +                             "public class Test {\n" +
 274.647 +                             "    void t1() {\n" +
 274.648 +                             "        int i = 0;\n" +
 274.649 +                             "        |System.err.println(i);\n" +
 274.650 +                             "         int i2 = 0;\n" +
 274.651 +                             "         System.err.println(i2);|\n" +
 274.652 +                             "    }\n" +
 274.653 +                             "    void t2() {\n" +
 274.654 +                             "        int a = 0;\n" +
 274.655 +                             "        |System.err.println(a);\n" +
 274.656 +                             "         int a2 = 0;\n" +
 274.657 +                             "         System.err.println(a2);|\n" +
 274.658 +                             "    }\n" +
 274.659 +                             "}\n",
 274.660 +                             "i",
 274.661 +                             Options.ALLOW_REMAP_VARIABLE_TO_EXPRESSION);
 274.662 +    }
 274.663 +
 274.664 +    public void testSimpleRemapping3() throws Exception {
 274.665 +        performRemappingTest("package test;\n" +
 274.666 +                             "public class Test {\n" +
 274.667 +                             "    void t1() {\n" +
 274.668 +                             "        |int i = 0;\n" +
 274.669 +                             "         System.err.println(i);\n" +
 274.670 +                             "         int i2 = 0;\n" +
 274.671 +                             "         System.err.println(i2);|\n" +
 274.672 +                             "    }\n" +
 274.673 +                             "    void t2() {\n" +
 274.674 +                             "        |int a = 0;\n" +
 274.675 +                             "         System.err.println(a);\n" +
 274.676 +                             "         int a2 = 0;\n" +
 274.677 +                             "         System.err.println(a2);|\n" +
 274.678 +                             "    }\n" +
 274.679 +                             "}\n",
 274.680 +                             "",
 274.681 +                             Options.ALLOW_REMAP_VARIABLE_TO_EXPRESSION);
 274.682 +    }
 274.683 +
 274.684 +    public void testSimpleRemapping4() throws Exception {
 274.685 +        performRemappingTest("package test;\n" +
 274.686 +                             "public class Test {\n" +
 274.687 +                             "    void t1() {\n" +
 274.688 +                             "        int i = 0;\n" +
 274.689 +                             "        |System.err.println(i);|\n" +
 274.690 +                             "    }\n" +
 274.691 +                             "    void t2() {\n" +
 274.692 +                             "        int[] a = {0};\n" +
 274.693 +                             "        |System.err.println(a[0]);|\n" +
 274.694 +                             "    }\n" +
 274.695 +                             "}\n",
 274.696 +                             "i",
 274.697 +                             Options.ALLOW_REMAP_VARIABLE_TO_EXPRESSION);
 274.698 +    }
 274.699 +
 274.700 +    public void testPreventRemapOnExpressions1() throws Exception {
 274.701 +        performRemappingTest("package test;\n" +
 274.702 +                             "public class Test {\n" +
 274.703 +                             "    void t1() {\n" +
 274.704 +                             "        Throwable t = null;\n" +
 274.705 +                             "        |System.err.println(t);|\n" +
 274.706 +                             "    }\n" +
 274.707 +                             "    void t2() {\n" +
 274.708 +                             "        Throwable t = null;\n" +
 274.709 +                             "        |System.err.println(t.getCause());|\n" +
 274.710 +                             "    }\n" +
 274.711 +                             "}\n",
 274.712 +                             "t",
 274.713 +                             Options.ALLOW_REMAP_VARIABLE_TO_EXPRESSION);
 274.714 +    }
 274.715 +
 274.716 +    public void testPreventRemapOnExpressions2() throws Exception {
 274.717 +        performRemappingTest("package test;\n" +
 274.718 +                             "public class Test {\n" +
 274.719 +                             "    void t1() {\n" +
 274.720 +                             "        Throwable t = null;\n" +
 274.721 +                             "        |System.err.println(t);|\n" +
 274.722 +                             "    }\n" +
 274.723 +                             "    void t2() {\n" +
 274.724 +                             "        Throwable t = null;\n" +
 274.725 +                             "        System.err.println(t.getCause());\n" +
 274.726 +                             "    }\n" +
 274.727 +                             "}\n",
 274.728 +                             "t");
 274.729 +    }
 274.730 +
 274.731 +    public void testVariableMemberSelect() throws Exception {
 274.732 +        performVariablesTest("package test; public class Test {public void test(String str) { str.length(); str.length(); } public void test1(String str) { str.length(); str.isEmpty(); } }",
 274.733 +                             "{ $str.$method(); $str.$method(); }",
 274.734 +                             new Pair[0],
 274.735 +                             new Pair[] {new Pair<String, String>("$method", "length")});
 274.736 +    }
 274.737 +
 274.738 +    public void testCorrectSite1() throws Exception {
 274.739 +        performVariablesTest("package test; public class Test { public void test(Object o) { o.wait(); } }",
 274.740 +                             "$s{java.util.concurrent.locks.Condition}.wait()",
 274.741 +                             new Pair[0],
 274.742 +                             new Pair[0],
 274.743 +                             new Pair[0],
 274.744 +                             true);
 274.745 +    }
 274.746 +
 274.747 +    public void testCorrectSite2() throws Exception {
 274.748 +        performVariablesTest("package test; public class Test { public void test(Object o) { wait(); } }",
 274.749 +                             "$s{java.util.concurrent.locks.Condition}.wait()",
 274.750 +                             new Pair[0],
 274.751 +                             new Pair[0],
 274.752 +                             new Pair[0],
 274.753 +                             true);
 274.754 +    }
 274.755 +
 274.756 +    public void testCorrectSite3() throws Exception {
 274.757 +        performVariablesTest("package test; public abstract class Test implements java.util.concurrent.locks.Condition { public void test() { new Runnable() { public void run() { wait(); } } } }",
 274.758 +                             "$0{java.util.concurrent.locks.Condition}.wait()",
 274.759 +                             new Pair[0],// {new Pair<String, int[]>("$s", new int[] {-1, -1})},
 274.760 +                             new Pair[0],
 274.761 +                             new Pair[0]);
 274.762 +    }
 274.763 +
 274.764 +    public void testCorrectSite4() throws Exception {
 274.765 +        performVariablesTest("package test; public class Test { public void test() { foo.stop(); } }",
 274.766 +                             "$0{java.lang.Thread}.stop()",
 274.767 +                             new Pair[0],
 274.768 +                             new Pair[0],
 274.769 +                             new Pair[0],
 274.770 +                             true);
 274.771 +    }
 274.772 +
 274.773 +    public void testDotClassForSameClass() throws Exception {
 274.774 +        performTest("package test; public class Test { {Class c = |Test.class|; c = |Test.class|; c = String.class; } }");
 274.775 +    }
 274.776 +
 274.777 +    public void testTryCatchVariable() throws Exception {
 274.778 +        performVariablesTest("package test; public class Test { { try { throw new java.io.IOException(); } catch (java.io.IOException ex) { } } }",
 274.779 +                             "try { $stmts$; } catch $catches$",
 274.780 +                             new Pair[] {
 274.781 +                             },
 274.782 +                             new Pair[] {
 274.783 +                                new Pair<String, int[]>("$stmts$", new int[] {42, 74}),
 274.784 +                                new Pair<String, int[]>("$catches$", new int[] {77, 111}),
 274.785 +                             },
 274.786 +                             new Pair[] {
 274.787 +                             },
 274.788 +                             false,
 274.789 +                             true);
 274.790 +    }
 274.791 +
 274.792 +    public void testMatchInterfaceNoFQN() throws Exception {
 274.793 +        performTest("package test; import java.util.*; public class Test { public void test() { |List| l1; |java.util.List| l2;} }");
 274.794 +    }
 274.795 +
 274.796 +    public void testUnresolvableNonMatchingConstraint() throws Exception {
 274.797 +        performVariablesTest("package test; public class Test { private Object a; {System.err.println(a);} }",
 274.798 +                             "System.err.println($v{does.not.Exist}",
 274.799 +                             new Pair[0],
 274.800 +                             new Pair[0],
 274.801 +                             new Pair[0],
 274.802 +                             true);
 274.803 +    }
 274.804 +
 274.805 +    public void testIndexOutOfBoundsInMultiList() throws Exception {
 274.806 +        performVariablesTest("package test;" +
 274.807 +                             "public class Test {" +
 274.808 +                             "    public void test() {" +
 274.809 +                             "        int i = 0;" +
 274.810 +                             "        int j = 0;" +
 274.811 +                             "        i++;" +
 274.812 +                             "        j++;" +
 274.813 +                             "    }" +
 274.814 +                             "}",
 274.815 +                             "{$type $i = $init; $stms$; $i++;}",
 274.816 +                             new Pair[0],
 274.817 +                             new Pair[0],
 274.818 +                             new Pair[0],
 274.819 +                             true,
 274.820 +                             false);
 274.821 +    }
 274.822 +
 274.823 +    public void testCorrectSite192812() throws Exception {
 274.824 +        performVariablesTest("package test; public class Test { private int i; public void test(Test t) { t.i = i - 10; } }",
 274.825 +                             "$t = $t - $v",
 274.826 +                             new Pair[0],
 274.827 +                             new Pair[0],
 274.828 +                             new Pair[0],
 274.829 +                             true,
 274.830 +                             true);
 274.831 +    }
 274.832 +
 274.833 +    public void testCorrectSite183367() throws Exception {
 274.834 +        performVariablesTest("package test; public class Test { public void test(java.util.List l) { l.subList(0, 0).remove(0); } }",
 274.835 +                             "$l{java.util.Collection}.remove($o{java.lang.Object})",
 274.836 +                             new Pair[0],
 274.837 +                             new Pair[0],
 274.838 +                             new Pair[0],
 274.839 +                             true,
 274.840 +                             true);
 274.841 +    }
 274.842 +
 274.843 +    public void testDisableVariablesWhenVerifyingDuplicates1() throws Exception {
 274.844 +        performVariablesTest("package test; public class Test { public void test() { int $i = 1, $j = 2; int k = $i + $i; } }",
 274.845 +                             "$i + $i",
 274.846 +                             new Pair[] {new Pair<String, int[]>("$i", new int[] {83, 85})},
 274.847 +                             new Pair[0],
 274.848 +                             new Pair[0],
 274.849 +                             false,
 274.850 +                             true);
 274.851 +    }
 274.852 +
 274.853 +    public void testDisableVariablesWhenVerifyingDuplicates2() throws Exception {
 274.854 +        performVariablesTest("package test; public class Test { public void test() { int $i = 1, $j = 2; int k = $i + $i; } }",
 274.855 +                             "$i + $i",
 274.856 +                             new Pair[] {new Pair<String, int[]>("$i", new int[] {83, 85})},
 274.857 +                             new Pair[0],
 274.858 +                             new Pair[0],
 274.859 +                             false,
 274.860 +                             false);
 274.861 +    }
 274.862 +
 274.863 +    public void testMethodMatchingMoreParams() throws Exception {
 274.864 +        performVariablesTest("package test; public class Test {public void test(String s1, String s2) { } }",
 274.865 +                             "public void test($params$) { }",
 274.866 +                             new Pair[0],
 274.867 +                             new Pair[] {new Pair<String, int[]>("$params$", new int[] {50, 59, 61, 70})},
 274.868 +                             new Pair[0],
 274.869 +                             false,
 274.870 +                             true);
 274.871 +    }
 274.872 +
 274.873 +    public void testLambdaInput1() throws Exception {
 274.874 +        performVariablesTest("package test; public class Test {public void test() { new java.io.FilenameFilter() { public boolean accept(File dir, String name) { } }; } }",
 274.875 +                             "new $type() {public $retType $name($params$) { $body$; } }",
 274.876 +                             new Pair[0],
 274.877 +                             new Pair[] {new Pair<String, int[]>("$params$", new int[] { 107, 115, 117, 128 })},
 274.878 +                             new Pair[] {new Pair<String, String>("$name", "accept")},
 274.879 +                             false,
 274.880 +                             false);
 274.881 +    }
 274.882 +
 274.883 +    public void testLambdaInput2() throws Exception {
 274.884 +        performVariablesTest("package test; public class Test {public void test() { new java.io.FilenameFilter() { public boolean accept(File dir, String name) { } }; } }",
 274.885 +                             "new $type() { $mods$ $retType $name($params$) { $body$; } }",
 274.886 +                             new Pair[0],
 274.887 +                             new Pair[] {new Pair<String, int[]>("$params$", new int[] { 107, 115, 117, 128 })},
 274.888 +                             new Pair[] {new Pair<String, String>("$name", "accept")},
 274.889 +                             false,
 274.890 +                             true);
 274.891 +    }
 274.892 +
 274.893 +    public void testSwitch1() throws Exception {
 274.894 +        performVariablesTest("package test;\n" +
 274.895 +                             "public class Test {\n" +
 274.896 +                             "     {\n" +
 274.897 +                             "         E e = null;\n" +
 274.898 +                             "         switch (e) {\n" +
 274.899 +                             "             case A: System.err.println(1); break;\n" +
 274.900 +                             "             case D: System.err.println(2); break;\n" +
 274.901 +                             "             case E: System.err.println(3); break;\n" +
 274.902 +                             "         }\n" +
 274.903 +                             "     }\n" +
 274.904 +                             "     public enum E {A, B, C, D, E, F;}\n" +
 274.905 +                             "}\n",
 274.906 +                             "switch ($0{test.Test.E}) { case $c1$ case D: $stmts$; case $c2$ }",
 274.907 +                             new Pair[] {new Pair<String, int[]>("$0", new int[] {79, 80})},
 274.908 +                             new Pair[] {
 274.909 +                                new Pair<String, int[]>("$stmts$", new int[] { 156, 178, 179, 185 }),
 274.910 +                                new Pair<String, int[]>("$c1$", new int[] { 97, 134 }),
 274.911 +                                new Pair<String, int[]>("$c2$", new int[] { 199, 236 }),
 274.912 +                             },
 274.913 +                             new Pair[0],
 274.914 +                             false,
 274.915 +                             false);
 274.916 +    }
 274.917 +
 274.918 +    public void testWildcard1() throws Exception {
 274.919 +        performTest("package test; import java.util.*; public class Test { public void test() { |List<?>| l1; |List<?>| l2;} }");
 274.920 +    }
 274.921 +
 274.922 +    public void testWildcard2() throws Exception {
 274.923 +        performTest("package test; import java.util.*; public class Test { public void test() { |List<? extends String>| l1; |List<? extends String>| l2;} }");
 274.924 +    }
 274.925 +
 274.926 +    public void testWildcard3() throws Exception {
 274.927 +        performTest("package test; import java.util.*; public class Test { public void test() { |List<? super String>| l1; |List<? super String>| l2;} }");
 274.928 +    }
 274.929 +
 274.930 +    public void testSingleVariableStrict() throws Exception {
 274.931 +        performVariablesTest("package test; public class Test { public void test() { if (true) System.err.println(1); } }",
 274.932 +                             "if ($c) $then; else $else;",
 274.933 +                             new Pair[0],
 274.934 +                             new Pair[0],
 274.935 +                             new Pair[0],
 274.936 +                             true,
 274.937 +                             true);
 274.938 +    }
 274.939 +
 274.940 +    public void testMultiVariableZeroOrOne1() throws Exception {
 274.941 +        performVariablesTest("package test; public class Test { public void test() { if (true) System.err.println(1); } }",
 274.942 +                             "if ($c) $then; else $else$;",
 274.943 +                             new Pair[] {new Pair<String, int[]>("$c", new int[] {59, 63}),
 274.944 +                                         new Pair<String, int[]>("$then", new int[] {65, 87})},
 274.945 +                             new Pair[0],
 274.946 +                             new Pair[0],
 274.947 +                             false,
 274.948 +                             true);
 274.949 +    }
 274.950 +
 274.951 +    public void testMultiVariableZeroOrOne2() throws Exception {
 274.952 +        performVariablesTest("package test; public class Test { public void test() { if (true) System.err.println(1); else System.err.println(2); } }",
 274.953 +                             "if ($c) $then; else $else$;",
 274.954 +                             new Pair[] {new Pair<String, int[]>("$c", new int[] {59, 63}),
 274.955 +                                         new Pair<String, int[]>("$then", new int[] {65, 87}),
 274.956 +                                         new Pair<String, int[]>("$else$", new int[] {93, 115})},
 274.957 +                             new Pair[0],
 274.958 +                             new Pair[0],
 274.959 +                             false,
 274.960 +                             true);
 274.961 +    }
 274.962 +
 274.963 +    public void testNonResolvableType() throws Exception {
 274.964 +        performVariablesTest("package test; public class Test { { java.io.File f = null; boolean b = f.isDirectory(); } }",
 274.965 +                             "$1{can.not.Resolve}.$m($args$)",
 274.966 +                             new Pair[0],
 274.967 +                             new Pair[0],
 274.968 +                             new Pair[0],
 274.969 +                             true,
 274.970 +                             true);
 274.971 +    }
 274.972 +
 274.973 +    public void testTryWithResources() throws Exception {
 274.974 +        performVariablesTest("package test; public class Test { { try (java.io.InputStream in = null) { System.err.println(1); } } }",
 274.975 +                             "try ($resources$) {$body$;}",
 274.976 +                             new Pair[] {
 274.977 +                             },
 274.978 +                             new Pair[] {
 274.979 +                                new Pair<String, int[]>("$resources$", new int[] {41, 70}),
 274.980 +                                new Pair<String, int[]>("$body$", new int[] {74, 96}),
 274.981 +                             },
 274.982 +                             new Pair[] {
 274.983 +                             },
 274.984 +                             false,
 274.985 +                             true);
 274.986 +    }
 274.987 +
 274.988 +    public void testIgnoreOtherKind() throws Exception {
 274.989 +        performVariablesTest("package test; public class Test { private java.util.Collection<String> x() { return java.util.Collections.emptySet(); } } }",
 274.990 +                             "$i{java.lang.Class}",
 274.991 +                             new Pair[] {
 274.992 +                             },
 274.993 +                             new Pair[] {
 274.994 +                             },
 274.995 +                             new Pair[] {
 274.996 +                             },
 274.997 +                             true,
 274.998 +                             true);
 274.999 +    }
274.1000 +
274.1001 +    public void testSearchPackageClause() throws Exception {
274.1002 +        performVariablesTest("package test.a; public class Test { }",
274.1003 +                             "test.$1",
274.1004 +                             new Pair[] {
274.1005 +                             },
274.1006 +                             new Pair[] {
274.1007 +                             },
274.1008 +                             new Pair[] {
274.1009 +                                 new Pair<String, String>("$1", "a"),
274.1010 +                             },
274.1011 +                             false,
274.1012 +                             true);
274.1013 +    }
274.1014 +
274.1015 +    public void testPackageImport() throws Exception {
274.1016 +        performVariablesTest("package test; import java.util.*; public class Test { }",
274.1017 +                             "java.$1",
274.1018 +                             new Pair[] {
274.1019 +                             },
274.1020 +                             new Pair[] {
274.1021 +                             },
274.1022 +                             new Pair[] {
274.1023 +                                 new Pair<String, String>("$1", "util"),
274.1024 +                             },
274.1025 +                             false,
274.1026 +                             true);
274.1027 +    }
274.1028 +    
274.1029 +    public void testSubclassMatching() throws Exception {
274.1030 +        performVariablesTest("package test; import java.util.*; public abstract class Test { Map.Entry e; }",
274.1031 +                             "java.util.Map.$1",
274.1032 +                             new Pair[] {
274.1033 +                             },
274.1034 +                             new Pair[] {
274.1035 +                             },
274.1036 +                             new Pair[] {
274.1037 +                                 new Pair<String, String>("$1", "Entry"),
274.1038 +                             },
274.1039 +                             false,
274.1040 +                             true);
274.1041 +    }
274.1042 +    
274.1043 +    public void testMethodTypeParameters1() throws Exception {
274.1044 +        performVariablesTest("package test; public class Test { private void t() { } }",
274.1045 +                             "$mods$ <$tp$> $ret $name($args$) { $body$; }",
274.1046 +                             new Pair[] {
274.1047 +                                new Pair<String, int[]>("$ret", new int[] {42, 46}),
274.1048 +                                new Pair<String, int[]>("$mods$", new int[] {34, 41}),
274.1049 +                             },
274.1050 +                             new Pair[] {
274.1051 +                                new Pair<String, int[]>("$tp$", new int[] {}),
274.1052 +                                new Pair<String, int[]>("$args$", new int[] {}),
274.1053 +                                new Pair<String, int[]>("$body$", new int[] {}),
274.1054 +                             },
274.1055 +                             new Pair[] {
274.1056 +                                 new Pair<String, String>("$name", "t")
274.1057 +                             },
274.1058 +                             false,
274.1059 +                             false);
274.1060 +    }
274.1061 +    
274.1062 +    public void testMethodTypeParameters2() throws Exception {
274.1063 +        performVariablesTest("package test; public class Test { private <A, B> String aa(int a, int b) { a = b; b = a;} }",
274.1064 +                             "$mods$ <$tp$> $ret $name($args$) { $body$; }",
274.1065 +                             new Pair[] {
274.1066 +                                new Pair<String, int[]>("$ret", new int[] {49, 55}),
274.1067 +                                new Pair<String, int[]>("$mods$", new int[] {34, 41}),
274.1068 +                             },
274.1069 +                             new Pair[] {
274.1070 +                                new Pair<String, int[]>("$tp$", new int[] {43, 44, 46, 47}),
274.1071 +                                new Pair<String, int[]>("$args$", new int[] {59, 64, 66, 71}),
274.1072 +                                new Pair<String, int[]>("$body$", new int[] {75, 81, 82, 88}),
274.1073 +                             },
274.1074 +                             new Pair[] {
274.1075 +                                 new Pair<String, String>("$name", "aa")
274.1076 +                             },
274.1077 +                             false,
274.1078 +                             true);
274.1079 +    }
274.1080 +    
274.1081 +    public void testMethodTypeParameters3() throws Exception {
274.1082 +        performVariablesTest("package test; public class Test { private <A> String aa(int a, int b) { a = b; b = a;} }",
274.1083 +                             "$mods$ <$tp> $ret $name($args$) { $body$; }",
274.1084 +                             new Pair[] {
274.1085 +                                new Pair<String, int[]>("$ret", new int[] {46, 52}),
274.1086 +                                new Pair<String, int[]>("$mods$", new int[] {34, 41}),
274.1087 +                                new Pair<String, int[]>("$tp", new int[] {43, 44}),
274.1088 +                             },
274.1089 +                             new Pair[] {
274.1090 +                                new Pair<String, int[]>("$args$", new int[] {56, 61, 63, 68}),
274.1091 +                                new Pair<String, int[]>("$body$", new int[] {72, 78, 79, 85}),
274.1092 +                             },
274.1093 +                             new Pair[] {
274.1094 +                                 new Pair<String, String>("$name", "aa")
274.1095 +                             },
274.1096 +                             false,
274.1097 +                             true);
274.1098 +    }
274.1099 +    
274.1100 +    public void testTypeParameters1() throws Exception {
274.1101 +        performVariablesTest("package test; public class Test { private <A extends String> void aa() { } }",
274.1102 +                             "$mods$ <$tp extends $bound&$obounds$> $ret $name($args$) { $body$; }",
274.1103 +                             new Pair[] {
274.1104 +                                new Pair<String, int[]>("$ret", new int[] {61, 65}),
274.1105 +                                new Pair<String, int[]>("$mods$", new int[] {34, 41}),
274.1106 +                                new Pair<String, int[]>("$tp", new int[] {43, 59}),
274.1107 +                                new Pair<String, int[]>("$bound", new int[] {53, 59}),
274.1108 +                             },
274.1109 +                             new Pair[] {
274.1110 +                                new Pair<String, int[]>("$obounds$", new int[] {}),
274.1111 +                             },
274.1112 +                             new Pair[] {
274.1113 +                                 new Pair<String, String>("$name", "aa"),
274.1114 +                                 new Pair<String, String>("$tp", "A")
274.1115 +                             },
274.1116 +                             false,
274.1117 +                             true);
274.1118 +    }
274.1119 +    
274.1120 +    public void testPartialModifiers1() throws Exception {
274.1121 +        performVariablesTest("package test; public class Test { @Deprecated @Override private void aa() { } }",
274.1122 +                             "$mods$ @Deprecated private $ret $name() { $body$; }",
274.1123 +                             new Pair[] {
274.1124 +                                new Pair<String, int[]>("$ret", new int[] {64, 68}),
274.1125 +                                new Pair<String, int[]>("$mods$", new int[] {34, 63}),
274.1126 +                             },
274.1127 +                             new Pair[] {
274.1128 +                             },
274.1129 +                             new Pair[] {
274.1130 +                                 new Pair<String, String>("$name", "aa"),
274.1131 +                             },
274.1132 +                             false,
274.1133 +                             true);
274.1134 +    }
274.1135 +    
274.1136 +    public void testPartialModifiers2() throws Exception {
274.1137 +        performVariablesTest("package test; public class Test { @Override private void aa() { } }",
274.1138 +                             "$mods$ @Deprecated private $ret $name() { $body$; }",
274.1139 +                             new Pair[0],
274.1140 +                             new Pair[0],
274.1141 +                             new Pair[0],
274.1142 +                             true,
274.1143 +                             true);
274.1144 +    }
274.1145 +    
274.1146 +    public void testNonStaticInnerClassesMatch() throws Exception {
274.1147 +        performVariablesTest("package test; import test.Test.Inner; public class Test { public class Inner { } } class Other { { Inner i = null; } }",
274.1148 +                             "test.Test.Inner $i = $init$;",
274.1149 +                             new Pair[] {
274.1150 +                                 new Pair<String, int[]>("$i", new int[] {99, 114}),
274.1151 +                                 new Pair<String, int[]>("$init$", new int[] {109, 113})
274.1152 +                             },
274.1153 +                             new Pair[0],
274.1154 +                             new Pair[] {
274.1155 +                                 new Pair<String, String>("$i", "i")
274.1156 +                             },
274.1157 +                             false,
274.1158 +                             true);
274.1159 +    }
274.1160 +    
274.1161 +    public void testNewClassTypeParams222066a() throws Exception {
274.1162 +        performVariablesTest("package test; public class Test { private Object aa() { return new java.util.ArrayList(1); } }",
274.1163 +                             "new java.util.ArrayList<$whatever$>($param)",
274.1164 +                             new Pair[] {
274.1165 +                                 new Pair<String, int[]>("$param", new int[] {87, 88})
274.1166 +                             },
274.1167 +                             new Pair[] {
274.1168 +                                 new Pair<String, int[]>("$whatever$", new int[0])
274.1169 +                             },
274.1170 +                             new Pair[0],
274.1171 +                             false,
274.1172 +                             false);
274.1173 +    }
274.1174 +    
274.1175 +    public void testNewClassTypeParams222066b() throws Exception {
274.1176 +        performVariablesTest("package test; import java.util.ArrayList; public class Test { private Object aa() { return new ArrayList(1); } }",
274.1177 +                             "new java.util.ArrayList<$whatever$>($param)",
274.1178 +                             new Pair[] {
274.1179 +                                 new Pair<String, int[]>("$param", new int[] {105, 106})
274.1180 +                             },
274.1181 +                             new Pair[] {
274.1182 +                                 new Pair<String, int[]>("$whatever$", new int[0])
274.1183 +                             },
274.1184 +                             new Pair[0],
274.1185 +                             false,
274.1186 +                             false);
274.1187 +    }
274.1188 +    
274.1189 +    public void testFindLambda() throws Exception {
274.1190 +        performVariablesTest("package test; import java.util.Comparator; public class Test { private void aa() { Comparator<String> c = (l, r) -> l.compareTo(r); } }",
274.1191 +                             "($args$) -> $expression",
274.1192 +                             new Pair[] {
274.1193 +                                 new Pair<String, int[]>("$expression", new int[] {116, 130})
274.1194 +                             },
274.1195 +                             new Pair[] {
274.1196 +                                 new Pair<String, int[]>("$args$", new int[] {107, 108, 110, 111})
274.1197 +                             },
274.1198 +                             new Pair[0],
274.1199 +                             false,
274.1200 +                             false);
274.1201 +    }
274.1202 +    
274.1203 +    public void testAnnotation1() throws Exception {
274.1204 +        performVariablesTest("package test; import test.Test.A; @A(i=1) public class Test { @interface A { public int i(); } }",
274.1205 +                             "@$annotation($args$)",
274.1206 +                             new Pair[] {
274.1207 +                                 new Pair<String, int[]>("$annotation", new int[] {35, 36})
274.1208 +                             },
274.1209 +                             new Pair[] {
274.1210 +                                 new Pair<String, int[]>("$args$", new int[] {37, 40})
274.1211 +                             },
274.1212 +                             new Pair[0],
274.1213 +                             false,
274.1214 +                             true);
274.1215 +    }
274.1216 +    
274.1217 +    public void testAnnotation2() throws Exception {
274.1218 +        performVariablesTest("package test; import test.Test.A; @A(i=1,b=true,l=2) public class Test { @interface A { public int i(); public boolean b(); public long l(); } }",
274.1219 +                             "@test.Test.A($prefix$, b=$value, $suffix$)",
274.1220 +                             new Pair[] {
274.1221 +                                 new Pair<String, int[]>("$value", new int[] {43, 47})
274.1222 +                             },
274.1223 +                             new Pair[] {
274.1224 +                                 new Pair<String, int[]>("$prefix$", new int[] {37, 40}),
274.1225 +                                 new Pair<String, int[]>("$suffix$", new int[] {48, 51})
274.1226 +                             },
274.1227 +                             new Pair[0],
274.1228 +                             false,
274.1229 +                             false);
274.1230 +    }
274.1231 +    
274.1232 +    protected void prepareTest(String code) throws Exception {
274.1233 +        prepareTest(code, -1);
274.1234 +    }
274.1235 +
274.1236 +    protected void prepareTest(String code, int testIndex) throws Exception {
274.1237 +        File workDirWithIndexFile = testIndex != (-1) ? new File(getWorkDir(), Integer.toString(testIndex)) : getWorkDir();
274.1238 +        FileObject workDirWithIndex = FileUtil.toFileObject(workDirWithIndexFile);
274.1239 +
274.1240 +        if (workDirWithIndex != null) {
274.1241 +            workDirWithIndex.delete();
274.1242 +        }
274.1243 +
274.1244 +        workDirWithIndex = FileUtil.createFolder(workDirWithIndexFile);
274.1245 +
274.1246 +        assertNotNull(workDirWithIndexFile);
274.1247 +
274.1248 +        FileObject sourceRoot = workDirWithIndex.createFolder("src");
274.1249 +        FileObject buildRoot  = workDirWithIndex.createFolder("build");
274.1250 +        FileObject cache = workDirWithIndex.createFolder("cache");
274.1251 +
274.1252 +        FileObject data = FileUtil.createData(sourceRoot, "test/Test.java");
274.1253 +
274.1254 +        TestUtilities.copyStringToFile(data, code);
274.1255 +
274.1256 +        data.refresh();
274.1257 +
274.1258 +        SourceUtilsTestUtil.prepareTest(sourceRoot, buildRoot, cache);
274.1259 +
274.1260 +        DataObject od = DataObject.find(data);
274.1261 +        EditorCookie ec = od.getLookup().lookup(EditorCookie.class);
274.1262 +
274.1263 +        assertNotNull(ec);
274.1264 +
274.1265 +        doc = ec.openDocument();
274.1266 +
274.1267 +        doc.putProperty(Language.class, JavaTokenId.language());
274.1268 +        doc.putProperty("mimeType", "text/x-java");
274.1269 +
274.1270 +        JavaSource js = JavaSource.forFileObject(data);
274.1271 +
274.1272 +        assertNotNull(js);
274.1273 +
274.1274 +        info = SourceUtilsTestUtil.getCompilationInfo(js, Phase.RESOLVED);
274.1275 +
274.1276 +        assertNotNull(info);
274.1277 +    }
274.1278 +
274.1279 +    private static String findRegions(String code, List<int[]> regions) {
274.1280 +        String[] split = code.split("\\|");
274.1281 +        StringBuilder filtered = new StringBuilder();
274.1282 +
274.1283 +        filtered.append(split[0]);
274.1284 +
274.1285 +        int offset = split[0].length();
274.1286 +
274.1287 +        for (int cntr = 1; cntr < split.length; cntr += 2) {
274.1288 +            int[] i = new int[] {
274.1289 +                offset,
274.1290 +                offset + split[cntr].length()
274.1291 +            };
274.1292 +
274.1293 +            regions.add(i);
274.1294 +
274.1295 +            filtered.append(split[cntr]);
274.1296 +            filtered.append(split[cntr + 1]);
274.1297 +
274.1298 +            offset += split[cntr].length();
274.1299 +            offset += split[cntr + 1].length();
274.1300 +        }
274.1301 +
274.1302 +        return filtered.toString();
274.1303 +    }
274.1304 +
274.1305 +    protected CompilationInfo info;
274.1306 +    private Document doc;
274.1307 +
274.1308 +    private void performTest(String code) throws Exception {
274.1309 +        performTest(code, true);
274.1310 +    }
274.1311 +
274.1312 +    private void performTest(String code, boolean verify) throws Exception {
274.1313 +        List<int[]> result = new LinkedList<int[]>();
274.1314 +
274.1315 +        code = findRegions(code, result);
274.1316 +
274.1317 +        int testIndex = 0;
274.1318 +
274.1319 +        for (int[] i : result) {
274.1320 +            int[] duplicates = new int[2 * (result.size() - 1)];
274.1321 +            int cntr = 0;
274.1322 +            List<int[]> l = new LinkedList<int[]>(result);
274.1323 +
274.1324 +            l.remove(i);
274.1325 +
274.1326 +            for (int[] span : l) {
274.1327 +                duplicates[cntr++] = span[0];
274.1328 +                duplicates[cntr++] = span[1];
274.1329 +            }
274.1330 +
274.1331 +            doPerformTest(code, i[0], i[1], testIndex++, verify, duplicates);
274.1332 +        }
274.1333 +    }
274.1334 +
274.1335 +    protected void performTest(String code, int start, int end, int... duplicates) throws Exception {
274.1336 +        doPerformTest(code, start, end, -1, true, duplicates);
274.1337 +    }
274.1338 +
274.1339 +    protected void doPerformTest(String code, int start, int end, int testIndex, int... duplicates) throws Exception {
274.1340 +        doPerformTest(code, start, end, testIndex, true, duplicates);
274.1341 +    }
274.1342 +
274.1343 +    protected void doPerformTest(String code, int start, int end, int testIndex, boolean verify, int... duplicates) throws Exception {
274.1344 +        prepareTest(code, testIndex);
274.1345 +
274.1346 +        TreePath path = info.getTreeUtilities().pathFor((start + end) / 2 + 1);
274.1347 +
274.1348 +        while (path != null) {
274.1349 +            Tree t = path.getLeaf();
274.1350 +            SourcePositions sp = info.getTrees().getSourcePositions();
274.1351 +
274.1352 +            if (   start == sp.getStartPosition(info.getCompilationUnit(), t)
274.1353 +                && end   == sp.getEndPosition(info.getCompilationUnit(), t)) {
274.1354 +                break;
274.1355 +            }
274.1356 +
274.1357 +            path = path.getParentPath();
274.1358 +        }
274.1359 +
274.1360 +        assertNotNull(path);
274.1361 +
274.1362 +        Collection<TreePath> result = computeDuplicates(path);
274.1363 +
274.1364 +        //        assertEquals(f.result.toString(), duplicates.length / 2, f.result.size());
274.1365 +
274.1366 +        if (verify) {
274.1367 +            int[] dupes = new int[result.size() * 2];
274.1368 +            int   index = 0;
274.1369 +
274.1370 +            for (TreePath tp : result) {
274.1371 +                dupes[index++] = (int) info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), tp.getLeaf());
274.1372 +                dupes[index++] = (int) info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), tp.getLeaf());
274.1373 +            }
274.1374 +
274.1375 +            assertTrue("Was: " + Arrays.toString(dupes) + " should have been: " + Arrays.toString(duplicates), Arrays.equals(duplicates, dupes));
274.1376 +        }
274.1377 +    }
274.1378 +
274.1379 +    protected void performVariablesTest(String code, String pattern, Pair<String, int[]>[] duplicatesPos, Pair<String, String>[] duplicatesNames) throws Exception {
274.1380 +        performVariablesTest(code, pattern, duplicatesPos, new Pair[0], duplicatesNames);
274.1381 +    }
274.1382 +
274.1383 +    protected void performVariablesTest(String code, String pattern, Pair<String, int[]>[] duplicatesPos, Pair<String, int[]>[] multiStatementPos, Pair<String, String>[] duplicatesNames) throws Exception {
274.1384 +        performVariablesTest(code, pattern, duplicatesPos, multiStatementPos, duplicatesNames, false);
274.1385 +    }
274.1386 +
274.1387 +    protected void performVariablesTest(String code, String pattern, Pair<String, int[]>[] duplicatesPos, Pair<String, int[]>[] multiStatementPos, Pair<String, String>[] duplicatesNames, boolean noOccurrences) throws Exception {
274.1388 +        performVariablesTest(code, pattern, duplicatesPos, multiStatementPos, duplicatesNames, noOccurrences, false);
274.1389 +    }
274.1390 +
274.1391 +    protected void performVariablesTest(String code, String pattern, Pair<String, int[]>[] duplicatesPos, Pair<String, int[]>[] multiStatementPos, Pair<String, String>[] duplicatesNames, boolean noOccurrences, boolean useBulkSearch) throws Exception {
274.1392 +        prepareTest(code, -1);
274.1393 +
274.1394 +        Map<String, TypeMirror> constraints = new HashMap<String, TypeMirror>();
274.1395 +        String patternCode = PatternCompilerUtilities.parseOutTypesFromPattern(info, pattern, constraints);
274.1396 +
274.1397 +        Pattern patternObj = PatternCompiler.compile(info, patternCode, constraints, Collections.<String>emptyList());
274.1398 +        TreePath patternPath = MatchingTestAccessor.getPattern(patternObj).iterator().next();
274.1399 +        Map<TreePath, VariableAssignments> result;
274.1400 +
274.1401 +        if (useBulkSearch) {
274.1402 +            result = new HashMap<TreePath, VariableAssignments>();
274.1403 +
274.1404 +            BulkPattern bulkPattern = BulkSearch.getDefault().create(info, new AtomicBoolean(), patternCode);
274.1405 +
274.1406 +            for (Entry<String, Collection<TreePath>> e : BulkSearch.getDefault().match(info, new AtomicBoolean(), new TreePath(info.getCompilationUnit()), bulkPattern).entrySet()) {
274.1407 +                for (TreePath tp : e.getValue()) {
274.1408 +                    VariableAssignments vars = computeVariables(info, patternPath, tp, new AtomicBoolean(), MatchingTestAccessor.getVariable2Type(patternObj));
274.1409 +
274.1410 +                    if (vars != null) {
274.1411 +                        result.put(tp, vars);
274.1412 +                    }
274.1413 +                }
274.1414 +            }
274.1415 +        } else {
274.1416 +            result = computeDuplicates(info, patternPath, new TreePath( info.getCompilationUnit()), new AtomicBoolean(), MatchingTestAccessor.getVariable2Type(patternObj));
274.1417 +        }
274.1418 +
274.1419 +        if (noOccurrences) {
274.1420 +            assertEquals(0, result.size());
274.1421 +            return ;
274.1422 +        }
274.1423 +
274.1424 +        assertSame(1, result.size());
274.1425 +
274.1426 +        Map<String, int[]> actual = new HashMap<String, int[]>();
274.1427 +
274.1428 +        for (Entry<String, TreePath> e : result.values().iterator().next().variables.entrySet()) {
274.1429 +            int[] span = new int[] {
274.1430 +                (int) info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), e.getValue().getLeaf()),
274.1431 +                (int) info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), e.getValue().getLeaf())
274.1432 +            };
274.1433 +
274.1434 +            actual.put(e.getKey(), span);
274.1435 +        }
274.1436 +
274.1437 +        for (Pair<String, int[]> dup : duplicatesPos) {
274.1438 +            int[] span = actual.remove(dup.getA());
274.1439 +
274.1440 +            if (span == null) {
274.1441 +                fail(dup.getA());
274.1442 +            }
274.1443 +            assertTrue(dup.getA() + ":" + Arrays.toString(span), Arrays.equals(span, dup.getB()));
274.1444 +        }
274.1445 +
274.1446 +        Map<String, int[]> actualMulti = new HashMap<String, int[]>();
274.1447 +
274.1448 +        for (Entry<String, Collection<? extends TreePath>> e : result.values().iterator().next().multiVariables.entrySet()) {
274.1449 +            int[] span = new int[2 * e.getValue().size()];
274.1450 +            int i = 0;
274.1451 +
274.1452 +            for (TreePath tp : e.getValue()) {
274.1453 +                span[i++] = (int) info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), tp.getLeaf());
274.1454 +                span[i++] = (int) info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), tp.getLeaf());
274.1455 +            }
274.1456 +
274.1457 +            actualMulti.put(e.getKey(), span);
274.1458 +        }
274.1459 +
274.1460 +        for (Pair<String, int[]> dup : multiStatementPos) {
274.1461 +            int[] span = actualMulti.remove(dup.getA());
274.1462 +
274.1463 +            if (span == null) {
274.1464 +                fail(dup.getA());
274.1465 +            }
274.1466 +            assertTrue(dup.getA() + ":" + Arrays.toString(span), Arrays.equals(span, dup.getB()));
274.1467 +        }
274.1468 +
274.1469 +        Map<String, String> golden = new HashMap<String, String>();
274.1470 +
274.1471 +        for ( Pair<String, String> e : duplicatesNames) {
274.1472 +            golden.put(e.getA(), e.getB());
274.1473 +        }
274.1474 +
274.1475 +        assertEquals(golden, result.values().iterator().next().variables2Names);
274.1476 +    }
274.1477 +
274.1478 +    protected VariableAssignments computeVariables(CompilationInfo info, TreePath searchingFor, TreePath scope, AtomicBoolean cancel, Map<String, TypeMirror> designedTypeHack) {
274.1479 +        Collection<VariableAssignments> values = CopyFinder.internalComputeDuplicates(info, Collections.singletonList(searchingFor), scope, null, null, new AtomicBooleanCancel(cancel), designedTypeHack, Options.ALLOW_VARIABLES_IN_PATTERN).values();
274.1480 +
274.1481 +        if (values.iterator().hasNext()) {
274.1482 +            return values.iterator().next();
274.1483 +        } else {
274.1484 +            return null;
274.1485 +        }
274.1486 +    }
274.1487 +
274.1488 +    protected Map<TreePath, VariableAssignments> computeDuplicates(CompilationInfo info, TreePath searchingFor, TreePath scope, AtomicBoolean cancel, Map<String, TypeMirror> designedTypeHack) {
274.1489 +        return CopyFinder.internalComputeDuplicates(info, Collections.singletonList(searchingFor), scope, null, null, new AtomicBooleanCancel(cancel), designedTypeHack, Options.ALLOW_VARIABLES_IN_PATTERN, Options.ALLOW_GO_DEEPER);
274.1490 +    }
274.1491 +
274.1492 +    private void performRemappingTest(String code, String remappableVariables, Options... options) throws Exception {
274.1493 +        List<int[]> regions = new LinkedList<int[]>();
274.1494 +
274.1495 +        code = findRegions(code, regions);
274.1496 +
274.1497 +        prepareTest(code, -1);
274.1498 +
274.1499 +        int[] statements = new int[2];
274.1500 +
274.1501 +        int[] currentRegion = regions.get(0);
274.1502 +        TreePathHandle tph = IntroduceMethodFix.validateSelectionForIntroduceMethod(info, currentRegion[0], currentRegion[1], statements);
274.1503 +
274.1504 +        assertNotNull(tph);
274.1505 +
274.1506 +        TreePath tp = tph.resolve(info);
274.1507 +
274.1508 +        assertNotNull(tp);
274.1509 +
274.1510 +        BlockTree bt = (BlockTree) tp.getParentPath().getLeaf();
274.1511 +        List<TreePath> searchFor = new LinkedList<TreePath>();
274.1512 +
274.1513 +        for (StatementTree t : bt.getStatements().subList(statements[0], statements[1] + 1)) {
274.1514 +            searchFor.add(new TreePath(tp, t));
274.1515 +        }
274.1516 +
274.1517 +        final Set<VariableElement> vars = new HashSet<VariableElement>();
274.1518 +
274.1519 +        for (final String name : remappableVariables.split(",")) {
274.1520 +            if (name.isEmpty()) continue;
274.1521 +            new TreePathScanner<Object, Object>() {
274.1522 +                @Override
274.1523 +                public Object visitVariable(VariableTree node, Object p) {
274.1524 +                    if (node.getName().contentEquals(name)) {
274.1525 +                        vars.add((VariableElement) info.getTrees().getElement(getCurrentPath()));
274.1526 +                    }
274.1527 +
274.1528 +                    return super.visitVariable(node, p);
274.1529 +                }
274.1530 +            }.scan(info.getCompilationUnit(), null);
274.1531 +        }
274.1532 +
274.1533 +        Set<Options> opts = EnumSet.of(Options.ALLOW_GO_DEEPER);
274.1534 +
274.1535 +        opts.addAll(Arrays.asList(options));
274.1536 +
274.1537 +        Map<TreePath, VariableAssignments> result = CopyFinder.internalComputeDuplicates(info, searchFor, new TreePath(info.getCompilationUnit()), null, vars, new AtomicBooleanCancel(), Collections.<String, TypeMirror>emptyMap(), opts.toArray(new Options[0]));
274.1538 +        Set<List<Integer>> realSpans = new HashSet<List<Integer>>();
274.1539 +
274.1540 +        for (Entry<TreePath, VariableAssignments> e : result.entrySet()) {
274.1541 +            List<? extends StatementTree> parentStatements = CopyFinder.getStatements(e.getKey());
274.1542 +            int dupeStart = parentStatements.indexOf(e.getKey().getLeaf());
274.1543 +            int startPos = (int) info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), parentStatements.get(dupeStart));
274.1544 +            int endPos = (int) info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), parentStatements.get(dupeStart + searchFor.size() - 1));
274.1545 +
274.1546 +            realSpans.add(Arrays.asList(startPos, endPos));
274.1547 +        }
274.1548 +
274.1549 +        Set<List<Integer>> goldenSpans = new HashSet<List<Integer>>();
274.1550 +
274.1551 +        for (int[] region : regions) {
274.1552 +            if (region == currentRegion) continue;
274.1553 +
274.1554 +            int[] stmts = new int[2];
274.1555 +            TreePathHandle gtph = IntroduceMethodFix.validateSelectionForIntroduceMethod(info, region[0], region[1], stmts);
274.1556 +
274.1557 +            assertNotNull(gtph);
274.1558 +
274.1559 +            TreePath gtp = gtph.resolve(info);
274.1560 +
274.1561 +            assertNotNull(gtp);
274.1562 +
274.1563 +            BlockTree b = (BlockTree) gtp.getParentPath().getLeaf();
274.1564 +
274.1565 +            int startPos = (int) info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), b.getStatements().get(stmts[0]));
274.1566 +            int endPos = (int) info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), b.getStatements().get(stmts[1]));
274.1567 +
274.1568 +            goldenSpans.add(Arrays.asList(startPos, endPos));
274.1569 +        }
274.1570 +
274.1571 +        assertEquals(goldenSpans, realSpans);
274.1572 +    }
274.1573 +
274.1574 +    protected Collection<TreePath> computeDuplicates(TreePath path) {
274.1575 +        return CopyFinder.internalComputeDuplicates(info, Collections.singletonList(path), new TreePath(info.getCompilationUnit()), null, null, new AtomicBooleanCancel(), null, Options.ALLOW_GO_DEEPER).keySet();
274.1576 +    }
274.1577 +
274.1578 +    public static final class Pair<A, B> {
274.1579 +        private final A a;
274.1580 +        private final B b;
274.1581 +
274.1582 +        public Pair(A a, B b) {
274.1583 +            this.a = a;
274.1584 +            this.b = b;
274.1585 +        }
274.1586 +
274.1587 +        public A getA() {
274.1588 +            return a;
274.1589 +        }
274.1590 +
274.1591 +        public B getB() {
274.1592 +            return b;
274.1593 +        }
274.1594 +
274.1595 +    }
274.1596 +
274.1597 +    private static final class AtomicBooleanCancel implements Cancel {
274.1598 +
274.1599 +        private final AtomicBoolean cancel;
274.1600 +
274.1601 +        public AtomicBooleanCancel() {
274.1602 +            this(new AtomicBoolean());
274.1603 +        }
274.1604 +
274.1605 +        public AtomicBooleanCancel(AtomicBoolean cancel) {
274.1606 +            this.cancel = cancel;
274.1607 +        }
274.1608 +
274.1609 +        @Override
274.1610 +        public boolean isCancelled() {
274.1611 +            return cancel.get();
274.1612 +        }
274.1613 +
274.1614 +    }
274.1615 +}
   275.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   275.2 +++ b/sandbox/java.hints/spi.java.hints/test/unit/src/org/netbeans/spi/java/hints/support/FixFactoryTest.java	Sun Oct 23 11:50:54 2016 +0200
   275.3 @@ -0,0 +1,79 @@
   275.4 +/*
   275.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   275.6 + *
   275.7 + * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
   275.8 + *
   275.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  275.10 + * Other names may be trademarks of their respective owners.
  275.11 + *
  275.12 + * The contents of this file are subject to the terms of either the GNU
  275.13 + * General Public License Version 2 only ("GPL") or the Common
  275.14 + * Development and Distribution License("CDDL") (collectively, the
  275.15 + * "License"). You may not use this file except in compliance with the
  275.16 + * License. You can obtain a copy of the License at
  275.17 + * http://www.netbeans.org/cddl-gplv2.html
  275.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  275.19 + * specific language governing permissions and limitations under the
  275.20 + * License.  When distributing the software, include this License Header
  275.21 + * Notice in each file and include the License file at
  275.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  275.23 + * particular file as subject to the "Classpath" exception as provided
  275.24 + * by Oracle in the GPL Version 2 section of the License file that
  275.25 + * accompanied this code. If applicable, add the following below the
  275.26 + * License Header, with the fields enclosed by brackets [] replaced by
  275.27 + * your own identifying information:
  275.28 + * "Portions Copyrighted [year] [name of copyright owner]"
  275.29 + *
  275.30 + * If you wish your version of this file to be governed by only the CDDL
  275.31 + * or only the GPL Version 2, indicate your decision by adding
  275.32 + * "[Contributor] elects to include this software in this distribution
  275.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
  275.34 + * single choice of license, a recipient has the option to distribute
  275.35 + * your version of this file under either the CDDL, the GPL Version 2 or
  275.36 + * to extend the choice of license to its licensees as provided above.
  275.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
  275.38 + * Version 2 license, then the option applies only if the new code is
  275.39 + * made subject to such option by the copyright holder.
  275.40 + *
  275.41 + * Contributor(s):
  275.42 + *
  275.43 + * Portions Copyrighted 2013 Sun Microsystems, Inc.
  275.44 + */
  275.45 +package org.netbeans.spi.java.hints.support;
  275.46 +
  275.47 +import com.sun.source.tree.ClassTree;
  275.48 +import com.sun.source.util.TreePath;
  275.49 +import java.util.EnumSet;
  275.50 +import javax.lang.model.element.Modifier;
  275.51 +import org.netbeans.api.java.source.SourceUtilsTestUtil;
  275.52 +import org.netbeans.modules.java.hints.spiimpl.TestBase;
  275.53 +import org.openide.LifecycleManager;
  275.54 +
  275.55 +/**
  275.56 + *
  275.57 + * @author lahvac
  275.58 + */
  275.59 +public class FixFactoryTest extends TestBase {
  275.60 +    
  275.61 +    public FixFactoryTest(String name) {
  275.62 +        super(name);
  275.63 +    }
  275.64 +
  275.65 +    @Override
  275.66 +    protected void setUp() throws Exception {
  275.67 +        super.setUp();
  275.68 +        SourceUtilsTestUtil.makeScratchDir(this);
  275.69 +    }
  275.70 +    
  275.71 +    public void testInterfaceModifiers() throws Exception {
  275.72 +        prepareTest("test/Test.java", "package test; public interface I { }");
  275.73 +        
  275.74 +        ClassTree i = (ClassTree) info.getCompilationUnit().getTypeDecls().get(0);
  275.75 +        
  275.76 +        FixFactory.removeModifiersFix(info, TreePath.getPath(info.getCompilationUnit(), i.getModifiers()), EnumSet.of(Modifier.PUBLIC), "").implement();
  275.77 +        
  275.78 +        LifecycleManager.getDefault().saveAll();
  275.79 +        
  275.80 +        assertEquals("package test; interface I { }", info.getFileObject().asText());
  275.81 +    }
  275.82 +}
  275.83 \ No newline at end of file