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

[17/24] incubator-netbeans-html4j git commit: [INFRA-15006] Initial donation of HTML/Java NetBeans API. Equivalent to the content of html4j-donation-review.zip donated as part of ApacheNetBeansDonation1.zip with SHA256 being 7f2ca0f61953a190613c9a0fbcc1b

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot/src/test/java/org/netbeans/html/boot/impl/JsMethods.java
----------------------------------------------------------------------
diff --git a/boot/src/test/java/org/netbeans/html/boot/impl/JsMethods.java b/boot/src/test/java/org/netbeans/html/boot/impl/JsMethods.java
new file mode 100644
index 0000000..e680bdf
--- /dev/null
+++ b/boot/src/test/java/org/netbeans/html/boot/impl/JsMethods.java
@@ -0,0 +1,157 @@
+/**
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013-2014 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 Oracle. Portions Copyright 2013-2016 Oracle. 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.
+ */
+package org.netbeans.html.boot.impl;
+
+import java.util.Map;
+import net.java.html.js.JavaScriptBody;
+import net.java.html.js.JavaScriptResource;
+
+
+/**
+ *
+ * @author Jaroslav Tulach
+ */
+@JavaScriptResource("jsmethods.js")
+public class JsMethods {
+    private java.lang.Object value;
+    
+    @JavaScriptBody(args = {}, body = "return 42;")
+    public static java.lang.Object fortyTwo() {
+        return -42;
+    }
+    
+    @JavaScriptBody(args = {"x", "y" }, body = "return x + y;")
+    public static native int plus(int x, int y);
+    
+    @JavaScriptBody(args = {"x"}, body = "return x;")
+    public static native int plus(int x);
+    
+    @JavaScriptBody(args = {}, body = "return this;")
+    public static native java.lang.Object staticThis();
+    
+    @JavaScriptBody(args = {}, body = "return this;")
+    public native java.lang.Object getThis();
+    @JavaScriptBody(args = {"x"}, body = "return x;")
+    public native int plusInst(int x);
+    
+    @JavaScriptBody(args = {}, body = "return true;")
+    public static boolean truth() {
+        return false;
+    }
+    
+    @JavaScriptBody(args = { "r" }, javacall=true, body = "r.@java.lang.Runnable::run()();")
+    public static native void callback(Runnable r);
+    
+    @JavaScriptBody(args = { "at", "arr" }, javacall = true, body =
+          "var a = 0;\n"
+        + "for (var i = 0; i < arr.length; i++) {\n"
+        + "  a = at.@org.netbeans.html.boot.impl.Arithm::sumTwo(II)(a, arr[i]);\n"
+        + "}\n"
+        + "return a;"
+    )
+    private static native int sumArr(Arithm at, int... arr);
+    
+    public static int sumArr(int... arr) {
+        return sumArr(new Arithm(), arr);
+    }
+    
+    @JavaScriptBody(args = { "x", "y" }, body = "return mul(x, y);")
+    public static native int useExternalMul(int x, int y);
+    
+    @JavaScriptBody(args = { "m" }, javacall = true, body = "return m.@org.netbeans.html.boot.impl.JsMethods::getThis()();")
+    public static native JsMethods returnYourSelf(JsMethods m);
+    
+    @JavaScriptBody(args = { "x", "y" }, javacall = true, body = "return @org.netbeans.html.boot.impl.JsMethods::useExternalMul(II)(x, y);")
+    public static native int staticCallback(int x, int y);
+
+    @JavaScriptBody(args = { "v" }, javacall = true, body = "return @java.lang.Integer::parseInt(Ljava/lang/String;)(v);")
+    public static native int parseInt(String v);
+    
+    @JavaScriptBody(args = { "v" }, body = "return v.toString();")
+    public static native String fromEnum(Enm v);
+    
+    @JavaScriptBody(args = "arr", body = "return arr;")
+    public static native java.lang.Object[] arr(java.lang.Object[] arr);
+    
+    @JavaScriptBody(args = { "useA", "useB", "a", "b" }, body = "var l = 0;"
+        + "if (useA) l += a;\n"
+        + "if (useB) l += b;\n"
+        + "return l;\n"
+    )
+    public static native long chooseLong(boolean useA, boolean useB, long a, long b);
+    
+    protected void onError(java.lang.Object o) throws Exception {
+        value = o;
+    }
+    
+    java.lang.Object getError() {
+        return value;
+    }
+    
+    @JavaScriptBody(args = { "err" }, javacall = true, body = 
+        "this.@org.netbeans.html.boot.impl.JsMethods::onError(Ljava/lang/Object;)(err);"
+      + "return this.@org.netbeans.html.boot.impl.JsMethods::getError()();"
+    )
+    public native java.lang.Object recordError(java.lang.Object err);
+    
+    @JavaScriptBody(args = { "x", "y" }, body = "return x + y;")
+    public static int plusOrMul(int x, int y) {
+        return x * y;
+    }
+    
+    @JavaScriptBody(args = { "x" }, keepAlive = false, body = "throw 'Do not call me!'")
+    public static native int checkAllowGC(java.lang.Object x);
+
+    @JavaScriptBody(args = { "map", "value" }, javacall = true, body =
+       "map.@java.util.Map::put(Ljava/lang/Object;Ljava/lang/Object;)('key',value);"
+    )
+    public static native void callParamTypes(Map<String,Integer> map, int value);
+
+    @JavaScriptBody(args = { "a", "b" }, body = "return [ a, b ];")
+    public static native double[] both(double a, double b);
+    
+    enum Enm {
+        A, B;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot/src/test/java/org/netbeans/html/boot/impl/KeepAliveTest.java
----------------------------------------------------------------------
diff --git a/boot/src/test/java/org/netbeans/html/boot/impl/KeepAliveTest.java b/boot/src/test/java/org/netbeans/html/boot/impl/KeepAliveTest.java
new file mode 100644
index 0000000..0f8761d
--- /dev/null
+++ b/boot/src/test/java/org/netbeans/html/boot/impl/KeepAliveTest.java
@@ -0,0 +1,113 @@
+/**
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013-2014 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 Oracle. Portions Copyright 2013-2016 Oracle. 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.
+ */
+package org.netbeans.html.boot.impl;
+
+import java.io.Closeable;
+import java.io.Reader;
+import java.net.URL;
+import java.util.Collection;
+import org.netbeans.html.boot.spi.Fn;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class KeepAliveTest implements Fn.Presenter, Fn.KeepAlive, FindResources {
+    private Class<?> jsMethods;
+    @Test public void keepAliveIsSetToFalse() throws Exception {
+        Closeable c = Fn.activate(this);
+        Number ret = (Number)jsMethods.getMethod("checkAllowGC", java.lang.Object.class).invoke(null, this);
+        c.close();
+        assertEquals(ret.intValue(), 0, "keepAlive is set to false");
+    }    
+
+    @Test public void keepAliveIsTheDefault() throws Exception {
+        Closeable c = Fn.activate(this);
+        Number ret = (Number)jsMethods.getMethod("plus", int.class, int.class).invoke(null, 40, 2);
+        c.close();
+        assertEquals(ret.intValue(), 1, "keepAlive returns true when the presenter is invoked");
+    }    
+
+    @BeforeMethod
+    public void initClass() throws ClassNotFoundException {
+        ClassLoader loader = FnUtils.newLoader(this, this, KeepAliveTest.class.getClassLoader().getParent());
+        jsMethods = loader.loadClass(JsMethods.class.getName());
+    }
+
+    @Override
+    public Fn defineFn(String code, String[] names, final boolean[] keepAlive) {
+        return new Fn(this) {
+            @Override
+            public java.lang.Object invoke(java.lang.Object thiz, java.lang.Object... args) throws Exception {
+                boolean res = true;
+                if (keepAlive != null) {
+                    for (int i = 0; i < keepAlive.length; i++) {
+                        res &= keepAlive[i];
+                    }
+                }
+                return res ? 1 : 0;
+            }
+        };
+    }
+    
+    @Override
+    public Fn defineFn(String code, String... names) {
+        throw new UnsupportedOperationException("Never called!");
+    }
+
+    @Override
+    public void displayPage(URL page, Runnable onPageLoad) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void loadScript(Reader code) throws Exception {
+    }
+
+    @Override
+    public void findResources(String path, Collection<? super URL> results, boolean oneIsEnough) {
+        URL u = ClassLoader.getSystemClassLoader().getResource(path);
+        if (u != null) {
+            results.add(u);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot/src/test/java/org/netbeans/html/boot/impl/Object.java
----------------------------------------------------------------------
diff --git a/boot/src/test/java/org/netbeans/html/boot/impl/Object.java b/boot/src/test/java/org/netbeans/html/boot/impl/Object.java
new file mode 100644
index 0000000..8c23265
--- /dev/null
+++ b/boot/src/test/java/org/netbeans/html/boot/impl/Object.java
@@ -0,0 +1,49 @@
+/**
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013-2014 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 Oracle. Portions Copyright 2013-2016 Oracle. 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.
+ */
+package org.netbeans.html.boot.impl;
+
+/** Fake class to cause confusion in the generated code and force it
+ * to use fully qualified names
+ */
+final class Object {
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot/src/test/resources/org/netbeans/html/boot/impl/empty.js
----------------------------------------------------------------------
diff --git a/boot/src/test/resources/org/netbeans/html/boot/impl/empty.js b/boot/src/test/resources/org/netbeans/html/boot/impl/empty.js
new file mode 100644
index 0000000..2ecbb58
--- /dev/null
+++ b/boot/src/test/resources/org/netbeans/html/boot/impl/empty.js
@@ -0,0 +1,42 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013-2014 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 Oracle. Portions Copyright 2013-2016 Oracle. 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.
+ */

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot/src/test/resources/org/netbeans/html/boot/impl/jsmethods.js
----------------------------------------------------------------------
diff --git a/boot/src/test/resources/org/netbeans/html/boot/impl/jsmethods.js b/boot/src/test/resources/org/netbeans/html/boot/impl/jsmethods.js
new file mode 100644
index 0000000..f88184b
--- /dev/null
+++ b/boot/src/test/resources/org/netbeans/html/boot/impl/jsmethods.js
@@ -0,0 +1,43 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013-2014 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 Oracle. Portions Copyright 2013-2016 Oracle. 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.
+ */
+function mul(x, y) { return x * y; }

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/context/pom.xml
----------------------------------------------------------------------
diff --git a/context/pom.xml b/context/pom.xml
new file mode 100644
index 0000000..c127c48
--- /dev/null
+++ b/context/pom.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+    Copyright 2013-2016 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 Oracle. Portions Copyright 2013-2016 Oracle. 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 xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.netbeans.html</groupId>
+    <artifactId>pom</artifactId>
+    <version>2.0-SNAPSHOT</version>
+  </parent>
+  <groupId>org.netbeans.html</groupId>
+  <artifactId>net.java.html</artifactId>
+  <version>2.0-SNAPSHOT</version>
+  <packaging>bundle</packaging>
+  <name>HTML Context</name>
+  <url>http://maven.apache.org</url>
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <publicPackages>net.java.html,org.netbeans.html.context.spi</publicPackages>
+  </properties>
+  <build>
+      <plugins>
+          <plugin>
+              <groupId>org.apache.felix</groupId>
+              <artifactId>maven-bundle-plugin</artifactId>
+              <configuration>
+                  <instructions>
+                      <Eclipse-BuddyPolicy>dependent</Eclipse-BuddyPolicy>
+                      <Require-Capability>osgi.extender;resolution:=optional;filter:="(osgi.extender=osgi.serviceloader.processor)",osgi.serviceloader;filter:="(osgi.serviceloader=org.netbeans.html.context.spi.Contexts$Provider)";cardinality:=multiple;resolution:=optional</Require-Capability>
+                  </instructions>
+              </configuration>
+          </plugin>
+      </plugins>
+  </build>
+  <dependencies>
+    <dependency>
+      <groupId>org.testng</groupId>
+      <artifactId>testng</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.netbeans.api</groupId>
+      <artifactId>org-openide-util-lookup</artifactId>
+      <scope>test</scope>
+      <type>jar</type>
+    </dependency>
+  </dependencies>
+    <description>Representation of an HTML page context a Java program operates in.</description>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/context/src/main/java/net/java/html/BrwsrCtx.java
----------------------------------------------------------------------
diff --git a/context/src/main/java/net/java/html/BrwsrCtx.java b/context/src/main/java/net/java/html/BrwsrCtx.java
new file mode 100644
index 0000000..59a4a21
--- /dev/null
+++ b/context/src/main/java/net/java/html/BrwsrCtx.java
@@ -0,0 +1,192 @@
+/**
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013-2014 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 Oracle. Portions Copyright 2013-2016 Oracle. 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.
+ */
+package net.java.html;
+
+import java.util.concurrent.Executor;
+import java.util.logging.Logger;
+import org.netbeans.html.context.impl.CtxAccssr;
+import org.netbeans.html.context.impl.CtxImpl;
+import org.netbeans.html.context.spi.Contexts;
+import org.netbeans.html.context.spi.Contexts.Id;
+
+/** Represents context where the <code>net.java.html.json.Model</code>
+ * and other objects
+ * operate in. The context is usually a particular HTML page in a browser.
+ * The context is also associated with the actual HTML technology
+ * in the HTML page - there is likely to be different context for 
+ * <a href="http://knockoutjs.com">knockout.js</a> and different one
+ * for <a href="http://angularjs.org">angular</a>. Since version 1.1
+ * the content of contexts can be selected by registering
+ * implementations under specific
+ * {@link Id technology identifiers} and requesting them during 
+ * {@link Contexts#newBuilder(java.lang.Object...) construction} of the
+ * context.
+ *
+ * @author Jaroslav Tulach
+ */
+public final class BrwsrCtx implements Executor {
+    private static final Logger LOG = Logger.getLogger(BrwsrCtx.class.getName());
+    private final CtxImpl impl;
+    private BrwsrCtx(CtxImpl impl) {
+        this.impl = impl;
+    }
+    /** currently {@link #execute(java.lang.Runnable) activated context} */
+    private static final ThreadLocal<BrwsrCtx> CURRENT = new ThreadLocal<BrwsrCtx>();
+    static {
+        new CtxAccssr() {
+            @Override
+            protected BrwsrCtx newContext(CtxImpl impl) {
+                return new BrwsrCtx(impl);
+            }
+
+            @Override
+            protected CtxImpl find(BrwsrCtx context) {
+                return context.impl;
+            }
+        };
+    }
+    /** Dummy context without binding to any real browser or technology. 
+     * Useful for simple unit testing of behavior of various business logic
+     * code.
+     */
+    public static final BrwsrCtx EMPTY = Contexts.newBuilder().build();
+    
+    
+    /** Seeks for the default context that is associated with the requesting
+     * class. If no suitable context is found, a warning message is
+     * printed and {@link #EMPTY} context is returned. One can enter 
+     * a context by calling {@link #execute(java.lang.Runnable)}.
+     * 
+     * @param requestor the class that makes the request
+     * @return appropriate context for the request
+     */
+    public static BrwsrCtx findDefault(Class<?> requestor) {
+        if (requestor == CtxAccssr.class) {
+            return EMPTY;
+        }
+        BrwsrCtx brwsr = CURRENT.get();
+        if (brwsr != null) {
+            return brwsr;
+        }
+        
+        org.netbeans.html.context.spi.Contexts.Builder cb = Contexts.newBuilder();
+        boolean found = Contexts.fillInByProviders(requestor, cb);
+        if (!found) {
+            LOG.config("No browser context found. Returning empty technology!");
+            return EMPTY;
+        }
+        return cb.build();
+    }
+
+    /** 
+     * <p>
+     * Runs provided code in the context of this {@link BrwsrCtx}.
+     * If there is an {@link Executor} {@link Contexts#find(net.java.html.BrwsrCtx, java.lang.Class)  registered in the context}
+     * it is used to perform the given code. While the code <code>exec</code>
+     * is running the value of {@link #findDefault(java.lang.Class)} returns
+     * <code>this</code>. If the executor supports a single thread execution
+     * policy, it may execute the runnable later (in such case this method
+     * returns immediately). If the call to this method is done on the right
+     * thread, the runnable should be executed synchronously.
+     * </p>
+     * <p>
+     * <b>Example Using a Timer</b>
+     * </p>
+<pre>
+<b>public final class</b> Periodicaly <b>extends</b> {@link java.util.TimerTask} {
+    <b>private final</b> {@link BrwsrCtx} ctx;
+
+    <b>private</b> Periodicaly(BrwsrCtx ctx) {
+        // remember the browser context and use it later
+        this.ctx = ctx;
+    }
+    
+    <b>public void</b> run() {
+        // arrives on wrong thread, needs to be re-scheduled
+        ctx.{@link #execute(java.lang.Runnable) execute}(new Runnable() {
+            <b>public void</b> run() {
+                // code that needs to run in a browser environment
+            }
+        });
+    }
+
+    // called when your page is ready
+    <b>public static void</b> onPageLoad(String... args) <b>throws</b> Exception {
+        // the context at the time of page initialization
+        BrwsrCtx initialCtx = BrwsrCtx.findDefault(Periodicaly.<b>class</b>);
+        // the task that is associated with context 
+        Periodicaly task = new Periodicaly(initialCtx);
+        // creates a timer
+        {@link java.util.Timer} t = new {@link java.util.Timer}("Move the box");
+        // run the task every 100ms
+        t.{@link java.util.Timer#scheduleAtFixedRate(java.util.TimerTask, long, long) scheduleAtFixedRate}(task, 0, 100);
+    }
+}
+</pre>    
+     * 
+     * @param exec the code to execute
+     * @since 0.7.6
+     */
+    @Override public final void execute(final Runnable exec) {
+        class Wrap implements Runnable {
+            @Override
+            public void run() {
+                BrwsrCtx prev = CURRENT.get();
+                try {
+                    CURRENT.set(BrwsrCtx.this);
+                    exec.run();
+                } finally {
+                    CURRENT.set(prev);
+                }
+            }
+        }
+        Wrap w = new Wrap();
+        Executor runIn = Contexts.find(this, Executor.class);
+        if (runIn == null) {
+            w.run();
+        } else {
+            runIn.execute(w);
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/context/src/main/java/net/java/html/package.html
----------------------------------------------------------------------
diff --git a/context/src/main/java/net/java/html/package.html b/context/src/main/java/net/java/html/package.html
new file mode 100644
index 0000000..007b8a0
--- /dev/null
+++ b/context/src/main/java/net/java/html/package.html
@@ -0,0 +1,49 @@
+<!--
+
+    DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+    Copyright 2013-2014 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 Oracle. Portions Copyright 2013-2016 Oracle. 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.
+
+-->
+<body>
+    <p>
+        Representation of the {@link net.java.html.BrwsrCtx browser context}.
+    </p>
+</body>

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/context/src/main/java/org/netbeans/html/context/impl/CtxAccssr.java
----------------------------------------------------------------------
diff --git a/context/src/main/java/org/netbeans/html/context/impl/CtxAccssr.java b/context/src/main/java/org/netbeans/html/context/impl/CtxAccssr.java
new file mode 100644
index 0000000..641ca7a
--- /dev/null
+++ b/context/src/main/java/org/netbeans/html/context/impl/CtxAccssr.java
@@ -0,0 +1,71 @@
+/**
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013-2014 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 Oracle. Portions Copyright 2013-2016 Oracle. 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.
+ */
+package org.netbeans.html.context.impl;
+
+import net.java.html.BrwsrCtx;
+import org.netbeans.html.context.spi.Contexts.Builder;
+
+/** Internal communication between API (e.g. {@link BrwsrCtx}), SPI
+ * (e.g. {@link Builder}) and the implementation package.
+ *
+ * @author Jaroslav Tulach
+ */
+public abstract class CtxAccssr {
+    private static CtxAccssr DEFAULT;
+    static {
+        // run initializers
+        BrwsrCtx.findDefault(CtxAccssr.class);
+    }
+    
+    protected CtxAccssr() {
+        if (DEFAULT != null) throw new IllegalStateException();
+        DEFAULT = this;
+    }
+    
+    protected abstract BrwsrCtx newContext(CtxImpl impl);
+    protected abstract CtxImpl find(BrwsrCtx context);
+    
+    static CtxAccssr getDefault() {
+        return DEFAULT;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/context/src/main/java/org/netbeans/html/context/impl/CtxImpl.java
----------------------------------------------------------------------
diff --git a/context/src/main/java/org/netbeans/html/context/impl/CtxImpl.java b/context/src/main/java/org/netbeans/html/context/impl/CtxImpl.java
new file mode 100644
index 0000000..a5c64b6
--- /dev/null
+++ b/context/src/main/java/org/netbeans/html/context/impl/CtxImpl.java
@@ -0,0 +1,139 @@
+/**
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013-2014 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 Oracle. Portions Copyright 2013-2016 Oracle. 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.
+ */
+package org.netbeans.html.context.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import net.java.html.BrwsrCtx;
+import org.netbeans.html.context.spi.Contexts;
+
+/** Implementation detail. Holds list of technologies for particular
+ * {@link BrwsrCtx}.
+ *
+ * @author Jaroslav Tulach
+ */
+public final class CtxImpl {
+    private final List<Bind<?>> techs;
+    private final Object[] context;
+    
+    public CtxImpl(Object[] context) {
+        this(context, new ArrayList<Bind<?>>());
+    }
+    
+    private CtxImpl(Object[] context, List<Bind<?>> techs) {
+        this.techs = techs;
+        this.context = context;
+    }
+    
+    public static <Tech> Tech find(BrwsrCtx context, Class<Tech> technology) {
+        CtxImpl impl = CtxAccssr.getDefault().find(context);
+        for (Bind<?> bind : impl.techs) {
+            if (technology == bind.clazz) {
+                return technology.cast(bind.impl);
+            }
+        }
+        return null;
+    }
+
+    public BrwsrCtx build() {
+        Collections.sort(techs, new BindCompare());
+        final List<Bind<?>> arr = Collections.unmodifiableList(techs);
+        CtxImpl impl = new CtxImpl(context, arr);
+        BrwsrCtx ctx = CtxAccssr.getDefault().newContext(impl);
+        return ctx;
+    }
+
+    public <Tech> void register(Class<Tech> type, Tech impl, int priority) {
+        techs.add(new Bind<Tech>(type, impl, priority));
+    }
+    
+    private static final class Bind<Tech> {
+        private final Class<Tech> clazz;
+        private final Tech impl;
+        private final int priority;
+
+        public Bind(Class<Tech> clazz, Tech impl, int priority) {
+            this.clazz = clazz;
+            this.impl = impl;
+            this.priority = priority;
+        }
+
+        @Override
+        public String toString() {
+            return "Bind{" + "clazz=" + clazz + "@" + clazz.getClassLoader() + ", impl=" + impl + ", priority=" + priority + '}';
+        }
+    }
+    
+    private final class BindCompare implements Comparator<Bind<?>> {
+        boolean isPrefered(Bind<?> b) {
+            final Class<?> implClazz = b.impl.getClass();
+            Contexts.Id id = implClazz.getAnnotation(Contexts.Id.class);
+            if (id == null) {
+                return false;
+            }
+            for (String v : id.value()) {
+                for (Object c : context) {
+                    if (v.equals(c)) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+        
+        @Override
+        public int compare(Bind<?> o1, Bind<?> o2) {
+            boolean p1 = isPrefered(o1);
+            boolean p2 = isPrefered(o2);
+            if (p1 != p2) {
+                return p1 ? -1 : 1;
+            }
+            if (o1.priority != o2.priority) {
+                return o1.priority - o2.priority;
+            }
+            return o1.clazz.getName().compareTo(o2.clazz.getName());
+        }
+    } // end of BindCompare
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/context/src/main/java/org/netbeans/html/context/spi/Contexts.java
----------------------------------------------------------------------
diff --git a/context/src/main/java/org/netbeans/html/context/spi/Contexts.java b/context/src/main/java/org/netbeans/html/context/spi/Contexts.java
new file mode 100644
index 0000000..5d45e1e
--- /dev/null
+++ b/context/src/main/java/org/netbeans/html/context/spi/Contexts.java
@@ -0,0 +1,244 @@
+/**
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013-2014 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 Oracle. Portions Copyright 2013-2016 Oracle. 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.
+ */
+package org.netbeans.html.context.spi;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.HashSet;
+import java.util.ServiceLoader;
+import java.util.Set;
+import net.java.html.BrwsrCtx;
+import org.netbeans.html.context.impl.CtxImpl;
+
+/** Factory class to assign various technologies 
+ * to a {@link BrwsrCtx browser context}. Start with {@link #newBuilder()}
+ * and then assign technologies with {@link Builder#register(java.lang.Class, java.lang.Object, int)}
+ * method.
+ *
+ * @author Jaroslav Tulach
+ */
+public final class Contexts {
+    private Contexts() {
+    }
+
+    /** Creates new, empty builder for creation of {@link BrwsrCtx}. At the
+     * end call the {@link Builder#build()} method to generate the context.
+     * 
+     * @param context instances of various classes or names of {@link Id technologies} 
+     *    to be preferred and used in the built {@link BrwsrCtx context}.
+     * @return new instance of the builder
+     * @since 1.1
+     */
+    public static Builder newBuilder(Object... context) {
+        return new Builder(context);
+    }
+    /** Creates new, empty builder for creation of {@link BrwsrCtx}. At the
+     * end call the {@link Builder#build()} method to generate the context.
+     * Simply calls {@link #newBuilder(java.lang.Object...) newBuilder(new Object[0])}.
+     * 
+     * @return new instance of the builder
+     */
+    public static Builder newBuilder() {
+        return newBuilder(new Object[0]);
+    }
+
+    /** Seeks for the specified technology in the provided context.
+     * 
+     * @param <Tech> type of the technology
+     * @param context the context to seek in 
+     *    (previously filled with ({@link Builder#register(java.lang.Class, java.lang.Object, int)})
+     * @param technology class that identifies the technology
+     * @return the technology in the context or <code>null</code>
+     */
+    public static <Tech> Tech find(BrwsrCtx context, Class<Tech> technology) {
+        return CtxImpl.find(context, technology);
+    }
+
+    /** Seeks {@link ServiceLoader} for all registered instances of
+     * {@link Provider} and asks them to {@link Provider#fillContext(org.netbeans.html.context.spi.Contexts.Builder, java.lang.Class) fill
+     * the builder}.
+     * 
+     * @param requestor the application class for which to find the context
+     * @param cb the context builder to register technologies into
+     * @return <code>true</code>, if some instances of the provider were
+     *    found, <code>false</code> otherwise
+     * @since 0.7.6
+     */
+    public static boolean fillInByProviders(Class<?> requestor, Contexts.Builder cb) {
+        boolean found = false;
+        ClassLoader l;
+        try {
+            l = requestor.getClassLoader();
+        } catch (SecurityException ex) {
+            l = null;
+        }
+        Set<Class<?>> classes = new HashSet<Class<?>>();
+        for (Provider cp : ServiceLoader.load(Provider.class, l)) {
+            if (!classes.add(cp.getClass())) {
+                continue;
+            }
+            cp.fillContext(cb, requestor);
+            found = true;
+        }
+        try {
+            for (Provider cp : ServiceLoader.load(Provider.class, Provider.class.getClassLoader())) {
+                if (!classes.add(cp.getClass())) {
+                    continue;
+                }
+                cp.fillContext(cb, requestor);
+                found = true;
+            }
+        } catch (SecurityException ex) {
+            if (!found) {
+                throw ex;
+            }
+        }
+        if (!found) {
+            for (Provider cp : ServiceLoader.load(Provider.class)) {
+                if (!classes.add(cp.getClass())) {
+                    continue;
+                }
+                cp.fillContext(cb, requestor);
+                found = true;
+            }
+        }
+        return found;
+    }
+    
+    /** Identifies the technologies passed to {@link Builder context builder}
+     * by a name. Each implementation of a technology 
+     * {@link Builder#register(java.lang.Class, java.lang.Object, int) registered into a context}
+     * can be annotated with a name (or multiple names). Such implementation
+     * will later be 
+     * {@link Contexts#fillInByProviders(java.lang.Class, org.netbeans.html.context.spi.Contexts.Builder)  preferred during lookup}
+     * if their name(s) has been requested in when 
+     * {@link Contexts#newBuilder(java.lang.Object...)  creating a context}.
+     * @since 1.1
+     */
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.TYPE)
+    @Documented
+    public @interface Id {
+        /** Identifier(s) for the implementation. 
+         * 
+         * @return one of more identifiers giving this implementation name(s)
+         */
+        public String[] value();
+    }
+
+    /** Implementors of various HTML technologies should
+     * register their implementation via <code>org.openide.util.lookup.ServiceProvider</code>, so
+     * {@link ServiceLoader} can find them, when their JARs are included
+     * on the classpath of the running application.
+     *
+     * @author Jaroslav Tulach
+     */
+    public static interface Provider {
+
+        /** Register into the context if suitable technology is
+         * available for the requesting class.
+         * The provider should check if its own technology is available in current
+         * scope (e.g. proper JDK, proper browser, etc.). The provider
+         * can also find the right context depending on requestor's classloader, etc.
+         * <p>
+         * Providers should use {@link Builder} to enrich appropriately
+         * the context.
+         *
+         * @param context the context builder to fill with technologies
+         * @param requestor the application class requesting access the the HTML page
+         * @see BrwsrCtx#findDefault(java.lang.Class)
+         */
+        void fillContext(Builder context, Class<?> requestor);
+    }
+
+    /** Support for providers of new {@link BrwsrCtx}. Providers of different
+     * technologies should be of particular interest in this class. End users
+     * designing their application with existing technologies should rather
+     * point their attention to {@link BrwsrCtx} and co.
+     *
+     * @author Jaroslav Tulach
+     */
+    public static final class Builder {
+        private final CtxImpl impl;
+
+        public Builder(Object[] context) {
+            this.impl = new CtxImpl(context);
+        }
+        
+        /** Registers new technology into the context. Each technology is
+         * exactly identified by its implementation class and can be associated
+         * with (positive) priority. In case of presence of multiple technologies
+         * with the same class, the one with higher lower priority takes precedence.
+         * @param <Tech> type of technology to register
+         * @param type the real class of the technology type
+         * @param impl an instance of the technology class
+         * @param position the lower position (but higher than zero), the more important implementation
+         *    which will be consulted sooner when seeking for a {@link Contexts#find(net.java.html.BrwsrCtx, java.lang.Class)}
+         *    an implementation
+         * @return this builder
+         * @throws IllegalStateException if the position isn't higher than <code>0</code>
+         */
+        public <Tech> Builder register(Class<Tech> type, Tech impl, int position) {
+            if (impl == null) {
+                return this;
+            }
+            if (position <= 0) {
+                throw new IllegalStateException();
+            }
+            this.impl.register(type, impl, position);
+            return this;
+        }
+
+        /** Generates context based on values previously inserted into
+         * this builder.
+         *
+         * @return new, immutable instance of {@link BrwsrCtx}
+         */
+        public BrwsrCtx build() {
+            return impl.build();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/context/src/main/java/org/netbeans/html/context/spi/package.html
----------------------------------------------------------------------
diff --git a/context/src/main/java/org/netbeans/html/context/spi/package.html b/context/src/main/java/org/netbeans/html/context/spi/package.html
new file mode 100644
index 0000000..ea999bb
--- /dev/null
+++ b/context/src/main/java/org/netbeans/html/context/spi/package.html
@@ -0,0 +1,50 @@
+<!--
+
+    DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+    Copyright 2013-2014 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 Oracle. Portions Copyright 2013-2016 Oracle. 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.
+
+-->
+<body>
+    <p>
+        Service provider classes to build {@link net.java.html.BrwsrCtx}
+        instances.
+    </p>
+</body>

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/context/src/test/java/net/java/html/BrwsrCtxTest.java
----------------------------------------------------------------------
diff --git a/context/src/test/java/net/java/html/BrwsrCtxTest.java b/context/src/test/java/net/java/html/BrwsrCtxTest.java
new file mode 100644
index 0000000..9253bec
--- /dev/null
+++ b/context/src/test/java/net/java/html/BrwsrCtxTest.java
@@ -0,0 +1,120 @@
+/**
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013-2014 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 Oracle. Portions Copyright 2013-2016 Oracle. 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.
+ */
+package net.java.html;
+
+import org.netbeans.html.context.spi.Contexts;
+import static org.testng.Assert.*;
+import org.testng.annotations.Test;
+
+/**
+ *
+ * @author Jaroslav Tulach
+ */
+public class BrwsrCtxTest {
+    
+    public BrwsrCtxTest() {
+    }
+
+
+    @org.testng.annotations.Test
+    public void canSetAssociateCtx() {
+        final BrwsrCtx ctx = Contexts.newBuilder().build();
+        final boolean[] arr = { false };
+        
+        assertNotSame(BrwsrCtx.findDefault(BrwsrCtxTest.class), ctx, "Not associated yet");
+        ctx.execute(new Runnable() {
+            @Override public void run() {
+                assertSame(BrwsrCtx.findDefault(BrwsrCtxTest.class), ctx, "Once same");
+                assertSame(BrwsrCtx.findDefault(BrwsrCtxTest.class), ctx, "2nd same");
+                arr[0] = true;
+            }
+        });
+        assertNotSame(BrwsrCtx.findDefault(BrwsrCtxTest.class), ctx, "Not associated again");
+        assertTrue(arr[0], "Runnable was executed");
+    }
+    
+    
+    @Test public void defaultOrderOfRegistrations() {
+        BrwsrCtx ctx = registerRs(Contexts.newBuilder());
+        Class<? extends Runnable> clazz = Contexts.find(ctx, Runnable.class).getClass();
+        assertEquals(clazz, R1.class, "R1 is registered at value 10");
+    }
+    
+    @Test public void preferOne() {
+        BrwsrCtx ctx = registerRs(Contexts.newBuilder("one"));
+        Class<? extends Runnable> clazz = Contexts.find(ctx, Runnable.class).getClass();
+        assertEquals(clazz, R1.class, "R1 is registered at value 10");
+    }
+
+    @Test public void preferTwo() {
+        BrwsrCtx ctx = registerRs(Contexts.newBuilder("two"));
+        Class<? extends Runnable> clazz = Contexts.find(ctx, Runnable.class).getClass();
+        assertEquals(clazz, R2.class, "R2 is preferred");
+    }
+
+    @Test public void preferBoth() {
+        BrwsrCtx ctx = registerRs(Contexts.newBuilder("one", "two"));
+        Class<? extends Runnable> clazz = Contexts.find(ctx, Runnable.class).getClass();
+        assertEquals(clazz, R1.class, "R1 is registered at value 10");
+    }
+    
+    private static BrwsrCtx registerRs(Contexts.Builder b) {
+        b.register(Runnable.class, new R1(), 10);
+        b.register(Runnable.class, new R2(), 20);
+        return b.build();
+    }
+
+    @Contexts.Id("one")
+    static final class R1 implements Runnable {
+        @Override
+        public void run() {
+        }
+    }
+    @Contexts.Id("two")
+    static final class R2 implements Runnable {
+        @Override
+        public void run() {
+        }
+    }
+    
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/context/src/test/java/org/netbeans/html/context/spi/ContextsTest.java
----------------------------------------------------------------------
diff --git a/context/src/test/java/org/netbeans/html/context/spi/ContextsTest.java b/context/src/test/java/org/netbeans/html/context/spi/ContextsTest.java
new file mode 100644
index 0000000..e579a37
--- /dev/null
+++ b/context/src/test/java/org/netbeans/html/context/spi/ContextsTest.java
@@ -0,0 +1,115 @@
+/**
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013-2014 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 Oracle. Portions Copyright 2013-2016 Oracle. 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.
+ */
+package org.netbeans.html.context.spi;
+
+import javax.xml.ws.ServiceMode;
+import net.java.html.BrwsrCtx;
+import org.openide.util.lookup.ServiceProvider;
+import static org.testng.Assert.*;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+/**
+ *
+ * @author Jaroslav Tulach
+ */
+public class ContextsTest {
+    
+    public ContextsTest() {
+    }
+
+    @Test public void twoInstancesButOneCall() {
+        class Two implements Runnable {
+            int cnt;
+
+            @Override
+            public void run() {
+                cnt++;
+            }
+        }
+        class One implements Runnable {
+            int cnt;
+
+            @Override
+            public void run() {
+                cnt++;
+            }
+        }
+        
+        One one = new One();
+        Two two = new Two();
+        
+        CountingProvider.onNew = two;
+        CountingProvider.onFill = one;
+        
+        Contexts.Builder b = Contexts.newBuilder();
+        Contexts.fillInByProviders(ContextsTest.class, b);
+
+        assertEquals(two.cnt, 2, "Two instances created");
+        assertEquals(one.cnt, 1, "But only one call to fill");
+    }
+
+    @ServiceProvider(service = Contexts.Provider.class)
+    public static final class CountingProvider implements Contexts.Provider {
+        static Runnable onNew;
+        static Runnable onFill;
+
+        public CountingProvider() {
+            if (onNew != null) {
+                onNew.run();
+            }
+        }
+        
+        @Override
+        public void fillContext(Contexts.Builder context, Class<?> requestor) {
+            if (onFill != null) {
+                onFill.run();
+                context.register(Runnable.class, onFill, 1);
+            }
+        }
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/equinox-agentclass-hook/pom.xml
----------------------------------------------------------------------
diff --git a/equinox-agentclass-hook/pom.xml b/equinox-agentclass-hook/pom.xml
new file mode 100644
index 0000000..436c7d5
--- /dev/null
+++ b/equinox-agentclass-hook/pom.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+    Copyright 2013-2016 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 Oracle. Portions Copyright 2013-2016 Oracle. 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 xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.netbeans.html</groupId>
+        <artifactId>pom</artifactId>
+        <version>2.0-SNAPSHOT</version>
+    </parent>
+    <name>AgentClass Hook for Equinox</name>
+    <artifactId>equinox-agentclass-hook</artifactId>
+    <packaging>bundle</packaging>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Fragment-Host>org.eclipse.osgi;bundle-version="[3.8.0,4.0)"</Fragment-Host>
+                        <Import-Package />
+                    </instructions>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>2.3.2</version>
+                <configuration>
+                    <source>1.5</source>
+                    <target>1.5</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <dependencies>
+        <dependency>
+            <groupId>org.eclipse</groupId>
+            <artifactId>org.eclipse.osgi</artifactId>
+            <version>3.8.0.v20120529-1548</version>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/equinox-agentclass-hook/src/main/java/org/netbeans/html/equinox/agentclass/AgentHook.java
----------------------------------------------------------------------
diff --git a/equinox-agentclass-hook/src/main/java/org/netbeans/html/equinox/agentclass/AgentHook.java b/equinox-agentclass-hook/src/main/java/org/netbeans/html/equinox/agentclass/AgentHook.java
new file mode 100644
index 0000000..c087d87
--- /dev/null
+++ b/equinox-agentclass-hook/src/main/java/org/netbeans/html/equinox/agentclass/AgentHook.java
@@ -0,0 +1,164 @@
+/**
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013-2014 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 Oracle. Portions Copyright 2013-2016 Oracle. 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.
+ */
+package org.netbeans.html.equinox.agentclass;
+
+import java.lang.instrument.IllegalClassFormatException;
+import java.security.ProtectionDomain;
+import java.util.ArrayList;
+import java.util.logging.Logger;
+
+import org.eclipse.osgi.baseadaptor.BaseData;
+import org.eclipse.osgi.baseadaptor.HookConfigurator;
+import org.eclipse.osgi.baseadaptor.HookRegistry;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry;
+import org.eclipse.osgi.baseadaptor.hooks.ClassLoadingHook;
+import org.eclipse.osgi.baseadaptor.loader.BaseClassLoader;
+import org.eclipse.osgi.baseadaptor.loader.ClasspathEntry;
+import org.eclipse.osgi.baseadaptor.loader.ClasspathManager;
+import org.eclipse.osgi.framework.adaptor.BundleProtectionDomain;
+import org.eclipse.osgi.framework.adaptor.BundleWatcher;
+import org.eclipse.osgi.framework.adaptor.ClassLoaderDelegate;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.wiring.BundleWiring;
+
+public class AgentHook implements HookConfigurator, BundleWatcher, ClassLoadingHook {
+    private static final Logger LOG = Logger.getLogger(AgentHook.class.getName());
+	private boolean all;
+	
+	@Override
+	public void addHooks(HookRegistry hookRegistry) {
+		LOG.info("Agent hook for Equinox initialized!");
+		hookRegistry.addWatcher(this);
+		hookRegistry.addClassLoadingHook(this);
+	}
+
+	@Override
+	public void watchBundle(Bundle bundle, int type) {
+		if (!all) {
+			BundleContext c = bundle.getBundleContext();
+			if (c != null) {
+				Bundle[] arr = bundle.getBundleContext().getBundles();
+				for (Bundle b : arr) {
+					agentBundle(b);
+				}
+				all = true;
+			}
+		}
+		if (type == BundleWatcher.END_ACTIVATION) {
+			agentBundle(bundle);
+		}
+	}
+
+	private void agentBundle(Bundle bundle) {
+		String agentClass = (String)bundle.getHeaders().get("Agent-Class");
+		if (agentClass != null) {
+			Class<?> agent;
+			try {
+				agent = bundle.loadClass(agentClass);
+				NbInstrumentation.registerAgent(agent.getClassLoader(), agent.getName());
+			} catch (ClassNotFoundException e) {
+				throw new IllegalStateException(e);
+			}
+		}
+	}
+
+	@Override
+	public byte[] processClass(String name, byte[] bytes,
+			ClasspathEntry ce, BundleEntry entry,
+			ClasspathManager manager) {
+        final BaseData bd = ce.getBaseData();
+        if (bd == null) {
+            return bytes;
+        }
+        final Bundle b = bd.getBundle();
+        if (b == null) {
+            return bytes;
+        }
+        BundleWiring w = (BundleWiring)b.adapt(BundleWiring.class);
+        if (w == null) {
+            return bytes;
+        }
+        ClassLoader loader = w.getClassLoader();
+		try {
+			return NbInstrumentation.patchByteCode(loader, name, ce.getDomain(), bytes);
+		} catch (IllegalClassFormatException e) {
+			return bytes;
+		}
+	}
+
+	@Override
+	public boolean addClassPathEntry(ArrayList cpEntries,
+			String cp, ClasspathManager hostmanager, BaseData sourcedata,
+			ProtectionDomain sourcedomain) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	@Override
+	public String findLibrary(BaseData data, String libName) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public ClassLoader getBundleClassLoaderParent() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public BaseClassLoader createClassLoader(ClassLoader parent,
+			ClassLoaderDelegate delegate, BundleProtectionDomain domain,
+			BaseData data, String[] bundleclasspath) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public void initializedClassLoader(BaseClassLoader baseClassLoader,
+			BaseData data) {
+		// TODO Auto-generated method stub
+		
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/equinox-agentclass-hook/src/main/java/org/netbeans/html/equinox/agentclass/NbInstrumentation.java
----------------------------------------------------------------------
diff --git a/equinox-agentclass-hook/src/main/java/org/netbeans/html/equinox/agentclass/NbInstrumentation.java b/equinox-agentclass-hook/src/main/java/org/netbeans/html/equinox/agentclass/NbInstrumentation.java
new file mode 100644
index 0000000..de0aa63
--- /dev/null
+++ b/equinox-agentclass-hook/src/main/java/org/netbeans/html/equinox/agentclass/NbInstrumentation.java
@@ -0,0 +1,213 @@
+/**
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013-2014 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 Oracle. Portions Copyright 2013-2016 Oracle. 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.
+ */
+package org.netbeans.html.equinox.agentclass;
+
+import java.lang.instrument.ClassDefinition;
+import java.lang.instrument.ClassFileTransformer;
+import java.lang.instrument.IllegalClassFormatException;
+import java.lang.instrument.Instrumentation;
+import java.lang.instrument.UnmodifiableClassException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.ProtectionDomain;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.jar.JarFile;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ * @author Jaroslav Tulach
+ */
+final class NbInstrumentation implements Instrumentation {
+    private static final Logger LOG = Logger.getLogger(NbInstrumentation.class.getName());
+    private static final Object LOCK = new Object();
+    private static volatile Collection<NbInstrumentation> ACTIVE;
+
+    private final List<ClassFileTransformer> transformers = new CopyOnWriteArrayList<ClassFileTransformer>();
+    private static final ThreadLocal<Boolean> IN = new ThreadLocal<Boolean>();
+    
+    static NbInstrumentation registerAgent(ClassLoader l, String agentClassName) {
+        try {
+            return registerImpl(agentClassName, l);
+        } catch (Throwable ex) {
+            LOG.log(Level.WARNING, "Cannot register " + agentClassName, ex);
+            return null;
+        }
+    }
+    static void unregisterAgent(NbInstrumentation instr) {
+        synchronized (LOCK) {
+            if (ACTIVE != null) {
+                Collection<NbInstrumentation> clone = new HashSet<NbInstrumentation>();
+                clone.addAll(ACTIVE);
+                clone.remove(instr);
+                ACTIVE = clone;
+            }
+        }
+    }
+    private static NbInstrumentation registerImpl(String agentClassName, ClassLoader l) throws ClassNotFoundException, IllegalArgumentException, NoSuchMethodException, SecurityException, IllegalAccessException, InvocationTargetException {
+        final NbInstrumentation inst = new NbInstrumentation();
+        synchronized (LOCK) {
+            if (ACTIVE == null) {
+                ACTIVE = new HashSet<NbInstrumentation>();
+            } else {
+                Set<NbInstrumentation> s = new HashSet<NbInstrumentation>();
+                s.addAll(ACTIVE);
+                ACTIVE = s;
+            }
+            ACTIVE.add(inst);
+        }
+        Class<?> agentClass = Class.forName(agentClassName, true, l);
+        try {
+            Method m = agentClass.getMethod("agentmain", String.class, Instrumentation.class); // NOI18N
+            m.invoke(null, "", inst);
+        } catch (NoSuchMethodException ex) {
+            Method m = agentClass.getMethod("agentmain", String.class); // NOI18N
+            m.invoke(null, "");
+        }
+        return inst;
+    }
+    
+    public static byte[] patchByteCode(ClassLoader l, String className, ProtectionDomain pd, byte[] arr) throws IllegalClassFormatException {
+        if (ACTIVE == null) {
+            return arr;
+        }
+        if (Boolean.TRUE.equals(IN.get())) {
+            return arr;
+        }
+        try {
+            IN.set(Boolean.TRUE);
+            for (NbInstrumentation inst : ACTIVE) {
+                for (ClassFileTransformer t : inst.transformers) {
+                    arr = t.transform(l, className, null, pd, arr);
+                }
+            }
+        } finally {
+            IN.set(null);
+        }
+        return arr;
+    }
+    
+    //
+    // Instrumentation methods
+    //
+
+    @Override
+    public void addTransformer(ClassFileTransformer transformer, boolean canRetransform) {
+        transformers.add(transformer);
+    }
+
+    @Override
+    public void addTransformer(ClassFileTransformer transformer) {
+        transformers.add(transformer);
+    }
+
+    @Override
+    public boolean removeTransformer(ClassFileTransformer transformer) {
+        return transformers.remove(transformer);
+    }
+
+    @Override
+    public boolean isRetransformClassesSupported() {
+        return false;
+    }
+
+    @Override
+    public void retransformClasses(Class<?>... classes) throws UnmodifiableClassException {
+        throw new UnmodifiableClassException();
+    }
+
+    @Override
+    public boolean isRedefineClassesSupported() {
+        return false;
+    }
+
+    @Override
+    public void redefineClasses(ClassDefinition... definitions) throws ClassNotFoundException, UnmodifiableClassException {
+        throw new UnmodifiableClassException();
+    }
+
+    @Override
+    public boolean isModifiableClass(Class<?> theClass) {
+        return false;
+    }
+
+    @Override
+    public Class[] getAllLoadedClasses() {
+        return new Class[0];
+    }
+
+    @Override
+    public Class[] getInitiatedClasses(ClassLoader loader) {
+        return new Class[0];
+    }
+
+    @Override
+    public long getObjectSize(Object objectToSize) {
+        return 42;
+    }
+
+    @Override
+    public void appendToBootstrapClassLoaderSearch(JarFile jarfile) {
+    }
+
+    @Override
+    public void appendToSystemClassLoaderSearch(JarFile jarfile) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isNativeMethodPrefixSupported() {
+        return false;
+    }
+
+    @Override
+    public void setNativeMethodPrefix(ClassFileTransformer transformer, String prefix) {
+        throw new UnsupportedOperationException();
+    }
+    
+}