Also need a copy of the java.hints.test for experimentation
authorJan Lahoda <jlahoda@netbeans.org>
Thu, 09 May 2013 22:04:33 +0200
changeset 9568ecdbdbce732
parent 955 bc3b5f486898
child 957 f0892c603898
Also need a copy of the java.hints.test for experimentation
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/project.properties
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/java.hints/java.hints.test/apichanges.xml	Thu May 09 22:04:33 2013 +0200
     1.3 @@ -0,0 +1,181 @@
     1.4 +<?xml version="1.0" encoding="UTF-8"?>
     1.5 +<!-- Search for CHANGEME in this document when copying and using it: -->
     1.6 +<!--
     1.7 +DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     1.8 +
     1.9 +Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
    1.10 +
    1.11 +Oracle and Java are registered trademarks of Oracle and/or its affiliates.
    1.12 +Other names may be trademarks of their respective owners.
    1.13 +
    1.14 +The contents of this file are subject to the terms of either the GNU
    1.15 +General Public License Version 2 only ("GPL") or the Common
    1.16 +Development and Distribution License("CDDL") (collectively, the
    1.17 +"License"). You may not use this file except in compliance with the
    1.18 +License. You can obtain a copy of the License at
    1.19 +http://www.netbeans.org/cddl-gplv2.html
    1.20 +or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    1.21 +specific language governing permissions and limitations under the
    1.22 +License.  When distributing the software, include this License Header
    1.23 +Notice in each file and include the License file at
    1.24 +nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
    1.25 +particular file as subject to the "Classpath" exception as provided
    1.26 +by Oracle in the GPL Version 2 section of the License file that
    1.27 +accompanied this code. If applicable, add the following below the
    1.28 +License Header, with the fields enclosed by brackets [] replaced by
    1.29 +your own identifying information:
    1.30 +"Portions Copyrighted [year] [name of copyright owner]"
    1.31 +
    1.32 +Contributor(s):
    1.33 +
    1.34 +The Original Software is NetBeans. The Initial Developer of the Original
    1.35 +Software is Sun Microsystems, Inc. Portions Copyright 1997-2010 Sun
    1.36 +Microsystems, Inc. All Rights Reserved.
    1.37 +
    1.38 +If you wish your version of this file to be governed by only the CDDL
    1.39 +or only the GPL Version 2, indicate your decision by adding
    1.40 +"[Contributor] elects to include this software in this distribution
    1.41 +under the [CDDL or GPL Version 2] license." If you do not indicate a
    1.42 +single choice of license, a recipient has the option to distribute
    1.43 +your version of this file under either the CDDL, the GPL Version 2 or
    1.44 +to extend the choice of license to its licensees as provided above.
    1.45 +However, if you add GPL Version 2 code and therefore, elected the GPL
    1.46 +Version 2 license, then the option applies only if the new code is
    1.47 +made subject to such option by the copyright holder.
    1.48 +-->
    1.49 +<?xml-stylesheet type="text/xml" href="../nbbuild/javadoctools/apichanges.xsl"?>
    1.50 +<!DOCTYPE apichanges PUBLIC "-//NetBeans//DTD API changes list 1.0//EN" "../nbbuild/javadoctools/apichanges.dtd">
    1.51 +
    1.52 +<!--
    1.53 +
    1.54 +INFO FOR PEOPLE ADDING CHANGES:
    1.55 +
    1.56 +Check the DTD (apichanges.dtd) for details on the syntax. You do not
    1.57 +need to regenerate the HTML, as this is part of Javadoc generation; just
    1.58 +change the XML. Rough syntax of a change (several parts optional):
    1.59 +
    1.60 +<change>
    1.61 +    <api name="compiler"/>
    1.62 +    <summary>Some brief description here, can use <b>XHTML</b></summary>
    1.63 +    <version major="1" minor="99"/>
    1.64 +    <date day="13" month="6" year="2001"/>
    1.65 +    <author login="jrhacker"/>
    1.66 +    <compatibility addition="yes"/>
    1.67 +    <description>
    1.68 +        The main description of the change here.
    1.69 +        Again can use full <b>XHTML</b> as needed.
    1.70 +    </description>
    1.71 +    <class package="org.openide.compiler" name="DoWhatIWantCompiler"/>
    1.72 +    <issue number="14309"/>
    1.73 +</change>
    1.74 +
    1.75 +Also permitted elements: <package>, <branch>. <version> is API spec
    1.76 +version, recommended for all new changes. <compatibility> should say
    1.77 +if things were added/modified/deprecated/etc. and give all information
    1.78 +related to upgrading old code. List affected top-level classes and
    1.79 +link to issue numbers if applicable. See the DTD for more details.
    1.80 +
    1.81 +Changes need not be in any particular order, they are sorted in various
    1.82 +ways by the stylesheet anyway.
    1.83 +
    1.84 +Dates are assumed to mean "on the trunk". If you *also* make the same
    1.85 +change on a stabilization branch, use the <branch> tag to indicate this
    1.86 +and explain why the change was made on a branch in the <description>.
    1.87 +
    1.88 +Please only change this file on the trunk! Rather: you can change it
    1.89 +on branches if you want, but these changes will be ignored; only the
    1.90 +trunk version of this file is important.
    1.91 +
    1.92 +Deprecations do not count as incompatible, assuming that code using the
    1.93 +deprecated calls continues to see their documented behavior. But do
    1.94 +specify deprecation="yes" in <compatibility>.
    1.95 +
    1.96 +This file is not a replacement for Javadoc: it is intended to list changes,
    1.97 +not describe the complete current behavior, for which ordinary documentation
    1.98 +is the proper place.
    1.99 +
   1.100 +-->
   1.101 +
   1.102 +<apichanges>
   1.103 +
   1.104 +    <!-- First, a list of API names you may use: -->
   1.105 +    <apidefs>
   1.106 +        <apidef name="JavaHintsTest">Java Hints Test API</apidef>
   1.107 +    </apidefs>
   1.108 +
   1.109 +    <!-- ACTUAL CHANGES BEGIN HERE: -->
   1.110 +
   1.111 +    <changes>
   1.112 +        <change id="HintTest-singleHint">
   1.113 +            <api name="JavaHintsTest"/>
   1.114 +            <summary>Allowed to check a single hint</summary>
   1.115 +            <version major="1" minor="9"/>
   1.116 +            <date day="3" month="4" year="2013"/>
   1.117 +            <author login="sdedic"/>
   1.118 +            <compatibility addition="yes" binary="compatible" deletion="no" deprecation="no" modification="no" semantic="compatible" source="compatible"/>
   1.119 +            <description>
   1.120 +                New method <code>run(Class, String)</code> was added so that hint with a specific ID can be run, if the
   1.121 +                class contains multiple hint implementations.
   1.122 +            </description>
   1.123 +            <class name="HintTest" package="org.netbeans.modules.java.hints.test.api"/>
   1.124 +            <issue number="227962"/>
   1.125 +        </change>
   1.126 +        <change id="HintTest-ensureJavaFixes">
   1.127 +             <api name="JavaHintsTest"/>
   1.128 +             <summary>Added assertFixes method to HintWarning</summary>
   1.129 +             <version major="1" minor="8"/>
   1.130 +             <date day="22" month="3" year="2013"/>
   1.131 +             <author login="jlahoda"/>
   1.132 +             <compatibility addition="no" binary="compatible" deletion="no" deprecation="no" modification="no" semantic="incompatible" source="compatible"/>
   1.133 +             <description>
   1.134 +                 <code>HintTest.HintWarning.applyFix</code> now enforces constraints for Inspect&amp;Transform. Unless a hint
   1.135 +                 is marked as <code>Options.QUERY</code>, <code>Options.NO_BULK</code> or <code>Kind.ACTION</code>,
   1.136 +                 the <code>Fix</code> that is being applied is tested to be <code>JavaFix</code> and repeatable,
   1.137 +                 which are the requirements of Inspect&amp;Transform.
   1.138 +             </description>
   1.139 +             <class name="HintTest" package="org.netbeans.modules.java.hints.test.api"/>
   1.140 +             <issue number="227271"/>
   1.141 +        </change>
   1.142 +        
   1.143 +        <change id="HintWarning-assertFixes">
   1.144 +             <api name="JavaHintsTest"/>
   1.145 +             <summary>Added assertFixes method to HintWarning</summary>
   1.146 +             <version major="1" minor="1"/>
   1.147 +             <date day="30" month="3" year="2012"/>
   1.148 +             <author login="jlahoda"/>
   1.149 +             <compatibility addition="yes" binary="compatible" deletion="no" deprecation="no" modification="no" semantic="compatible" source="compatible"/>
   1.150 +             <description>
   1.151 +                 Added assertFixes method to HintWarning
   1.152 +             </description>
   1.153 +             <class name="HintTest" package="org.netbeans.modules.java.hints.test.api"/>
   1.154 +             <issue number="209828"/>
   1.155 +        </change>
   1.156 +
   1.157 +    </changes>
   1.158 +
   1.159 +    <!-- Now the surrounding HTML text and document structure: -->
   1.160 +
   1.161 +    <htmlcontents>
   1.162 +<!-- Generated from apichanges.xml -->
   1.163 +    <head>
   1.164 +      <title>Change History for the Editor Hints SPI</title>
   1.165 +      <link rel="stylesheet" href="prose.css" type="text/css"/>
   1.166 +    </head>
   1.167 +    <body>
   1.168 +
   1.169 +<p class="overviewlink"><a href="@TOP@/overview-summary.html">Overview</a></p>
   1.170 +
   1.171 +<h1>Introduction</h1>
   1.172 +
   1.173 +<p>This document lists changes made to the <a href="@TOP@/overview-summary.html">Editor Hints SPI</a>.</p>
   1.174 +
   1.175 +<!-- The actual lists of changes, as summaries and details: -->
   1.176 +      <hr/>
   1.177 +      <standard-changelists module-code-name="org.netbeans.spi.editor.hints/0"/>
   1.178 +
   1.179 +      <hr/><p>@FOOTER@</p>
   1.180 +
   1.181 +    </body>
   1.182 +  </htmlcontents>
   1.183 +
   1.184 +</apichanges>
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/java.hints/java.hints.test/arch.xml	Thu May 09 22:04:33 2013 +0200
     2.3 @@ -0,0 +1,1078 @@
     2.4 +<?xml version="1.0" encoding="UTF-8"?>
     2.5 +<!DOCTYPE api-answers PUBLIC "-//NetBeans//DTD Arch Answers//EN" "../nbbuild/antsrc/org/netbeans/nbbuild/Arch.dtd" [
     2.6 +  <!ENTITY api-questions SYSTEM "../nbbuild/antsrc/org/netbeans/nbbuild/Arch-api-questions.xml">
     2.7 +]>
     2.8 +
     2.9 +<api-answers
    2.10 +  question-version="1.29"
    2.11 +  author="yourname@netbeans.org"
    2.12 +>
    2.13 +
    2.14 +  &api-questions;
    2.15 +
    2.16 +
    2.17 +<!--
    2.18 +        <question id="arch-overall" when="init">
    2.19 +            Describe the overall architecture. 
    2.20 +            <hint>
    2.21 +            What will be API for 
    2.22 +            <a href="http://wiki.netbeans.org/API_Design#Separate_API_for_clients_from_support_API">
    2.23 +                clients and what support API</a>? 
    2.24 +            What parts will be pluggable?
    2.25 +            How will plug-ins be registered? Please use <code>&lt;api type="export"/&gt;</code>
    2.26 +            to describe your general APIs and specify their
    2.27 +            <a href="http://wiki.netbeans.org/API_Stability#Private">
    2.28 +            stability categories</a>.
    2.29 +            If possible please provide simple diagrams.
    2.30 +            </hint>
    2.31 +        </question>
    2.32 +-->
    2.33 + <answer id="arch-overall">
    2.34 +  <p>
    2.35 +   <api type="export" category="devel" group="java" name="java.hints.test">
    2.36 +       API to create tests for the custom Java hints.
    2.37 +   </api>
    2.38 +  </p>
    2.39 + </answer>
    2.40 +
    2.41 +
    2.42 +
    2.43 +<!--
    2.44 +        <question id="arch-quality" when="init">
    2.45 +            How will the <a href="http://www.netbeans.org/community/guidelines/q-evangelism.html">quality</a>
    2.46 +            of your code be tested and 
    2.47 +            how are future regressions going to be prevented?
    2.48 +            <hint>
    2.49 +            What kind of testing do
    2.50 +            you want to use? How much functionality, in which areas,
    2.51 +            should be covered by the tests? How you find out that your
    2.52 +            project was successful?
    2.53 +            </hint>
    2.54 +        </question>
    2.55 +-->
    2.56 + <answer id="arch-quality">
    2.57 +  <p>
    2.58 +   XXX no answer for arch-quality
    2.59 +  </p>
    2.60 + </answer>
    2.61 +
    2.62 +
    2.63 +
    2.64 +<!--
    2.65 +        <question id="arch-time" when="init">
    2.66 +            What are the time estimates of the work?
    2.67 +            <hint>
    2.68 +            Please express your estimates of how long the design, implementation,
    2.69 +            stabilization are likely to last. How many people will be needed to
    2.70 +            implement this and what is the expected milestone by which the work should be 
    2.71 +            ready?
    2.72 +            </hint>
    2.73 +        </question>
    2.74 +-->
    2.75 + <answer id="arch-time">
    2.76 +  <p>
    2.77 +   XXX no answer for arch-time
    2.78 +  </p>
    2.79 + </answer>
    2.80 +
    2.81 +
    2.82 +
    2.83 +<!--
    2.84 +        <question id="arch-usecases" when="init">
    2.85 +            <hint>
    2.86 +                Content of this answer will be displayed as part of page at
    2.87 +                http://www.netbeans.org/download/dev/javadoc/usecases.html 
    2.88 +                You can use tags &lt;usecase name="name&gt; regular html description &lt;/usecase&gt;
    2.89 +                and if you want to use an URL you can prefix if with @TOP@ to begin
    2.90 +                at the root of your javadoc
    2.91 +            </hint>
    2.92 +        
    2.93 +            Describe the main <a href="http://wiki.netbeans.org/API_Design#The_Importance_of_Being_Use_Case_Oriented">
    2.94 +            use cases</a> of the new API. Who will use it under
    2.95 +            what circumstances? What kind of code would typically need to be written
    2.96 +            to use the module?
    2.97 +        </question>
    2.98 +-->
    2.99 + <answer id="arch-usecases">
   2.100 +  <p>
   2.101 +   XXX no answer for arch-usecases
   2.102 +  </p>
   2.103 + </answer>
   2.104 +
   2.105 +
   2.106 +
   2.107 +<!--
   2.108 +        <question id="arch-what" when="init">
   2.109 +            What is this project good for?
   2.110 +            <hint>
   2.111 +            Please provide here a few lines describing the project, 
   2.112 +            what problem it should solve, provide links to documentation, 
   2.113 +            specifications, etc.
   2.114 +            </hint>
   2.115 +        </question>
   2.116 +-->
   2.117 + <answer id="arch-what">
   2.118 +  <p>
   2.119 +   XXX no answer for arch-what
   2.120 +  </p>
   2.121 + </answer>
   2.122 +
   2.123 +
   2.124 +
   2.125 +<!--
   2.126 +        <question id="arch-where" when="impl">
   2.127 +            Where one can find sources for your module?
   2.128 +            <hint>
   2.129 +                Please provide link to the Hg web client at
   2.130 +                http://hg.netbeans.org/
   2.131 +                or just use tag defaultanswer generate='here'
   2.132 +            </hint>
   2.133 +        </question>
   2.134 +-->
   2.135 + <answer id="arch-where">
   2.136 +  <defaultanswer generate='here' />
   2.137 + </answer>
   2.138 +
   2.139 +
   2.140 +
   2.141 +<!--
   2.142 +        <question id="compat-deprecation" when="init">
   2.143 +            How the introduction of your project influences functionality
   2.144 +            provided by previous version of the product?
   2.145 +            <hint>
   2.146 +            If you are planning to deprecate/remove/change any existing APIs,
   2.147 +            list them here accompanied with the reason explaining why you
   2.148 +            are doing so.
   2.149 +            </hint>
   2.150 +        </question>
   2.151 +-->
   2.152 + <answer id="compat-deprecation">
   2.153 +  <p>
   2.154 +   XXX no answer for compat-deprecation
   2.155 +  </p>
   2.156 + </answer>
   2.157 +
   2.158 +
   2.159 +
   2.160 +<!--
   2.161 +        <question id="compat-i18n" when="impl">
   2.162 +            Is your module correctly internationalized?
   2.163 +            <hint>
   2.164 +            Correct internationalization means that it obeys instructions 
   2.165 +            at <a href="http://www.netbeans.org/download/dev/javadoc/org-openide-modules/org/openide/modules/doc-files/i18n-branding.html">
   2.166 +            NetBeans I18N pages</a>.
   2.167 +            </hint>
   2.168 +        </question>
   2.169 +-->
   2.170 + <answer id="compat-i18n">
   2.171 +  <p>
   2.172 +   XXX no answer for compat-i18n
   2.173 +  </p>
   2.174 + </answer>
   2.175 +
   2.176 +
   2.177 +
   2.178 +<!--
   2.179 +        <question id="compat-standards" when="init">
   2.180 +            Does the module implement or define any standards? Is the 
   2.181 +            implementation exact or does it deviate somehow?
   2.182 +        </question>
   2.183 +-->
   2.184 + <answer id="compat-standards">
   2.185 +  <p>
   2.186 +   XXX no answer for compat-standards
   2.187 +  </p>
   2.188 + </answer>
   2.189 +
   2.190 +
   2.191 +
   2.192 +<!--
   2.193 +        <question id="compat-version" when="impl">
   2.194 +            Can your module coexist with earlier and future
   2.195 +            versions of itself? Can you correctly read all old settings? Will future
   2.196 +            versions be able to read your current settings? Can you read
   2.197 +            or politely ignore settings stored by a future version?
   2.198 +            
   2.199 +            <hint>
   2.200 +            Very helpful for reading settings is to store version number
   2.201 +            there, so future versions can decide whether how to read/convert
   2.202 +            the settings and older versions can ignore the new ones.
   2.203 +            </hint>
   2.204 +        </question>
   2.205 +-->
   2.206 + <answer id="compat-version">
   2.207 +  <p>
   2.208 +   XXX no answer for compat-version
   2.209 +  </p>
   2.210 + </answer>
   2.211 +
   2.212 +
   2.213 +
   2.214 +<!--
   2.215 +        <question id="dep-jre" when="final">
   2.216 +            Which version of JRE do you need (1.2, 1.3, 1.4, etc.)?
   2.217 +            <hint>
   2.218 +            It is expected that if your module runs on 1.x that it will run 
   2.219 +            on 1.x+1 if no, state that please. Also describe here cases where
   2.220 +            you run different code on different versions of JRE and why.
   2.221 +            </hint>
   2.222 +        </question>
   2.223 +-->
   2.224 + <answer id="dep-jre">
   2.225 +  <p>
   2.226 +   XXX no answer for dep-jre
   2.227 +  </p>
   2.228 + </answer>
   2.229 +
   2.230 +
   2.231 +
   2.232 +<!--
   2.233 +        <question id="dep-jrejdk" when="final">
   2.234 +            Do you require the JDK or is the JRE enough?
   2.235 +        </question>
   2.236 +-->
   2.237 + <answer id="dep-jrejdk">
   2.238 +  <p>
   2.239 +   XXX no answer for dep-jrejdk
   2.240 +  </p>
   2.241 + </answer>
   2.242 +
   2.243 +
   2.244 +
   2.245 +<!--
   2.246 +        <question id="dep-nb" when="init">
   2.247 +            What other NetBeans projects and modules does this one depend on?
   2.248 +            <hint>
   2.249 +            Depending on other NetBeans projects influnces the ability of
   2.250 +            users of your work to customize their own branded version of
   2.251 +            NetBeans by enabling and disabling some modules. Too
   2.252 +            much dependencies restrict this kind of customization. If that
   2.253 +            is your case, then you may want to split your functionality into
   2.254 +            pieces of autoload, eager and regular modules which can be
   2.255 +            enabled independently. Usually the answer to this question
   2.256 +            is generated from your <code>project.xml</code> file, but
   2.257 +            if it is not guessed correctly, you can suppress it by
   2.258 +            specifying &lt;defaultanswer generate="none"/&gt; and
   2.259 +            write here your own. Please describe such projects as imported APIs using
   2.260 +            the <code>&lt;api name="identification" type="import or export" category="stable" url="where is the description" /&gt;</code>.
   2.261 +            By doing this information gets listed in the summary page of your
   2.262 +            javadoc.
   2.263 +            </hint>
   2.264 +        </question>
   2.265 +-->
   2.266 + <answer id="dep-nb">
   2.267 +  <defaultanswer generate='here' />
   2.268 + </answer>
   2.269 +
   2.270 +
   2.271 +
   2.272 +<!--
   2.273 +        <question id="dep-non-nb" when="init">
   2.274 +            What other projects outside NetBeans does this one depend on?
   2.275 +            
   2.276 +            <hint>
   2.277 +            Depending on 3rd party libraries is always problematic,
   2.278 +            especially if they are not open source, as that complicates
   2.279 +            the licensing scheme of NetBeans. Please enumerate your
   2.280 +            external dependencies here, so it is correctly understood since
   2.281 +            the begining what are the legal implications of your project.
   2.282 +            Also please note that
   2.283 +            some non-NetBeans projects are packaged as NetBeans modules
   2.284 +            (see <a href="http://libs.netbeans.org/">libraries</a>) and
   2.285 +            it is preferred to use this approach when more modules may
   2.286 +            depend and share such third-party libraries.
   2.287 +            </hint>
   2.288 +        </question>
   2.289 +-->
   2.290 + <answer id="dep-non-nb">
   2.291 +  <p>
   2.292 +   XXX no answer for dep-non-nb
   2.293 +  </p>
   2.294 + </answer>
   2.295 +
   2.296 +
   2.297 +
   2.298 +<!--
   2.299 +        <question id="dep-platform" when="init">
   2.300 +            On which platforms does your module run? Does it run in the same
   2.301 +            way on each?
   2.302 +            <hint>
   2.303 +            If you plan any dependency on OS or any usage of native code,
   2.304 +            please describe why you are doing so and describe how you envision
   2.305 +            to enforce the portability of your code.
   2.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
   2.307 +            enabled modules</a> which together with autoload/eager modules
   2.308 +            can allow you to enable to provide the best OS aware support
   2.309 +            on certain OSes while providing compatibility bridge on the not
   2.310 +            supported ones.
   2.311 +            Also please list the supported
   2.312 +            OSes/HW platforms and mentioned the lovest version of JDK required
   2.313 +            for your project to run on. Also state whether JRE is enough or
   2.314 +            you really need JDK.
   2.315 +            </hint>
   2.316 +        </question>
   2.317 +-->
   2.318 + <answer id="dep-platform">
   2.319 +  <p>
   2.320 +   XXX no answer for dep-platform
   2.321 +  </p>
   2.322 + </answer>
   2.323 +
   2.324 +
   2.325 +
   2.326 +<!--
   2.327 +        <question id="deploy-dependencies" when="final">
   2.328 +            What do other modules need to do to declare a dependency on this one,
   2.329 +            in addition to or instead of the normal module dependency declaration
   2.330 +            (e.g. tokens to require)?
   2.331 +            <hint>
   2.332 +                Provide a sample of the actual lines you would add to a module manifest
   2.333 +                to declare a dependency, for example OpenIDE-Module-Requires: some.token.
   2.334 +                If other modules should not depend on this module, or should just use a
   2.335 +                simple regular module dependency, you can just answer "nothing". If you
   2.336 +                intentionally expose a semistable API to clients using implementation
   2.337 +                dependencies, you should mention that here (but there is no need to give
   2.338 +                an example of usage).
   2.339 +            </hint>
   2.340 +        </question>
   2.341 +-->
   2.342 + <answer id="deploy-dependencies">
   2.343 +  <p>
   2.344 +   XXX no answer for deploy-dependencies
   2.345 +  </p>
   2.346 + </answer>
   2.347 +
   2.348 +
   2.349 +
   2.350 +<!--
   2.351 +        <question id="deploy-jar" when="impl">
   2.352 +            Do you deploy just module JAR file(s) or other files as well?
   2.353 +            <hint>
   2.354 +            Usually a module consist of one JAR file (perhaps with Class-Path
   2.355 +            extensions) and also a configuration file that enables it. If you
   2.356 +            have any other files, use
   2.357 +            &lt;api group="java.io.File" name="yourname" type="export" category="friend"&gt;...&lt;/api&gt;
   2.358 +            to define the location, name and stability of your files (of course
   2.359 +            changing "yourname" and "friend" to suit your needs).
   2.360 +            
   2.361 +            If it uses more than one JAR, describe where they are located, how
   2.362 +            they refer to each other. 
   2.363 +            If it consist of module JAR(s) and other files, please describe
   2.364 +            what is their purpose, why other files are necessary. Please 
   2.365 +            make sure that installation/uninstallation leaves the system 
   2.366 +            in state as it was before installation.
   2.367 +            </hint>
   2.368 +        </question>
   2.369 +-->
   2.370 + <answer id="deploy-jar">
   2.371 +  <p>
   2.372 +   XXX no answer for deploy-jar
   2.373 +  </p>
   2.374 + </answer>
   2.375 +
   2.376 +
   2.377 +
   2.378 +<!--
   2.379 +        <question id="deploy-nbm" when="impl">
   2.380 +            Can you deploy an NBM via the Update Center?
   2.381 +            <hint>
   2.382 +            If not why?
   2.383 +            </hint>
   2.384 +        </question>
   2.385 +-->
   2.386 + <answer id="deploy-nbm">
   2.387 +  <p>
   2.388 +   XXX no answer for deploy-nbm
   2.389 +  </p>
   2.390 + </answer>
   2.391 +
   2.392 +
   2.393 +
   2.394 +<!--
   2.395 +        <question id="deploy-packages" when="init">
   2.396 +            Are packages of your module made inaccessible by not declaring them
   2.397 +            public?
   2.398 +            
   2.399 +            <hint>
   2.400 +            By default NetBeans build harness treats all packages are private.
   2.401 +            If you export some of them - either as public or friend packages,
   2.402 +            you should have a reason. If the reason is described elsewhere
   2.403 +            in this document, you can ignore this question.
   2.404 +            </hint>
   2.405 +        </question>
   2.406 +-->
   2.407 + <answer id="deploy-packages">
   2.408 +  <p>
   2.409 +   XXX no answer for deploy-packages
   2.410 +  </p>
   2.411 + </answer>
   2.412 +
   2.413 +
   2.414 +
   2.415 +<!--
   2.416 +        <question id="deploy-shared" when="final">
   2.417 +            Do you need to be installed in the shared location only, or in the user directory only,
   2.418 +            or can your module be installed anywhere?
   2.419 +            <hint>
   2.420 +            Installation location shall not matter, if it does explain why.
   2.421 +            Consider also whether <code>InstalledFileLocator</code> can help.
   2.422 +            </hint>
   2.423 +        </question>
   2.424 +-->
   2.425 + <answer id="deploy-shared">
   2.426 +  <p>
   2.427 +   XXX no answer for deploy-shared
   2.428 +  </p>
   2.429 + </answer>
   2.430 +
   2.431 +
   2.432 +
   2.433 +<!--
   2.434 +        <question id="exec-ant-tasks" when="impl">
   2.435 +            Do you define or register any ant tasks that other can use?
   2.436 +            
   2.437 +            <hint>
   2.438 +            If you provide an ant task that users can use, you need to be very
   2.439 +            careful about its syntax and behaviour, as it most likely forms an
   2.440 +	          API for end users and as there is a lot of end users, their reaction
   2.441 +            when such API gets broken can be pretty strong.
   2.442 +            </hint>
   2.443 +        </question>
   2.444 +-->
   2.445 + <answer id="exec-ant-tasks">
   2.446 +  <p>
   2.447 +   XXX no answer for exec-ant-tasks
   2.448 +  </p>
   2.449 + </answer>
   2.450 +
   2.451 +
   2.452 +
   2.453 +<!--
   2.454 +        <question id="exec-classloader" when="impl">
   2.455 +            Does your code create its own class loader(s)?
   2.456 +            <hint>
   2.457 +            A bit unusual. Please explain why and what for.
   2.458 +            </hint>
   2.459 +        </question>
   2.460 +-->
   2.461 + <answer id="exec-classloader">
   2.462 +  <p>
   2.463 +   XXX no answer for exec-classloader
   2.464 +  </p>
   2.465 + </answer>
   2.466 +
   2.467 +
   2.468 +
   2.469 +<!--
   2.470 +        <question id="exec-component" when="impl">
   2.471 +            Is execution of your code influenced by any (string) property
   2.472 +            of any of your components?
   2.473 +            
   2.474 +            <hint>
   2.475 +            Often <code>JComponent.getClientProperty</code>, <code>Action.getValue</code>
   2.476 +            or <code>PropertyDescriptor.getValue</code>, etc. are used to influence
   2.477 +            a behavior of some code. This of course forms an interface that should
   2.478 +            be documented. Also if one depends on some interface that an object
   2.479 +            implements (<code>component instanceof Runnable</code>) that forms an
   2.480 +            API as well.
   2.481 +            </hint>
   2.482 +        </question>
   2.483 +-->
   2.484 + <answer id="exec-component">
   2.485 +  <p>
   2.486 +   XXX no answer for exec-component
   2.487 +  </p>
   2.488 + </answer>
   2.489 +
   2.490 +
   2.491 +
   2.492 +<!--
   2.493 +        <question id="exec-introspection" when="impl">
   2.494 +            Does your module use any kind of runtime type information (<code>instanceof</code>,
   2.495 +            work with <code>java.lang.Class</code>, etc.)?
   2.496 +            <hint>
   2.497 +            Check for cases when you have an object of type A and you also
   2.498 +            expect it to (possibly) be of type B and do some special action. That
   2.499 +            should be documented. The same applies on operations in meta-level
   2.500 +            (Class.isInstance(...), Class.isAssignableFrom(...), etc.).
   2.501 +            </hint>
   2.502 +        </question>
   2.503 +-->
   2.504 + <answer id="exec-introspection">
   2.505 +  <p>
   2.506 +   XXX no answer for exec-introspection
   2.507 +  </p>
   2.508 + </answer>
   2.509 +
   2.510 +
   2.511 +
   2.512 +<!--
   2.513 +        <question id="exec-privateaccess" when="final">
   2.514 +            Are you aware of any other parts of the system calling some of 
   2.515 +            your methods by reflection?
   2.516 +            <hint>
   2.517 +            If so, describe the "contract" as an API. Likely private or friend one, but
   2.518 +            still API and consider rewrite of it.
   2.519 +            </hint>
   2.520 +        </question>
   2.521 +-->
   2.522 + <answer id="exec-privateaccess">
   2.523 +  <p>
   2.524 +   XXX no answer for exec-privateaccess
   2.525 +  </p>
   2.526 + </answer>
   2.527 +
   2.528 +
   2.529 +
   2.530 +<!--
   2.531 +        <question id="exec-process" when="impl">
   2.532 +            Do you execute an external process from your module? How do you ensure
   2.533 +            that the result is the same on different platforms? Do you parse output?
   2.534 +            Do you depend on result code?
   2.535 +            <hint>
   2.536 +            If you feed an input, parse the output please declare that as an API.
   2.537 +            </hint>
   2.538 +        </question>
   2.539 +-->
   2.540 + <answer id="exec-process">
   2.541 +  <p>
   2.542 +   XXX no answer for exec-process
   2.543 +  </p>
   2.544 + </answer>
   2.545 +
   2.546 +
   2.547 +
   2.548 +<!--
   2.549 +        <question id="exec-property" when="impl">
   2.550 +            Is execution of your code influenced by any environment or
   2.551 +            Java system (<code>System.getProperty</code>) property?
   2.552 +            On a similar note, is there something interesting that you
   2.553 +            pass to <code>java.util.logging.Logger</code>? Or do you observe
   2.554 +            what others log?
   2.555 +            <hint>
   2.556 +            If there is a property that can change the behavior of your 
   2.557 +            code, somebody will likely use it. You should describe what it does 
   2.558 +            and the <a href="http://wiki.netbeans.org/API_Stability">stability category</a>
   2.559 +            of this API. You may use
   2.560 +            <pre>
   2.561 +                &lt;api type="export" group="property" name="id" category="private" url="http://..."&gt;
   2.562 +                    description of the property, where it is used, what it influence, etc.
   2.563 +                &lt;/api&gt;            
   2.564 +            </pre>
   2.565 +            </hint>
   2.566 +        </question>
   2.567 +-->
   2.568 + <answer id="exec-property">
   2.569 +  <p>
   2.570 +   XXX no answer for exec-property
   2.571 +  </p>
   2.572 + </answer>
   2.573 +
   2.574 +
   2.575 +
   2.576 +<!--
   2.577 +        <question id="exec-reflection" when="impl">
   2.578 +            Does your code use Java Reflection to execute other code?
   2.579 +            <hint>
   2.580 +            This usually indicates a missing or insufficient API in the other
   2.581 +            part of the system. If the other side is not aware of your dependency
   2.582 +            this contract can be easily broken.
   2.583 +            </hint>
   2.584 +        </question>
   2.585 +-->
   2.586 + <answer id="exec-reflection">
   2.587 +  <p>
   2.588 +   XXX no answer for exec-reflection
   2.589 +  </p>
   2.590 + </answer>
   2.591 +
   2.592 +
   2.593 +
   2.594 +<!--
   2.595 +        <question id="exec-threading" when="init">
   2.596 +            What threading models, if any, does your module adhere to? How the
   2.597 +            project behaves with respect to threading?
   2.598 +            <hint>
   2.599 +                Is your API threadsafe? Can it be accessed from any threads or
   2.600 +                just from some dedicated ones? Any special relation to AWT and
   2.601 +                its Event Dispatch thread? Also
   2.602 +                if your module calls foreign APIs which have a specific threading model,
   2.603 +                indicate how you comply with the requirements for multithreaded access
   2.604 +                (synchronization, mutexes, etc.) applicable to those APIs.
   2.605 +                If your module defines any APIs, or has complex internal structures
   2.606 +                that might be used from multiple threads, declare how you protect
   2.607 +                data against concurrent access, race conditions, deadlocks, etc.,
   2.608 +                and whether such rules are enforced by runtime warnings, errors, assertions, etc.
   2.609 +                Examples: a class might be non-thread-safe (like Java Collections); might
   2.610 +                be fully thread-safe (internal locking); might require access through a mutex
   2.611 +                (and may or may not automatically acquire that mutex on behalf of a client method);
   2.612 +                might be able to run only in the event queue; etc.
   2.613 +                Also describe when any events are fired: synchronously, asynchronously, etc.
   2.614 +                Ideas: <a href="http://core.netbeans.org/proposals/threading/index.html#recommendations">Threading Recommendations</a> (in progress)
   2.615 +            </hint>
   2.616 +        </question>
   2.617 +-->
   2.618 + <answer id="exec-threading">
   2.619 +  <p>
   2.620 +   XXX no answer for exec-threading
   2.621 +  </p>
   2.622 + </answer>
   2.623 +
   2.624 +
   2.625 +
   2.626 +<!--
   2.627 +        <question id="format-clipboard" when="impl">
   2.628 +            Which data flavors (if any) does your code read from or insert to
   2.629 +            the clipboard (by access to clipboard on means calling methods on <code>java.awt.datatransfer.Transferable</code>?
   2.630 +            
   2.631 +            <hint>
   2.632 +            Often Node's deal with clipboard by usage of <code>Node.clipboardCopy, Node.clipboardCut and Node.pasteTypes</code>.
   2.633 +            Check your code for overriding these methods.
   2.634 +            </hint>
   2.635 +        </question>
   2.636 +-->
   2.637 + <answer id="format-clipboard">
   2.638 +  <p>
   2.639 +   XXX no answer for format-clipboard
   2.640 +  </p>
   2.641 + </answer>
   2.642 +
   2.643 +
   2.644 +
   2.645 +<!--
   2.646 +        <question id="format-dnd" when="impl">
   2.647 +            Which protocols (if any) does your code understand during Drag &amp; Drop?
   2.648 +            <hint>
   2.649 +            Often Node's deal with clipboard by usage of <code>Node.drag, Node.getDropType</code>. 
   2.650 +            Check your code for overriding these methods. Btw. if they are not overridden, they
   2.651 +            by default delegate to <code>Node.clipboardCopy, Node.clipboardCut and Node.pasteTypes</code>.
   2.652 +            </hint>
   2.653 +        </question>
   2.654 +-->
   2.655 + <answer id="format-dnd">
   2.656 +  <p>
   2.657 +   XXX no answer for format-dnd
   2.658 +  </p>
   2.659 + </answer>
   2.660 +
   2.661 +
   2.662 +
   2.663 +<!--
   2.664 +        <question id="format-types" when="impl">
   2.665 +            Which protocols and file formats (if any) does your module read or write on disk,
   2.666 +            or transmit or receive over the network? Do you generate an ant build script?
   2.667 +            Can it be edited and modified? 
   2.668 +            
   2.669 +            <hint>
   2.670 +            <p>
   2.671 +            Files can be read and written by other programs, modules and users. If they influence
   2.672 +            your behaviour, make sure you either document the format or claim that it is a private
   2.673 +            api (using the &lt;api&gt; tag). 
   2.674 +            </p>
   2.675 +            
   2.676 +            <p>
   2.677 +            If you generate an ant build file, this is very likely going to be seen by end users and
   2.678 +            they will be attempted to edit it. You should be ready for that and provide here a link
   2.679 +            to documentation that you have for such purposes and also describe how you are going to
   2.680 +            understand such files during next release, when you (very likely) slightly change the 
   2.681 +            format.
   2.682 +            </p>
   2.683 +            </hint>
   2.684 +        </question>
   2.685 +-->
   2.686 + <answer id="format-types">
   2.687 +  <p>
   2.688 +   XXX no answer for format-types
   2.689 +  </p>
   2.690 + </answer>
   2.691 +
   2.692 +
   2.693 +
   2.694 +<!--
   2.695 +        <question id="lookup-lookup" when="init">
   2.696 +            Does your module use <code>org.openide.util.Lookup</code>
   2.697 +            or any similar technology to find any components to communicate with? Which ones?
   2.698 +            
   2.699 +            <hint>
   2.700 +            NetBeans is build around a generic registry of services called
   2.701 +            lookup. It is preferable to use it for registration and discovery
   2.702 +            if possible. See
   2.703 +            <a href="http://www.netbeans.org/download/dev/javadoc/org-openide-util/org/openide/util/lookup/doc-files/index.html">
   2.704 +            The Solution to Comunication Between Components
   2.705 +            </a>. If you do not plan to use lookup and insist usage
   2.706 +            of other solution, then please describe why it is not working for
   2.707 +            you.
   2.708 +            <br/>
   2.709 +            When filling the final version of your arch document, please
   2.710 +            describe the interfaces you are searching for, where 
   2.711 +            are defined, whether you are searching for just one or more of them,
   2.712 +            if the order is important, etc. Also classify the stability of such
   2.713 +            API contract. Use &lt;api group=&amp;lookup&amp; /&gt; tag, so
   2.714 +            your information gets listed in the summary page of your javadoc.
   2.715 +            </hint>
   2.716 +        </question>
   2.717 +-->
   2.718 + <answer id="lookup-lookup">
   2.719 +  <p>
   2.720 +   XXX no answer for lookup-lookup
   2.721 +  </p>
   2.722 + </answer>
   2.723 +
   2.724 +
   2.725 +
   2.726 +<!--
   2.727 +        <question id="lookup-register" when="final">
   2.728 +            Do you register anything into lookup for other code to find?
   2.729 +            <hint>
   2.730 +            Do you register using layer file or using a declarative annotation such as <code>@ServiceProvider</code>?
   2.731 +            Who is supposed to find your component?
   2.732 +            </hint>
   2.733 +        </question>
   2.734 +-->
   2.735 + <answer id="lookup-register">
   2.736 +  <p>
   2.737 +   XXX no answer for lookup-register
   2.738 +  </p>
   2.739 + </answer>
   2.740 +
   2.741 +
   2.742 +
   2.743 +<!--
   2.744 +        <question id="lookup-remove" when="final">
   2.745 +            Do you remove entries of other modules from lookup?
   2.746 +            <hint>
   2.747 +            Why? Of course, that is possible, but it can be dangerous. Is the module
   2.748 +            your are masking resource from aware of what you are doing?
   2.749 +            </hint>
   2.750 +        </question>
   2.751 +-->
   2.752 + <answer id="lookup-remove">
   2.753 +  <p>
   2.754 +   XXX no answer for lookup-remove
   2.755 +  </p>
   2.756 + </answer>
   2.757 +
   2.758 +
   2.759 +
   2.760 +<!--
   2.761 +        <question id="perf-exit" when="final">
   2.762 +            Does your module run any code on exit?
   2.763 +        </question>
   2.764 +-->
   2.765 + <answer id="perf-exit">
   2.766 +  <p>
   2.767 +   XXX no answer for perf-exit
   2.768 +  </p>
   2.769 + </answer>
   2.770 +
   2.771 +
   2.772 +
   2.773 +<!--
   2.774 +        <question id="perf-huge_dialogs" when="final">
   2.775 +            Does your module contain any dialogs or wizards with a large number of
   2.776 +            GUI controls such as combo boxes, lists, trees, or text areas?
   2.777 +        </question>
   2.778 +-->
   2.779 + <answer id="perf-huge_dialogs">
   2.780 +  <p>
   2.781 +   XXX no answer for perf-huge_dialogs
   2.782 +  </p>
   2.783 + </answer>
   2.784 +
   2.785 +
   2.786 +
   2.787 +<!--
   2.788 +        <question id="perf-limit" when="init">
   2.789 +            Are there any hard-coded or practical limits in the number or size of
   2.790 +            elements your code can handle?
   2.791 +            <hint>
   2.792 +                Most of algorithms have increasing memory and speed complexity
   2.793 +                with respect to size of data they operate on. What is the critical
   2.794 +                part of your project that can be seen as a bottleneck with
   2.795 +                respect to speed or required memory? What are the practical
   2.796 +                sizes of data you tested your project with? What is your estimate
   2.797 +                of potential size of data that would cause visible performance
   2.798 +                problems? Is there some kind of check to detect such situation
   2.799 +                and prevent "hard" crashes - for example the CloneableEditorSupport
   2.800 +                checks for size of a file to be opened in editor
   2.801 +                and if it is larger than 1Mb it shows a dialog giving the
   2.802 +                user the right to decide - e.g. to cancel or commit suicide.
   2.803 +            </hint>
   2.804 +        </question>
   2.805 +-->
   2.806 + <answer id="perf-limit">
   2.807 +  <p>
   2.808 +   XXX no answer for perf-limit
   2.809 +  </p>
   2.810 + </answer>
   2.811 +
   2.812 +
   2.813 +
   2.814 +<!--
   2.815 +        <question id="perf-mem" when="final">
   2.816 +            How much memory does your component consume? Estimate
   2.817 +            with a relation to the number of windows, etc.
   2.818 +        </question>
   2.819 +-->
   2.820 + <answer id="perf-mem">
   2.821 +  <p>
   2.822 +   XXX no answer for perf-mem
   2.823 +  </p>
   2.824 + </answer>
   2.825 +
   2.826 +
   2.827 +
   2.828 +<!--
   2.829 +        <question id="perf-menus" when="final">
   2.830 +            Does your module use dynamically updated context menus, or
   2.831 +            context-sensitive actions with complicated and slow enablement logic?
   2.832 +            <hint>
   2.833 +                If you do a lot of tricks when adding actions to regular or context menus, you can significantly
   2.834 +                slow down display of the menu, even when the user is not using your action. Pay attention to
   2.835 +                actions you add to the main menu bar, and to context menus of foreign nodes or components. If
   2.836 +                the action is conditionally enabled, or changes its display dynamically, you need to check the
   2.837 +                impact on performance. In some cases it may be more appropriate to make a simple action that is
   2.838 +                always enabled but does more detailed checks in a dialog if it is actually run.
   2.839 +            </hint>
   2.840 +        </question>
   2.841 +-->
   2.842 + <answer id="perf-menus">
   2.843 +  <p>
   2.844 +   XXX no answer for perf-menus
   2.845 +  </p>
   2.846 + </answer>
   2.847 +
   2.848 +
   2.849 +
   2.850 +<!--
   2.851 +        <question id="perf-progress" when="final">
   2.852 +            Does your module execute any long-running tasks?
   2.853 +            
   2.854 +            <hint>Long running tasks should never block 
   2.855 +            AWT thread as it badly hurts the UI
   2.856 +            <a href="http://performance.netbeans.org/responsiveness/issues.html">
   2.857 +            responsiveness</a>.
   2.858 +            Tasks like connecting over
   2.859 +            network, computing huge amount of data, compilation
   2.860 +            be done asynchronously (for example
   2.861 +            using <code>RequestProcessor</code>), definitively it should 
   2.862 +            not block AWT thread.
   2.863 +            </hint>
   2.864 +        </question>
   2.865 +-->
   2.866 + <answer id="perf-progress">
   2.867 +  <p>
   2.868 +   XXX no answer for perf-progress
   2.869 +  </p>
   2.870 + </answer>
   2.871 +
   2.872 +
   2.873 +
   2.874 +<!--
   2.875 +        <question id="perf-scale" when="init">
   2.876 +            Which external criteria influence the performance of your
   2.877 +            program (size of file in editor, number of files in menu, 
   2.878 +            in source directory, etc.) and how well your code scales?
   2.879 +            <hint>
   2.880 +            Please include some estimates, there are other more detailed 
   2.881 +            questions to answer in later phases of implementation. 
   2.882 +            </hint>
   2.883 +        </question>
   2.884 +-->
   2.885 + <answer id="perf-scale">
   2.886 +  <p>
   2.887 +   XXX no answer for perf-scale
   2.888 +  </p>
   2.889 + </answer>
   2.890 +
   2.891 +
   2.892 +
   2.893 +<!--
   2.894 +        <question id="perf-spi" when="init">
   2.895 +            How the performance of the plugged in code will be enforced?
   2.896 +            <hint>
   2.897 +            If you allow foreign code to be plugged into your own module, how
   2.898 +            do you enforce that it will behave correctly and quickly and will not
   2.899 +            negatively influence the performance of your own module?
   2.900 +            </hint>
   2.901 +        </question>
   2.902 +-->
   2.903 + <answer id="perf-spi">
   2.904 +  <p>
   2.905 +   XXX no answer for perf-spi
   2.906 +  </p>
   2.907 + </answer>
   2.908 +
   2.909 +
   2.910 +
   2.911 +<!--
   2.912 +        <question id="perf-startup" when="final">
   2.913 +            Does your module run any code on startup?
   2.914 +        </question>
   2.915 +-->
   2.916 + <answer id="perf-startup">
   2.917 +  <p>
   2.918 +   XXX no answer for perf-startup
   2.919 +  </p>
   2.920 + </answer>
   2.921 +
   2.922 +
   2.923 +
   2.924 +<!--
   2.925 +        <question id="perf-wakeup" when="final">
   2.926 +            Does any piece of your code wake up periodically and do something
   2.927 +            even when the system is otherwise idle (no user interaction)?
   2.928 +        </question>
   2.929 +-->
   2.930 + <answer id="perf-wakeup">
   2.931 +  <p>
   2.932 +   XXX no answer for perf-wakeup
   2.933 +  </p>
   2.934 + </answer>
   2.935 +
   2.936 +
   2.937 +
   2.938 +<!--
   2.939 +        <question id="resources-file" when="final">
   2.940 +            Does your module use <code>java.io.File</code> directly?
   2.941 +            
   2.942 +            <hint>
   2.943 +            NetBeans provide a logical wrapper over plain files called 
   2.944 +            <code>org.openide.filesystems.FileObject</code> that
   2.945 +            provides uniform access to such resources and is the preferred
   2.946 +            way that should be used. But of course there can be situations when
   2.947 +            this is not suitable.
   2.948 +            </hint>
   2.949 +        </question>
   2.950 +-->
   2.951 + <answer id="resources-file">
   2.952 +  <p>
   2.953 +   XXX no answer for resources-file
   2.954 +  </p>
   2.955 + </answer>
   2.956 +
   2.957 +
   2.958 +
   2.959 +<!--
   2.960 +        <question id="resources-layer" when="final">
   2.961 +            Does your module provide own layer? Does it create any files or
   2.962 +            folders in it? What it is trying to communicate by that and with which 
   2.963 +            components?
   2.964 +            
   2.965 +            <hint>
   2.966 +            NetBeans allows automatic and declarative installation of resources 
   2.967 +            by module layers. Module register files into appropriate places
   2.968 +            and other components use that information to perform their task
   2.969 +            (build menu, toolbar, window layout, list of templates, set of
   2.970 +            options, etc.). 
   2.971 +            </hint>
   2.972 +        </question>
   2.973 +-->
   2.974 + <answer id="resources-layer">
   2.975 +  <p>
   2.976 +   XXX no answer for resources-layer
   2.977 +  </p>
   2.978 + </answer>
   2.979 +
   2.980 +
   2.981 +
   2.982 +<!--
   2.983 +        <question id="resources-mask" when="final">
   2.984 +            Does your module mask/hide/override any resources provided by other modules in
   2.985 +            their layers?
   2.986 +            
   2.987 +            <hint>
   2.988 +            If you mask a file provided by another module, you probably depend
   2.989 +            on that and do not want the other module to (for example) change
   2.990 +            the file's name. That module shall thus make that file available as an API
   2.991 +            of some stability category.
   2.992 +            </hint>
   2.993 +        </question>
   2.994 +-->
   2.995 + <answer id="resources-mask">
   2.996 +  <p>
   2.997 +   XXX no answer for resources-mask
   2.998 +  </p>
   2.999 + </answer>
  2.1000 +
  2.1001 +
  2.1002 +
  2.1003 +<!--
  2.1004 +        <question id="resources-preferences" when="final">
  2.1005 +            Does your module uses preferences via Preferences API? Does your module use NbPreferences or
  2.1006 +            or regular JDK Preferences ? Does it read, write or both ? 
  2.1007 +            Does it share preferences with other modules ? If so, then why ?
  2.1008 +            <hint>
  2.1009 +                You may use
  2.1010 +                    &lt;api type="export" group="preferences"
  2.1011 +                    name="preference node name" category="private"&gt;
  2.1012 +                    description of individual keys, where it is used, what it
  2.1013 +                    influences, whether the module reads/write it, etc.
  2.1014 +                    &lt;/api&gt;
  2.1015 +                Due to XML ID restrictions, rather than /org/netbeans/modules/foo give the "name" as org.netbeans.modules.foo.
  2.1016 +                Note that if you use NbPreferences this name will then be the same as the code name base of the module.
  2.1017 +            </hint>
  2.1018 +        </question>
  2.1019 +-->
  2.1020 + <answer id="resources-preferences">
  2.1021 +  <p>
  2.1022 +   XXX no answer for resources-preferences
  2.1023 +  </p>
  2.1024 + </answer>
  2.1025 +
  2.1026 +
  2.1027 +
  2.1028 +<!--
  2.1029 +        <question id="resources-read" when="final">
  2.1030 +            Does your module read any resources from layers? For what purpose?
  2.1031 +            
  2.1032 +            <hint>
  2.1033 +            As this is some kind of intermodule dependency, it is a kind of API.
  2.1034 +            Please describe it and classify according to 
  2.1035 +            <a href="http://wiki.netbeans.org/API_Design#What_is_an_API.3F">
  2.1036 +            common stability categories</a>.
  2.1037 +            </hint>
  2.1038 +        </question>
  2.1039 +-->
  2.1040 + <answer id="resources-read">
  2.1041 +  <p>
  2.1042 +   XXX no answer for resources-read
  2.1043 +  </p>
  2.1044 + </answer>
  2.1045 +
  2.1046 +
  2.1047 +
  2.1048 +<!--
  2.1049 +        <question id="security-grant" when="final">
  2.1050 +            Does your code grant additional rights to some other code?
  2.1051 +            <hint>Avoid using a class loader that adds extra
  2.1052 +            permissions to loaded code unless really necessary.
  2.1053 +            Also note that your API implementation
  2.1054 +            can also expose unneeded permissions to enemy code by
  2.1055 +            calling AccessController.doPrivileged().</hint>
  2.1056 +        </question>
  2.1057 +-->
  2.1058 + <answer id="security-grant">
  2.1059 +  <p>
  2.1060 +   XXX no answer for security-grant
  2.1061 +  </p>
  2.1062 + </answer>
  2.1063 +
  2.1064 +
  2.1065 +
  2.1066 +<!--
  2.1067 +        <question id="security-policy" when="final">
  2.1068 +            Does your functionality require modifications to the standard policy file?
  2.1069 +            <hint>Your code might pass control to third-party code not
  2.1070 +            coming from trusted domains. This could be code downloaded over the
  2.1071 +            network or code coming from libraries that are not bundled
  2.1072 +            with NetBeans. Which permissions need to be granted to which domains?</hint>
  2.1073 +        </question>
  2.1074 +-->
  2.1075 + <answer id="security-policy">
  2.1076 +  <p>
  2.1077 +   XXX no answer for security-policy
  2.1078 +  </p>
  2.1079 + </answer>
  2.1080 +
  2.1081 +</api-answers>
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/java.hints/java.hints.test/build.xml	Thu May 09 22:04:33 2013 +0200
     3.3 @@ -0,0 +1,8 @@
     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="org.netbeans.modules.java.hints.test" default="netbeans" basedir=".">
     3.9 +    <description>Builds, tests, and runs the project org.netbeans.modules.java.hints.test.</description>
    3.10 +    <import file="nbproject/build-impl.xml"/>
    3.11 +</project>
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/java.hints/java.hints.test/manifest.mf	Thu May 09 22:04:33 2013 +0200
     4.3 @@ -0,0 +1,5 @@
     4.4 +Manifest-Version: 1.0
     4.5 +OpenIDE-Module: org.netbeans.modules.java.hints.test/1
     4.6 +OpenIDE-Module-Implementation-Version: 1
     4.7 +OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/java/hints/test/Bundle.properties
     4.8 +
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/java.hints/java.hints.test/nbproject/build-impl.xml	Thu May 09 22:04:33 2013 +0200
     5.3 @@ -0,0 +1,45 @@
     5.4 +<?xml version="1.0" encoding="UTF-8"?>
     5.5 +<!--
     5.6 +*** GENERATED FROM project.xml - DO NOT EDIT  ***
     5.7 +***         EDIT ../build.xml INSTEAD         ***
     5.8 +-->
     5.9 +<project name="org.netbeans.modules.java.hints.test-impl" basedir="..">
    5.10 +    <fail message="Please build using Ant 1.7.1 or higher.">
    5.11 +        <condition>
    5.12 +            <not>
    5.13 +                <antversion atleast="1.7.1"/>
    5.14 +            </not>
    5.15 +        </condition>
    5.16 +    </fail>
    5.17 +    <property file="nbproject/private/suite-private.properties"/>
    5.18 +    <property file="nbproject/suite.properties"/>
    5.19 +    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
    5.20 +    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
    5.21 +    <property file="${suite.dir}/nbproject/platform.properties"/>
    5.22 +    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
    5.23 +        <attribute name="name"/>
    5.24 +        <attribute name="value"/>
    5.25 +        <sequential>
    5.26 +            <property name="@{name}" value="${@{value}}"/>
    5.27 +        </sequential>
    5.28 +    </macrodef>
    5.29 +    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
    5.30 +        <attribute name="property"/>
    5.31 +        <attribute name="value"/>
    5.32 +        <sequential>
    5.33 +            <property name="@{property}" value="@{value}"/>
    5.34 +        </sequential>
    5.35 +    </macrodef>
    5.36 +    <property file="${user.properties.file}"/>
    5.37 +    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
    5.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"/>
    5.39 +    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
    5.40 +    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
    5.41 +        <condition>
    5.42 +            <not>
    5.43 +                <contains string="${cluster.path.evaluated}" substring="platform"/>
    5.44 +            </not>
    5.45 +        </condition>
    5.46 +    </fail>
    5.47 +    <import file="${harness.dir}/build.xml"/>
    5.48 +</project>
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/java.hints/java.hints.test/nbproject/genfiles.properties	Thu May 09 22:04:33 2013 +0200
     6.3 @@ -0,0 +1,8 @@
     6.4 +build.xml.data.CRC32=294cad92
     6.5 +build.xml.script.CRC32=fb578ef0
     6.6 +build.xml.stylesheet.CRC32=a56c6a5b@2.58
     6.7 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
     6.8 +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
     6.9 +nbproject/build-impl.xml.data.CRC32=294cad92
    6.10 +nbproject/build-impl.xml.script.CRC32=c676886e
    6.11 +nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.58
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/java.hints/java.hints.test/nbproject/org-netbeans-modules-java-hints-test.sig	Thu May 09 22:04:33 2013 +0200
     7.3 @@ -0,0 +1,67 @@
     7.4 +#Signature file v4.1
     7.5 +#Version 1.6.1
     7.6 +
     7.7 +CLSS public java.lang.Object
     7.8 +cons public init()
     7.9 +meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
    7.10 +meth protected void finalize() throws java.lang.Throwable
    7.11 +meth public boolean equals(java.lang.Object)
    7.12 +meth public final java.lang.Class<?> getClass()
    7.13 +meth public final void notify()
    7.14 +meth public final void notifyAll()
    7.15 +meth public final void wait() throws java.lang.InterruptedException
    7.16 +meth public final void wait(long) throws java.lang.InterruptedException
    7.17 +meth public final void wait(long,int) throws java.lang.InterruptedException
    7.18 +meth public int hashCode()
    7.19 +meth public java.lang.String toString()
    7.20 +
    7.21 +CLSS public org.netbeans.modules.java.hints.test.api.HintTest
    7.22 +innr public final AppliedFix
    7.23 +innr public final HintOutput
    7.24 +innr public final HintWarning
    7.25 +meth public !varargs org.netbeans.modules.java.hints.test.api.HintTest classpath(java.net.URL[])
    7.26 +meth public org.netbeans.modules.java.hints.test.api.HintTest input(java.lang.String) throws java.lang.Exception
    7.27 +meth public org.netbeans.modules.java.hints.test.api.HintTest input(java.lang.String,boolean) throws java.lang.Exception
    7.28 +meth public org.netbeans.modules.java.hints.test.api.HintTest input(java.lang.String,java.lang.String) throws java.lang.Exception
    7.29 +meth public org.netbeans.modules.java.hints.test.api.HintTest input(java.lang.String,java.lang.String,boolean) throws java.lang.Exception
    7.30 +meth public org.netbeans.modules.java.hints.test.api.HintTest preference(java.lang.String,boolean)
    7.31 +meth public org.netbeans.modules.java.hints.test.api.HintTest preference(java.lang.String,int)
    7.32 +meth public org.netbeans.modules.java.hints.test.api.HintTest preference(java.lang.String,java.lang.String)
    7.33 +meth public org.netbeans.modules.java.hints.test.api.HintTest setCaretMarker(char)
    7.34 +meth public org.netbeans.modules.java.hints.test.api.HintTest sourceLevel(java.lang.String)
    7.35 +meth public org.netbeans.modules.java.hints.test.api.HintTest$HintOutput run(java.lang.Class<?>) throws java.lang.Exception
    7.36 +meth public static org.netbeans.modules.java.hints.test.api.HintTest create() throws java.lang.Exception
    7.37 +supr java.lang.Object
    7.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
    7.39 +hcls DeadlockTask,TempPreferences,TestProxyClassPathProvider,TestSourceForBinaryQuery,TestSourceLevelQueryImplementation
    7.40 +
    7.41 +CLSS public final org.netbeans.modules.java.hints.test.api.HintTest$AppliedFix
    7.42 + outer org.netbeans.modules.java.hints.test.api.HintTest
    7.43 +cons public init(org.netbeans.modules.java.hints.test.api.HintTest)
    7.44 +meth public java.lang.String getOutput() throws java.lang.Exception
    7.45 +meth public java.lang.String getOutput(java.lang.String) throws java.lang.Exception
    7.46 +meth public org.netbeans.modules.java.hints.test.api.HintTest$AppliedFix assertCompilable() throws java.lang.Exception
    7.47 +meth public org.netbeans.modules.java.hints.test.api.HintTest$AppliedFix assertCompilable(java.lang.String) throws java.lang.Exception
    7.48 +meth public org.netbeans.modules.java.hints.test.api.HintTest$AppliedFix assertOutput(java.lang.String) throws java.lang.Exception
    7.49 +meth public org.netbeans.modules.java.hints.test.api.HintTest$AppliedFix assertOutput(java.lang.String,java.lang.String) throws java.lang.Exception
    7.50 +meth public org.netbeans.modules.java.hints.test.api.HintTest$AppliedFix assertVerbatimOutput(java.lang.String) throws java.lang.Exception
    7.51 +meth public org.netbeans.modules.java.hints.test.api.HintTest$AppliedFix assertVerbatimOutput(java.lang.String,java.lang.String) throws java.lang.Exception
    7.52 +supr java.lang.Object
    7.53 +
    7.54 +CLSS public final org.netbeans.modules.java.hints.test.api.HintTest$HintOutput
    7.55 + outer org.netbeans.modules.java.hints.test.api.HintTest
    7.56 +meth public !varargs org.netbeans.modules.java.hints.test.api.HintTest$HintOutput assertContainsWarnings(java.lang.String[])
    7.57 +meth public !varargs org.netbeans.modules.java.hints.test.api.HintTest$HintOutput assertNotContainsWarnings(java.lang.String[])
    7.58 +meth public !varargs org.netbeans.modules.java.hints.test.api.HintTest$HintOutput assertWarnings(java.lang.String[])
    7.59 +meth public org.netbeans.modules.java.hints.test.api.HintTest$HintWarning findWarning(java.lang.String)
    7.60 +supr java.lang.Object
    7.61 +hfds errors
    7.62 +
    7.63 +CLSS public final org.netbeans.modules.java.hints.test.api.HintTest$HintWarning
    7.64 + outer org.netbeans.modules.java.hints.test.api.HintTest
    7.65 +meth public !varargs org.netbeans.modules.java.hints.test.api.HintTest$HintWarning assertFixes(java.lang.String[]) throws java.lang.Exception
    7.66 +meth public org.netbeans.modules.java.hints.test.api.HintTest$AppliedFix applyFix() throws java.lang.Exception
    7.67 +meth public org.netbeans.modules.java.hints.test.api.HintTest$AppliedFix applyFix(java.lang.String) throws java.lang.Exception
    7.68 +supr java.lang.Object
    7.69 +hfds warning
    7.70 +
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/java.hints/java.hints.test/nbproject/project.properties	Thu May 09 22:04:33 2013 +0200
     8.3 @@ -0,0 +1,7 @@
     8.4 +is.autoload=true
     8.5 +javac.source=1.7
     8.6 +javac.compilerargs=-Xlint -Xlint:-serial
     8.7 +spec.version.base=2.0.0
     8.8 +javadoc.arch=${basedir}/arch.xml
     8.9 +javadoc.apichanges=${basedir}/apichanges.xml
    8.10 +requires.nb.javac=true
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/java.hints/java.hints.test/nbproject/project.xml	Thu May 09 22:04:33 2013 +0200
     9.3 @@ -0,0 +1,211 @@
     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.java.hints.test</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.13</specification-version>
    9.19 +                    </run-dependency>
    9.20 +                </dependency>
    9.21 +                <dependency>
    9.22 +                    <code-name-base>org.netbeans.api.java</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.37</specification-version>
    9.28 +                    </run-dependency>
    9.29 +                </dependency>
    9.30 +                <dependency>
    9.31 +                    <code-name-base>org.netbeans.api.java.classpath</code-name-base>
    9.32 +                    <build-prerequisite/>
    9.33 +                    <compile-dependency/>
    9.34 +                    <run-dependency>
    9.35 +                        <release-version>1</release-version>
    9.36 +                        <specification-version>1.32</specification-version>
    9.37 +                    </run-dependency>
    9.38 +                </dependency>
    9.39 +                <dependency>
    9.40 +                    <code-name-base>org.netbeans.core.startup</code-name-base>
    9.41 +                    <build-prerequisite/>
    9.42 +                    <compile-dependency/>
    9.43 +                    <run-dependency>
    9.44 +                        <release-version>1</release-version>
    9.45 +                        <specification-version>1.41</specification-version>
    9.46 +                    </run-dependency>
    9.47 +                </dependency>
    9.48 +                <dependency>
    9.49 +                    <code-name-base>org.netbeans.libs.javacapi</code-name-base>
    9.50 +                    <build-prerequisite/>
    9.51 +                    <compile-dependency/>
    9.52 +                    <run-dependency>
    9.53 +                        <specification-version>7.9</specification-version>
    9.54 +                    </run-dependency>
    9.55 +                </dependency>
    9.56 +                <dependency>
    9.57 +                    <code-name-base>org.netbeans.libs.junit4</code-name-base>
    9.58 +                    <build-prerequisite/>
    9.59 +                    <compile-dependency/>
    9.60 +                    <run-dependency>
    9.61 +                        <specification-version>1.13</specification-version>
    9.62 +                    </run-dependency>
    9.63 +                </dependency>
    9.64 +                <dependency>
    9.65 +                    <code-name-base>org.netbeans.modules.editor.mimelookup</code-name-base>
    9.66 +                    <build-prerequisite/>
    9.67 +                    <compile-dependency/>
    9.68 +                    <run-dependency>
    9.69 +                        <release-version>1</release-version>
    9.70 +                        <specification-version>1.25</specification-version>
    9.71 +                    </run-dependency>
    9.72 +                </dependency>
    9.73 +                <dependency>
    9.74 +                    <code-name-base>org.netbeans.modules.java.lexer</code-name-base>
    9.75 +                    <build-prerequisite/>
    9.76 +                    <compile-dependency/>
    9.77 +                    <run-dependency>
    9.78 +                        <release-version>1</release-version>
    9.79 +                        <specification-version>1.17</specification-version>
    9.80 +                    </run-dependency>
    9.81 +                </dependency>
    9.82 +                <dependency>
    9.83 +                    <code-name-base>org.netbeans.modules.java.source</code-name-base>
    9.84 +                    <build-prerequisite/>
    9.85 +                    <compile-dependency/>
    9.86 +                    <run-dependency>
    9.87 +                        <implementation-version/>
    9.88 +                    </run-dependency>
    9.89 +                </dependency>
    9.90 +                <dependency>
    9.91 +                    <code-name-base>org.netbeans.modules.lexer</code-name-base>
    9.92 +                    <build-prerequisite/>
    9.93 +                    <compile-dependency/>
    9.94 +                    <run-dependency>
    9.95 +                        <release-version>2</release-version>
    9.96 +                        <specification-version>1.43</specification-version>
    9.97 +                    </run-dependency>
    9.98 +                </dependency>
    9.99 +                <dependency>
   9.100 +                    <code-name-base>org.netbeans.modules.nbjunit</code-name-base>
   9.101 +                    <build-prerequisite/>
   9.102 +                    <compile-dependency/>
   9.103 +                    <run-dependency>
   9.104 +                        <release-version>1</release-version>
   9.105 +                        <specification-version>1.74</specification-version>
   9.106 +                    </run-dependency>
   9.107 +                </dependency>
   9.108 +                <dependency>
   9.109 +                    <code-name-base>org.netbeans.modules.parsing.api</code-name-base>
   9.110 +                    <build-prerequisite/>
   9.111 +                    <compile-dependency/>
   9.112 +                    <run-dependency>
   9.113 +                        <release-version>1</release-version>
   9.114 +                        <implementation-version/>
   9.115 +                    </run-dependency>
   9.116 +                </dependency>
   9.117 +                <dependency>
   9.118 +                    <code-name-base>org.netbeans.modules.projectapi</code-name-base>
   9.119 +                    <build-prerequisite/>
   9.120 +                    <compile-dependency/>
   9.121 +                    <run-dependency>
   9.122 +                        <release-version>1</release-version>
   9.123 +                        <specification-version>1.41</specification-version>
   9.124 +                    </run-dependency>
   9.125 +                </dependency>
   9.126 +                <dependency>
   9.127 +                    <code-name-base>org.netbeans.modules.projectuiapi</code-name-base>
   9.128 +                    <build-prerequisite/>
   9.129 +                    <compile-dependency/>
   9.130 +                    <run-dependency>
   9.131 +                        <release-version>1</release-version>
   9.132 +                        <specification-version>1.54</specification-version>
   9.133 +                    </run-dependency>
   9.134 +                </dependency>
   9.135 +                <dependency>
   9.136 +                    <code-name-base>org.netbeans.modules.refactoring.api</code-name-base>
   9.137 +                    <build-prerequisite/>
   9.138 +                    <compile-dependency/>
   9.139 +                    <run-dependency>
   9.140 +                        <specification-version>1.34</specification-version>
   9.141 +                    </run-dependency>
   9.142 +                </dependency>
   9.143 +                <dependency>
   9.144 +                    <code-name-base>org.netbeans.spi.editor.hints</code-name-base>
   9.145 +                    <build-prerequisite/>
   9.146 +                    <compile-dependency/>
   9.147 +                    <run-dependency>
   9.148 +                        <release-version>0-1</release-version>
   9.149 +                        <specification-version>1.22</specification-version>
   9.150 +                    </run-dependency>
   9.151 +                </dependency>
   9.152 +                <dependency>
   9.153 +                    <code-name-base>org.netbeans.spi.java.hints</code-name-base>
   9.154 +                    <build-prerequisite/>
   9.155 +                    <compile-dependency/>
   9.156 +                    <run-dependency>
   9.157 +                        <implementation-version/>
   9.158 +                    </run-dependency>
   9.159 +                </dependency>
   9.160 +                <dependency>
   9.161 +                    <code-name-base>org.openide.filesystems</code-name-base>
   9.162 +                    <build-prerequisite/>
   9.163 +                    <compile-dependency/>
   9.164 +                    <run-dependency>
   9.165 +                        <specification-version>7.55</specification-version>
   9.166 +                    </run-dependency>
   9.167 +                </dependency>
   9.168 +                <dependency>
   9.169 +                    <code-name-base>org.openide.loaders</code-name-base>
   9.170 +                    <build-prerequisite/>
   9.171 +                    <compile-dependency/>
   9.172 +                    <run-dependency>
   9.173 +                        <specification-version>7.33</specification-version>
   9.174 +                    </run-dependency>
   9.175 +                </dependency>
   9.176 +                <dependency>
   9.177 +                    <code-name-base>org.openide.nodes</code-name-base>
   9.178 +                    <build-prerequisite/>
   9.179 +                    <compile-dependency/>
   9.180 +                    <run-dependency>
   9.181 +                        <specification-version>7.26</specification-version>
   9.182 +                    </run-dependency>
   9.183 +                </dependency>
   9.184 +                <dependency>
   9.185 +                    <code-name-base>org.openide.text</code-name-base>
   9.186 +                    <build-prerequisite/>
   9.187 +                    <compile-dependency/>
   9.188 +                    <run-dependency>
   9.189 +                        <specification-version>6.44</specification-version>
   9.190 +                    </run-dependency>
   9.191 +                </dependency>
   9.192 +                <dependency>
   9.193 +                    <code-name-base>org.openide.util</code-name-base>
   9.194 +                    <build-prerequisite/>
   9.195 +                    <compile-dependency/>
   9.196 +                    <run-dependency>
   9.197 +                        <specification-version>8.20</specification-version>
   9.198 +                    </run-dependency>
   9.199 +                </dependency>
   9.200 +                <dependency>
   9.201 +                    <code-name-base>org.openide.util.lookup</code-name-base>
   9.202 +                    <build-prerequisite/>
   9.203 +                    <compile-dependency/>
   9.204 +                    <run-dependency>
   9.205 +                        <specification-version>8.12</specification-version>
   9.206 +                    </run-dependency>
   9.207 +                </dependency>
   9.208 +            </module-dependencies>
   9.209 +            <public-packages>
   9.210 +                <package>org.netbeans.modules.java.hints.test.api</package>
   9.211 +            </public-packages>
   9.212 +        </data>
   9.213 +    </configuration>
   9.214 +</project>
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/java.hints/java.hints.test/nbproject/suite.properties	Thu May 09 22:04:33 2013 +0200
    10.3 @@ -0,0 +1,1 @@
    10.4 +suite.dir=${basedir}/..
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/java.hints/java.hints.test/src/org/netbeans/modules/java/hints/test/Bundle.properties	Thu May 09 22:04:33 2013 +0200
    11.3 @@ -0,0 +1,1 @@
    11.4 +OpenIDE-Module-Name=Java Hints Test API
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/java.hints/java.hints.test/src/org/netbeans/modules/java/hints/test/Utilities.java	Thu May 09 22:04:33 2013 +0200
    12.3 @@ -0,0 +1,104 @@
    12.4 +/*
    12.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    12.6 + *
    12.7 + * Copyright 2012 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 2012 Sun Microsystems, Inc.
   12.44 + */
   12.45 +package org.netbeans.modules.java.hints.test;
   12.46 +
   12.47 +import org.netbeans.api.editor.mimelookup.MimePath;
   12.48 +import org.netbeans.modules.java.source.indexing.JavaCustomIndexer;
   12.49 +import org.netbeans.modules.java.source.parsing.JavacParser;
   12.50 +import org.netbeans.modules.java.source.parsing.JavacParserFactory;
   12.51 +import org.netbeans.spi.editor.mimelookup.MimeDataProvider;
   12.52 +import org.openide.filesystems.FileObject;
   12.53 +import org.openide.filesystems.MIMEResolver;
   12.54 +import org.openide.util.Lookup;
   12.55 +import org.openide.util.lookup.Lookups;
   12.56 +import org.openide.util.lookup.ProxyLookup;
   12.57 +import org.openide.util.lookup.ServiceProvider;
   12.58 +
   12.59 +/**
   12.60 + *
   12.61 + * @author lahvac
   12.62 + */
   12.63 +public class Utilities {
   12.64 +
   12.65 +    @ServiceProvider(service = Lookup.class)
   12.66 +    public static final class TestLookup extends ProxyLookup {
   12.67 +
   12.68 +        public void setLookupsImpl(Lookup... lookups) {
   12.69 +            setLookups(lookups);
   12.70 +        }
   12.71 +
   12.72 +    }
   12.73 +
   12.74 +    @ServiceProvider(service=MimeDataProvider.class)
   12.75 +    public static final class JavacParserProvider implements MimeDataProvider {
   12.76 +
   12.77 +        private Lookup javaLookup = Lookups.fixed(new JavacParserFactory(), new JavaCustomIndexer.Factory());
   12.78 +
   12.79 +        public Lookup getLookup(MimePath mimePath) {
   12.80 +            if (mimePath.getPath().endsWith(JavacParser.MIME_TYPE)) {
   12.81 +                return javaLookup;
   12.82 +            }
   12.83 +
   12.84 +            return Lookup.EMPTY;
   12.85 +        }
   12.86 +
   12.87 +    }
   12.88 +
   12.89 +    @ServiceProvider(service=MIMEResolver.class)
   12.90 +    public static final class JavaMimeResolver extends MIMEResolver {
   12.91 +
   12.92 +        public JavaMimeResolver() {
   12.93 +            super(JavacParser.MIME_TYPE);
   12.94 +        }
   12.95 +
   12.96 +        @Override
   12.97 +        public String findMIMEType(FileObject fo) {
   12.98 +            if ("java".equals(fo.getExt())) {
   12.99 +                return JavacParser.MIME_TYPE;
  12.100 +            }
  12.101 +
  12.102 +            return null;
  12.103 +        }
  12.104 +
  12.105 +    }
  12.106 +
  12.107 +}
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/java.hints/java.hints.test/src/org/netbeans/modules/java/hints/test/api/HintTest.java	Thu May 09 22:04:33 2013 +0200
    13.3 @@ -0,0 +1,1378 @@
    13.4 +/*
    13.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    13.6 + *
    13.7 + * Copyright 2012 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 2012 Sun Microsystems, Inc.
   13.44 + */
   13.45 +package org.netbeans.modules.java.hints.test.api;
   13.46 +
   13.47 +import com.sun.source.tree.CompilationUnitTree;
   13.48 +import com.sun.source.util.TreePath;
   13.49 +import java.io.File;
   13.50 +import java.io.FileInputStream;
   13.51 +import java.io.IOException;
   13.52 +import java.io.OutputStream;
   13.53 +import java.lang.ref.Reference;
   13.54 +import java.lang.ref.WeakReference;
   13.55 +import java.net.URL;
   13.56 +import java.util.ArrayList;
   13.57 +import java.util.Arrays;
   13.58 +import java.util.Collection;
   13.59 +import java.util.Collections;
   13.60 +import java.util.Comparator;
   13.61 +import java.util.Enumeration;
   13.62 +import java.util.HashMap;
   13.63 +import java.util.HashSet;
   13.64 +import java.util.IdentityHashMap;
   13.65 +import java.util.LinkedList;
   13.66 +import java.util.List;
   13.67 +import java.util.Map;
   13.68 +import java.util.Map.Entry;
   13.69 +import java.util.Properties;
   13.70 +import java.util.Set;
   13.71 +import java.util.concurrent.atomic.AtomicBoolean;
   13.72 +import java.util.logging.Handler;
   13.73 +import java.util.logging.Level;
   13.74 +import java.util.logging.LogRecord;
   13.75 +import java.util.logging.Logger;
   13.76 +import java.util.prefs.AbstractPreferences;
   13.77 +import java.util.prefs.BackingStoreException;
   13.78 +import java.util.prefs.Preferences;
   13.79 +import java.util.regex.Pattern;
   13.80 +import javax.swing.event.ChangeListener;
   13.81 +import javax.swing.text.Document;
   13.82 +import javax.tools.Diagnostic;
   13.83 +import junit.framework.Assert;
   13.84 +import static junit.framework.Assert.assertEquals;
   13.85 +import static junit.framework.Assert.assertFalse;
   13.86 +import static junit.framework.Assert.assertNotNull;
   13.87 +import static junit.framework.Assert.assertNotSame;
   13.88 +import static junit.framework.Assert.assertTrue;
   13.89 +
   13.90 +import org.netbeans.api.editor.mimelookup.MimeLookup;
   13.91 +import org.netbeans.api.java.classpath.ClassPath;
   13.92 +import org.netbeans.api.java.lexer.JavaTokenId;
   13.93 +import org.netbeans.api.java.queries.SourceForBinaryQuery;
   13.94 +import org.netbeans.api.java.source.ClasspathInfo;
   13.95 +import org.netbeans.api.java.source.CompilationController;
   13.96 +import org.netbeans.api.java.source.CompilationInfo;
   13.97 +import org.netbeans.api.java.source.JavaSource;
   13.98 +import org.netbeans.api.java.source.JavaSource.Phase;
   13.99 +import org.netbeans.api.java.source.ModificationResult;
  13.100 +import org.netbeans.api.java.source.ModificationResult.Difference;
  13.101 +import org.netbeans.api.java.source.Task;
  13.102 +import org.netbeans.api.java.source.WorkingCopy;
  13.103 +import org.netbeans.api.lexer.Language;
  13.104 +import org.netbeans.core.startup.Main;
  13.105 +import org.netbeans.junit.NbTestCase;
  13.106 +import org.netbeans.modules.java.JavaDataLoader;
  13.107 +import org.netbeans.modules.java.hints.providers.code.CodeHintProviderImpl;
  13.108 +import org.netbeans.modules.java.hints.providers.code.FSWrapper;
  13.109 +import org.netbeans.modules.java.hints.providers.code.FSWrapper.ClassWrapper;
  13.110 +import org.netbeans.modules.java.hints.providers.spi.HintDescription;
  13.111 +import org.netbeans.modules.java.hints.providers.spi.HintDescription.Worker;
  13.112 +import org.netbeans.modules.java.hints.providers.spi.HintDescriptionFactory;
  13.113 +import org.netbeans.modules.java.hints.providers.spi.HintMetadata;
  13.114 +import org.netbeans.modules.java.hints.providers.spi.HintMetadata.Options;
  13.115 +import org.netbeans.modules.java.hints.spiimpl.JavaFixImpl;
  13.116 +import org.netbeans.modules.java.hints.spiimpl.JavaFixImpl.Accessor;
  13.117 +import org.netbeans.modules.java.hints.spiimpl.MessageImpl;
  13.118 +import org.netbeans.modules.java.hints.spiimpl.SyntheticFix;
  13.119 +import org.netbeans.modules.java.hints.spiimpl.batch.BatchUtilities;
  13.120 +import org.netbeans.modules.java.hints.spiimpl.hints.HintsInvoker;
  13.121 +import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings;
  13.122 +import org.netbeans.modules.java.hints.test.Utilities.TestLookup;
  13.123 +import org.netbeans.modules.java.source.JavaSourceAccessor;
  13.124 +import org.netbeans.modules.java.source.TreeLoader;
  13.125 +import org.netbeans.modules.parsing.api.indexing.IndexingManager;
  13.126 +import org.netbeans.modules.parsing.impl.indexing.CacheFolder;
  13.127 +import org.netbeans.modules.parsing.impl.indexing.MimeTypes;
  13.128 +import org.netbeans.modules.refactoring.spi.RefactoringElementImplementation;
  13.129 +import org.netbeans.spi.editor.hints.ErrorDescription;
  13.130 +import org.netbeans.spi.editor.hints.Fix;
  13.131 +import org.netbeans.spi.editor.hints.Severity;
  13.132 +import org.netbeans.spi.java.classpath.ClassPathProvider;
  13.133 +import org.netbeans.spi.java.classpath.support.ClassPathSupport;
  13.134 +import org.netbeans.spi.java.hints.Hint.Kind;
  13.135 +import org.netbeans.spi.java.hints.HintContext;
  13.136 +import org.netbeans.spi.java.hints.JavaFix;
  13.137 +import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation;
  13.138 +import org.netbeans.spi.java.queries.SourceLevelQueryImplementation;
  13.139 +import org.openide.LifecycleManager;
  13.140 +import org.openide.cookies.EditorCookie;
  13.141 +import org.openide.filesystems.FileObject;
  13.142 +import org.openide.filesystems.FileStateInvalidException;
  13.143 +import org.openide.filesystems.FileSystem;
  13.144 +import org.openide.filesystems.FileUtil;
  13.145 +import org.openide.filesystems.MultiFileSystem;
  13.146 +import org.openide.filesystems.Repository;
  13.147 +import org.openide.filesystems.URLMapper;
  13.148 +import org.openide.filesystems.XMLFileSystem;
  13.149 +import org.openide.loaders.DataObject;
  13.150 +import org.openide.loaders.DataObjectNotFoundException;
  13.151 +import org.openide.util.Exceptions;
  13.152 +import org.openide.util.Lookup;
  13.153 +import org.openide.util.NbBundle;
  13.154 +import org.openide.util.lookup.Lookups;
  13.155 +
  13.156 +/**A support class for writing a test for a Java Hint. A test verifying that correct
  13.157 + * warnings are produced should look like:
  13.158 + * <pre>
  13.159 + * HintTest.create()
  13.160 + *         .input("&lt;input Java source code>")
  13.161 + *         .run(&lt;class containg the hint>)
  13.162 + *         .assertWarnings("&lt;required warning(s)>");
  13.163 + * </pre>
  13.164 + *
  13.165 + * Note: when verifying that no warnings are produced in a particular situation,
  13.166 + * do not pass any warnings to the {@code assertWarnings} method.
  13.167 + *
  13.168 + * A test verifying that a hint's transformation is correct:
  13.169 + * <pre>
  13.170 + * HintTest.create()
  13.171 + *         .input("&lt;input Java source code>")
  13.172 + *         .run(&lt;class containg the hint>)
  13.173 + *         .findWarning("&lt;a warning produce by the hint>")
  13.174 + *         .applyFix() //fill apply the only fix in the given ErrorDescription
  13.175 + *         .assertCompilable()
  13.176 + *         .assertOutput("&lt;output Java source code>");
  13.177 + * </pre>
  13.178 + *
  13.179 + * All the tests run under the {@code test} branding, which allows to specify test values
  13.180 + * for bundle keys for warning and fix in {@code Bundle_test.properties}, to isolate the
  13.181 + * test from changes in the production {@code Bundle.properties}.
  13.182 + *
  13.183 + * @author lahvac
  13.184 + */
  13.185 +public class HintTest {
  13.186 +
  13.187 +    private static final Logger INDEXING_LOGGER = /* RepositoryUpdater.UI_LOGGER */ Logger.getLogger("org.netbeans.ui.indexing");
  13.188 +    static {
  13.189 +        INDEXING_LOGGER.setLevel(Level.WARNING);
  13.190 +    }
  13.191 +
  13.192 +    private final File workDir;
  13.193 +    private final FileObject sourceRoot;
  13.194 +    private final FileObject buildRoot;
  13.195 +    private final FileObject cache;
  13.196 +    private final Preferences testPreferences;
  13.197 +    private final HintsSettings hintSettings;
  13.198 +    private final List<FileObject> checkCompilable = new ArrayList<FileObject>();
  13.199 +    private String sourceLevel = "1.5";
  13.200 +    private Character caretMarker;
  13.201 +    private FileObject testFile;
  13.202 +    private int caret = -1;
  13.203 +    private ClassPath sourcePath;
  13.204 +    private ClassPath compileClassPath = ClassPathSupport.createClassPath(new URL[0]);
  13.205 +
  13.206 +    private HintTest() throws Exception {
  13.207 +        List<URL> layers = new LinkedList<URL>();
  13.208 +
  13.209 +        for (String layer : new String[] {"META-INF/generated-layer.xml"}) {
  13.210 +            boolean found = false;
  13.211 +
  13.212 +            for (Enumeration<URL> en = Thread.currentThread().getContextClassLoader().getResources(layer); en.hasMoreElements(); ) {
  13.213 +                found = true;
  13.214 +                layers.add(en.nextElement());
  13.215 +            }
  13.216 +
  13.217 +            Assert.assertTrue(layer, found);
  13.218 +        }
  13.219 +
  13.220 +        XMLFileSystem xmlFS = new XMLFileSystem();
  13.221 +        xmlFS.setXmlUrls(layers.toArray(new URL[0]));
  13.222 +
  13.223 +        FileSystem system = new MultiFileSystem(new FileSystem[] {FileUtil.createMemoryFileSystem(), xmlFS});
  13.224 +
  13.225 +        Repository repository = new Repository(system);
  13.226 +
  13.227 +        assertEquals(Lookup.getDefault().getClass().getCanonicalName(), TestLookup.class, Lookup.getDefault().getClass());
  13.228 +
  13.229 +        ((TestLookup) Lookup.getDefault()).setLookupsImpl(
  13.230 +            Lookups.fixed(repository,
  13.231 +                          new TestProxyClassPathProvider(),
  13.232 +                          new TestSourceForBinaryQuery(),
  13.233 +                          new TestSourceLevelQueryImplementation(),
  13.234 +                          JavaDataLoader.findObject(JavaDataLoader.class, true)),
  13.235 +            Lookups.metaInfServices(HintTest.class.getClassLoader()),
  13.236 +            Lookups.singleton(HintTest.class.getClassLoader())
  13.237 +        );
  13.238 +
  13.239 +        Set<String> amt = MimeTypes.getAllMimeTypes();
  13.240 +        if (amt == null) {
  13.241 +            amt = new HashSet<String>();
  13.242 +        } else {
  13.243 +            amt = new HashSet<String>(amt);
  13.244 +        }
  13.245 +        amt.add("text/x-java");
  13.246 +        MimeTypes.setAllMimeTypes(amt);
  13.247 +        org.netbeans.api.project.ui.OpenProjects.getDefault().getOpenProjects();
  13.248 +
  13.249 +        TreeLoader.DISABLE_CONFINEMENT_TEST = true;
  13.250 +        testPreferences = new TempPreferences();
  13.251 +        hintSettings = new HintsSettings() {
  13.252 +            @Override public boolean isEnabled(HintMetadata hint) {
  13.253 +                return true;
  13.254 +            }
  13.255 +            @Override public void setEnabled(HintMetadata hint, boolean value) {
  13.256 +                throw new UnsupportedOperationException("Not supported.");
  13.257 +            }
  13.258 +            @Override public Preferences getHintPreferences(HintMetadata hint) {
  13.259 +                return testPreferences;
  13.260 +            }
  13.261 +            @Override public Severity getSeverity(HintMetadata hint) {
  13.262 +                return hint.severity;
  13.263 +            }
  13.264 +            @Override public void setSeverity(HintMetadata hint, Severity severity) {
  13.265 +                throw new UnsupportedOperationException("Not supported.");
  13.266 +            }
  13.267 +        };
  13.268 +
  13.269 +        workDir = getWorkDir();
  13.270 +        deleteSubFiles(workDir);
  13.271 +        FileUtil.refreshFor(workDir);
  13.272 +
  13.273 +        FileObject wd = FileUtil.toFileObject(workDir);
  13.274 +        
  13.275 +        assertNotNull(wd);
  13.276 +
  13.277 +        sourceRoot = FileUtil.createFolder(wd, "src");
  13.278 +        buildRoot = FileUtil.createFolder(wd, "build");
  13.279 +        cache = FileUtil.createFolder(wd, "cache");
  13.280 +
  13.281 +        CacheFolder.setCacheFolder(cache);
  13.282 +
  13.283 +        NbBundle.setBranding("test");
  13.284 +
  13.285 +        sourcePath = ClassPathSupport.createClassPath(sourceRoot);
  13.286 +        
  13.287 +        Main.initializeURLFactory();
  13.288 +    }
  13.289 +
  13.290 +    /**Bootstraps the test framework.
  13.291 +     *
  13.292 +     * @return the test framework - call more methods on it to set-up a test, then call {@code run} method and assert results.
  13.293 +     */
  13.294 +    public static HintTest create() throws Exception {
  13.295 +        return new HintTest();
  13.296 +    }
  13.297 +
  13.298 +    /**A character to use as a marker of a caret in the input code. The caret position
  13.299 +     * during the run method will be set to the position of this character in the first input file.
  13.300 +     *
  13.301 +     * @param c a caret marker
  13.302 +     * @return itself
  13.303 +     */
  13.304 +    public HintTest setCaretMarker(char c) {
  13.305 +        this.caretMarker = c;
  13.306 +        return this;
  13.307 +    }
  13.308 +
  13.309 +    /**Use the specified {@link java.net.URL}s as compile classpath while parsing
  13.310 +     * the Java input. The {@link java.net.URL}s need to be "folder" {@link java.net.URL}s,
  13.311 +     * ready to be passed to {@link ClassPathSupport#createClassPath(java.net.URL[]) }.
  13.312 +     *
  13.313 +     * @param entries that should become roots of the compile classpath
  13.314 +     * @return itself
  13.315 +     * @see FileUtil#urlForArchiveOrDir(java.io.File)
  13.316 +     * @see FileUtil#getArchiveRoot(java.net.URL)
  13.317 +     */
  13.318 +    public HintTest classpath(URL... entries) {
  13.319 +        compileClassPath = ClassPathSupport.createClassPath(entries);
  13.320 +        return this;
  13.321 +    }
  13.322 +
  13.323 +    /**Create a test file. Equivalent to calling {@code input("test/Test.java", code, true)}.
  13.324 +     *
  13.325 +     * @param code the content of the newly created test file
  13.326 +     * @return itself
  13.327 +     */
  13.328 +    public HintTest input(String code) throws Exception {
  13.329 +        return input("test/Test.java", code, true);
  13.330 +    }
  13.331 +
  13.332 +    /**Create a test file. Equivalent to calling {@code input("test/Test.java", code, compilable)}.
  13.333 +     *
  13.334 +     * @param code the content of the newly created test file
  13.335 +     * @param compilable if true, it will be verified that the file does not contain
  13.336 +     *                   compilation errors before the hint is run on it
  13.337 +     * @return itself
  13.338 +     */
  13.339 +    public HintTest input(String code, boolean compilable) throws Exception {
  13.340 +        return input("test/Test.java", code, compilable);
  13.341 +    }
  13.342 +
  13.343 +    /**Create a test file. Equivalent to calling {@code input(fileName, code, true)}.
  13.344 +     *
  13.345 +     * @param fileName a relative file name of the newly created file from a (automatically created) source root
  13.346 +     * @param code the content of the newly created test file
  13.347 +     * @return itself
  13.348 +     */
  13.349 +    public HintTest input(String fileName, String code) throws Exception {
  13.350 +        return input(fileName, code, true);
  13.351 +    }
  13.352 +    
  13.353 +    /**Create a test file. Any number of files can be created for one test, but the hint
  13.354 +     * will be run only on the first one.
  13.355 +     *
  13.356 +     * @param fileName a relative file name of the newly created file from a (automatically created) source root
  13.357 +     * @param code the content of the newly created test file
  13.358 +     * @param compilable if true, it will be verified that the file does not contain
  13.359 +     *                   compilation errors before the hint is run on it
  13.360 +     * @return itself
  13.361 +     */
  13.362 +    public HintTest input(String fileName, String code, boolean compilable) throws Exception {
  13.363 +        int caret = -1;
  13.364 +
  13.365 +        if (caretMarker != null && testFile == null) {
  13.366 +            caret = code.indexOf(caretMarker);
  13.367 +
  13.368 +            assertNotSame("A caret location must be specified", -1, caret);
  13.369 +
  13.370 +            code = code.substring(0, caret) + code.substring(caret + 1);
  13.371 +        }
  13.372 +
  13.373 +        FileObject file = FileUtil.createData(sourceRoot, fileName);
  13.374 +
  13.375 +        copyStringToFile(file, code);
  13.376 +
  13.377 +        if (compilable) {
  13.378 +            checkCompilable.add(file);
  13.379 +        }
  13.380 +
  13.381 +        if (testFile == null) {
  13.382 +            testFile = file;
  13.383 +            this.caret = caret;
  13.384 +        }
  13.385 +        
  13.386 +        return this;
  13.387 +    }
  13.388 +
  13.389 +    private void ensureCompilable(FileObject file) throws IOException, AssertionError, IllegalArgumentException {
  13.390 +        CompilationInfo info = parse(file);
  13.391 +
  13.392 +        assertNotNull(info);
  13.393 +
  13.394 +        for (Diagnostic d : info.getDiagnostics()) {
  13.395 +            if (d.getKind() == Diagnostic.Kind.ERROR)
  13.396 +                throw new AssertionError(d.getLineNumber() + ":" + d.getColumnNumber() + " " + d.getMessage(null));
  13.397 +        }
  13.398 +    }
  13.399 +
  13.400 +    /**Sets a source level for all Java files used in this test.
  13.401 +     *
  13.402 +     * @param sourceLevel the source level to use while parsing Java files
  13.403 +     * @return itself
  13.404 +     */
  13.405 +    public HintTest sourceLevel(String sourceLevel) {
  13.406 +        this.sourceLevel = sourceLevel;
  13.407 +        return this;
  13.408 +    }
  13.409 +
  13.410 +    /**Sets a preference that will be visible to the hint.
  13.411 +     *
  13.412 +     * @param preferencesKey a key for the preferences
  13.413 +     * @param value the value to set
  13.414 +     * @return itself
  13.415 +     */
  13.416 +    public HintTest preference(String preferencesKey, String value) {
  13.417 +        this.testPreferences.put(preferencesKey, value);
  13.418 +        return this;
  13.419 +    }
  13.420 +
  13.421 +    /**Sets a preference that will be visible to the hint.
  13.422 +     *
  13.423 +     * @param preferencesKey a key for the preferences
  13.424 +     * @param value the value to set
  13.425 +     * @return itself
  13.426 +     */
  13.427 +    public HintTest preference(String preferencesKey, int value) {
  13.428 +        this.testPreferences.putInt(preferencesKey, value);
  13.429 +        return this;
  13.430 +    }
  13.431 +
  13.432 +    /**Sets a preference that will be visible to the hint.
  13.433 +     *
  13.434 +     * @param preferencesKey a key for the preferences
  13.435 +     * @param value the value to set
  13.436 +     * @return itself
  13.437 +     */
  13.438 +    public HintTest preference(String preferencesKey, boolean value) {
  13.439 +        this.testPreferences.putBoolean(preferencesKey, value);
  13.440 +        return this;
  13.441 +    }
  13.442 +    
  13.443 +    /**Runs the given hint(s) on the first file written by a {@code input} method.
  13.444 +     *
  13.445 +     * @param hint all hints in this class will be run on the file
  13.446 +     * @return a wrapper over the hint output that allows verifying results of the hint
  13.447 +     */
  13.448 +    public HintOutput run(Class<?> hint) throws Exception {
  13.449 +        return run(hint, null);
  13.450 +    }
  13.451 +
  13.452 +    /**Runs the given hint(s) on the first file written by a {@code input} method.
  13.453 +     * Runs only hints with the specified {@code hintCode}. Null hintCode includes
  13.454 +     * all hints from the class
  13.455 +     *
  13.456 +     * @param hint all hints in this class will be run on the file
  13.457 +     * @param hintCode if not {@code null}, only hints with the same id will be run
  13.458 +     * @return a wrapper over the hint output that allows verifying results of the hint
  13.459 +     */
  13.460 +    public HintOutput run(Class<?> hint, String hintCode) throws Exception {
  13.461 +        IndexingManager.getDefault().refreshIndexAndWait(sourceRoot.toURL(), null);
  13.462 +        
  13.463 +        for (FileObject file : checkCompilable) {
  13.464 +            ensureCompilable(file);
  13.465 +        }
  13.466 +        
  13.467 +        Map<HintMetadata, Collection<HintDescription>> hints = new HashMap<HintMetadata, Collection<HintDescription>>();
  13.468 +        List<ClassWrapper> found = new ArrayList<ClassWrapper>();
  13.469 +
  13.470 +        for (ClassWrapper w : FSWrapper.listClasses()) {
  13.471 +            if (hint.getCanonicalName().equals(w.getName().replace('$', '.'))) {
  13.472 +                found.add(w);
  13.473 +            }
  13.474 +        }
  13.475 +
  13.476 +        assertFalse(found.isEmpty());
  13.477 +
  13.478 +        for (ClassWrapper w : found) {
  13.479 +            CodeHintProviderImpl.processClass(w, hints);
  13.480 +        }
  13.481 +
  13.482 +        List<HintDescription> total = new LinkedList<HintDescription>();
  13.483 +        final Set<ErrorDescription> requiresJavaFix = Collections.newSetFromMap(new IdentityHashMap<ErrorDescription, Boolean>());
  13.484 +
  13.485 +        for (final Entry<HintMetadata, Collection<HintDescription>> e : hints.entrySet()) {
  13.486 +            if (null != hintCode && !e.getKey().id.equals(hintCode)) {
  13.487 +                continue;
  13.488 +            }
  13.489 +            if (   e.getKey().options.contains(Options.NO_BATCH)
  13.490 +                || e.getKey().options.contains(Options.QUERY)
  13.491 +                || e.getKey().kind == Kind.ACTION) {
  13.492 +                total.addAll(e.getValue());
  13.493 +                continue;
  13.494 +            }
  13.495 +            for (final HintDescription hd : e.getValue()) {
  13.496 +                total.add(HintDescriptionFactory.create()
  13.497 +                                               .setTrigger(hd.getTrigger())
  13.498 +                                               .setMetadata(e.getKey())
  13.499 +                                               .setAdditionalConstraints(hd.getAdditionalConstraints())
  13.500 +                                               .addOptions(hd.getOptions().toArray(new Options[0]))
  13.501 +                                               .setWorker(new Worker() {
  13.502 +                                                    @Override public Collection<? extends ErrorDescription> createErrors(HintContext ctx) {
  13.503 +                                                        Collection<? extends ErrorDescription> errors = hd.getWorker().createErrors(ctx);
  13.504 + 
  13.505 +                                                        if (errors != null) {
  13.506 +                                                            for (ErrorDescription ed : errors) {
  13.507 +                                                                requiresJavaFix.add(ed);
  13.508 +                                                            }
  13.509 +                                                        }
  13.510 +                                                        
  13.511 +                                                        return errors;
  13.512 +                                                     }
  13.513 +                                                })
  13.514 +                                              .produce());
  13.515 +            }
  13.516 +        }
  13.517 +        
  13.518 +        CompilationInfo info = parse(testFile);
  13.519 +
  13.520 +        assertNotNull(info);
  13.521 +
  13.522 +        List<ErrorDescription> result = new ArrayList<ErrorDescription>();
  13.523 +
  13.524 +        Handler h = new Handler() {
  13.525 +            @Override public void publish(LogRecord record) {
  13.526 +                if (   record.getLevel().intValue() >= Level.WARNING.intValue()
  13.527 +                    && record.getThrown() != null) {
  13.528 +                    throw new IllegalStateException(record.getThrown());
  13.529 +                }
  13.530 +            }
  13.531 +            @Override public void flush() { }
  13.532 +            @Override public void close() throws SecurityException { }
  13.533 +        };
  13.534 +        Logger log = Logger.getLogger(Exceptions.class.getName());
  13.535 +        log.addHandler(h);
  13.536 +        Map<HintDescription, List<ErrorDescription>> errors = computeErrors(info, total, new AtomicBoolean());
  13.537 +        log.removeHandler(h);
  13.538 +        for (Entry<HintDescription, List<ErrorDescription>> e : errors.entrySet()) {
  13.539 +            result.addAll(e.getValue());
  13.540 +        }
  13.541 +
  13.542 +        Collections.sort(result, ERRORS_COMPARATOR);
  13.543 +        
  13.544 +        Reference<CompilationInfo> infoRef = new WeakReference<CompilationInfo>(info);
  13.545 +        Reference<CompilationUnitTree> cut = new WeakReference<CompilationUnitTree>(info.getCompilationUnit());
  13.546 +        
  13.547 +        info = null;
  13.548 +        
  13.549 +        DEBUGGING_HELPER.add(result);
  13.550 +        NbTestCase.assertGC("noone holds CompilationInfo", infoRef);
  13.551 +        NbTestCase.assertGC("noone holds javac", cut);
  13.552 +        DEBUGGING_HELPER.remove(result);
  13.553 +        
  13.554 +        return new HintOutput(result, requiresJavaFix);
  13.555 +    }
  13.556 +    
  13.557 +    //must keep the error descriptions (and their Fixes through them) in a field
  13.558 +    //so that assertGC is able to provide a useful trace of references:
  13.559 +    private static Set<List<ErrorDescription>> DEBUGGING_HELPER = Collections.newSetFromMap(new IdentityHashMap<List<ErrorDescription>, Boolean>());
  13.560 +
  13.561 +    private CompilationInfo parse(FileObject file) throws DataObjectNotFoundException, IllegalArgumentException, IOException {
  13.562 +        DataObject od = DataObject.find(file);
  13.563 +        EditorCookie ec = od.getLookup().lookup(EditorCookie.class);
  13.564 +
  13.565 +        assertNotNull(ec);
  13.566 +
  13.567 +        Document doc = ec.openDocument();
  13.568 +
  13.569 +        doc.putProperty(Language.class, JavaTokenId.language());
  13.570 +        doc.putProperty("mimeType", "text/x-java");
  13.571 +
  13.572 +        JavaSource js = JavaSource.create(ClasspathInfo.create(file), file);
  13.573 +
  13.574 +        assertNotNull("found JavaSource for " + file, js);
  13.575 +
  13.576 +        final DeadlockTask bt = new DeadlockTask(Phase.RESOLVED);
  13.577 +
  13.578 +        js.runUserActionTask(bt, true);
  13.579 +        
  13.580 +        return bt.info;
  13.581 +    }
  13.582 +
  13.583 +    private Map<HintDescription, List<ErrorDescription>> computeErrors(CompilationInfo info, Iterable<? extends HintDescription> hints, AtomicBoolean cancel) {
  13.584 +        return new HintsInvoker(hintSettings, caret, cancel).computeHints(info, new TreePath(info.getCompilationUnit()), hints, new LinkedList<MessageImpl>());
  13.585 +    }
  13.586 +
  13.587 +    FileObject getSourceRoot() {
  13.588 +        return sourceRoot;
  13.589 +    }
  13.590 +
  13.591 +    private static class TempPreferences extends AbstractPreferences {
  13.592 +
  13.593 +        /*private*/Properties properties;
  13.594 +
  13.595 +        private TempPreferences() {
  13.596 +            super(null, "");
  13.597 +        }
  13.598 +
  13.599 +        private  TempPreferences(TempPreferences parent, String name)  {
  13.600 +            super(parent, name);
  13.601 +            newNode = true;
  13.602 +        }
  13.603 +
  13.604 +        protected final String getSpi(String key) {
  13.605 +            return properties().getProperty(key);
  13.606 +        }
  13.607 +
  13.608 +        protected final String[] childrenNamesSpi() throws BackingStoreException {
  13.609 +            return new String[0];
  13.610 +        }
  13.611 +
  13.612 +        protected final String[] keysSpi() throws BackingStoreException {
  13.613 +            return properties().keySet().toArray(new String[0]);
  13.614 +        }
  13.615 +
  13.616 +        protected final void putSpi(String key, String value) {
  13.617 +            properties().put(key,value);
  13.618 +        }
  13.619 +
  13.620 +        protected final void removeSpi(String key) {
  13.621 +            properties().remove(key);
  13.622 +        }
  13.623 +
  13.624 +        protected final void removeNodeSpi() throws BackingStoreException {}
  13.625 +        protected  void flushSpi() throws BackingStoreException {}
  13.626 +        protected void syncSpi() throws BackingStoreException {
  13.627 +            properties().clear();
  13.628 +        }
  13.629 +
  13.630 +        @Override
  13.631 +        public void put(String key, String value) {
  13.632 +            try {
  13.633 +                super.put(key, value);
  13.634 +            } catch (IllegalArgumentException iae) {
  13.635 +                if (iae.getMessage().contains("too long")) {
  13.636 +                    // Not for us!
  13.637 +                    putSpi(key, value);
  13.638 +                } else {
  13.639 +                    throw iae;
  13.640 +                }
  13.641 +            }
  13.642 +        }
  13.643 +
  13.644 +        Properties properties()  {
  13.645 +            if (properties == null) {
  13.646 +                properties = new Properties();
  13.647 +            }
  13.648 +            return properties;
  13.649 +        }
  13.650 +
  13.651 +        protected AbstractPreferences childSpi(String name) {
  13.652 +            return new TempPreferences(this, name);
  13.653 +        }
  13.654 +    }
  13.655 +
  13.656 +    private class TestSourceForBinaryQuery implements SourceForBinaryQueryImplementation {
  13.657 +
  13.658 +        public SourceForBinaryQuery.Result findSourceRoots(URL binaryRoot) {
  13.659 +            FileObject f = URLMapper.findFileObject(binaryRoot);
  13.660 +
  13.661 +            if (buildRoot.equals(f)) {
  13.662 +                return new SourceForBinaryQuery.Result() {
  13.663 +                    public FileObject[] getRoots() {
  13.664 +                        return new FileObject[] {
  13.665 +                            sourceRoot,
  13.666 +                        };
  13.667 +                    }
  13.668 +
  13.669 +                    public void addChangeListener(ChangeListener l) {
  13.670 +                    }
  13.671 +
  13.672 +                    public void removeChangeListener(ChangeListener l) {
  13.673 +                    }
  13.674 +                };
  13.675 +            }
  13.676 +
  13.677 +            return null;
  13.678 +        }
  13.679 +
  13.680 +    }
  13.681 +
  13.682 +    private static List<URL> bootClassPath;
  13.683 +
  13.684 +    private static Logger log = Logger.getLogger(HintTest.class.getName());
  13.685 +
  13.686 +    private static synchronized List<URL> getBootClassPath() {
  13.687 +        if (bootClassPath == null) {
  13.688 +            try {
  13.689 +                String cp = System.getProperty("sun.boot.class.path");
  13.690 +                List<URL> urls = new ArrayList<URL>();
  13.691 +                String[] paths = cp.split(Pattern.quote(System.getProperty("path.separator")));
  13.692 +
  13.693 +                for (String path : paths) {
  13.694 +                    File f = new File(path);
  13.695 +
  13.696 +                    if (!f.canRead())
  13.697 +                        continue;
  13.698 +
  13.699 +                    FileObject fo = FileUtil.toFileObject(f);
  13.700 +
  13.701 +                    if (FileUtil.isArchiveFile(fo)) {
  13.702 +                        fo = FileUtil.getArchiveRoot(fo);
  13.703 +                    }
  13.704 +
  13.705 +                    if (fo != null) {
  13.706 +                        urls.add(fo.getURL());
  13.707 +                    }
  13.708 +                }
  13.709 +
  13.710 +                bootClassPath = urls;
  13.711 +            } catch (FileStateInvalidException e) {
  13.712 +                if (log.isLoggable(Level.SEVERE))
  13.713 +                    log.log(Level.SEVERE, e.getMessage(), e);
  13.714 +            }
  13.715 +        }
  13.716 +
  13.717 +        return bootClassPath;
  13.718 +    }
  13.719 +    
  13.720 +    private class TestProxyClassPathProvider implements ClassPathProvider {
  13.721 +
  13.722 +        public ClassPath findClassPath(FileObject file, String type) {
  13.723 +            try {
  13.724 +            if (ClassPath.BOOT == type) {
  13.725 +                // XXX simpler to use JavaPlatformManager.getDefault().getDefaultPlatform().getBootstrapLibraries()
  13.726 +                return ClassPathSupport.createClassPath(getBootClassPath().toArray(new URL[0]));
  13.727 +            }
  13.728 +
  13.729 +            if (ClassPath.SOURCE == type) {
  13.730 +                return sourcePath;
  13.731 +            }
  13.732 +
  13.733 +            if (ClassPath.COMPILE == type) {
  13.734 +                return compileClassPath;
  13.735 +            }
  13.736 +
  13.737 +            if (ClassPath.EXECUTE == type) {
  13.738 +                return ClassPathSupport.createClassPath(new FileObject[] {
  13.739 +                    buildRoot
  13.740 +                });
  13.741 +            }
  13.742 +            } catch (Exception e) {
  13.743 +                e.printStackTrace();
  13.744 +            }
  13.745 +            return null;
  13.746 +        }
  13.747 +
  13.748 +    }
  13.749 +
  13.750 +    private class TestSourceLevelQueryImplementation implements SourceLevelQueryImplementation {
  13.751 +
  13.752 +        public String getSourceLevel(FileObject javaFile) {
  13.753 +            return sourceLevel;
  13.754 +        }
  13.755 +
  13.756 +    }
  13.757 +
  13.758 +
  13.759 +    private static class DeadlockTask implements Task<CompilationController> {
  13.760 +
  13.761 +        private final Phase phase;
  13.762 +        private CompilationInfo info;
  13.763 +
  13.764 +        public DeadlockTask(Phase phase) {
  13.765 +            assert phase != null;
  13.766 +            this.phase = phase;
  13.767 +        }
  13.768 +
  13.769 +        public void run( CompilationController info ) {
  13.770 +            try {
  13.771 +                info.toPhase(this.phase);
  13.772 +                this.info = info;
  13.773 +            } catch (IOException ioe) {
  13.774 +                if (log.isLoggable(Level.SEVERE))
  13.775 +                    log.log(Level.SEVERE, ioe.getMessage(), ioe);
  13.776 +            }
  13.777 +        }
  13.778 +
  13.779 +    }
  13.780 +
  13.781 +    /**Encapsulated the output of the hint.
  13.782 +     */
  13.783 +    public final class HintOutput {
  13.784 +        
  13.785 +        private final List<ErrorDescription> errors;
  13.786 +        private final Set<ErrorDescription> requiresJavaFix;
  13.787 +
  13.788 +        private HintOutput(List<ErrorDescription> errors, Set<ErrorDescription> requiresJavaFix) {
  13.789 +            this.errors = errors;
  13.790 +            this.requiresJavaFix = requiresJavaFix;
  13.791 +
  13.792 +        }
  13.793 +
  13.794 +        /**Assert that the hint(s) produced the given warnings. The provided strings
  13.795 +         * should match {@code toString()} results of {@link ErrorDescription}s produced
  13.796 +         * by the hint(s).
  13.797 +         *
  13.798 +         * @param warnings expected {@code toString()} results of {@link ErrorDescription}s produced
  13.799 +         *                 by the hint
  13.800 +         * @return itself
  13.801 +         * @throws AssertionError if the given warnings do not match the actual warnings
  13.802 +         */
  13.803 +        public HintOutput assertWarnings(String... warnings) {
  13.804 +            assertEquals("The warnings provided by the hint do not match expected warnings.", Arrays.toString(warnings), errors.toString());
  13.805 +
  13.806 +            return this;
  13.807 +        }
  13.808 +
  13.809 +        /**Assert that the hint(s) produced warnings include the given warnings. The provided strings
  13.810 +         * should match {@code toString()} results of {@link ErrorDescription}s produced
  13.811 +         * by the hint(s).
  13.812 +         *
  13.813 +         * @param warnings expected {@code toString()} results of {@link ErrorDescription}s produced
  13.814 +         *                 by the hint
  13.815 +         * @return itself
  13.816 +         * @throws AssertionError if the given warnings do not match the actual warnings
  13.817 +         */
  13.818 +        public HintOutput assertContainsWarnings(String... warnings) {
  13.819 +            Set<String> goldenSet = new HashSet<String>(Arrays.asList(warnings));
  13.820 +            List<String> errorsNames = new LinkedList<String>();
  13.821 +
  13.822 +            for (ErrorDescription d : errors) {
  13.823 +                goldenSet.remove(d.toString());
  13.824 +                errorsNames.add(d.toString());
  13.825 +            }
  13.826 +            
  13.827 +            assertTrue("The warnings provided by the hint do not contain expected warnings. Provided warnings: " + errorsNames.toString(), goldenSet.isEmpty());
  13.828 +
  13.829 +            return this;
  13.830 +        }
  13.831 +
  13.832 +        /**Assert that the hint(s) produced warnings do not include the given warnings. The provided strings
  13.833 +         * should match {@code toString()} results of {@link ErrorDescription}s produced
  13.834 +         * by the hint(s).
  13.835 +         *
  13.836 +         * @param warnings expected {@code toString()} results of {@link ErrorDescription}s produced
  13.837 +         *                 by the hint
  13.838 +         * @return itself
  13.839 +         * @throws AssertionError if the given warnings do not match the actual warnings
  13.840 +         */
  13.841 +        public HintOutput assertNotContainsWarnings(String... warnings) {
  13.842 +            Set<String> goldenSet = new HashSet<String>(Arrays.asList(warnings));
  13.843 +            List<String> errorsNames = new LinkedList<String>();
  13.844 +
  13.845 +            boolean fail = false;
  13.846 +            for (ErrorDescription d : errors) {
  13.847 +                if (goldenSet.remove(d.getDescription()))
  13.848 +                    fail = true;
  13.849 +                errorsNames.add(d.toString());
  13.850 +            }
  13.851 +            
  13.852 +            assertFalse("The warnings provided by the hint do not exclude expected warnings. Provided warnings: " + errorsNames.toString(), fail);
  13.853 +
  13.854 +            return this;
  13.855 +        }
  13.856 +        
  13.857 +        /**Find a specific warning.
  13.858 +         *
  13.859 +         * @param warning the warning to find - must be equivalent to {@code toString()}
  13.860 +         *                results of the {@link ErrorDescription}.
  13.861 +         * @return a wrapper about the given specific warnings
  13.862 +         * @throws AssertionError if the given warning cannot be found
  13.863 +         */
  13.864 +        public HintWarning findWarning(String warning) {
  13.865 +            ErrorDescription toFix = null;
  13.866 +
  13.867 +            for (ErrorDescription d : errors) {
  13.868 +                if (warning.equals(d.toString())) {
  13.869 +                    toFix = d;
  13.870 +                    break;
  13.871 +                }
  13.872 +            }
  13.873 +
  13.874 +            assertNotNull("Warning: \"" + warning + "\" not found. All ErrorDescriptions: " + errors.toString(), toFix);
  13.875 +
  13.876 +            return new HintWarning(toFix, requiresJavaFix.contains(toFix));
  13.877 +        }
  13.878 +    }
  13.879 +
  13.880 +    /**A wrapper over a single warning.
  13.881 +     */
  13.882 +    public final class HintWarning {
  13.883 +        private final ErrorDescription warning;
  13.884 +        private final boolean requiresJavaFix;
  13.885 +        HintWarning(ErrorDescription warning, boolean requiresJavaFix) {
  13.886 +            this.warning = warning;
  13.887 +            this.requiresJavaFix = requiresJavaFix;
  13.888 +        }
  13.889 +        /**Applies the only fix of the current warning. Fails if the given warning
  13.890 +         * does not have exactly one fix.
  13.891 +         *
  13.892 +         * Note this is a destructive operation - the {@link #run(java.lang.Class)} or {@link #applyFix}
  13.893 +         * cannot be run in the future on any object that follows the chain from the same invocation of {@link #create()}.
  13.894 +         *
  13.895 +         * @return a wrapper over resulting source code
  13.896 +         * @throws AssertionError if there is not one fix for the given {@link ErrorDescription}
  13.897 +         */
  13.898 +        public AppliedFix applyFix() throws Exception {
  13.899 +            return applyFix(true);
  13.900 +        }
  13.901 +
  13.902 +        AppliedFix applyFix(boolean saveAll) throws Exception {
  13.903 +            assertTrue("Must be computed", warning.getFixes().isComputed());
  13.904 +
  13.905 +            List<Fix> fixes = warning.getFixes().getFixes();
  13.906 +
  13.907 +            assertEquals(1, fixes.size());
  13.908 +
  13.909 +            doApplyFix(fixes.get(0));
  13.910 +
  13.911 +            if (saveAll)
  13.912 +                LifecycleManager.getDefault().saveAll();
  13.913 +            
  13.914 +            return new AppliedFix();
  13.915 +        }
  13.916 +        /**Applies the specified fix of the current warning.
  13.917 +         *
  13.918 +         * Note this is a destructive operation - the {@link #run(java.lang.Class)} or {@link #applyFix}
  13.919 +         * cannot be run in the future on any object that follows the chain from the same invocation of {@link #create()}.
  13.920 +         *
  13.921 +         * @param fix {@link Fix#getText() } result of the required fix
  13.922 +         * @return a wrapper over resulting source code
  13.923 +         * @throws AssertionError if the fix cannot be found
  13.924 +         */
  13.925 +        public AppliedFix applyFix(String fix) throws Exception {
  13.926 +            assertTrue("Must be computed", warning.getFixes().isComputed());
  13.927 +
  13.928 +            List<Fix> fixes = warning.getFixes().getFixes();
  13.929 +            List<String> fixNames = new LinkedList<String>();
  13.930 +            Fix toApply = null;
  13.931 +
  13.932 +            for (Fix f : fixes) {
  13.933 +                if (fix.equals(f.getText())) {
  13.934 +                    toApply = f;
  13.935 +                }
  13.936 +
  13.937 +                fixNames.add(f.getText());
  13.938 +            }
  13.939 +
  13.940 +            assertNotNull("Cannot find fix to invoke: " + fixNames.toString(), toApply);
  13.941 +
  13.942 +            doApplyFix(toApply);
  13.943 +            
  13.944 +            LifecycleManager.getDefault().saveAll();
  13.945 +
  13.946 +            return new AppliedFix();
  13.947 +        }
  13.948 +        private void doApplyFix(Fix f) throws Exception {
  13.949 +            Preferences preferences = MimeLookup.getLookup(JavaTokenId.language().mimeType()).lookup(Preferences.class);
  13.950 +            preferences.putBoolean("importInnerClasses", true);
  13.951 +            try {
  13.952 +                if (requiresJavaFix) {
  13.953 +                    assertTrue("The fix must be a JavaFix", f instanceof JavaFixImpl);
  13.954 +                    
  13.955 +                    ModificationResult result1 = runJavaFix(((JavaFixImpl) f).jf);
  13.956 +                    ModificationResult result2 = runJavaFix(((JavaFixImpl) f).jf);
  13.957 +                    
  13.958 +                    //ensure the results are the same:
  13.959 +                    assertEquals("The fix must be repeatable", result1.getModifiedFileObjects(), result2.getModifiedFileObjects());
  13.960 +                    
  13.961 +                    for (FileObject file : result1.getModifiedFileObjects()) {
  13.962 +                        assertEquals("The fix must be repeatable", result1.getResultingSource(file), result2.getResultingSource(file));
  13.963 +                    }
  13.964 +                    
  13.965 +                    result1.commit();
  13.966 +                } else {
  13.967 +                    f.implement();
  13.968 +                }
  13.969 +            } finally {
  13.970 +                preferences.remove("importInnerClasses");
  13.971 +            }
  13.972 +        }
  13.973 +        private ModificationResult runJavaFix(final JavaFix jf) throws IOException {
  13.974 +            FileObject file = Accessor.INSTANCE.getFile(jf);
  13.975 +            JavaSource js = JavaSource.forFileObject(file);
  13.976 +            final Map<FileObject, List<Difference>> changes = new HashMap<FileObject, List<Difference>>();
  13.977 +
  13.978 +            ModificationResult mr = js.runModificationTask(new Task<WorkingCopy>() {
  13.979 +                public void run(WorkingCopy wc) throws Exception {
  13.980 +                    if (wc.toPhase(Phase.RESOLVED).compareTo(Phase.RESOLVED) < 0) {
  13.981 +                        return;
  13.982 +                    }
  13.983 +
  13.984 +                    Map<FileObject, byte[]> resourceContentChanges = new HashMap<FileObject, byte[]>();
  13.985 +                    Accessor.INSTANCE.process(jf, wc, true, resourceContentChanges, /*Ignored for now:*/new ArrayList<RefactoringElementImplementation>());
  13.986 +                    BatchUtilities.addResourceContentChanges(resourceContentChanges, changes);
  13.987 +                    
  13.988 +                }
  13.989 +            });
  13.990 +            
  13.991 +            changes.putAll(JavaSourceAccessor.getINSTANCE().getDiffsFromModificationResult(mr));
  13.992 +            
  13.993 +            return JavaSourceAccessor.getINSTANCE().createModificationResult(changes, Collections.<Object, int[]>emptyMap());
  13.994 +        }
  13.995 +        /**Verifies that the current warning provides the given fixes.
  13.996 +         *
  13.997 +         * @param fixes the {@link Fix#getText() } of the expected fixes
  13.998 +         * @return itself
  13.999 +         * @throws AssertionError if the expected fixes do not match the provided fixes
 13.1000 +         * @since 1.1
 13.1001 +         */
 13.1002 +        public HintWarning assertFixes(String... expectedFixes) throws Exception {
 13.1003 +            assertTrue("Must be computed", warning.getFixes().isComputed());
 13.1004 +
 13.1005 +            List<String> fixNames = new LinkedList<String>();
 13.1006 +
 13.1007 +            for (Fix f : warning.getFixes().getFixes()) {
 13.1008 +                if (f instanceof SyntheticFix) continue;
 13.1009 +                fixNames.add(f.getText());
 13.1010 +            }
 13.1011 +
 13.1012 +            assertEquals("Fixes for the current warning do not match the expected fixes. All fixes: " + fixNames.toString(), Arrays.asList(expectedFixes), fixNames);
 13.1013 +
 13.1014 +            return this;
 13.1015 +        }
 13.1016 +    }
 13.1017 +
 13.1018 +    /**A wrapper over result after applying a fix.
 13.1019 +     */
 13.1020 +    public final class AppliedFix {
 13.1021 +        /**Require that the result is compilable. Equivalent to {@code assertCompilable("test/Test.java")}
 13.1022 +         *
 13.1023 +         * @return the wrapper itself
 13.1024 +         * @throws AssertionError if the result is not compilable
 13.1025 +         */
 13.1026 +        public AppliedFix assertCompilable() throws Exception {
 13.1027 +            return assertCompilable("test/Test.java");
 13.1028 +        }
 13.1029 +        /**Require that the given resulting file is compilable.
 13.1030 +         *
 13.1031 +         * @param fileName the name of the file that should be verified
 13.1032 +         * @return the wrapper itself
 13.1033 +         * @throws AssertionError if the result is not compilable
 13.1034 +         */
 13.1035 +        public AppliedFix assertCompilable(String fileName) throws Exception {
 13.1036 +            FileObject toCheck = sourceRoot.getFileObject(fileName);
 13.1037 +
 13.1038 +            assertNotNull(toCheck);
 13.1039 +
 13.1040 +            ensureCompilable(toCheck);
 13.1041 +            return this;
 13.1042 +        }
 13.1043 +        /**Verify the content of the resulting file. Equivalent to {@code assertOutput("test/Test.java")}.
 13.1044 +         *
 13.1045 +         * This method will "normalize" whitespaces in the file: generally, all
 13.1046 +         * whitespaces are reduced to a single space both in the given code and
 13.1047 +         * the code read from the file, before the comparison.
 13.1048 +         *
 13.1049 +         * @param code expected content of the resulting file.
 13.1050 +         * @return the wrapper itself
 13.1051 +         * @throws AssertionError if the file does not have the correct content
 13.1052 +         */
 13.1053 +        public AppliedFix assertOutput(String code) throws Exception {
 13.1054 +            return assertOutput("test/Test.java", code);
 13.1055 +        }
 13.1056 +        /**Verify the content of the given resulting file.
 13.1057 +         *
 13.1058 +         * This method will "normalize" whitespaces in the file: generally, all
 13.1059 +         * whitespaces are reduced to a single space both in the given code and
 13.1060 +         * the code read from the file, before the comparison.
 13.1061 +         *
 13.1062 +         * @param fileName the name of the file that should be verified
 13.1063 +         * @param code expected content of the resulting file.
 13.1064 +         * @return the wrapper itself
 13.1065 +         * @throws AssertionError if the file does not have the correct content
 13.1066 +         */
 13.1067 +        public AppliedFix assertOutput(String fileName, String code) throws Exception {
 13.1068 +            FileObject toCheck = sourceRoot.getFileObject(fileName);
 13.1069 +
 13.1070 +            assertNotNull("Required file: " + fileName + " not found", toCheck);
 13.1071 +
 13.1072 +            DataObject toCheckDO = DataObject.find(toCheck);
 13.1073 +            EditorCookie ec = toCheckDO.getLookup().lookup(EditorCookie.class);
 13.1074 +            Document toCheckDocument = ec.openDocument();
 13.1075 +
 13.1076 +            String realCode = toCheckDocument.getText(0, toCheckDocument.getLength());
 13.1077 +
 13.1078 +            //ignore whitespaces:
 13.1079 +            realCode = reduceWhitespaces(realCode);
 13.1080 +
 13.1081 +            assertEquals("The output code does not match the expected code.", reduceWhitespaces(code), realCode);
 13.1082 +
 13.1083 +            return this;
 13.1084 +        }
 13.1085 +        
 13.1086 +        private String reduceWhitespaces(String str) {
 13.1087 +            StringBuilder result = new StringBuilder();
 13.1088 +            int i = 0;
 13.1089 +            boolean wasWhitespace = false;
 13.1090 +            
 13.1091 +            while (i < str.length()) {
 13.1092 +                int codePoint = str.codePointAt(i);
 13.1093 +                
 13.1094 +                if (Character.isWhitespace(codePoint)) {
 13.1095 +                    if (!wasWhitespace) {
 13.1096 +                        result.append(" ");
 13.1097 +                        wasWhitespace = true;
 13.1098 +                    }
 13.1099 +                } else {
 13.1100 +                    result.appendCodePoint(codePoint);
 13.1101 +                    wasWhitespace = false;
 13.1102 +                }
 13.1103 +                i += Character.charCount(codePoint);
 13.1104 +            }
 13.1105 +            
 13.1106 +            return result.toString();
 13.1107 +        }
 13.1108 +        
 13.1109 +        /**Verify the content of the resulting file. Equivalent to {@code assertVerbatimOutput("test/Test.java")}.
 13.1110 +         *
 13.1111 +         * This method will compare the content of the file exactly with the provided
 13.1112 +         * code.
 13.1113 +         *
 13.1114 +         * @param fileName the name of the file that should be verified
 13.1115 +         * @param code expected content of the resulting file.
 13.1116 +         * @return the wrapper itself
 13.1117 +         * @throws AssertionError if the result is not compilable
 13.1118 +         */
 13.1119 +        public AppliedFix assertVerbatimOutput(String code) throws Exception {
 13.1120 +            return assertVerbatimOutput("test/Test.java", code);
 13.1121 +        }
 13.1122 +        /**Verify the content of the given resulting file.
 13.1123 +         *
 13.1124 +         * This method will compare the content of the file exactly with the provided
 13.1125 +         * code.
 13.1126 +         *
 13.1127 +         * @param fileName the name of the file that should be verified
 13.1128 +         * @param code expected content of the resulting file.
 13.1129 +         * @return the wrapper itself
 13.1130 +         * @throws AssertionError if the result is not compilable
 13.1131 +         */
 13.1132 +        public AppliedFix assertVerbatimOutput(String fileName, String code) throws Exception {
 13.1133 +            FileObject toCheck = sourceRoot.getFileObject(fileName);
 13.1134 +
 13.1135 +            assertNotNull(toCheck);
 13.1136 +
 13.1137 +            DataObject toCheckDO = DataObject.find(toCheck);
 13.1138 +            EditorCookie ec = toCheckDO.getLookup().lookup(EditorCookie.class);
 13.1139 +            Document toCheckDocument = ec.openDocument();
 13.1140 +
 13.1141 +            String realCode = toCheckDocument.getText(0, toCheckDocument.getLength());
 13.1142 +
 13.1143 +            assertEquals("The output code does not match the expected code.", code, realCode);
 13.1144 +
 13.1145 +            return this;
 13.1146 +        }
 13.1147 +
 13.1148 +        /**Return code after the fix has been applied.
 13.1149 +         *
 13.1150 +         * @return the code after the fix has been applied
 13.1151 +         */
 13.1152 +        public String getOutput() throws Exception {
 13.1153 +            return getOutput("test/Test.java");
 13.1154 +        }
 13.1155 +
 13.1156 +        /**Return code after the fix has been applied.
 13.1157 +         *
 13.1158 +         * @param fileName file for which the code should be returned
 13.1159 +         * @return the code after the fix has been applied
 13.1160 +         */
 13.1161 +        public String getOutput(String fileName) throws Exception {
 13.1162 +            FileObject toCheck = sourceRoot.getFileObject(fileName);
 13.1163 +
 13.1164 +            assertNotNull(toCheck);
 13.1165 +
 13.1166 +            DataObject toCheckDO = DataObject.find(toCheck);
 13.1167 +            EditorCookie ec = toCheckDO.getLookup().lookup(EditorCookie.class);
 13.1168 +            Document toCheckDocument = ec.openDocument();
 13.1169 +
 13.1170 +            return toCheckDocument.getText(0, toCheckDocument.getLength());
 13.1171 +        }
 13.1172 +    }
 13.1173 +
 13.1174 +    private static final Comparator<ErrorDescription> ERRORS_COMPARATOR = new Comparator<ErrorDescription> () {
 13.1175 +
 13.1176 +        public int compare (ErrorDescription e1, ErrorDescription e2) {
 13.1177 +            return e1.getRange ().getBegin ().getOffset () - e2.getRange ().getBegin ().getOffset ();
 13.1178 +        }
 13.1179 +    };
 13.1180 +
 13.1181 +    static {
 13.1182 +        System.setProperty("org.openide.util.Lookup", TestLookup.class.getName());
 13.1183 +        Assert.assertEquals(TestLookup.class, Lookup.getDefault().getClass());
 13.1184 +    }
 13.1185 +
 13.1186 +    //workdir computation (copied from NbTestCase):
 13.1187 +    private static File getWorkDir() throws IOException {
 13.1188 +        // now we have path, so if not available, create workdir
 13.1189 +        File workdir = FileUtil.normalizeFile(new File(getWorkDirPath()));
 13.1190 +        if (workdir.exists()) {
 13.1191 +            if (!workdir.isDirectory()) {
 13.1192 +                // work dir exists, but is not directory - this should not happen
 13.1193 +                // trow exception
 13.1194 +                throw new IOException("workdir exists, but is not a directory, workdir = " + workdir);
 13.1195 +            } else {
 13.1196 +                // everything looks correctly, return the path
 13.1197 +                return workdir;
 13.1198 +            }
 13.1199 +        } else {
 13.1200 +            // we need to create it
 13.1201 +            boolean result = workdir.mkdirs();
 13.1202 +            if (result == false) {
 13.1203 +                // mkdirs() failed - throw an exception
 13.1204 +                throw new IOException("workdir creation failed: " + workdir);
 13.1205 +            } else {
 13.1206 +                // everything looks ok - return path
 13.1207 +                return workdir;
 13.1208 +            }
 13.1209 +        }
 13.1210 +    }
 13.1211 +
 13.1212 +    private static String getWorkDirPath() {
 13.1213 +        StackTraceElement caller = null;
 13.1214 +        boolean seenItself = false;
 13.1215 +        
 13.1216 +        for (StackTraceElement e : new Exception().getStackTrace()) {
 13.1217 +            if (HintTest.class.getName().equals(e.getClassName())) seenItself = true;
 13.1218 +            if (seenItself && !HintTest.class.getName().equals(e.getClassName())) {
 13.1219 +                caller = e;
 13.1220 +                break;
 13.1221 +            }
 13.1222 +        }
 13.1223 +        
 13.1224 +        String name = caller != null ? caller.getMethodName() : "unknownTest";
 13.1225 +        // start - PerformanceTestCase overrides getName() method and then
 13.1226 +        // name can contain illegal characters
 13.1227 +        String osName = System.getProperty("os.name");
 13.1228 +        if (osName != null && osName.startsWith("Windows")) {
 13.1229 +            char ntfsIllegal[] ={'"','/','\\','?','<','>','|',':'};
 13.1230 +            for (int i=0; i<ntfsIllegal.length; i++) {
 13.1231 +                name = name.replace(ntfsIllegal[i], '~');
 13.1232 +            }
 13.1233 +        }
 13.1234 +        // end
 13.1235 +        
 13.1236 +        final String workDirPath = getWorkDirPathFromManager();
 13.1237 +        
 13.1238 +        // #94319 - shorten workdir path if the following is too long
 13.1239 +        // "Manager.getWorkDirPath()+File.separator+getClass().getName()+File.separator+name"
 13.1240 +        int len1 = workDirPath.length();
 13.1241 +        String clazz = caller != null ? caller.getClassName() : "unknown.Class";
 13.1242 +        int len2 = clazz.length();
 13.1243 +        int len3 = name.length();
 13.1244 +        
 13.1245 +        int tooLong = Integer.getInteger("nbjunit.too.long", 100);
 13.1246 +        if (len1 + len2 + len3 > tooLong) {
 13.1247 +            clazz = abbrevDots(clazz);
 13.1248 +            len2 = clazz.length();
 13.1249 +        }
 13.1250 +
 13.1251 +        if (len1 + len2 + len3 > tooLong) {
 13.1252 +            name = abbrevCapitals(name);
 13.1253 +        }
 13.1254 +        
 13.1255 +        String p = workDirPath + File.separator + clazz + File.separator + name;
 13.1256 +        String realP;
 13.1257 +        
 13.1258 +        for (int i = 0; ; i++) {
 13.1259 +            realP = i == 0 ? p : p + "-" + i;
 13.1260 +            if (usedPaths.add(realP)) {
 13.1261 +                break;
 13.1262 +            }
 13.1263 +        }
 13.1264 +        
 13.1265 +        return realP;
 13.1266 +    }
 13.1267 +
 13.1268 +    private static Set<String> usedPaths = new HashSet<String>();
 13.1269 +    
 13.1270 +    private static String abbrevDots(String dotted) {
 13.1271 +        StringBuilder sb = new StringBuilder();
 13.1272 +        String sep = "";
 13.1273 +        for (String item : dotted.split("\\.")) {
 13.1274 +            sb.append(sep);
 13.1275 +            sb.append(item.charAt(0));
 13.1276 +            sep = ".";
 13.1277 +        }
 13.1278 +        return sb.toString();
 13.1279 +    }
 13.1280 +
 13.1281 +    private static String abbrevCapitals(String name) {
 13.1282 +        if (name.startsWith("test")) {
 13.1283 +            name = name.substring(4);
 13.1284 +        }
 13.1285 +        StringBuilder sb = new StringBuilder();
 13.1286 +        for (int i = 0; i < name.length(); i++) {
 13.1287 +            if (Character.isUpperCase(name.charAt(i))) {
 13.1288 +                sb.append(Character.toLowerCase(name.charAt(i)));
 13.1289 +            }
 13.1290 +        }
 13.1291 +        return sb.toString();
 13.1292 +    }
 13.1293 +
 13.1294 +    private static final String JUNIT_PROPERTIES_FILENAME = "junit.properties";
 13.1295 +    private static final String JUNIT_PROPERTIES_LOCATION_PROPERTY = "junit.properties.file";
 13.1296 +    private static final String NBJUNIT_WORKDIR = "nbjunit.workdir";
 13.1297 +    
 13.1298 +    private static String getWorkDirPathFromManager() {
 13.1299 +        String path = System.getProperty(NBJUNIT_WORKDIR);
 13.1300 +                
 13.1301 +        if (path == null) {            
 13.1302 +            // try to get property from user's settings
 13.1303 +            path = readProperties().getProperty(NBJUNIT_WORKDIR);
 13.1304 +        }
 13.1305 +        if (path != null) {
 13.1306 +            path = path.replace('/', File.separatorChar);
 13.1307 +        } else {
 13.1308 +            // Fallback value, guaranteed to be defined.
 13.1309 +            path = System.getProperty("java.io.tmpdir") + File.separatorChar + "tests-" + System.getProperty("user.name");
 13.1310 +        }
 13.1311 +        return path;
 13.1312 +    }
 13.1313 +
 13.1314 +    private static Properties readProperties() {
 13.1315 +        Properties result = new Properties();
 13.1316 +        try {
 13.1317 +            File propFile = getPreferencesFile();
 13.1318 +            FileInputStream is = new FileInputStream(propFile);
 13.1319 +            try {
 13.1320 +                result.load(is);
 13.1321 +            } finally {
 13.1322 +                is.close();
 13.1323 +            }
 13.1324 +        }  catch (IOException e) {
 13.1325 +        }
 13.1326 +        
 13.1327 +        return result;
 13.1328 +    }
 13.1329 +
 13.1330 +    private static File getPreferencesFile() {
 13.1331 +        String junitPropertiesLocation = System.getProperty(JUNIT_PROPERTIES_LOCATION_PROPERTY);
 13.1332 +        if (junitPropertiesLocation != null) {
 13.1333 +            File propertyFile = new File(junitPropertiesLocation);
 13.1334 +            if (propertyFile.exists()) {
 13.1335 +                return propertyFile;
 13.1336 +            }
 13.1337 +        }
 13.1338 +        // property file was not found - lets fall back to defaults
 13.1339 +        String home= System.getProperty("user.home");
 13.1340 +        return new File(home, JUNIT_PROPERTIES_FILENAME);
 13.1341 +    }
 13.1342 +
 13.1343 +    // private method for deleting a file/directory (and all its subdirectories/files)
 13.1344 +    private static void deleteFile(File file) throws IOException {
 13.1345 +        if (file.isDirectory() && file.equals(file.getCanonicalFile())) {
 13.1346 +            // file is a directory - delete sub files first
 13.1347 +            File files[] = file.listFiles();
 13.1348 +            for (int i = 0; i < files.length; i++) {
 13.1349 +                deleteFile(files[i]);
 13.1350 +            }
 13.1351 +            
 13.1352 +        }
 13.1353 +        // file is a File :-)
 13.1354 +        boolean result = file.delete();
 13.1355 +        if (result == false ) {
 13.1356 +            // a problem has appeared
 13.1357 +            throw new IOException("Cannot delete file, file = "+file.getPath());
 13.1358 +        }
 13.1359 +    }
 13.1360 +    
 13.1361 +    // private method for deleting every subfiles/subdirectories of a file object
 13.1362 +    private static void deleteSubFiles(File file) throws IOException {
 13.1363 +        File files[] = file.getCanonicalFile().listFiles();
 13.1364 +        if (files != null) {
 13.1365 +            for (File f : files) {
 13.1366 +                deleteFile(f);
 13.1367 +            }
 13.1368 +        } else {
 13.1369 +            // probably do nothing - file is not a directory
 13.1370 +        }
 13.1371 +    }
 13.1372 +
 13.1373 +    private static FileObject copyStringToFile (FileObject f, String content) throws Exception {
 13.1374 +        OutputStream os = f.getOutputStream();
 13.1375 +        os.write(content.getBytes("UTF-8"));
 13.1376 +        os.close ();
 13.1377 +
 13.1378 +        return f;
 13.1379 +    }
 13.1380 +
 13.1381 +}
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/java.hints/java.hints.test/src/org/netbeans/modules/parsing/impl/indexing/MimeTypes.java	Thu May 09 22:04:33 2013 +0200
    14.3 @@ -0,0 +1,66 @@
    14.4 +/*
    14.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    14.6 + *
    14.7 + * Copyright 2011 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 2011 Sun Microsystems, Inc.
   14.44 + */
   14.45 +package org.netbeans.modules.parsing.impl.indexing;
   14.46 +
   14.47 +import java.util.Set;
   14.48 +import org.netbeans.api.annotations.common.CheckForNull;
   14.49 +import org.netbeans.api.annotations.common.NonNull;
   14.50 +import org.openide.util.Parameters;
   14.51 +
   14.52 +/**Not an API!
   14.53 + *
   14.54 + * @author Tomas Zezula
   14.55 + */
   14.56 +public class MimeTypes {
   14.57 +
   14.58 +    private MimeTypes() {}
   14.59 +
   14.60 +    public static void setAllMimeTypes(@NonNull final Set<String> allMimeTypes) {
   14.61 +        Parameters.notNull("allMimeTypes", allMimeTypes);   //NOI18N
   14.62 +        Util.allMimeTypes = allMimeTypes;
   14.63 +    }
   14.64 +
   14.65 +    @CheckForNull
   14.66 +    public static Set<String> getAllMimeTypes() {
   14.67 +        return Util.allMimeTypes;
   14.68 +    }
   14.69 +}
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/java.hints/java.hints.test/test/unit/src/org/netbeans/modules/java/hints/test/api/HintTestTest.java	Thu May 09 22:04:33 2013 +0200
    15.3 @@ -0,0 +1,307 @@
    15.4 +/*
    15.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    15.6 + *
    15.7 + * Copyright 2012 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 2012 Sun Microsystems, Inc.
   15.44 + */
   15.45 +package org.netbeans.modules.java.hints.test.api;
   15.46 +
   15.47 +import com.sun.source.tree.Tree.Kind;
   15.48 +import com.sun.source.util.TreePath;
   15.49 +import java.io.ByteArrayOutputStream;
   15.50 +import java.io.InputStreamReader;
   15.51 +import java.io.OutputStream;
   15.52 +import java.io.OutputStreamWriter;
   15.53 +import java.io.Reader;
   15.54 +import java.io.Writer;
   15.55 +import javax.swing.text.Document;
   15.56 +import org.junit.Assert;
   15.57 +import org.junit.Test;
   15.58 +import org.netbeans.api.java.source.ClasspathInfo.PathKind;
   15.59 +import org.netbeans.api.java.source.CompilationInfo;
   15.60 +import org.netbeans.api.java.source.JavaSource;
   15.61 +import org.netbeans.spi.editor.hints.ChangeInfo;
   15.62 +import org.netbeans.spi.editor.hints.ErrorDescription;
   15.63 +import org.netbeans.spi.editor.hints.Fix;
   15.64 +import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
   15.65 +import org.netbeans.spi.java.hints.Hint;
   15.66 +import org.netbeans.spi.java.hints.HintContext;
   15.67 +import org.netbeans.spi.java.hints.JavaFix;
   15.68 +import org.netbeans.spi.java.hints.JavaFix.TransformationContext;
   15.69 +import org.netbeans.spi.java.hints.TriggerTreeKind;
   15.70 +import org.openide.cookies.EditorCookie;
   15.71 +import org.openide.filesystems.FileObject;
   15.72 +import org.openide.filesystems.FileUtil;
   15.73 +import org.openide.loaders.DataObject;
   15.74 +
   15.75 +/**
   15.76 + *
   15.77 + * @author lahvac
   15.78 + */
   15.79 +public class HintTestTest {
   15.80 +
   15.81 +    public HintTestTest() {
   15.82 +    }
   15.83 +
   15.84 +    @Test
   15.85 +    public void testNonJavaChanges() throws Exception {
   15.86 +        HintTest.create()
   15.87 +                .input("package test;\n" +
   15.88 +                       "public class Test { }\n")
   15.89 +                .input("test/test.txt", "1\n2\n", false)
   15.90 +                .run(NonJavaChanges.class)
   15.91 +                .findWarning("1:13-1:17:verifier:Test")
   15.92 +                .applyFix()
   15.93 +                .assertVerbatimOutput("test/test.txt", "2\n3\n");
   15.94 +    }
   15.95 +
   15.96 +    @Test
   15.97 +    public void test220070() throws Exception {
   15.98 +        HintTest.create()
   15.99 +                .input("package test;\n" +
  15.100 +                       "public class Test { }\n")
  15.101 +                .input("test/test.txt", "1\n2\n", false)
  15.102 +                .run(NonJavaChanges.class)
  15.103 +                .findWarning("1:13-1:17:verifier:Test")
  15.104 +                .applyFix()
  15.105 +                .assertOutput("test/test.txt", "2\r3\r");
  15.106 +    }
  15.107 +    
  15.108 +    @Test
  15.109 +    public void testNonJavaChangesOpenedInEditor() throws Exception {
  15.110 +        HintTest ht = HintTest.create()
  15.111 +                              .input("package test;\n" +
  15.112 +                                     "public class Test { }\n")
  15.113 +                              .input("test/test.txt", "1\n2\n", false);
  15.114 +        FileObject resource = ht.getSourceRoot().getFileObject("test/test.txt");
  15.115 +        DataObject od = DataObject.find(resource);
  15.116 +        EditorCookie ec = od.getLookup().lookup(EditorCookie.class);
  15.117 +        Document doc = ec.openDocument();
  15.118 +        doc.remove(0, doc.getLength());
  15.119 +        doc.insertString(0, "5\n6\n", null);
  15.120 +        ht.run(NonJavaChanges.class)
  15.121 +          .findWarning("1:13-1:17:verifier:Test")
  15.122 +          .applyFix(false)
  15.123 +          .assertVerbatimOutput("test/test.txt", "6\n7\n");
  15.124 +        Assert.assertEquals("1\n2\n", resource.asText("UTF-8"));
  15.125 +        Assert.assertEquals("6\n7\n", doc.getText(0, doc.getLength()));
  15.126 +    }
  15.127 +
  15.128 +    @Hint(displayName="testingNonJavaChanges", description="testingNonJavaChanges", category="test")
  15.129 +    public static final class NonJavaChanges {
  15.130 +        @TriggerTreeKind(Kind.CLASS)
  15.131 +        public static ErrorDescription hint(HintContext ctx) {
  15.132 +            return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), "Test", new TestingNonJavaChangesFix(ctx.getInfo(), ctx.getPath()).toEditorFix());
  15.133 +        }
  15.134 +    }
  15.135 +
  15.136 +    private static final class TestingNonJavaChangesFix extends JavaFix {
  15.137 +
  15.138 +        public TestingNonJavaChangesFix(CompilationInfo info, TreePath tp) {
  15.139 +            super(info, tp);
  15.140 +        }
  15.141 +
  15.142 +        @Override protected String getText() {
  15.143 +            return "Test";
  15.144 +        }
  15.145 +
  15.146 +        @Override protected void performRewrite(TransformationContext ctx) {
  15.147 +            try {
  15.148 +                FileObject resource = ctx.getWorkingCopy().getFileObject().getParent().getFileObject("test.txt");
  15.149 +                Assert.assertNotNull(resource);
  15.150 +                Reader r = new InputStreamReader(ctx.getResourceContent(resource), "UTF-8");
  15.151 +                ByteArrayOutputStream outData = new ByteArrayOutputStream();
  15.152 +                Writer w = new OutputStreamWriter(outData, "UTF-8");
  15.153 +                int read;
  15.154 +
  15.155 +                while ((read = r.read()) != -1) {
  15.156 +                    if (read != '\n') read++;
  15.157 +                    w.write(read);
  15.158 +                }
  15.159 +
  15.160 +                r.close();
  15.161 +                w.close();
  15.162 +
  15.163 +                OutputStream out = ctx.getResourceOutput(resource);
  15.164 +
  15.165 +                out.write(outData.toByteArray());
  15.166 +
  15.167 +                out.close();
  15.168 +            } catch (Exception ex) {
  15.169 +                throw new IllegalStateException(ex);
  15.170 +            }
  15.171 +        }
  15.172 +
  15.173 +    }
  15.174 +
  15.175 +    @Test
  15.176 +    public void testMeaningfullSourcePath() throws Exception {
  15.177 +        HintTest.create()
  15.178 +                .input("package test;\n" +
  15.179 +                       "public class Test { }\n")
  15.180 +                .run(MeaningfullSourcePath.class)
  15.181 +                .assertWarnings();
  15.182 +    }
  15.183 +
  15.184 +    @Hint(displayName="meaningfullSourcePath", description="meaningfullSourcePath", category="test")
  15.185 +    public static final class MeaningfullSourcePath {
  15.186 +        @TriggerTreeKind(Kind.CLASS)
  15.187 +        public static ErrorDescription hint(HintContext ctx) {
  15.188 +            if (ctx.getInfo().getClasspathInfo().getClassPath(PathKind.SOURCE).findOwnerRoot(ctx.getInfo().getFileObject()) == null) {
  15.189 +                return ErrorDescriptionFactory.forTree(ctx, ctx.getPath(), "Broken Source Path");
  15.190 +            }
  15.191 +
  15.192 +            return null;
  15.193 +        }
  15.194 +    }
  15.195 +
  15.196 +    @Test
  15.197 +    public void testCompilationClassPath() throws Exception {
  15.198 +        HintTest.create()
  15.199 +                .input("package test;\n" +
  15.200 +                       "public class Test { }\n")
  15.201 +                .classpath(FileUtil.getArchiveRoot(JavaSource.class.getProtectionDomain().getCodeSource().getLocation()))
  15.202 +                .run(CompilationClassPath.class)
  15.203 +                .assertWarnings();
  15.204 +    }
  15.205 +
  15.206 +    @Hint(displayName="compilationClassPath", description="compilationClassPath", category="test")
  15.207 +    public static final class CompilationClassPath {
  15.208 +        @TriggerTreeKind(Kind.CLASS)
  15.209 +        public static ErrorDescription hint(HintContext ctx) {
  15.210 +            FileObject clazz = ctx.getInfo().getClasspathInfo().getClassPath(PathKind.COMPILE).findResource("org/netbeans/api/java/source/JavaSource.class");
  15.211 +
  15.212 +            if (clazz == null) {
  15.213 +                return ErrorDescriptionFactory.forTree(ctx, ctx.getPath(), "Broken Compilation ClassPath");
  15.214 +            }
  15.215 +
  15.216 +            return null;
  15.217 +        }
  15.218 +    }
  15.219 +
  15.220 +    @Test
  15.221 +    public void testHintThrowsException() throws Exception {
  15.222 +        HintTest ht = HintTest.create()
  15.223 +                              .input("package test;\n" +
  15.224 +                                     "public class Test { }\n");
  15.225 +        try {
  15.226 +            ht.run(HintThrowsException.class);
  15.227 +            Assert.fail("No exception thrown");
  15.228 +        } catch (Exception ex) {
  15.229 +            //ok
  15.230 +            Assert.assertEquals(IllegalStateException.class, ex.getClass());
  15.231 +            Assert.assertNotNull(ex.getCause());
  15.232 +            Assert.assertEquals(NullPointerException.class, ex.getCause().getClass());
  15.233 +            Assert.assertEquals("a", ex.getCause().getMessage());
  15.234 +        }
  15.235 +    }
  15.236 +    
  15.237 +    @Hint(displayName="hintThrowsException", description="hintThrowsException", category="test")
  15.238 +    public static final class HintThrowsException {
  15.239 +        @TriggerTreeKind(Kind.CLASS)
  15.240 +        public static ErrorDescription hint(HintContext ctx) {
  15.241 +            throw new NullPointerException("a");
  15.242 +        }
  15.243 +    }
  15.244 +
  15.245 +    @Test
  15.246 +    public void testNonJavaFix() throws Exception {
  15.247 +        HintTest ht = HintTest.create()
  15.248 +                              .input("package test;\n" +
  15.249 +                                     "public class Test { }\n");
  15.250 +        try {
  15.251 +            ht.run(NonJavaFix.class)
  15.252 +              .findWarning("1:0-1:21:verifier:Test")
  15.253 +              .applyFix();
  15.254 +            Assert.fail("No exception thrown");
  15.255 +        } catch (AssertionError ae) {
  15.256 +            //ok
  15.257 +            Assert.assertEquals("The fix must be a JavaFix", ae.getMessage());
  15.258 +        }
  15.259 +    }
  15.260 +    
  15.261 +    @Hint(displayName="nonJavaFix", description="nonJavaFix", category="test")
  15.262 +    public static final class NonJavaFix {
  15.263 +        @TriggerTreeKind(Kind.CLASS)
  15.264 +        public static ErrorDescription hint(HintContext ctx) {
  15.265 +            return ErrorDescriptionFactory.forTree(ctx, ctx.getPath(), "Test", new Fix() {
  15.266 +                @Override public String getText() {
  15.267 +                    return "Fix";
  15.268 +                }
  15.269 +                @Override public ChangeInfo implement() throws Exception {
  15.270 +                    return null;
  15.271 +                }
  15.272 +            });
  15.273 +        }
  15.274 +    }
  15.275 +    
  15.276 +    @Test
  15.277 +    public void testNotRepeatableJavaFix() throws Exception {
  15.278 +        HintTest ht = HintTest.create()
  15.279 +                              .input("package test;\n" +
  15.280 +                                     "public class Test { }\n");
  15.281 +        try {
  15.282 +            ht.run(NotRepeatableJavaFix.class)
  15.283 +              .findWarning("1:0-1:21:verifier:Test")
  15.284 +              .applyFix();
  15.285 +            Assert.fail("No exception thrown");
  15.286 +        } catch (AssertionError ae) {
  15.287 +            //ok
  15.288 +            Assert.assertTrue(ae.getMessage().startsWith("The fix must be repeatable"));
  15.289 +        }
  15.290 +    }
  15.291 +    
  15.292 +    @Hint(displayName="notRepeatableJavaFix", description="notRepeatableJavaFix", category="test")
  15.293 +    public static final class NotRepeatableJavaFix {
  15.294 +        @TriggerTreeKind(Kind.CLASS)
  15.295 +        public static ErrorDescription hint(HintContext ctx) {
  15.296 +            Fix f = new JavaFix(ctx.getInfo(), ctx.getPath()) {
  15.297 +                private boolean wasRun;
  15.298 +                @Override protected String getText() {
  15.299 +                    return "Fix";
  15.300 +                }
  15.301 +                @Override protected void performRewrite(TransformationContext ctx) throws Exception {
  15.302 +                    if (wasRun) return ;
  15.303 +                    ctx.getWorkingCopy().rewrite(ctx.getPath().getLeaf(), ctx.getWorkingCopy().getTreeMaker().setLabel(ctx.getPath().getLeaf(), "Nue"));
  15.304 +                    wasRun = true;
  15.305 +                }
  15.306 +            }.toEditorFix();
  15.307 +            return ErrorDescriptionFactory.forTree(ctx, ctx.getPath(), "Test", f);
  15.308 +        }
  15.309 +    }
  15.310 +}
    16.1 --- a/java.hints/nbproject/project.properties	Wed May 08 21:48:30 2013 +0200
    16.2 +++ b/java.hints/nbproject/project.properties	Thu May 09 22:04:33 2013 +0200
    16.3 @@ -1,3 +1,5 @@
    16.4  modules=\
    16.5 -    ${project.org.netbeans.spi.java.hints}
    16.6 +    ${project.org.netbeans.spi.java.hints}:\
    16.7 +    ${project.org.netbeans.modules.java.hints.test}
    16.8 +project.org.netbeans.modules.java.hints.test=java.hints.test
    16.9  project.org.netbeans.spi.java.hints=spi.java.hints