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:41 UTC

[08/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/json/src/main/java/org/netbeans/html/json/spi/Technology.java
----------------------------------------------------------------------
diff --git a/json/src/main/java/org/netbeans/html/json/spi/Technology.java b/json/src/main/java/org/netbeans/html/json/spi/Technology.java
new file mode 100644
index 0000000..b53f05e
--- /dev/null
+++ b/json/src/main/java/org/netbeans/html/json/spi/Technology.java
@@ -0,0 +1,216 @@
+/**
+ * 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.json.spi;
+
+import net.java.html.BrwsrCtx;
+import net.java.html.json.Model;
+import net.java.html.json.Models;
+import org.netbeans.html.context.spi.Contexts.Id;
+
+/** An implementation of a binding between model classes (see {@link Model})
+ * and particular technology like <a href="http://knockoutjs.com">knockout.js</a>
+ * in a browser window, etc.
+ * Since introduction of {@link Id technology identifiers} one can choose between
+ * different background implementations to handle the conversion and
+ * communication requests. The currently known provider is
+ * <code>org.netbeans.html:ko4j</code> module which registers 
+ * a <a href="http://knockoutjs.com" target="_blank">knockout.js</a>
+ * implementation called <b>ko4j</b>.
+ *
+ * @author Jaroslav Tulach
+ */
+public interface Technology<Data> {
+    /** Creates an object to wrap the provided model object. The model
+     * has previously been generated by annotation processor associated 
+     * with {@link Model} annotation.
+     * 
+     * @param model the model generated from {@link Model}
+     * @return internal object representing the model
+     */
+    public Data wrapModel(Object model);
+    
+    /** Converts an element potentially representing a model into the model.
+     * @param <M> the type of the <code>modelClass</code>
+     * @param modelClass expected class to convert the data to
+     * @param data the current data provided from the browser
+     * @return the instance of modelClass somehow extracted from the data, may return <code>null</code>
+     */
+    public <M> M toModel(Class<M> modelClass, Object data);
+    
+    /** Binds a property between the model and the data as used by the technology.
+     * 
+     * @param b the description of the requested binding
+     * @param model the original instance of the model
+     * @param data the data to bind with the model
+     */
+    public void bind(PropertyBinding b, Object model, Data data);
+
+    /** Model for given data has changed its value. The technology is
+     * supposed to update its state (for example DOM nodes associated
+     * with the model). The update usually happens asynchronously.
+     * 
+     * @param data technology's own representation of the model
+     * @param propertyName name of the model property that changed
+     */
+    public void valueHasMutated(Data data, String propertyName);
+
+    public void expose(FunctionBinding fb, Object model, Data d);
+    
+    /** Applies given data to current context (usually an HTML page).
+     * @param data the data to apply
+     */
+    public void applyBindings(Data data);
+    
+    /**
+     * Some technologies may require wrapping a Java array into a special
+     * object. In such case they may return it from this method.
+     *
+     * @param arr original array
+     * @return wrapped array
+     */
+    public Object wrapArray(Object[] arr);
+    
+    /** 
+     * Run given runnable in a safe mode. If the runnable can be executed
+     * immediately, do it. If we need to switch to some other thread, do it
+     * and invoke r asynchronously immediately returning from the call to
+     * runSafe method.
+     * 
+     * @param r the runnable to execute
+     * @deprecated Use {@link BrwsrCtx#execute(java.lang.Runnable)}
+     */
+    @Deprecated
+    public void runSafe(Runnable r);
+
+    /** For certain rendering technologies it may be more efficient to register
+     * property and function bindings for one instance of the model at once, 
+     * rather then doing it incrementally via 
+     * {@link Technology#expose(org.netbeans.html.json.spi.FunctionBinding, java.lang.Object, java.lang.Object) }
+     * and 
+     * {@link Technology#bind(org.netbeans.html.json.spi.PropertyBinding, java.lang.Object, java.lang.Object) }.
+     * In such case implement the {@link #wrapModel(java.lang.Object, org.netbeans.html.json.spi.PropertyBinding[], org.netbeans.html.json.spi.FunctionBinding[]) }
+     * method of this interface and it will be called instead of the 
+     * previous two ones.
+     * 
+     * @since 0.6
+     */
+    public static interface BatchInit<D> extends Technology<D> {
+        /** Wrap the given model into rendering technology appropriate object
+         * <code>D</code> and expose given properties and functions on it.
+         * 
+         * @param model the {@link Models#isModel(java.lang.Class) model} in Java
+         * @param propArr array of property bindings to expose
+         * @param funcArr array of functions to expose
+         * @return appropriate wrapper around the model
+         */
+        public D wrapModel(Object model, PropertyBinding[] propArr, FunctionBinding[] funcArr);
+    }
+
+    /** Some technologies are more effective when number of calls between
+     * Java and JavaScript is limited - to do that when a value of property
+     * is changed they should implement this additional interface.
+     * 
+     * @param <D> internal type of the technology
+     * @since 0.7.6
+     */
+    public static interface ValueMutated<D> extends Technology<D> {
+        /** Model for given data has changed its value. The technology is
+         * supposed to update its state (for example DOM nodes associated
+         * with the model). The update usually happens asynchronously.
+         * <p>
+         * If both <code>oldValue</code> and <code>newValue</code> are 
+         * <code>null</code> then the real value of the technology is
+         * not known.
+         * <p>
+         * If this method is present, then it is called instead of 
+         * old, plain {@link #valueHasMutated(java.lang.Object, java.lang.String)}
+         * which is never called by the infrastructure then.
+         * 
+         * @param data technology's own representation of the model
+         * @param propertyName name of the model property that changed
+         * @param oldValue provides previous value of the property
+         * @param newValue provides new value of the property
+         */
+        public void valueHasMutated(D data, String propertyName, Object oldValue, Object newValue);
+    }
+    
+    /** Apply technology bindings at selected subtree of the HTML page.
+     * Can be accessed via {@link Proto#applyBindings(java.lang.String)} or
+     * via method <code>applyBindings(String)</code> generated when one
+     * is using the {@link Model} annotation.
+     * 
+     * @param <D> the internal data for the technology
+     * @since 1.1
+     */
+    public static interface ApplyId<D> extends Technology<D> {
+        /** Applies given data to current context (usually an element on an 
+         * HTML page).
+         * 
+         * @param id the id of an element to apply the data to
+         * @param data the data to apply
+         */
+        public void applyBindings(String id, D data);
+    }
+
+    /** Extension of {@link BatchInit} with enhanced support for
+     * copying values. Technologies that support this interface provide a
+     * guarantee that result {@link Models#toRaw(java.lang.Object)}
+     * wrapped by {@link Models#fromRaw(net.java.html.BrwsrCtx, java.lang.Class, java.lang.Object)}
+     * will share essential properties (and not just values) of the original object.
+     *
+     * @since 1.3
+     */
+    public static interface BatchCopy<D> extends Technology<D> {
+        /** Wrap the given model into rendering technology appropriate object
+         * <code>D</code> and expose given properties and functions on it.
+         *
+         * @param model the {@link Models#isModel(java.lang.Class) model} in Java
+         * @param copyFrom the object to copy data from
+         *      (expectably of type D, but that isn't guaranteed) or <code>null</code>
+         * @param propArr array of property bindings to expose
+         * @param funcArr array of functions to expose
+         * @return appropriate wrapper around the model
+         */
+        public D wrapModel(Object model, Object copyFrom, PropertyBinding[] propArr, FunctionBinding[] funcArr);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/json/src/main/java/org/netbeans/html/json/spi/Transfer.java
----------------------------------------------------------------------
diff --git a/json/src/main/java/org/netbeans/html/json/spi/Transfer.java b/json/src/main/java/org/netbeans/html/json/spi/Transfer.java
new file mode 100644
index 0000000..b70371f
--- /dev/null
+++ b/json/src/main/java/org/netbeans/html/json/spi/Transfer.java
@@ -0,0 +1,96 @@
+/**
+ * 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.json.spi;
+
+import java.io.IOException;
+import java.io.InputStream;
+import org.netbeans.html.context.spi.Contexts.Builder;
+import org.netbeans.html.context.spi.Contexts.Id;
+
+/** A {@link Builder service provider interface} responsible for 
+ * conversion of JSON objects to Java ones and vice-versa.
+ * Since introduction of {@link Id technology identifiers} one can choose between
+ * different background implementations to handle the conversion and
+ * communication requests. The known providers include
+ * <code>org.netbeans.html:ko4j</code> module which registers 
+ * a native browser implementation called <b>xhr</b>, and a
+ * <code>org.netbeans.html:ko-ws-tyrus</code> module which registers 
+ * Java based implementation named <b>tyrus</b>.
+ *
+ * @author Jaroslav Tulach
+ */
+public interface Transfer {
+    /**
+     * Called to inspect properties of an object (usually a JSON or JavaScript
+     * wrapper).
+     *
+     * @param obj the object to inspect
+     * @param props the names of properties to check on the object
+     * <code>obj</code>
+     * @param values array of the same length as <code>props</code> should be
+     * filled by values of properties on the <code>obj</code>. If a property is
+     * not defined, a <code>null</code> value should be stored in the array
+     */
+    public void extract(Object obj, String[] props, Object[] values);
+    
+    /** Reads content of a stream and creates its JSON representation.
+     * The returned object is implementation dependant. It however needs
+     * to be acceptable as first argument of {@link #extract(java.lang.Object, java.lang.String[], java.lang.Object[]) extract}
+     * method. If the stream contains representation or a JSON array,
+     * an Object[] should be returned - each of its members should, by itself
+     * be acceptable argument to 
+     * the {@link #extract(java.lang.Object, java.lang.String[], java.lang.Object[]) extract} method.
+     * 
+     * @param is input stream to read data from
+     * @return an object representing the JSON data
+     * @throws IOException if something goes wrong
+     */
+    public Object toJSON(InputStream is) throws IOException;
+    
+    /** Starts the JSON or JSONP query. 
+     * 
+     * @param call description of the call to make
+     */
+    public void loadJSON(JSONCall call);
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/json/src/main/java/org/netbeans/html/json/spi/WSTransfer.java
----------------------------------------------------------------------
diff --git a/json/src/main/java/org/netbeans/html/json/spi/WSTransfer.java b/json/src/main/java/org/netbeans/html/json/spi/WSTransfer.java
new file mode 100644
index 0000000..16a8882
--- /dev/null
+++ b/json/src/main/java/org/netbeans/html/json/spi/WSTransfer.java
@@ -0,0 +1,92 @@
+/**
+ * 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.json.spi;
+
+import net.java.html.BrwsrCtx;
+import org.netbeans.html.context.spi.Contexts.Provider;
+import org.netbeans.html.context.spi.Contexts.Id;
+
+/** Interface for providers of WebSocket protocol. Register into a 
+ * {@link BrwsrCtx context} in your own {@link Provider}.
+ * Since introduction of {@link Id technology identifiers} one can choose between
+ * different background implementations to handle the conversion and
+ * communication requests. The known providers include
+ * <code>org.netbeans.html:ko4j</code> module which registers 
+ * a native browser implementation called <b>websocket</b>, and a
+ * <code>org.netbeans.html:ko-ws-tyrus</code> module which registers 
+ * Java based implementation named <b>tyrus</b>.
+ *
+ * @author Jaroslav Tulach
+ * @param <WebSocket> internal implementation type representing the socket
+ * @since 0.5
+ */
+public interface WSTransfer<WebSocket> {
+    /** Initializes a web socket. The <code>callback</code> object should 
+     * have mostly empty values: {@link JSONCall#isDoOutput()} should be 
+     * <code>false</code> and thus there should be no {@link JSONCall#getMessage()}.
+     * The method of connection {@link JSONCall#getMethod()} is "WebSocket".
+     * Once the connection is open call {@link JSONCall#notifySuccess(java.lang.Object) notifySuccess(null)}.
+     * When the server sends some data then, pass them to 
+     * {@link JSONCall#notifySuccess(java.lang.Object) notifySuccess} method
+     * as well. If there is an error call {@link JSONCall#notifyError(java.lang.Throwable)}.
+     * 
+     * @param url the URL to connect to
+     * @param callback a way to provide results back to the client
+     * @return your object representing the established web socket
+     */
+    public WebSocket open(String url, JSONCall callback);
+
+    /** Sends data to the server. The most important value
+     * of the <code>data</code> parameter is {@link JSONCall#getMessage()},
+     * rest can be ignored.
+     * 
+     * @param socket internal representation of the socket
+     * @param data the message to be sent
+     */
+    public void send(WebSocket socket, JSONCall data);
+
+    /** A request to close the socket.
+     * @param socket internal representation of the socket
+     */
+    public void close(WebSocket socket);
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/json/src/main/java/org/netbeans/html/json/spi/package.html
----------------------------------------------------------------------
diff --git a/json/src/main/java/org/netbeans/html/json/spi/package.html b/json/src/main/java/org/netbeans/html/json/spi/package.html
new file mode 100644
index 0000000..1912dd1
--- /dev/null
+++ b/json/src/main/java/org/netbeans/html/json/spi/package.html
@@ -0,0 +1,51 @@
+<!--
+
+    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.
+
+-->
+<html>
+    <body>
+        <div>Service Provider Interfaces for those who wish to integrate own
+            <a href="Technology.html">technology</a> with the HTML for Java API.
+        </div>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/json/src/main/resources/org/netbeans/html/json/impl/Bundle.properties
----------------------------------------------------------------------
diff --git a/json/src/main/resources/org/netbeans/html/json/impl/Bundle.properties b/json/src/main/resources/org/netbeans/html/json/impl/Bundle.properties
new file mode 100644
index 0000000..489c7be
--- /dev/null
+++ b/json/src/main/resources/org/netbeans/html/json/impl/Bundle.properties
@@ -0,0 +1,97 @@
+#
+# 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.
+#
+
+MSG_Completion_GET=The GET method means retrieve whatever information \
+ (in the form of an entity) is identified by the Request-URI. \
+ If the Request-URI refers to a data-producing process, \
+ it is the produced data which shall be returned as the entity in \
+ the response and not the source text of the process, \
+ unless that text happens to be the output of the process.
+
+MSG_Completion_HEAD=The HEAD method is identical to GET except that the server \
+ MUST NOT return a message-body in the response. The metainformation \
+ contained in the HTTP headers in response to a HEAD request SHOULD be \
+ identical to the information sent in response to a GET request. \
+ This method can be used for obtaining metainformation about the entity implied \
+ by the request without transferring the entity-body itself. \
+ This method is often used for testing hypertext links for validity, \
+ accessibility, and recent modification.
+
+MSG_Completion_POST=The POST method is used to request that the origin server \
+ accept the entity enclosed in the request as a new subordinate of the resource \
+ identified by the Request-URI in the Request-Line. POST is designed to allow \
+ a uniform method to cover annotation of existing resources,\ 
+ posting a message to a bulletin board, newsgroup, mailing list, or similar \
+ group of articles, providing a block of data, such as the result of submitting a \
+ form, to a data-handling process or extending a database through an append operation. \
+ The actual function performed by the POST method is determined by the server \
+ and is usually dependent on the Request-URI. The posted entity is subordinate \
+ to that URI in the same way that a file is subordinate to a directory containing it, \
+ a news article is subordinate to a newsgroup to which it is posted, \
+ or a record is subordinate to a database.
+
+MSG_Completion_PUT=The PUT method requests that the enclosed entity be stored \
+ under the supplied Request-URI. If the Request-URI refers to an already \
+ existing resource, the enclosed entity SHOULD be considered as a modified \
+ version of the one residing on the origin server. If the Request-URI does \
+ not point to an existing resource, and that URI is capable of being defined \
+ as a new resource by the requesting user agent, the origin server can \
+ create the resource with that URI. If a new resource is created, the origin \
+ server MUST inform the user agent via the 201 (Created) response. \
+ If an existing resource is modified, either the 200 (OK) or 204 (No Content) \
+ response codes SHOULD be sent to indicate successful completion of the request. \
+ If the resource could not be created or modified with the Request-URI, an \
+ appropriate error response SHOULD be given that reflects the nature of the problem. \
+ The recipient of the entity MUST NOT ignore any Content-* (e.g. Content-Range) \
+ headers that it does not understand or implement and MUST return \
+ a 501 (Not Implemented) response in such cases.
+
+MSG_Completion_DELETE=The DELETE method requests that the origin server delete \
+ the resource identified by the Request-URI. This method MAY be overridden \
+ by human intervention (or other means) on the origin server. The client \
+ cannot be guaranteed that the operation has been carried out, even if \
+ the status code returned from the origin server indicates that the action \
+ has been completed successfully. However, the server SHOULD NOT indicate \
+ success unless, at the time the response is given, it intends to delete \
+ the resource or move it to an inaccessible location.
+

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/json/src/main/resources/org/netbeans/html/json/spi/package.html
----------------------------------------------------------------------
diff --git a/json/src/main/resources/org/netbeans/html/json/spi/package.html b/json/src/main/resources/org/netbeans/html/json/spi/package.html
new file mode 100644
index 0000000..80517a4
--- /dev/null
+++ b/json/src/main/resources/org/netbeans/html/json/spi/package.html
@@ -0,0 +1,59 @@
+<!--
+
+    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.
+
+-->
+<!DOCTYPE html>
+<html>
+    <head>
+        <title></title>
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+    <body>
+        <div>Implement 
+            <a href="Technology.html">Technology</a> and
+            <a href="Transfer.html">Transfer</a> and use 
+            <a href="ContextBuilder.html">ContextBuilder</a> to create an instance
+            of <code>Context</code> representing your technology.
+        </div>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/json/src/test/java/net/java/html/json/AdressTest.java
----------------------------------------------------------------------
diff --git a/json/src/test/java/net/java/html/json/AdressTest.java b/json/src/test/java/net/java/html/json/AdressTest.java
new file mode 100644
index 0000000..8388fab
--- /dev/null
+++ b/json/src/test/java/net/java/html/json/AdressTest.java
@@ -0,0 +1,59 @@
+/**
+ * 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.json;
+
+import net.java.html.json.Model;
+import net.java.html.json.Property;
+import static org.testng.Assert.assertNotNull;
+import org.testng.annotations.Test;
+
+@Model(className = "Address", properties = {
+    @Property(name = "street", type = net.java.html.json.sub.Street.class)
+})
+public class AdressTest {
+    @Test
+    public void addressHoldsAPerson() {
+        Address address = new Address();
+        assertNotNull(address.getStreet(), "Street is initialized");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/json/src/test/java/net/java/html/json/BoardTest.java
----------------------------------------------------------------------
diff --git a/json/src/test/java/net/java/html/json/BoardTest.java b/json/src/test/java/net/java/html/json/BoardTest.java
new file mode 100644
index 0000000..4b8d645
--- /dev/null
+++ b/json/src/test/java/net/java/html/json/BoardTest.java
@@ -0,0 +1,83 @@
+/**
+ * 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.json;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import org.testng.annotations.Test;
+
+/**
+ *
+ * @author Jaroslav Tulach
+ */
+@Model(className = "Board", properties = {
+    @Property(name = "rows", type = Row.class, array = true)
+})
+public class BoardTest {
+    
+    @Model(className = "Row", properties = {
+        @Property(name = "column", type = Column.class, array = true)
+    })
+    static class RowModel {
+    }
+    
+    @Model(className = "Column", properties = {
+        @Property(name = "black", type = boolean.class)
+    })
+    static class ColumnModel {
+    }
+
+    @Test public void deepClone() {
+        Board orig = new Board(new Row(new Column(true)));
+        assertTrue(orig.getRows().get(0).getColumn().get(0).isBlack(), "Really true");
+        
+        Board clone = orig.clone();
+        assertTrue(clone.getRows().get(0).getColumn().get(0).isBlack(), "Clone also true");
+        
+        clone.getRows().get(0).getColumn().get(0).setBlack(false);
+        
+        assertFalse(clone.getRows().get(0).getColumn().get(0).isBlack(), "Clone also is not false");
+        assertTrue(orig.getRows().get(0).getColumn().get(0).isBlack(), "Orig still true");
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/json/src/test/java/net/java/html/json/BooleanArrayTest.java
----------------------------------------------------------------------
diff --git a/json/src/test/java/net/java/html/json/BooleanArrayTest.java b/json/src/test/java/net/java/html/json/BooleanArrayTest.java
new file mode 100644
index 0000000..78c134d
--- /dev/null
+++ b/json/src/test/java/net/java/html/json/BooleanArrayTest.java
@@ -0,0 +1,80 @@
+/**
+ * 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.json;
+
+import java.util.Collections;
+import java.util.List;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ *
+ * @author Jaroslav Tulach
+ */
+@Model(className="BooleanArray", builder = "put", properties = {
+    @Property(name = "array", type = boolean.class, array = true)
+})
+public class BooleanArrayTest {
+    @ComputedProperty static int length(List<Boolean> array) {
+        return array.size();
+    }
+
+    @ComputedProperty static List<Integer> lengthAsList(List<Boolean> array) {
+        return Collections.nCopies(1, array.size());
+    }
+
+    @ComputedProperty static List<String> lengthTextList(List<Boolean> array) {
+        return Collections.nCopies(1, "" + array.size());
+    }
+    
+    @Test public void generatedConstructorWithPrimitiveType() {
+        boolean[] arr = new boolean[10];
+        arr[3] = true;
+        BooleanArray a = new BooleanArray().putArray(arr);
+        Assert.assertEquals(a.getArray().size(), 10, "Ten elements");
+        Assert.assertEquals(a.getArray().get(3).booleanValue(), true, "Value ten");
+        Assert.assertEquals(a.getLength(), 10, "Derived property is OK too");
+        Assert.assertEquals(a.getLengthTextList().get(0), "10", "Derived string list property is OK");
+        Assert.assertEquals((int)a.getLengthAsList().get(0), 10, "Derived Integer list property is OK");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/json/src/test/java/net/java/html/json/Compile.java
----------------------------------------------------------------------
diff --git a/json/src/test/java/net/java/html/json/Compile.java b/json/src/test/java/net/java/html/json/Compile.java
new file mode 100644
index 0000000..13b812e
--- /dev/null
+++ b/json/src/test/java/net/java/html/json/Compile.java
@@ -0,0 +1,311 @@
+/**
+ * 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.json;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticListener;
+import javax.tools.FileObject;
+import javax.tools.ForwardingJavaFileManager;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+import javax.tools.JavaFileObject.Kind;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+import static org.testng.Assert.*;
+
+/**
+ *
+ * @author Jaroslav Tulach
+ */
+final class Compile implements DiagnosticListener<JavaFileObject> {
+    private final List<Diagnostic<? extends JavaFileObject>> errors = 
+            new ArrayList<Diagnostic<? extends JavaFileObject>>();
+    private final Map<String, byte[]> classes;
+    private final String pkg;
+    private final String cls;
+    private final String html;
+    private final String sourceLevel;
+
+    private Compile(String html, String code, String sl) throws IOException {
+        this.pkg = findPkg(code);
+        this.cls = findCls(code);
+        this.html = html;
+        this.sourceLevel = sl;
+        classes = compile(html, code);
+    }
+
+    /** Performs compilation of given HTML page and associated Java code
+     */
+    public static Compile create(String html, String code) throws IOException {
+        return create(html, code, "1.7");
+    }
+    static Compile create(String html, String code, String sourceLevel) throws IOException {
+        return new Compile(html, code, sourceLevel);
+    }
+    
+    /** Checks for given class among compiled resources */
+    public byte[] get(String res) {
+        return classes.get(res);
+    }
+    
+    /** Obtains errors created during compilation.
+     */
+    public List<Diagnostic<? extends JavaFileObject>> getErrors() {
+        List<Diagnostic<? extends JavaFileObject>> err;
+        err = new ArrayList<Diagnostic<? extends JavaFileObject>>();
+        for (Diagnostic<? extends JavaFileObject> diagnostic : errors) {
+            if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
+                err.add(diagnostic);
+            }
+        }
+        return err;
+    }
+    
+    private Map<String, byte[]> compile(final String html, final String code) throws IOException {
+        StandardJavaFileManager sjfm = ToolProvider.getSystemJavaCompiler().getStandardFileManager(this, null, null);
+
+        final Map<String, ByteArrayOutputStream> class2BAOS;
+        class2BAOS = new HashMap<String, ByteArrayOutputStream>();
+
+        JavaFileObject file = new SimpleJavaFileObject(URI.create("mem://mem"), Kind.SOURCE) {
+            @Override
+            public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
+                return code;
+            }
+        };
+        final JavaFileObject htmlFile = new SimpleJavaFileObject(URI.create("mem://mem2"), Kind.OTHER) {
+            @Override
+            public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
+                return html;
+            }
+
+            @Override
+            public InputStream openInputStream() throws IOException {
+                return new ByteArrayInputStream(html.getBytes());
+            }
+        };
+        
+        final URI scratch;
+        try {
+            scratch = new URI("mem://mem3");
+        } catch (URISyntaxException ex) {
+            throw new IOException(ex);
+        }
+        
+        JavaFileManager jfm = new ForwardingJavaFileManager<JavaFileManager>(sjfm) {
+            @Override
+            public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling) throws IOException {
+                if (kind  == Kind.CLASS) {
+                    final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+
+                    class2BAOS.put(className.replace('.', '/') + ".class", buffer);
+                    return new SimpleJavaFileObject(sibling.toUri(), kind) {
+                        @Override
+                        public OutputStream openOutputStream() throws IOException {
+                            return buffer;
+                        }
+                    };
+                }
+                
+                if (kind == Kind.SOURCE) {
+                    final String n = className.replace('.', '/') + ".java";
+                    final URI un;
+                    try {
+                        un = new URI("mem://" + n);
+                    } catch (URISyntaxException ex) {
+                        throw new IOException(ex);
+                    }
+                    return new VirtFO(un/*sibling.toUri()*/, kind, n);
+                }
+                
+                throw new IllegalStateException();
+            }
+
+            @Override
+            public FileObject getFileForInput(Location location, String packageName, String relativeName) throws IOException {
+                if (location == StandardLocation.SOURCE_PATH) {
+                    if (packageName.equals(pkg)) {
+                        return htmlFile;
+                    }
+                }
+                
+                return null;
+            }
+
+            @Override
+            public boolean isSameFile(FileObject a, FileObject b) {
+                if (a instanceof VirtFO && b instanceof VirtFO) {
+                    return ((VirtFO)a).getName().equals(((VirtFO)b).getName());
+                }
+                
+                return super.isSameFile(a, b);
+            }
+
+            class VirtFO extends SimpleJavaFileObject {
+
+                private final String n;
+
+                public VirtFO(URI uri, Kind kind, String n) {
+                    super(uri, kind);
+                    this.n = n;
+                }
+                private final ByteArrayOutputStream data = new ByteArrayOutputStream() {
+
+                    @Override
+                    public void close() throws IOException {
+                        super.close();
+
+                        int opening = count(toString(), '{');
+                        int closing = count(toString(), '}');
+
+                        assertEquals(opening, closing, "There should be pair number of { and } in\n" + toString());
+                    }
+                };
+
+                int count(String where, char what) {
+                    int at = -1;
+                    int cnt = 0;
+                    for (;;) {
+                        at = where.indexOf(what, at + 1);
+                        if (at == -1) {
+                            return cnt;
+                        }
+                        cnt++;
+                    }
+                }
+
+                @Override
+                public OutputStream openOutputStream() throws IOException {
+                    return data;
+                }
+
+                @Override
+                public String getName() {
+                    return n;
+                }
+
+                @Override
+                public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
+                    data.close();
+                    return new String(data.toByteArray());
+                }
+            }
+        };
+
+        ToolProvider.getSystemJavaCompiler().getTask(null, jfm, this, /*XXX:*/Arrays.asList("-source", sourceLevel, "-target", "1.7"), null, Arrays.asList(file)).call();
+
+        Map<String, byte[]> result = new HashMap<String, byte[]>();
+
+        for (Map.Entry<String, ByteArrayOutputStream> e : class2BAOS.entrySet()) {
+            result.put(e.getKey(), e.getValue().toByteArray());
+        }
+
+        return result;
+    }
+
+
+    @Override
+    public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+        errors.add(diagnostic);
+    }
+    private static String findPkg(String java) throws IOException {
+        Pattern p = Pattern.compile("package\\p{javaWhitespace}*([\\p{Alnum}\\.]+)\\p{javaWhitespace}*;", Pattern.MULTILINE);
+        Matcher m = p.matcher(java);
+        if (!m.find()) {
+            throw new IOException("Can't find package declaration in the java file");
+        }
+        String pkg = m.group(1);
+        return pkg;
+    }
+    private static String findCls(String java) throws IOException {
+        Pattern p = Pattern.compile("class\\p{javaWhitespace}*([\\p{Alnum}\\.]+)\\p{javaWhitespace}", Pattern.MULTILINE);
+        Matcher m = p.matcher(java);
+        if (!m.find()) {
+            throw new IOException("Can't find package declaration in the java file");
+        }
+        String cls = m.group(1);
+        return cls;
+    }
+
+    String getHtml() {
+        String fqn = "'" + pkg + '.' + cls + "'";
+        return html.replace("'${fqn}'", fqn);
+    }
+    void assertErrors() {
+        assertFalse(getErrors().isEmpty(), "There are supposed to be some errors");
+    }
+    void assertNoErrors() {
+        assertTrue(getErrors().isEmpty(), "There are supposed to be no errors: " + getErrors());
+    }
+
+    void assertError(String expMsg) {
+        StringBuilder sb = new StringBuilder();
+        sb.append("Can't find ").append(expMsg).append(" among:");
+        for (Diagnostic<? extends JavaFileObject> e : errors) {
+            String msg = e.getMessage(Locale.US);
+            if (msg.contains(expMsg)) {
+                return;
+            }
+            sb.append("\n");
+            sb.append(msg);
+        }
+        fail(sb.toString());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/json/src/test/java/net/java/html/json/KeywordsTest.java
----------------------------------------------------------------------
diff --git a/json/src/test/java/net/java/html/json/KeywordsTest.java b/json/src/test/java/net/java/html/json/KeywordsTest.java
new file mode 100644
index 0000000..9e79895
--- /dev/null
+++ b/json/src/test/java/net/java/html/json/KeywordsTest.java
@@ -0,0 +1,99 @@
+/**
+ * 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.json;
+
+import static org.testng.Assert.*;
+import org.testng.annotations.Test;
+
+@Model(className = "Keywords", properties = {
+    @Property(name = "private", type = String.class),
+    @Property(name = "public", type = double.class),
+    @Property(name = "final", type = String.class),
+    @Property(name = "int", type = int.class),
+    @Property(name = "class", type = String.class),
+//    @Property(name = "{", type = String.class),
+    @Property(name = "array", type = KeywordsInArray.class)
+})
+public class KeywordsTest {
+    @Model(className = "KeywordsInArray", properties = {
+        @Property(name = "private", type = String.class, array = true),
+        @Property(name = "public", type = double.class, array = true),
+        @Property(name = "final", type = String.class, array = true),
+        @Property(name = "int", type = int.class, array = true),
+        @Property(name = "class", type = String.class, array = true),
+//    @Property(name = "{", type = String.class),
+        @Property(name = "array", type = Keywords.class, array = true)
+    })
+    static class KeywordsInArrayCntrl {
+    }
+    
+    @Test public void verifyKeywordsClassCompiles() {
+        Keywords k = new Keywords();
+        k.setClass("c");
+        k.setFinal("f");
+        k.setInt(10);
+        k.setPrivate("p");
+        k.setPublic(42.0);
+        
+        assertEquals(k.accessClass(), "c");
+        assertEquals(k.getFinal(), "f");
+        assertEquals(k.getInt(), 10);
+        assertEquals(k.getPrivate(), "p");
+        assertEquals(k.getPublic(), 42.0);
+    }
+    
+    @Test public void verifyKeywordsInArrayClassCompiles() {
+        KeywordsInArray k = new KeywordsInArray();
+        k.accessClass().add("c");
+        k.getFinal().add("f");
+        k.getInt().add(10);
+        k.getPrivate().add("p");
+        k.getPublic().add(42.0);
+        
+        assertEquals(k.accessClass().get(0), "c");
+        assertEquals(k.getFinal().get(0), "f");
+        assertEquals(k.getInt().get(0), Integer.valueOf(10));
+        assertEquals(k.getPrivate().get(0), "p");
+        assertEquals(k.getPublic().get(0), 42.0);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/json/src/test/java/net/java/html/json/MapModelNotMutableTest.java
----------------------------------------------------------------------
diff --git a/json/src/test/java/net/java/html/json/MapModelNotMutableTest.java b/json/src/test/java/net/java/html/json/MapModelNotMutableTest.java
new file mode 100644
index 0000000..4851c5a
--- /dev/null
+++ b/json/src/test/java/net/java/html/json/MapModelNotMutableTest.java
@@ -0,0 +1,227 @@
+/**
+ * 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.json;
+
+import java.util.Map;
+import net.java.html.BrwsrCtx;
+import org.netbeans.html.context.spi.Contexts;
+import org.netbeans.html.json.spi.Technology;
+import org.netbeans.html.json.spi.Transfer;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.fail;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+@Model(className = "ConstantValues", properties = {
+    @Property(name = "byteNumber", type = byte.class, mutable = false),
+    @Property(name = "shortNumber", type = short.class, mutable = false),
+    @Property(name = "intNumber", type = int.class, mutable = false),
+    @Property(name = "longNumber", type = long.class, mutable = false),
+    @Property(name = "floatNumber", type = float.class, mutable = false),
+    @Property(name = "doubleNumber", type = double.class, mutable = false),
+    @Property(name = "stringValue", type = String.class, mutable = false),
+    @Property(name = "byteArray", type = byte.class, mutable = false, array = true),
+    @Property(name = "shortArray", type = short.class, mutable = false, array = true),
+    @Property(name = "intArray", type = int.class, mutable = false, array = true),
+    @Property(name = "longArray", type = long.class, mutable = false, array = true),
+    @Property(name = "floatArray", type = float.class, mutable = false, array = true),
+    @Property(name = "doubleArray", type = double.class, mutable = false, array = true),
+    @Property(name = "stringArray", type = String.class, mutable = false, array = true),
+})
+public class MapModelNotMutableTest {
+    private BrwsrCtx c;
+
+    @BeforeMethod
+    public void initTechnology() {
+        MapModelTest.MapTechnology t = new MapModelTest.MapTechnology();
+        c = Contexts.newBuilder().register(Technology.class, t, 1).
+            register(Transfer.class, t, 1).build();
+    }
+
+    @Test
+    public void byteConstant() throws Exception {
+        ConstantValues value = Models.bind(new ConstantValues(), c);
+        value.setByteNumber((byte)13);
+
+        Map m = (Map) Models.toRaw(value);
+        Object v = m.get("byteNumber");
+        assertNotNull(v, "Value should be in the map");
+        assertEquals(v.getClass(), MapModelTest.One.class, "It is instance of One");
+        MapModelTest.One o = (MapModelTest.One) v;
+        assertEquals(o.changes, 0, "No change so far the only one change happened before we connected");
+        assertEquals((byte)13, o.get());
+
+        try {
+            value.setByteNumber((byte)15);
+            fail("Changing value shouldn't succeed!");
+        } catch (IllegalStateException ex) {
+            // OK
+        }
+        assertEquals(o.get(), (byte)13, "Old value should still be in the map");
+        assertEquals(o.changes, 0, "No change");
+        assertFalse(o.pb.isReadOnly(), "Mutable property");
+    }
+
+    @Test
+    public void shortConstant() throws Exception {
+        ConstantValues value = Models.bind(new ConstantValues(), c);
+        value.setShortNumber((short)13);
+
+        Map m = (Map) Models.toRaw(value);
+        Object v = m.get("shortNumber");
+        assertNotNull(v, "Value should be in the map");
+        assertEquals(v.getClass(), MapModelTest.One.class, "It is instance of One");
+        MapModelTest.One o = (MapModelTest.One) v;
+        assertEquals(o.changes, 0, "No change so far the only one change happened before we connected");
+        assertEquals((short)13, o.get());
+
+        try {
+            value.setShortNumber((short)15);
+            fail("Changing value shouldn't succeed!");
+        } catch (IllegalStateException ex) {
+            // OK
+        }
+        assertEquals(o.get(), (short)13, "Old value should still be in the map");
+        assertEquals(o.changes, 0, "No change");
+        assertFalse(o.pb.isReadOnly(), "Mutable property");
+    }
+
+    @Test
+    public void intConstant() throws Exception {
+        ConstantValues value = Models.bind(new ConstantValues(), c);
+        value.setIntNumber(13);
+
+        Map m = (Map) Models.toRaw(value);
+        Object v = m.get("intNumber");
+        assertNotNull(v, "Value should be in the map");
+        assertEquals(v.getClass(), MapModelTest.One.class, "It is instance of One");
+        MapModelTest.One o = (MapModelTest.One) v;
+        assertEquals(o.changes, 0, "No change so far the only one change happened before we connected");
+        assertEquals(13, o.get());
+
+        try {
+            value.setIntNumber(15);
+            fail("Changing value shouldn't succeed!");
+        } catch (IllegalStateException ex) {
+            // OK
+        }
+        assertEquals(o.get(), 13, "Old value should still be in the map");
+        assertEquals(o.changes, 0, "No change");
+        assertFalse(o.pb.isReadOnly(), "Mutable property");
+    }
+
+    @Test
+    public void doubleConstant() throws Exception {
+        ConstantValues value = Models.bind(new ConstantValues(), c);
+        value.setDoubleNumber(13);
+
+        Map m = (Map) Models.toRaw(value);
+        Object v = m.get("doubleNumber");
+        assertNotNull(v, "Value should be in the map");
+        assertEquals(v.getClass(), MapModelTest.One.class, "It is instance of One");
+        MapModelTest.One o = (MapModelTest.One) v;
+        assertEquals(o.changes, 0, "No change so far the only one change happened before we connected");
+        assertEquals(13.0, o.get());
+
+        try {
+            value.setDoubleNumber(15);
+            fail("Changing value shouldn't succeed!");
+        } catch (IllegalStateException ex) {
+            // OK
+        }
+        assertEquals(o.get(), 13.0, "Old value should still be in the map");
+        assertEquals(o.changes, 0, "No change");
+        assertFalse(o.pb.isReadOnly(), "Mutable property");
+    }
+
+    @Test
+    public void stringConstant() throws Exception {
+        ConstantValues value = Models.bind(new ConstantValues(), c);
+        value.setStringValue("Hi");
+
+        Map m = (Map) Models.toRaw(value);
+        Object v = m.get("stringValue");
+        assertNotNull(v, "Value should be in the map");
+        assertEquals(v.getClass(), MapModelTest.One.class, "It is instance of One");
+        MapModelTest.One o = (MapModelTest.One) v;
+        assertEquals(o.changes, 0, "No change so far the only one change happened before we connected");
+        assertEquals("Hi", o.get());
+
+        try {
+            value.setStringValue("Hello");
+            fail("Changing value shouldn't succeed!");
+        } catch (IllegalStateException ex) {
+            // OK
+        }
+        assertEquals(o.get(), "Hi", "Old value should still be in the map");
+        assertEquals(o.changes, 0, "No change");
+        assertFalse(o.pb.isReadOnly(), "Mutable property");
+    }
+
+    @Test
+    public void stringArray() throws Exception {
+        ConstantValues value = Models.bind(new ConstantValues(), c);
+        value.getStringArray().add("Hi");
+
+        Map m = (Map) Models.toRaw(value);
+        Object v = m.get("stringArray");
+        assertNotNull(v, "Value should be in the map");
+        assertEquals(v.getClass(), MapModelTest.One.class, "It is instance of One");
+        MapModelTest.One o = (MapModelTest.One) v;
+        assertEquals(o.changes, 0, "No change so far the only one change happened before we connected");
+        assertEquals(o.get(), new String[] { "Hi" }, "One element");
+
+        try {
+            value.getStringArray().add("Hello");
+            fail("Changing value shouldn't succeed!");
+        } catch (UnsupportedOperationException ex) {
+            // OK
+        }
+        assertEquals(o.get(), new String[] { "Hi" }, "Old value should still be in the map");
+        assertEquals(o.changes, 0, "No change");
+        assertFalse(o.pb.isReadOnly(), "Mutable property");
+    }
+
+}