You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by po...@apache.org on 2017/09/03 17:33:28 UTC

[35/51] [partial] incubator-netbeans-jackpot30 git commit: INFRA-15006 Import for http://bits.netbeans.org/download/apache-donation

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/batch/EnhancedScopes.java
----------------------------------------------------------------------
diff --git a/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/batch/EnhancedScopes.java b/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/batch/EnhancedScopes.java
new file mode 100644
index 0000000..075aea9
--- /dev/null
+++ b/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/batch/EnhancedScopes.java
@@ -0,0 +1,500 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2009-2011 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2009-2011 Sun Microsystems, Inc.
+ */
+
+package org.netbeans.modules.jackpot30.indexing.batch;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.codeviation.pojson.Pojson;
+import org.netbeans.api.java.classpath.ClassPath;
+import org.netbeans.api.java.source.ClasspathInfo;
+import org.netbeans.api.java.source.CompilationController;
+import org.netbeans.api.java.source.JavaSource;
+import org.netbeans.api.java.source.Task;
+import org.netbeans.modules.jackpot30.indexing.index.IndexQuery;
+import org.netbeans.modules.jackpot30.indexing.index.Indexer;
+import org.netbeans.modules.jackpot30.remoting.api.RemoteIndex;
+import org.netbeans.modules.jackpot30.remoting.api.WebUtilities;
+import static org.netbeans.modules.jackpot30.remoting.api.WebUtilities.escapeForQuery;
+import org.netbeans.modules.java.hints.providers.spi.HintDescription;
+import org.netbeans.modules.java.hints.providers.spi.Trigger.PatternDescription;
+import org.netbeans.modules.java.hints.spiimpl.MessageImpl;
+import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.Folder;
+import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.IndexEnquirer;
+import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.LocalIndexEnquirer;
+import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.MapIndices;
+import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.Resource;
+import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.Scope;
+import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.VerifiedSpansCallBack;
+import org.netbeans.modules.java.hints.spiimpl.batch.ProgressHandleWrapper;
+import org.netbeans.modules.java.hints.spiimpl.batch.Scopes;
+import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings;
+import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch.BulkPattern;
+import org.netbeans.modules.java.preprocessorbridge.spi.JavaIndexerPlugin;
+import org.netbeans.modules.parsing.impl.indexing.FileObjectIndexable;
+import org.netbeans.modules.parsing.impl.indexing.IndexableImpl;
+import org.netbeans.modules.parsing.impl.indexing.SPIAccessor;
+import org.netbeans.spi.editor.hints.ErrorDescription;
+import org.netbeans.spi.editor.hints.ErrorDescriptionFactory;
+import org.netbeans.spi.editor.hints.Severity;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileUtil;
+import org.openide.filesystems.URLMapper;
+import org.openide.util.Exceptions;
+
+/**
+ *
+ * @author lahvac
+ */
+public class EnhancedScopes {
+
+    private static final Logger LOG = Logger.getLogger(EnhancedScopes.class.getName());
+
+    public static Scope allRemote() {
+        return new RemoteIndexScope();
+    }
+
+    public static final class GivenFolderScope extends Scope {
+
+        public final String folder;
+        public final String indexURL;
+        public final String subIndex;
+        public final boolean update;
+
+        public GivenFolderScope(String folder, String indexURL, String subIndex, boolean update) {
+            this.folder = folder;
+            this.indexURL = indexURL;
+            this.subIndex = subIndex;
+            this.update = update;
+        }
+
+        @Override
+        public String getDisplayName() {
+            return folder;
+        }
+
+        @Override
+        public Collection<? extends Folder> getTodo() {
+            return Collections.singletonList(new Folder(FileUtil.toFileObject(new File(folder))));
+        }
+
+        @Override
+        public MapIndices getIndexMapper(Iterable<? extends HintDescription> patterns) {
+            MapIndices mapper;
+
+            if (indexURL != null) {
+                if (subIndex == null) {
+                    mapper = new MapIndices() {
+                        public IndexEnquirer findIndex(FileObject root, ProgressHandleWrapper progress, boolean recursive) {
+                            try {
+                                return new SimpleIndexIndexEnquirer(root, createOrUpdateIndex(root, new File(indexURL), update, progress, recursive));
+                            } catch (IOException ex) {
+                                Exceptions.printStackTrace(ex);
+                                return null;
+                            }
+                        }
+                    };
+                } else {
+                    mapper = new MapIndices() {
+                        public IndexEnquirer findIndex(FileObject root, ProgressHandleWrapper progress, boolean recursive) {
+                            progress.startNextPart(1);
+                            try {
+                                return new SimpleIndexIndexEnquirer(root, IndexQuery.remote(RemoteIndex.create(root.toURL(), new URL(indexURL), subIndex)));
+                            } catch (MalformedURLException ex) {
+                                Exceptions.printStackTrace(ex);
+                                return null;
+                            }
+                        }
+                    };
+                }
+            } else {
+                mapper = Scopes.getDefaultIndicesMapper();
+            }
+
+            return mapper;
+        }
+
+    }
+
+    private static final class RemoteIndexScope extends Scope {
+        @Override
+        public String getDisplayName() {
+            return "All Remote Indices";
+        }
+
+        @Override
+        public Collection<? extends Folder> getTodo() {
+            Collection<Folder> todo = new HashSet<Folder>();
+
+            for (RemoteIndex remoteIndex : RemoteIndex.loadIndices()) {
+                FileObject localFolder = URLMapper.findFileObject(remoteIndex.getLocalFolder());
+
+                if (localFolder == null) continue;
+                todo.add(new Folder(localFolder));
+            }
+
+            return todo;
+        }
+
+        @Override
+        public MapIndices getIndexMapper(final Iterable<? extends HintDescription> patterns) {
+            return new MapIndices() {
+                public IndexEnquirer findIndex(FileObject root, ProgressHandleWrapper progress, boolean recursive) {
+                    for (RemoteIndex remoteIndex : RemoteIndex.loadIndices()) {
+                        FileObject localFolder = URLMapper.findFileObject(remoteIndex.getLocalFolder());
+
+                        if (localFolder == null) continue;
+                        if (localFolder == root) {
+                            return enquirerForRemoteIndex(root, remoteIndex, patterns);
+                        }
+                    }
+                    throw new IllegalStateException();
+                }
+            };
+        }
+    }
+
+    private static IndexQuery createOrUpdateIndex(final FileObject src, File indexRoot, boolean update, ProgressHandleWrapper progress, boolean recursive) throws IOException {
+        final JavaIndexerPlugin index = new Indexer.FactoryImpl().create(src.toURL(), FileUtil.toFileObject(indexRoot));
+
+        File timeStampsFile = new File(indexRoot, "timestamps.properties");
+        Properties timeStamps = new Properties();
+
+        if (timeStampsFile.exists()) {
+            if (!update) {
+                progress.startNextPart(1);
+                return IndexQuery.open(src.toURL());
+            }
+
+            InputStream in = null;
+
+            try {
+                in = new BufferedInputStream(new FileInputStream(timeStampsFile));
+                timeStamps.load(in);
+            } catch (IOException ex) {
+                Exceptions.printStackTrace(ex);
+            } finally {
+                try {
+                    if (in != null)
+                        in.close();
+                } catch (IOException ex) {
+                    Exceptions.printStackTrace(ex);
+                }
+            }
+        }
+
+        Collection<FileObject> collected = new LinkedList<FileObject>();
+        Set<String> removed = new HashSet<String>(timeStamps.stringPropertyNames());
+
+        org.netbeans.modules.java.hints.spiimpl.batch.BatchUtilities.recursive(src, src, collected, progress, 0, timeStamps, removed, recursive);
+
+        for (String r : removed) {
+            index.delete(SPIAccessor.getInstance().create(new FakeIndexableImpl(r)));
+        }
+        
+        JavaSource js = JavaSource.create(ClasspathInfo.create(ClassPath.EMPTY, ClassPath.EMPTY, ClassPath.EMPTY), collected);
+        
+        js.runUserActionTask(new Task<CompilationController>() {
+            @Override public void run(CompilationController parameter) throws Exception {
+                if (parameter.toPhase(JavaSource.Phase.PARSED).compareTo(JavaSource.Phase.PARSED) < 0) return;
+                
+                index.process(parameter.getCompilationUnit(), SPIAccessor.getInstance().create(new FileObjectIndexable(src, parameter.getFileObject())), null);
+            }
+        }, true);
+        
+        OutputStream out = null;
+
+        try {
+            out = new BufferedOutputStream(new FileOutputStream(timeStampsFile));
+            timeStamps.store(out, null);
+        } finally {
+            try {
+                if (out != null) {
+                    out.close();
+                }
+            } catch (IOException ex) {
+                Exceptions.printStackTrace(ex);
+            }
+        }
+
+        return IndexQuery.open(src.toURL());
+    }
+    
+    private static final class FakeIndexableImpl implements IndexableImpl {
+
+        private final String path;
+
+        public FakeIndexableImpl(String path) {
+            this.path = path;
+        }
+        
+        @Override public String getRelativePath() {
+            return path;
+        }
+
+        @Override public URL getURL() {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        @Override public String getMimeType() {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        @Override public boolean isTypeOf(String mimeType) {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+        
+    }
+
+    private static boolean isAttributedIndexWithSpans(RemoteIndex remoteIndex) {
+        try {
+            URI capabilitiesURI = new URI(remoteIndex.remote.toExternalForm() + "/capabilities");
+            String capabilitiesString = WebUtilities.requestStringResponse(capabilitiesURI);
+
+            if (capabilitiesURI == null) return false;
+
+            @SuppressWarnings("unchecked")
+            Map<String, Object> capabilities = Pojson.load(HashMap.class, capabilitiesString);
+
+            return capabilities.get("attributed") == Boolean.TRUE; //TODO: should also check "methods contains findWithSpans"
+        } catch (URISyntaxException ex) {
+            LOG.log(Level.FINE, null, ex);
+            return false;
+        }
+    }
+
+    private static IndexEnquirer enquirerForRemoteIndex(FileObject src, RemoteIndex remoteIndex, Iterable<? extends HintDescription> hints) {
+        if (hints == null) return null;
+        
+        boolean fullySupported = isAttributedIndexWithSpans(remoteIndex);
+        StringBuilder textualRepresentation = new StringBuilder();
+
+        for (HintDescription hd : hints) {
+            if (!(hd.getTrigger() instanceof PatternDescription)) {
+                fullySupported = false;
+                break;
+            }
+
+            if (((PatternDescription) hd.getTrigger()).getImports().iterator().hasNext()) {
+                fullySupported = false;
+            }
+
+            if (!fullySupported) break;
+
+            String hintText = hd.getHintText();
+
+            if (hintText != null) {
+                textualRepresentation.append(hintText);
+            } else {
+                textualRepresentation.append(defaultHintText(hd));
+                fullySupported = false;
+            }
+
+            textualRepresentation.append("\n");
+        }
+
+        if (fullySupported) {
+            return new RemoteFullyAttributedIndexEnquirer(src, remoteIndex, textualRepresentation.toString());
+        } else {
+            return new SimpleIndexIndexEnquirer(src, IndexQuery.remote(remoteIndex));
+        }
+    }
+
+    private static final class SimpleIndexIndexEnquirer extends LocalIndexEnquirer {
+        private final IndexQuery idx;
+        public SimpleIndexIndexEnquirer(FileObject src, IndexQuery idx) {
+            super(src);
+            this.idx = idx;
+        }
+        public Collection<? extends Resource> findResources(final Iterable<? extends HintDescription> hints, ProgressHandleWrapper progress, final Callable<BulkPattern> bulkPattern, final Collection<? super MessageImpl> problems, HintsSettings settingsProvider) {
+            final Collection<Resource> result = new ArrayList<Resource>();
+
+            progress.startNextPart(1);
+
+            try {
+                BulkPattern bp = bulkPattern.call();
+
+                for (String candidate : idx.findCandidates(bp)) {
+                    result.add(new Resource(this, candidate, hints, bp, settingsProvider));
+                }
+            } catch (Exception ex) {
+                Exceptions.printStackTrace(ex);
+            }
+
+            return result;
+        }
+
+    }
+
+    private static final class RemoteFullyAttributedIndexEnquirer extends IndexEnquirer {
+        private final RemoteIndex remoteIndex;
+        private final String textualHintRepresentation;
+        public RemoteFullyAttributedIndexEnquirer(FileObject src, RemoteIndex remoteIndex, String textualHintRepresentation) {
+            super(src);
+            assert isAttributedIndexWithSpans(remoteIndex);
+            this.remoteIndex = remoteIndex;
+            this.textualHintRepresentation = textualHintRepresentation;
+        }
+        public Collection<? extends Resource> findResources(final Iterable<? extends HintDescription> hints, ProgressHandleWrapper progress, final Callable<BulkPattern> bulkPattern, final Collection<? super MessageImpl> problems, HintsSettings settingsProvider) {
+            final Collection<Resource> result = new ArrayList<Resource>();
+
+            progress.startNextPart(1);
+
+            try {
+                URI u = new URI(remoteIndex.remote.toExternalForm() + "/find?path=" + escapeForQuery(remoteIndex.remoteSegment) + "&pattern=" + escapeForQuery(textualHintRepresentation));
+
+                for (String occurrence : new ArrayList<String>(WebUtilities.requestStringArrayResponse(u))) {
+                    try {
+                        BulkPattern bp = bulkPattern.call();
+                        result.add(new Resource(this, occurrence, hints, bp, settingsProvider));
+                    } catch (Exception ex) {
+                        //from bulkPattern.call()? should not happen.
+                        Exceptions.printStackTrace(ex);
+                    }
+                }
+
+            } catch (URISyntaxException ex) {
+                Exceptions.printStackTrace(ex);
+            }
+
+            return result;
+        }
+
+        @Override
+        public void validateResource(Collection<? extends Resource> resources, ProgressHandleWrapper progress, VerifiedSpansCallBack callback, boolean doNotRegisterClassPath, Collection<? super MessageImpl> problems, AtomicBoolean cancel) {
+            for (Resource r : resources) {
+                try {
+                    URI spanURI = new URI(remoteIndex.remote.toExternalForm() + "/findSpans?path=" + escapeForQuery(remoteIndex.remoteSegment) + "&relativePath=" + escapeForQuery(r.getRelativePath()) + "&pattern=" + escapeForQuery(textualHintRepresentation));
+                    FileObject fo = r.getResolvedFile();
+
+                    if (fo == null) {
+                        callback.cannotVerifySpan(r);
+                    } else {
+                        List<ErrorDescription> result = new ArrayList<ErrorDescription>();
+
+                        for (int[] span : parseSpans(WebUtilities.requestStringResponse(spanURI))) {
+                            result.add(ErrorDescriptionFactory.createErrorDescription(Severity.WARNING, "Occurrence", fo, span[0], span[1]));
+                        }
+
+                        callback.spansVerified(null, r, result);
+                    }
+                } catch (Exception ex) {
+                    Exceptions.printStackTrace(ex);
+                }
+            }
+        }
+
+    }
+
+    private static Iterable<int[]> parseSpans(String from) {
+        if (from.isEmpty()) {
+            return Collections.emptyList();
+        }
+        String[] split = from.split(":");
+        List<int[]> result = new LinkedList<int[]>();
+
+        for (int i = 0; i < split.length; i += 2) {
+            result.add(new int[] {
+                Integer.parseInt(split[i + 0].trim()),
+                Integer.parseInt(split[i + 1].trim())
+            });
+        }
+
+        return result;
+    }
+
+    private static String defaultHintText(HintDescription hd) {
+        StringBuilder result = new StringBuilder();
+
+        PatternDescription pd = (PatternDescription) hd.getTrigger();
+
+        if (pd == null) return null;
+
+        if (pd.getImports().iterator().hasNext()) {
+            //cannot currently handle patterns with imports:
+            return null;
+        }
+
+        result.append(pd.getPattern());
+
+        if (!pd.getConstraints().isEmpty()) {
+            result.append(" :: ");
+
+            for (Iterator<Entry<String, String>> it = pd.getConstraints().entrySet().iterator(); it.hasNext(); ) {
+                Entry<String, String> e = it.next();
+
+                result.append(e.getKey()).append(" instanceof ").append(e.getValue());
+
+                if (it.hasNext()) {
+                    result.append(" && ");
+                }
+            }
+        }
+
+        result.append(";;\n");
+
+        return result.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/batch/OptionProcessorImpl.java
----------------------------------------------------------------------
diff --git a/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/batch/OptionProcessorImpl.java b/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/batch/OptionProcessorImpl.java
new file mode 100644
index 0000000..bb51cf5
--- /dev/null
+++ b/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/batch/OptionProcessorImpl.java
@@ -0,0 +1,276 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008-2010 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2008-2010 Sun Microsystems, Inc.
+ */
+
+package org.netbeans.modules.jackpot30.indexing.batch;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.logging.Logger;
+import org.netbeans.api.java.classpath.ClassPath;
+import org.netbeans.api.java.source.ModificationResult;
+import org.netbeans.api.project.Project;
+import org.netbeans.api.project.ProjectManager;
+import org.netbeans.api.project.ProjectUtils;
+import org.netbeans.api.project.SourceGroup;
+import org.netbeans.api.project.ui.OpenProjects;
+import org.netbeans.api.sendopts.CommandException;
+import org.netbeans.modules.java.hints.providers.spi.HintDescription;
+import org.netbeans.modules.java.hints.spiimpl.MessageImpl;
+import org.netbeans.modules.java.hints.spiimpl.Utilities;
+import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch;
+import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.BatchResult;
+import org.netbeans.modules.java.hints.spiimpl.batch.BatchSearch.Folder;
+import org.netbeans.modules.java.hints.spiimpl.batch.BatchUtilities;
+import org.netbeans.modules.java.hints.spiimpl.batch.ProgressHandleWrapper;
+import org.netbeans.modules.java.hints.spiimpl.batch.Scopes;
+import org.netbeans.spi.java.classpath.support.ClassPathSupport;
+import org.netbeans.spi.java.hints.HintContext.MessageKind;
+import org.netbeans.spi.sendopts.Env;
+import org.netbeans.spi.sendopts.Option;
+import org.netbeans.spi.sendopts.OptionProcessor;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileUtil;
+import org.openide.util.lookup.ServiceProvider;
+
+/**
+ *
+ * @author Jan Lahoda
+ */
+@ServiceProvider(service=OptionProcessor.class)
+public class OptionProcessorImpl extends OptionProcessor {
+
+    private static final Logger LOG = Logger.getLogger(OptionProcessorImpl.class.getName());
+
+    private static final String APPLY_TRANSFORMATIONS_PROJECT_OPTION = "apply-transformations-project";
+
+    private static final Option LIST = Option.withoutArgument(Option.NO_SHORT_NAME, "list-hints-transformation");
+    private static final Option APPLY_TRANSFORMATIONS = Option.shortDescription(
+                                                            Option.requiredArgument(Option.NO_SHORT_NAME, "apply-transformations"),
+                                                            "org.netbeans.modules.jackpot30.impl.batch.Bundle",
+                                                            "SD_ApplyTransformations");
+    private static final Option APPLY_TRANSFORMATIONS_PROJECT = Option.shortDescription(
+                                                            Option.additionalArguments(Option.NO_SHORT_NAME, APPLY_TRANSFORMATIONS_PROJECT_OPTION),
+                                                            "org.netbeans.modules.jackpot30.impl.batch.Bundle",
+                                                            "SD_ApplyTransformationsProject");
+
+    private static final Set<Option> OPTIONS = new HashSet<Option>(Arrays.asList(LIST, APPLY_TRANSFORMATIONS, APPLY_TRANSFORMATIONS_PROJECT));
+
+    @Override
+    protected Set<Option> getOptions() {
+        return OPTIONS;
+    }
+
+    @Override
+    protected void process(Env env, Map<Option, String[]> optionValues) throws CommandException {
+        List<Project> projects = new LinkedList<Project>();
+        Map<String, List<ClassPath>> classPaths = new HashMap<String, List<ClassPath>>();
+
+        if (optionValues.containsKey(APPLY_TRANSFORMATIONS_PROJECT)) {
+            String[] projectNames = optionValues.get(APPLY_TRANSFORMATIONS_PROJECT);
+
+            if (projectNames.length == 0) {
+                env.getErrorStream().println("At least one parameter needed for " + APPLY_TRANSFORMATIONS_PROJECT_OPTION);
+                throw new CommandException(1);
+            }
+
+            FileObject currentDirectory = FileUtil.toFileObject(env.getCurrentDirectory());
+
+            OUTER: for (String p : projectNames) {
+                FileObject projectFile = currentDirectory.getFileObject(p);
+
+                if (projectFile == null) {
+                    projectFile = FileUtil.toFileObject(new File(p));
+                }
+
+                if (projectFile == null) {
+                    env.getErrorStream().println("Ignoring file " + p + " - cannot be found.");
+                    continue;
+                }
+
+                if (!projectFile.isFolder()) {
+                    env.getErrorStream().println("Ignoring file " + p + " - not a folder.");
+                    continue;
+                }
+
+                Project project = null;
+                String  error   = null;
+
+                try {
+                    project = ProjectManager.getDefault().findProject(projectFile);
+                } catch (IOException ex) {
+                    error = ex.getLocalizedMessage();
+                } catch (IllegalArgumentException ex) {
+                    error = ex.getLocalizedMessage();
+                }
+
+                if (project == null) {
+                    if (error == null) {
+                        env.getErrorStream().println("Ignoring file " + p + " - not a project.");
+                    } else {
+                        env.getErrorStream().println("Ignoring file " + p + " - not a project (" + error + ").");
+                    }
+
+                    continue;
+                }
+
+                for (SourceGroup sg : ProjectUtils.getSources(project).getSourceGroups("java")) {
+                    FileObject root = sg.getRootFolder();
+
+                    for (String type : Arrays.asList(ClassPath.BOOT, ClassPath.COMPILE, ClassPath.SOURCE)) {
+                        if (!handleClassPath(root, type, env, p, classPaths)) {
+                            continue OUTER;
+                        }
+                    }
+                }
+
+                projects.add(project);
+            }
+        } else {
+            projects.addAll(Arrays.asList(OpenProjects.getDefault().getOpenProjects()));
+        }
+
+        if (optionValues.containsKey(LIST)) {
+            env.getOutputStream().println("Supported Hints:");
+
+            Set<ClassPath> cps = new HashSet<ClassPath>();
+
+            for (List<ClassPath> c : classPaths.values()) {
+                cps.addAll(c);
+            }
+
+            Set<String> displayNames = Utilities.sortOutHints(Utilities.listAllHints(cps), new TreeMap<String, Collection<HintDescription>>()).keySet();
+
+            for (String displayName : displayNames) {
+                env.getOutputStream().println(displayName);
+            }
+        }
+
+        if (optionValues.containsKey(APPLY_TRANSFORMATIONS)) {
+            String hintsArg = optionValues.get(APPLY_TRANSFORMATIONS)[0];
+            List<HintDescription> hintDescriptions = new LinkedList<HintDescription>();
+            Set<ClassPath> cps = new HashSet<ClassPath>();
+
+            for (List<ClassPath> c : classPaths.values()) {
+                cps.addAll(c);
+            }
+
+            Map<String, Collection<HintDescription>> sorted = Utilities.sortOutHints(Utilities.listAllHints(cps), new TreeMap<String, Collection<HintDescription>>());
+
+            for (String hint : hintsArg.split(":")) {
+                Collection<HintDescription> descs = sorted.get(hint);
+
+                if (descs == null) {
+                    env.getErrorStream().println("Unknown hint: " + hint);
+                    continue;
+                }
+
+                hintDescriptions.addAll(descs);
+            }
+
+            Collection<Folder> roots = new ArrayList<Folder>();
+
+            for (FileObject f : BatchUtilities.getSourceGroups(projects)) {
+                roots.add(new Folder(f));
+            }
+
+            BatchResult candidates = BatchSearch.findOccurrences(hintDescriptions, Scopes.specifiedFoldersScope(roots.toArray(new Folder[0])));
+            List<MessageImpl> problems = new LinkedList<MessageImpl>(candidates.problems);
+            Collection<? extends ModificationResult> res = BatchUtilities.applyFixes(candidates, new ProgressHandleWrapper(100), null, problems);
+            Set<FileObject> modified = new HashSet<FileObject>();
+
+            for (ModificationResult mr : res) {
+                try {
+                    mr.commit();
+                } catch (IOException ex) {
+                    ex.printStackTrace(env.getErrorStream());
+                    problems.add(new MessageImpl(MessageKind.ERROR, "Cannot apply changes: " + ex.getLocalizedMessage()));
+                }
+                modified.addAll(mr.getModifiedFileObjects());
+            }
+
+            try {
+                org.netbeans.modules.jackpot30.indexing.batch.BatchUtilities.removeUnusedImports(modified);
+            } catch (IOException ex) {
+                ex.printStackTrace(env.getErrorStream());
+                problems.add(new MessageImpl(MessageKind.ERROR, "Cannot remove unused imports: " + ex.getLocalizedMessage()));
+            }
+
+            if (!problems.isEmpty()) {
+                env.getErrorStream().println("Problem encountered while applying the transformations:");
+
+                for (MessageImpl problem : problems) {
+                    env.getErrorStream().println(problem.text);
+                }
+            }
+        }
+
+    }
+
+    private boolean handleClassPath(FileObject root, String type, Env env, String p, Map<String, List<ClassPath>> classPaths) {
+        ClassPath cp = ClassPath.getClassPath(root, type);
+
+        if (cp == null) {
+            env.getErrorStream().println("Ignoring file " + p + " - no " + type + " classpath for source group: " + FileUtil.getFileDisplayName(root));
+            return false;
+        }
+
+        List<ClassPath> cps = classPaths.get(type);
+
+        if (cps == null) {
+            classPaths.put(type, cps = new LinkedList<ClassPath>());
+        }
+
+        cp = ClassPathSupport.createProxyClassPath(cp);
+
+        cps.add(cp);
+
+        return true;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/index/IndexQuery.java
----------------------------------------------------------------------
diff --git a/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/index/IndexQuery.java b/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/index/IndexQuery.java
new file mode 100644
index 0000000..ba48594
--- /dev/null
+++ b/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/index/IndexQuery.java
@@ -0,0 +1,255 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2009-2010 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2009-2010 Sun Microsystems, Inc.
+ */
+
+package org.netbeans.modules.jackpot30.indexing.index;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.zip.DataFormatException;
+import org.apache.lucene.analysis.KeywordAnalyzer;
+import org.apache.lucene.document.CompressionTools;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.FieldSelector;
+import org.apache.lucene.document.FieldSelectorResult;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.queryParser.ParseException;
+import org.apache.lucene.search.BooleanClause;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.PhraseQuery;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.TermQuery;
+import org.netbeans.api.annotations.common.NullAllowed;
+import org.netbeans.modules.jackpot30.remoting.api.RemoteIndex;
+import org.netbeans.modules.jackpot30.remoting.api.WebUtilities;
+import org.netbeans.modules.java.hints.providers.spi.HintDescription.AdditionalQueryConstraints;
+import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch;
+import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch.BulkPattern;
+import org.netbeans.modules.parsing.lucene.support.Convertor;
+import org.netbeans.modules.parsing.lucene.support.Index;
+import org.netbeans.modules.parsing.lucene.support.Index.Status;
+import org.netbeans.modules.parsing.lucene.support.IndexManager;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileUtil;
+import org.openide.util.Exceptions;
+
+/**
+ *
+ * @author lahvac
+ */
+public abstract class IndexQuery {
+
+    public abstract Collection<? extends String> findCandidates(BulkPattern pattern) throws IOException;
+
+    public abstract Map<String, Map<String, Integer>> findCandidatesWithFrequencies(BulkPattern pattern) throws IOException;
+
+    public static Map<String, Map<String, Integer>> performLocalQuery(Index index, final BulkPattern pattern, final boolean withFrequencies) throws IOException, InterruptedException, ParseException {
+        final Map<String, Map<String, Integer>> result = new HashMap<String, Map<String, Integer>>();
+
+        index.query(new ArrayList<Object>(), new Convertor<Document, Object>() {
+            @Override public Object convert(Document doc) {
+                try {
+                    ByteArrayInputStream in = new ByteArrayInputStream(CompressionTools.decompress(doc.getField("languageEncoded").getBinaryValue()));
+
+                    try {
+                        Map<String, Integer> freqs;
+                        boolean matches;
+
+                        if (withFrequencies) {
+                            freqs = BulkSearch.getDefault().matchesWithFrequencies(in, pattern, new AtomicBoolean());
+                            matches = !freqs.isEmpty();
+                        } else {
+                            freqs = null;
+                            matches = BulkSearch.getDefault().matches(in, new AtomicBoolean(), pattern);
+                        }
+
+                        if (matches) {
+                            result.put(doc.getField("languagePath").stringValue(), freqs);
+                        }
+                    } finally {
+                        in.close();
+                    }
+                } catch (DataFormatException ex) {
+                    throw new IllegalStateException(ex);
+                } catch (IOException ex) {
+                    throw new IllegalStateException(ex);
+                }
+
+                return null;
+            }
+        }, new FieldSelector() {
+            public FieldSelectorResult accept(String string) {
+                return "languageEncoded".equals(string) || "languagePath".equals(string) ? FieldSelectorResult.LOAD : FieldSelectorResult.NO_LOAD;
+            }
+        }, null, query(pattern));
+
+        return result;
+    }
+
+    private static Query query(BulkPattern pattern) throws ParseException {
+        BooleanQuery result = new BooleanQuery();
+
+        for (int cntr = 0; cntr < pattern.getIdentifiers().size(); cntr++) {
+            assert !pattern.getRequiredContent().get(cntr).isEmpty();
+
+            BooleanQuery emb = new BooleanQuery();
+
+            for (List<String> c : pattern.getRequiredContent().get(cntr)) {
+                if (c.isEmpty()) continue;
+
+                PhraseQuery pq = new PhraseQuery();
+
+                for (String s : c) {
+                    pq.add(new Term("languageContent", s));
+                }
+
+                emb.add(pq, BooleanClause.Occur.MUST);
+            }
+
+            AdditionalQueryConstraints additionalConstraints = pattern.getAdditionalConstraints().get(cntr);
+
+            if (additionalConstraints != null && !additionalConstraints.requiredErasedTypes.isEmpty()) {
+                BooleanQuery constraintsQuery = new BooleanQuery();
+
+                constraintsQuery.add(new TermQuery(new Term("languageAttributed", "false")), BooleanClause.Occur.SHOULD);
+
+                BooleanQuery constr = new BooleanQuery();
+
+                for (String tc : additionalConstraints.requiredErasedTypes) {
+                    constr.add(new TermQuery(new Term("languageErasedTypes", tc)), BooleanClause.Occur.MUST);
+                }
+
+                constraintsQuery.add(constr, BooleanClause.Occur.SHOULD);
+                emb.add(constraintsQuery, BooleanClause.Occur.MUST);
+            }
+
+            result.add(emb, BooleanClause.Occur.SHOULD);
+        }
+
+        return result;
+    }
+
+    private static final class LocalIndexQuery extends IndexQuery {
+        private final @NullAllowed File cacheDir;
+
+        public LocalIndexQuery(@NullAllowed File cacheDir) {
+            this.cacheDir = cacheDir;
+        }
+
+        public Collection<? extends String> findCandidates(BulkPattern pattern) throws IOException {
+            return findCandidates(pattern, false).keySet();
+        }
+
+        public Map<String, Map<String, Integer>> findCandidatesWithFrequencies(BulkPattern pattern) throws IOException {
+            return findCandidates(pattern, true);
+        }
+
+        private Map<String, Map<String, Integer>> findCandidates(BulkPattern pattern, boolean withFrequencies) throws IOException {
+            Index index = IndexManager.createIndex(cacheDir, new KeywordAnalyzer());
+
+            if (index.getStatus(true) != Status.VALID) {
+                 return Collections.emptyMap();
+            }
+
+            try {
+                return performLocalQuery(index, pattern, withFrequencies);
+            } catch (InterruptedException ex) {
+                throw new IOException(ex);
+            } catch (ParseException ex) {
+                throw new IOException(ex);
+            } finally {
+                index.close();
+            }
+        }
+
+    }
+    
+    private static final class RemoteIndexQuery extends IndexQuery {
+        private final RemoteIndex idx;
+
+        public RemoteIndexQuery(RemoteIndex idx) {
+            this.idx = idx;
+        }
+        
+        @Override
+        public Collection<? extends String> findCandidates(BulkPattern pattern) throws IOException {
+            try {
+                StringBuilder patterns = new StringBuilder();
+
+                for (String p : pattern.getPatterns()) {
+                    patterns.append(p);
+                    patterns.append(";;");
+                }
+
+                URI u = new URI(idx.remote.toExternalForm() + "?path=" + WebUtilities.escapeForQuery(idx.remoteSegment) + "&pattern=" + WebUtilities.escapeForQuery(patterns.toString()));
+
+                return new ArrayList<String>(WebUtilities.requestStringArrayResponse(u));
+            } catch (URISyntaxException ex) {
+                //XXX: better handling?
+                Exceptions.printStackTrace(ex);
+                return Collections.emptyList();
+            }
+        }
+        @Override
+        public Map<String, Map<String, Integer>> findCandidatesWithFrequencies(BulkPattern pattern) throws IOException {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+    }
+    
+    public static IndexQuery open(URL sourceRoot) throws IOException {
+        FileObject cacheFO  = Indexer.resolveCacheFolder(sourceRoot).getFileObject(Indexer.INDEX_NAME);
+        File cache = cacheFO != null ? FileUtil.toFile(cacheFO) : null;
+        
+        return new LocalIndexQuery(cache);
+    }
+
+    public static IndexQuery remote(RemoteIndex idx) {
+        return new RemoteIndexQuery(idx);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/index/Indexer.java
----------------------------------------------------------------------
diff --git a/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/index/Indexer.java b/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/index/Indexer.java
new file mode 100644
index 0000000..962015f
--- /dev/null
+++ b/language/ide/indexing/src/org/netbeans/modules/jackpot30/indexing/index/Indexer.java
@@ -0,0 +1,241 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2009-2012 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2009-2012 Sun Microsystems, Inc.
+ */
+
+package org.netbeans.modules.jackpot30.indexing.index;
+
+import org.netbeans.modules.jackpot30.common.api.IndexAccess;
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.util.TreePath;
+import com.sun.source.util.TreePathScanner;
+import com.sun.source.util.Trees;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.lang.model.type.ArrayType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Types;
+import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.tokenattributes.TermAttribute;
+import org.apache.lucene.document.CompressionTools;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.index.CorruptIndexException;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.Term;
+import org.netbeans.api.annotations.common.NonNull;
+import org.netbeans.api.editor.mimelookup.MimeRegistration;
+import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch;
+import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch.EncodingContext;
+import org.netbeans.modules.java.preprocessorbridge.spi.JavaIndexerPlugin;
+import org.netbeans.modules.java.source.indexing.JavaIndex;
+import org.netbeans.modules.parsing.impl.indexing.CacheFolder;
+import org.netbeans.modules.parsing.spi.indexing.Indexable;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileUtil;
+import org.openide.util.Exceptions;
+import org.openide.util.Lookup;
+
+/**
+ *
+ * @author lahvac
+ */
+public final class Indexer implements JavaIndexerPlugin {
+
+    public static final String INDEX_NAME = "jackpot30";
+    private final @NonNull URL root;
+    private final @NonNull FileObject cacheRoot;
+    private final @NonNull IndexAccess access;
+
+    private  Indexer(URL root, FileObject cacheRoot) {
+        this.root = root;
+        this.cacheRoot = cacheRoot;
+        this.access = Lookup.getDefault().lookup(IndexAccess.class);
+    }
+    
+    @Override
+    public void process (@NonNull CompilationUnitTree toProcess, @NonNull Indexable indexable, @NonNull Lookup services) {
+        IndexWriter luceneWriter = access.getIndexWriter(root, cacheRoot, INDEX_NAME);
+        String relative = access.getRelativePath(indexable);
+        ByteArrayOutputStream out = null;
+        EncodingContext ec;
+
+        try {
+            out = new ByteArrayOutputStream();
+
+            ec = new EncodingContext(out, false);
+
+            BulkSearch.getDefault().encode(toProcess, ec, new AtomicBoolean());
+
+            luceneWriter.deleteDocuments(new Term("languagePath", relative));
+
+            Document doc = new Document();
+
+            doc.add(new Field("languageContent", new TokenStreamImpl(ec.getContent())));
+            out.close();
+            doc.add(new Field("languageEncoded", CompressionTools.compress(out.toByteArray()), Field.Store.YES));
+            doc.add(new Field("languagePath", relative, Field.Store.YES, Field.Index.NOT_ANALYZED));
+
+            if (services != null) {
+                final Set<String> erased = new HashSet<String>();
+                final Trees trees = services.lookup(Trees.class);
+                final Types types = services.lookup(Types.class);
+
+                new TreePathScanner<Void, Void>() {
+                    @Override
+                    public Void scan(Tree tree, Void p) {
+                        if (tree != null) {
+                            TreePath tp = new TreePath(getCurrentPath(), tree);
+                            TypeMirror type = trees.getTypeMirror(tp);
+
+                            if (type != null) {
+                                if (type.getKind() == TypeKind.ARRAY) {
+                                    erased.add(types.erasure(type).toString());
+                                    type = ((ArrayType) type).getComponentType();
+                                }
+
+                                if (type.getKind().isPrimitive() || type.getKind() == TypeKind.DECLARED) {
+                                    addErasedTypeAndSuperTypes(types, erased, type);
+                                }
+                            }
+
+                            //bounds for type variables!!!
+                        }
+                        return super.scan(tree, p);
+                    }
+                }.scan(toProcess, null);
+
+                doc.add(new Field("languageErasedTypes", new TokenStreamImpl(erased)));
+            }
+            
+            luceneWriter.addDocument(doc);
+        } catch (ThreadDeath td) {
+            throw td;
+        } catch (Throwable t) {
+            Logger.getLogger(Indexer.class.getName()).log(Level.WARNING, null, t);
+        } finally {
+            if (out != null) {
+                try {
+                    out.close();
+                } catch (IOException ex) {
+                    Exceptions.printStackTrace(ex);
+                }
+            }
+        }
+    }
+
+
+    @Override
+    public void delete (@NonNull Indexable indexable) {
+        IndexWriter luceneWriter = access.getIndexWriter(root, cacheRoot, INDEX_NAME);
+        String relative = access.getRelativePath(indexable);
+        
+        try {
+            luceneWriter.deleteDocuments(new Term("languagePath", relative));
+        } catch (CorruptIndexException ex) {
+            Logger.getLogger(Indexer.class.getName()).log(Level.WARNING, null, ex);
+        } catch (IOException ex) {
+            Logger.getLogger(Indexer.class.getName()).log(Level.WARNING, null, ex);
+        }
+    }
+
+    @Override
+    public void finish () {
+        access.finish();
+    }
+
+    private static void addErasedTypeAndSuperTypes(Types javacTypes, Set<String> types, TypeMirror type) {
+        if (type.getKind() == TypeKind.DECLARED) {
+            if (types.add(javacTypes.erasure(type).toString())) {
+                for (TypeMirror sup : javacTypes.directSupertypes(type)) {
+                    addErasedTypeAndSuperTypes(javacTypes, types, sup);
+                }
+            }
+        } else if (type.getKind().isPrimitive()) {
+            types.add(type.toString());
+        }
+    }
+
+    public static final class TokenStreamImpl extends TokenStream {
+
+        private final Iterator<? extends String> tokens;
+        private final TermAttribute termAtt;
+
+        public TokenStreamImpl(Iterable<? extends String> tokens) {
+            this.tokens = tokens != null ? tokens.iterator() : /*???*/Collections.<String>emptyList().iterator();
+            this.termAtt = addAttribute(TermAttribute.class);
+        }
+
+        @Override
+        public boolean incrementToken() throws IOException {
+            if (!tokens.hasNext())
+                return false;
+
+            String t = tokens.next();
+
+            termAtt.setTermBuffer(t);
+            
+            return true;
+        }
+    }
+
+    public static @NonNull FileObject resolveCacheFolder(@NonNull URL sourceRoot) throws IOException {
+        FileObject dataFolder = CacheFolder.getDataFolder(sourceRoot);
+        
+        return FileUtil.createFolder(dataFolder, JavaIndex.NAME + "/" + JavaIndex.VERSION);
+    }
+    
+    @MimeRegistration(mimeType="text/x-java", service=Factory.class)
+    public static final class FactoryImpl implements Factory {
+
+        @Override
+        public JavaIndexerPlugin create(URL root, FileObject cacheFolder) {
+            return new Indexer(root, cacheFolder);
+        }
+        
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/language/ide/indexing/test/unit/src/org/netbeans/modules/jackpot30/indexing/index/IndexerTest.java
----------------------------------------------------------------------
diff --git a/language/ide/indexing/test/unit/src/org/netbeans/modules/jackpot30/indexing/index/IndexerTest.java b/language/ide/indexing/test/unit/src/org/netbeans/modules/jackpot30/indexing/index/IndexerTest.java
new file mode 100644
index 0000000..be974d1
--- /dev/null
+++ b/language/ide/indexing/test/unit/src/org/netbeans/modules/jackpot30/indexing/index/IndexerTest.java
@@ -0,0 +1,304 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2009 Sun Microsystems, Inc.
+ */
+
+package org.netbeans.modules.jackpot30.indexing.index;
+
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.netbeans.api.editor.mimelookup.MimePath;
+import org.netbeans.api.java.classpath.ClassPath;
+import org.netbeans.api.java.source.ClasspathInfo;
+import org.netbeans.api.java.source.CompilationController;
+import org.netbeans.api.java.source.JavaSource;
+import org.netbeans.api.java.source.SourceUtilsTestUtil;
+import org.netbeans.api.java.source.Task;
+import org.netbeans.api.java.source.TestUtilities;
+import org.netbeans.modules.jackpot30.common.test.IndexTestBase;
+import org.netbeans.modules.java.hints.providers.spi.HintDescription.AdditionalQueryConstraints;
+import org.netbeans.modules.java.hints.spiimpl.Utilities;
+import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch;
+import org.netbeans.modules.java.hints.spiimpl.pm.BulkSearch.BulkPattern;
+import org.netbeans.modules.parsing.api.indexing.IndexingManager;
+import org.netbeans.spi.editor.mimelookup.MimeDataProvider;
+import org.netbeans.spi.java.classpath.support.ClassPathSupport;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileUtil;
+import org.openide.util.Lookup;
+import org.openide.util.lookup.Lookups;
+import org.openide.util.lookup.ServiceProvider;
+
+
+/**
+ *
+ * @author lahvac
+ */
+public class IndexerTest extends IndexTestBase {
+
+    public IndexerTest(String name) {
+        super(name);
+    }
+
+    public void testMultiplePatternsIndexing() throws Exception {
+        writeFilesAndWaitForScan(src,
+                                 new File("test/Test1.java", "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); } }"),
+                                 new File("test/Test2.java", "package test; public class Test2 { private void test() { new javax.swing.ImageIcon(null); } }"));
+
+        String[] patterns = new String[] {
+            "$1.isDirectory()",
+            "new ImageIcon($1)"
+        };
+
+        verifyIndex(patterns, "test/Test1.java", "test/Test2.java");
+    }
+
+    public void testLambdaPattern() throws Exception {
+        writeFilesAndWaitForScan(src,
+                                 new File("test/Test1.java", "package test; public class Test1 { private void test() { Runnable r = new Runnable() { public void run() { System.err.println(); } } } }"));
+
+        String[] patterns = new String[] {
+            "new $type() {\n $mods$ $resultType $methodName($args$) {\n $statements$;\n }\n }\n",
+        };
+
+        verifyIndex(patterns, "test/Test1.java");
+    }
+
+    public void testUpdates() throws Exception {
+        String[] patterns = new String[] {
+            "$1.isDirectory()",
+            "new ImageIcon($1)"
+        };
+
+        writeFilesAndWaitForScan(src,
+                                 new File("test/Test1.java", "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); } }"),
+                                 new File("test/Test2.java", "package test; public class Test2 { private void test() { new javax.swing.ImageIcon(null); } }"));
+
+        verifyIndex(patterns, "test/Test1.java", "test/Test2.java");
+//        assertEquals(2, FileBasedIndex.get(src.getURL()).getIndexInfo().totalFiles);
+
+        src.getFileObject("test/Test1.java").delete();
+
+        assertNull(src.getFileObject("test/Test1.java"));
+
+        IndexingManager.getDefault().refreshIndexAndWait(src.toURL(), null, true);
+
+        verifyIndex(patterns, "test/Test2.java");
+//        assertEquals(1, FileBasedIndex.get(src.getURL()).getIndexInfo().totalFiles);
+
+        FileObject test3 = FileUtil.createData(src, "test/Test3.java");
+        TestUtilities.copyStringToFile(test3, "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); } }");
+
+        IndexingManager.getDefault().refreshIndexAndWait(src.toURL(), null, true);
+
+        verifyIndex(patterns, "test/Test2.java", "test/Test3.java");
+//        assertEquals(2, FileBasedIndex.get(src.getURL()).getIndexInfo().totalFiles);
+    }
+
+    public void testPartiallyAttributed1() throws Exception {
+        writeFilesAndWaitForScan(src,
+                   new File("test/Test1.java", "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); } }"),
+                   new File("test/Test2.java", "package test; public class Test2 { private void isDirectory() { this.isDirectory(); } }"),
+                   new File("test/Test3.java", "package test; public class Test3 { private void isDirectory() { this.isDirectory(); } }"));
+
+        verifyIndex("$1.isDirectory()", new AdditionalQueryConstraints(Collections.singleton("java.io.File")), "test/Test1.java");
+    }
+
+    public void testPartiallyAttributed2() throws Exception {
+        writeFilesAndWaitForScan(src,
+                   new File("test/Test1.java", "package test; public class Test1 { private void test() { String str = null; int l = str.length(); } }"));
+
+        verifyIndex("$1.length()", new AdditionalQueryConstraints(Collections.singleton("java.lang.CharSequence")), "test/Test1.java");
+    }
+
+    public void testFrequencies() throws Exception {
+        writeFilesAndWaitForScan(src,
+                                 new File("test/Test1.java", "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); f.isDirectory(); } }"),
+                                 new File("test/Test2.java", "package test; public class Test2 { private void test() { new javax.swing.ImageIcon(null); java.io.File f = null; f.isDirectory(); } }"),
+                                 new File("test/Test3.java", "package test; public class Test3 { private void test() { new javax.swing.ImageIcon(null); new javax.swing.ImageIcon(null); } }")
+                                );
+
+        String[] patterns = new String[] {
+            "$1.isDirectory()",
+            "new ImageIcon($1)"
+        };
+
+        Map<String, Map<String, Integer>> golden = new HashMap<String, Map<String, Integer>>();
+        
+        golden.put("test/Test3.java", Collections.singletonMap("new ImageIcon($1)", 2));
+        golden.put("test/Test1.java", Collections.singletonMap("$1.isDirectory()", 2));
+        
+        Map<String, Integer> freqsTest2 = new HashMap<String, Integer>();
+        
+        freqsTest2.put("$1.isDirectory()", 1);
+        freqsTest2.put("new ImageIcon($1)", 1);
+        
+        golden.put("test/Test2.java", freqsTest2);
+        
+        verifyIndexWithFrequencies(patterns, golden);
+    }
+
+    public void testInnerClass() throws Exception {
+        writeFilesAndWaitForScan(src,
+                                 new File("test/Test1.java", "package test; public class Test1 { private static final class O implements Iterable<String> { private String next; private String computeNext() { return null; } public String hasNext() { next = computeNext(); return next != null; } } }"));
+
+        verifyIndex("$this.computeNext()", new AdditionalQueryConstraints(Collections.singleton("test.Test1.O")), "test/Test1.java");
+    }
+
+    public void testIndexing() throws Exception {
+        writeFilesAndWaitForScan(src,
+                                 new File("test/Test1.java", "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); } }"),
+                                 new File("test/Test2.java", "package test; public class Test2 { private void test() { new javax.swing.ImageIcon(null); } }"));
+
+        verifyIndex("$1.isDirectory()", "test/Test1.java");
+        verifyIndex("new ImageIcon($1)", "test/Test2.java");
+        
+        writeFilesAndWaitForScan(src,
+                                 new File("test/Test1.java", "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); new javax.swing.ImageIcon(null); } }"),
+                                 new File("test/Test2.java", "package test; public class Test2 { private void test() { new javax.swing.ImageIcon(null); } }"));
+
+        verifyIndex("$1.isDirectory()", "test/Test1.java");
+        verifyIndex("new ImageIcon($1)", "test/Test1.java", "test/Test2.java");
+        
+        writeFilesAndWaitForScan(src,
+                                 new File("test/Test1.java", "package test; public class Test1 { private void test() { java.io.File f = null; f.isDirectory(); new javax.swing.ImageIcon(null); } }"),
+                                 new File("test/Test2.java", "package test; public class Test2 { }"));
+
+        verifyIndex("$1.isDirectory()", "test/Test1.java");
+        verifyIndex("new ImageIcon($1)", "test/Test1.java");
+    }
+    
+    private void verifyIndex(final String[] patterns, String... containedIn) throws Exception {
+        ClassPath EMPTY = ClassPathSupport.createClassPath(new FileObject[0]);
+        ClasspathInfo cpInfo = ClasspathInfo.create(ClassPathSupport.createClassPath(SourceUtilsTestUtil.getBootClassPath().toArray(new URL[0])),
+                                                    EMPTY,
+                                                    EMPTY);
+
+        final Set<String> real = new HashSet<String>();
+        
+        JavaSource.create(cpInfo).runUserActionTask(new Task<CompilationController>() {
+            public void run(CompilationController parameter) throws Exception {
+                real.addAll(IndexQuery.open(src.toURL()).findCandidates(BulkSearch.getDefault().create(parameter, new AtomicBoolean(), patterns)));
+            }
+        }, true);
+
+        Set<String> golden = new HashSet<String>(Arrays.asList(containedIn));
+
+        assertEquals(golden, real);
+    }
+
+    private void verifyIndex(final String pattern, final AdditionalQueryConstraints additionalConstraints, String... containedIn) throws Exception {
+        ClassPath EMPTY = ClassPathSupport.createClassPath(new FileObject[0]);
+        ClasspathInfo cpInfo = ClasspathInfo.create(ClassPathSupport.createClassPath(SourceUtilsTestUtil.getBootClassPath().toArray(new URL[0])),
+                                                    EMPTY,
+                                                    EMPTY);
+
+        final Set<String> real = new HashSet<String>();
+
+        JavaSource.create(cpInfo).runUserActionTask(new Task<CompilationController>() {
+            public void run(CompilationController parameter) throws Exception {
+                BulkPattern bulkPattern = BulkSearch.getDefault().create(Collections.singletonList(pattern),
+                                                                          Collections.singletonList(Utilities.parseAndAttribute(parameter, pattern, null)),
+                                                                          Collections.singletonList(additionalConstraints),
+                                                                          new AtomicBoolean());
+                
+                real.addAll(IndexQuery.open(src.toURL()).findCandidates(bulkPattern));
+            }
+        }, true);
+
+        Set<String> golden = new HashSet<String>(Arrays.asList(containedIn));
+
+        assertEquals(golden, real);
+    }
+
+    private void verifyIndexWithFrequencies(final String[] patterns, Map<String, Map<String, Integer>> golden) throws Exception {
+        ClassPath EMPTY = ClassPathSupport.createClassPath(new FileObject[0]);
+        ClasspathInfo cpInfo = ClasspathInfo.create(ClassPathSupport.createClassPath(SourceUtilsTestUtil.getBootClassPath().toArray(new URL[0])),
+                                                    EMPTY,
+                                                    EMPTY);
+
+        final Map<String, Map<String, Integer>> real = new HashMap<String, Map<String, Integer>>();
+
+        JavaSource.create(cpInfo).runUserActionTask(new Task<CompilationController>() {
+            public void run(CompilationController parameter) throws Exception {
+                real.putAll(IndexQuery.open(src.toURL()).findCandidatesWithFrequencies(BulkSearch.getDefault().create(parameter, new AtomicBoolean(), patterns)));
+            }
+        }, true);
+
+        assertEquals(golden, real);
+    }
+
+    private void verifyIndex(final String pattern, String... containedIn) throws Exception {
+        ClassPath EMPTY = ClassPathSupport.createClassPath(new FileObject[0]);
+        ClasspathInfo cpInfo = ClasspathInfo.create(ClassPathSupport.createClassPath(SourceUtilsTestUtil.getBootClassPath().toArray(new URL[0])),
+                                                    EMPTY,
+                                                    EMPTY);
+
+        final Set<String> real = new HashSet<String>();
+        
+        JavaSource.create(cpInfo).runUserActionTask(new Task<CompilationController>() {
+            public void run(CompilationController parameter) throws Exception {
+                real.addAll(IndexQuery.open(src.toURL()).findCandidates(BulkSearch.getDefault().create(parameter, new AtomicBoolean(), pattern)));
+            }
+        }, true);
+
+        Set<String> golden = new HashSet<String>(Arrays.asList(containedIn));
+
+        assertEquals(golden, real);
+    }
+    
+    @ServiceProvider(service=MimeDataProvider.class)
+    public static final class MimeDataProviderImpl implements MimeDataProvider {
+
+        private static final Lookup L = Lookups.fixed(new Indexer.FactoryImpl());
+        
+        @Override
+        public Lookup getLookup(MimePath mp) {
+            if ("text/x-java".equals(mp.getPath())) {
+                return L;
+            }
+            return Lookup.EMPTY;
+        }
+        
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/language/ide/nbproject/build-impl.xml
----------------------------------------------------------------------
diff --git a/language/ide/nbproject/build-impl.xml b/language/ide/nbproject/build-impl.xml
new file mode 100644
index 0000000..e667e4e
--- /dev/null
+++ b/language/ide/nbproject/build-impl.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+Copyright 2009-2017 Oracle and/or its affiliates. All rights reserved.
+
+Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+Other names may be trademarks of their respective owners.
+
+The contents of this file are subject to the terms of either the GNU
+General Public License Version 2 only ("GPL") or the Common
+Development and Distribution License("CDDL") (collectively, the
+"License"). You may not use this file except in compliance with the
+License. You can obtain a copy of the License at
+http://www.netbeans.org/cddl-gplv2.html
+or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+specific language governing permissions and limitations under the
+License.  When distributing the software, include this License Header
+Notice in each file and include the License file at
+nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+particular file as subject to the "Classpath" exception as provided
+by Oracle in the GPL Version 2 section of the License file that
+accompanied this code. If applicable, add the following below the
+License Header, with the fields enclosed by brackets [] replaced by
+your own identifying information:
+"Portions Copyrighted [year] [name of copyright owner]"
+
+Contributor(s):
+
+The Original Software is NetBeans. The Initial Developer of the Original
+Software is Sun Microsystems, Inc. Portions Copyright 2009-2010 Sun
+Microsystems, Inc. All Rights Reserved.
+
+If you wish your version of this file to be governed by only the CDDL
+or only the GPL Version 2, indicate your decision by adding
+"[Contributor] elects to include this software in this distribution
+under the [CDDL or GPL Version 2] license." If you do not indicate a
+single choice of license, a recipient has the option to distribute
+your version of this file under either the CDDL, the GPL Version 2 or
+to extend the choice of license to its licensees as provided above.
+However, if you add GPL Version 2 code and therefore, elected the GPL
+Version 2 license, then the option applies only if the new code is
+made subject to such option by the copyright holder.
+-->
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="language-ide-impl" basedir=".." xmlns:sproject="http://www.netbeans.org/ns/nb-module-suite-project/1">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/platform-private.properties"/>
+    <property file="nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-suite-project/1">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-suite-project/1">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <sproject:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir"/>
+    <sproject:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir"/>
+    <sproject:evalprops property="cluster.path.evaluated" value="${cluster.path}"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <ant antfile="nbproject/platform.xml"/>
+    <fail message="Cannot find NetBeans build harness. ${line.separator}Check that nbplatform.${nbplatform.active}.netbeans.dest.dir and nbplatform.${nbplatform.active}.harness.dir are defined. ${line.separator}On a developer machine these are normally defined in ${user.properties.file}=${netbeans.user}/build.properties ${line.separator}but for automated builds you should pass these properties to Ant explicitly. ${line.separator}You may instead download the harness and platform: -Dbootstrap.url=.../tasks.jar -Dautoupdate.catalog.url=.../updates.xml">
+        <condition>
+            <not>
+                <available file="${harness.dir}/suite.xml"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/suite.xml"/>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/language/ide/nbproject/genfiles.properties
----------------------------------------------------------------------
diff --git a/language/ide/nbproject/genfiles.properties b/language/ide/nbproject/genfiles.properties
new file mode 100644
index 0000000..4d0ed1d
--- /dev/null
+++ b/language/ide/nbproject/genfiles.properties
@@ -0,0 +1,52 @@
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+#
+# Copyright 2009-2017 Oracle and/or its affiliates. All rights reserved.
+#
+# Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+# Other names may be trademarks of their respective owners.
+#
+# The contents of this file are subject to the terms of either the GNU
+# General Public License Version 2 only ("GPL") or the Common
+# Development and Distribution License("CDDL") (collectively, the
+# "License"). You may not use this file except in compliance with the
+# License. You can obtain a copy of the License at
+# http://www.netbeans.org/cddl-gplv2.html
+# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+# specific language governing permissions and limitations under the
+# License.  When distributing the software, include this License Header
+# Notice in each file and include the License file at
+# nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the GPL Version 2 section of the License file that
+# accompanied this code. If applicable, add the following below the
+# License Header, with the fields enclosed by brackets [] replaced by
+# your own identifying information:
+# "Portions Copyrighted [year] [name of copyright owner]"
+#
+# Contributor(s):
+#
+# The Original Software is NetBeans. The Initial Developer of the Original
+# Software is Sun Microsystems, Inc. Portions Copyright 2009-2010 Sun
+# Microsystems, Inc. All Rights Reserved.
+#
+# If you wish your version of this file to be governed by only the CDDL
+# or only the GPL Version 2, indicate your decision by adding
+# "[Contributor] elects to include this software in this distribution
+# under the [CDDL or GPL Version 2] license." If you do not indicate a
+# single choice of license, a recipient has the option to distribute
+# your version of this file under either the CDDL, the GPL Version 2 or
+# to extend the choice of license to its licensees as provided above.
+# However, if you add GPL Version 2 code and therefore, elected the GPL
+# Version 2 license, then the option applies only if the new code is
+# made subject to such option by the copyright holder.
+build.xml.data.CRC32=d27fe1de
+build.xml.script.CRC32=466d9285
+build.xml.stylesheet.CRC32=eaf9f76a@2.49
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=c11ee7c3
+nbproject/build-impl.xml.script.CRC32=74ef45bc
+nbproject/build-impl.xml.stylesheet.CRC32=0f381476@2.49
+nbproject/platform.xml.data.CRC32=c11ee7c3
+nbproject/platform.xml.script.CRC32=6dcbd131
+nbproject/platform.xml.stylesheet.CRC32=4e1f53d4@2.70

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/language/ide/nbproject/platform.properties
----------------------------------------------------------------------
diff --git a/language/ide/nbproject/platform.properties b/language/ide/nbproject/platform.properties
new file mode 100644
index 0000000..8cef692
--- /dev/null
+++ b/language/ide/nbproject/platform.properties
@@ -0,0 +1,58 @@
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+#
+# Copyright 2009-2017 Oracle and/or its affiliates. All rights reserved.
+#
+# Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+# Other names may be trademarks of their respective owners.
+#
+# The contents of this file are subject to the terms of either the GNU
+# General Public License Version 2 only ("GPL") or the Common
+# Development and Distribution License("CDDL") (collectively, the
+# "License"). You may not use this file except in compliance with the
+# License. You can obtain a copy of the License at
+# http://www.netbeans.org/cddl-gplv2.html
+# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+# specific language governing permissions and limitations under the
+# License.  When distributing the software, include this License Header
+# Notice in each file and include the License file at
+# nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the GPL Version 2 section of the License file that
+# accompanied this code. If applicable, add the following below the
+# License Header, with the fields enclosed by brackets [] replaced by
+# your own identifying information:
+# "Portions Copyrighted [year] [name of copyright owner]"
+#
+# Contributor(s):
+#
+# The Original Software is NetBeans. The Initial Developer of the Original
+# Software is Sun Microsystems, Inc. Portions Copyright 2009-2010 Sun
+# Microsystems, Inc. All Rights Reserved.
+#
+# If you wish your version of this file to be governed by only the CDDL
+# or only the GPL Version 2, indicate your decision by adding
+# "[Contributor] elects to include this software in this distribution
+# under the [CDDL or GPL Version 2] license." If you do not indicate a
+# single choice of license, a recipient has the option to distribute
+# your version of this file under either the CDDL, the GPL Version 2 or
+# to extend the choice of license to its licensees as provided above.
+# However, if you add GPL Version 2 code and therefore, elected the GPL
+# Version 2 license, then the option applies only if the new code is
+# made subject to such option by the copyright holder.
+cluster.path=\
+    ${nbplatform.active.dir}/apisupport:\
+    ${nbplatform.active.dir}/harness:\
+    ${nbplatform.active.dir}/ide:\
+    ${nbplatform.active.dir}/extide:\
+    ${nbplatform.active.dir}/java:\
+    ${nbplatform.active.dir}/nb:\
+    ${nbplatform.active.dir}/platform:\
+    ${nbplatform.active.dir}/profiler:\
+    ${nbplatform.active.dir}/websvccommon:\
+    ../../remoting/common/build/cluster:\
+    ../../remoting/ide/build/cluster
+extcluster.../../remoting/ide/build/cluster.javadoc=
+extcluster.../../remoting/ide/build/cluster.sources=../../remoting/ide
+extcluster.../remoting/common/build/cluster.javadoc=
+extcluster.../remoting/common/build/cluster.sources=../../remoting/common
+nbplatform.active=default

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-jackpot30/blob/9ed0a377/language/ide/nbproject/platform.xml
----------------------------------------------------------------------
diff --git a/language/ide/nbproject/platform.xml b/language/ide/nbproject/platform.xml
new file mode 100644
index 0000000..1917e28
--- /dev/null
+++ b/language/ide/nbproject/platform.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+Copyright 2009-2017 Oracle and/or its affiliates. All rights reserved.
+
+Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+Other names may be trademarks of their respective owners.
+
+The contents of this file are subject to the terms of either the GNU
+General Public License Version 2 only ("GPL") or the Common
+Development and Distribution License("CDDL") (collectively, the
+"License"). You may not use this file except in compliance with the
+License. You can obtain a copy of the License at
+http://www.netbeans.org/cddl-gplv2.html
+or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+specific language governing permissions and limitations under the
+License.  When distributing the software, include this License Header
+Notice in each file and include the License file at
+nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+particular file as subject to the "Classpath" exception as provided
+by Oracle in the GPL Version 2 section of the License file that
+accompanied this code. If applicable, add the following below the
+License Header, with the fields enclosed by brackets [] replaced by
+your own identifying information:
+"Portions Copyrighted [year] [name of copyright owner]"
+
+Contributor(s):
+
+The Original Software is NetBeans. The Initial Developer of the Original
+Software is Sun Microsystems, Inc. Portions Copyright 2009-2010 Sun
+Microsystems, Inc. All Rights Reserved.
+
+If you wish your version of this file to be governed by only the CDDL
+or only the GPL Version 2, indicate your decision by adding
+"[Contributor] elects to include this software in this distribution
+under the [CDDL or GPL Version 2] license." If you do not indicate a
+single choice of license, a recipient has the option to distribute
+your version of this file under either the CDDL, the GPL Version 2 or
+to extend the choice of license to its licensees as provided above.
+However, if you add GPL Version 2 code and therefore, elected the GPL
+Version 2 license, then the option applies only if the new code is
+made subject to such option by the copyright holder.
+-->
+<project name="platform" default="download" basedir="..">
+    <condition property="download.required">
+        <and>
+            <not>
+                <available file="${harness.dir}/suite.xml"/>
+            </not>
+            <isset property="bootstrap.url"/>
+            <isset property="autoupdate.catalog.url"/>
+        </and>
+    </condition>
+    <target name="download" if="download.required">
+        <mkdir dir="${harness.dir}"/>
+        <pathconvert pathsep="|" property="download.clusters">
+            <mapper type="flatten"/>
+            <path path="${cluster.path}"/>
+        </pathconvert>
+        <property name="disabled.modules" value=""/>
+        <pathconvert property="module.includes" pathsep="">
+            <mapper type="glob" from="${basedir}${file.separator}*" to="(?!^\Q*\E$)"/>
+            <path>
+                <filelist files="${disabled.modules}" dir="."/>
+            </path>
+        </pathconvert>
+        <echo message="Downloading clusters ${download.clusters}"/>
+        <property name="tasks.jar" location="${java.io.tmpdir}/tasks.jar"/>
+        <get src="${bootstrap.url}" dest="${tasks.jar}" usetimestamp="true" verbose="true"/>
+        <taskdef name="autoupdate" classname="org.netbeans.nbbuild.AutoUpdate" classpath="${tasks.jar}"/>
+        <autoupdate installdir="${nbplatform.active.dir}" updatecenter="${autoupdate.catalog.url}">
+            <modules includes="${module.includes}.*" clusters="${download.clusters}"/>
+            <modules includes="org[.]netbeans[.]modules[.]apisupport[.]harness" clusters="harness"/>
+        </autoupdate>
+    </target>
+</project>