changeset 9234:b759c97f60fa 9-b80

8088670: Remove use of internal classes methods from toys Reviewed-by: kcr
author Chien Yang <chien.yang@oracle.com>
date Fri, 28 Aug 2015 16:55:26 -0700
parents 617cf3444954
children f9099a722530 8ecb30e4c65e
files apps/toys/FX8-3DFeatures/src/fx83dfeatures/Camera3D.java apps/toys/FX8-3DFeatures/src/fx83dfeatures/CameraController.java apps/toys/FX8-3DFeatures/src/fx83dfeatures/SpecularColorTestApp.java apps/toys/FX8-3DFeatures/src/fx83dfeatures/utils3d/Camera3D.java apps/toys/FX8-3DFeatures/src/fx83dfeatures/utils3d/CameraController.java apps/toys/FX8-3DFeatures/src/fx83dfeatures/utils3d/Vec2d.java apps/toys/FX8-3DFeatures/src/fx83dfeatures/utils3d/Vec2f.java apps/toys/FX8-3DFeatures/src/fx83dfeatures/utils3d/Vec3d.java apps/toys/FX8-3DFeatures/src/fx83dfeatures/utils3d/Vec3f.java apps/toys/Hello/src/main/java/hello/BMPOutputStream.java apps/toys/Hello/src/main/java/hello/HelloFPS.java apps/toys/Hello/src/main/java/hello/HelloRectangle3D.java apps/toys/Hello/src/main/java/hello/HelloSanity.java apps/toys/Hello/src/main/java/hello/HelloTiger.java apps/toys/Hello/src/main/java/hello/HelloTouch.java apps/toys/Hello/src/main/java/hello/TestBuilder.java apps/toys/Industrial/src/industrial/Controller.java apps/toys/Industrial/src/industrial/Industrial.java apps/toys/Industrial/src/industrial/Model.java tests/manual/Robot/build.xml tests/manual/Robot/manifest.mf tests/manual/Robot/nbproject/build-impl.xml tests/manual/Robot/nbproject/genfiles.properties tests/manual/Robot/nbproject/project.properties tests/manual/Robot/nbproject/project.xml tests/manual/Robot/src/robottest/BMPOutputStream.java tests/manual/Robot/src/robottest/RobotBuilder.java tests/manual/Robot/src/robottest/RobotTest.java tests/manual/Robot/src/robottest/RobotTestStyles.css
diffstat 29 files changed, 3948 insertions(+), 1260 deletions(-) [+]
line wrap: on
line diff
--- a/apps/toys/FX8-3DFeatures/src/fx83dfeatures/Camera3D.java	Fri Aug 28 09:10:39 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,230 +0,0 @@
-/*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package fx83dfeatures;
-
-import com.sun.javafx.geom.Vec3d;
-import com.sun.javafx.geom.Vec3f;
-import javafx.beans.property.DoubleProperty;
-import javafx.beans.property.SimpleDoubleProperty;
-import javafx.geometry.Point3D;
-import javafx.scene.PerspectiveCamera;
-import javafx.scene.transform.Affine;
-
-/**
- * A movable 3D camera node
- * The camera looks into positive Z direction
- */
-public class Camera3D extends PerspectiveCamera {
-    public final Vec3d FORWARD = new Vec3d(0,0,1);
-    public final Vec3d UP = new Vec3d(0,-1,0);
-    public final Vec3d RIGHT = new Vec3d(1,0,0);
-
-    private final Affine transform = new Affine();
-
-    private final DoubleProperty upX = new SimpleDoubleProperty(0){
-        @Override protected void invalidated() { updateLookup(); }
-    };
-    public final double getUpX() { return upX.getValue(); }
-    public final void setUpX(double value) { upX.setValue(value); }
-    public final DoubleProperty upXModel() { return upX; }
-
-    private final DoubleProperty upY = new SimpleDoubleProperty(-1){
-        @Override protected void invalidated() { updateLookup(); }
-    };
-    public final double getUpY() { return upY.getValue(); }
-    public final void setUpY(double value) { upY.setValue(value); }
-    public final DoubleProperty upYModel() { return upY; }
-
-    private final DoubleProperty upZ = new SimpleDoubleProperty(0){
-        @Override protected void invalidated() { updateLookup(); }
-    };
-    public final double getUpZ() { return upZ.getValue(); }
-    public final void setUpZ(double value) { upZ.setValue(value); }
-    public final DoubleProperty upZModel() { return upZ; }
-
-    private final DoubleProperty targetX = new SimpleDoubleProperty(0){
-        @Override protected void invalidated() { updateLookup(); }
-    };
-    public final double getTargetX() { return targetX.getValue(); }
-    public final void setTargetX(double value) { targetX.setValue(value); }
-    public final DoubleProperty targetXModel() { return targetX; }
-
-    private final DoubleProperty targetY = new SimpleDoubleProperty(0){
-        @Override protected void invalidated() { updateLookup(); }
-    };
-    public final double getTargetY() { return targetY.getValue(); }
-    public final void setTargetY(double value) { targetY.setValue(value); }
-    public final DoubleProperty targetYModel() { return targetY; }
-
-    private final DoubleProperty targetZ = new SimpleDoubleProperty(1){
-        @Override protected void invalidated() { updateLookup(); }
-    };
-    public final double getTargetZ() { return targetZ.getValue(); }
-    public final void setTargetZ(double value) { targetZ.setValue(value); }
-    public final DoubleProperty targetZModel() { return targetZ; }
-
-    private final DoubleProperty posX = new SimpleDoubleProperty(0){
-        @Override protected void invalidated() { updateLookup(); }
-    };
-    public final double getPosX() { return posX.getValue(); }
-    public final void setPosX(double value) { posX.setValue(value); }
-    public final DoubleProperty posXModel() { return posX; }
-
-    private final DoubleProperty posY = new SimpleDoubleProperty(0){
-        @Override protected void invalidated() { updateLookup(); }
-    };
-    public final double getPosY() { return posY.getValue(); }
-    public final void setPosY(double value) { posY.setValue(value); }
-    public final DoubleProperty posYModel() { return posY; }
-
-    private final DoubleProperty posZ = new SimpleDoubleProperty(0){
-        @Override protected void invalidated() { updateLookup(); }
-    };
-    public final double getPosZ() { return posZ.getValue(); }
-    public final void setPosZ(double value) { posZ.setValue(value); }
-    public final DoubleProperty posZModel() { return posZ; }
-    
-    public Camera3D() {
-        super(true);
-        getTransforms().add(transform);
-        updateLookup();
-    }
-
-    private final Vec3f tm[] = new Vec3f[]{new Vec3f(),new Vec3f(),new Vec3f(),};
-    
-    private void updateLookup() {
-        Vec3f pos = new Vec3f((float)getPosX(), (float)getPosY(), (float)getPosZ());
-        Vec3f target = new Vec3f((float)getTargetX(), (float)getTargetY(), (float)getTargetZ());
-        Vec3f up = new Vec3f((float)getUpX(), (float)getUpY(), (float)getUpZ());
-        tm[2].sub(target, pos);         // z looks to the target
-        tm[1].set(-up.x, -up.y, -up.z); // y looks down
-        tm[0].cross(tm[1], tm[2]);      // x = y ^ z;
-        tm[1].cross(tm[2], tm[0]);      // y = z ^ x
-
-        for (int i=0; i!=3; ++i) {
-            tm[i].normalize();
-        }
-        //Vec3f pos, Vec3f tm[], Affine tma) {
-        transform.setMxx(tm[0].x); transform.setMxy(tm[1].x); transform.setMxz(tm[2].x);
-        transform.setMyx(tm[0].y); transform.setMyy(tm[1].y); transform.setMyz(tm[2].y);
-        transform.setMzx(tm[0].z); transform.setMzy(tm[1].z); transform.setMzz(tm[2].z);
-        transform.setTx (pos.x);   transform.setTy(pos.y);    transform.setTz(pos.z);
-    }
-
-    public Affine getTransform() {
-        return transform;
-    }
-
-    public void setPos(double x, double y, double z) {
-        setPosX(x);
-        setPosY(y);
-        setPosZ(z);
-    }
-    
-    public void setTarget(double x, double y, double z) {
-        setTargetX(x);
-        setTargetY(y);
-        setTargetZ(z);
-    }
-    
-    public void setUp(double x, double y, double z) {
-        setUpX(x);
-        setUpY(y);
-        setUpZ(z);
-    }
-    
-    /*
-     * returns 3D direction from the Camera position to the mouse
-     * in the Scene space 
-     */
-    
-    public Vec3d unProjectDirection(double sceneX, double sceneY, double sWidth, double sHeight) {
-        Vec3d vMouse = null;
-        
-        if (isVerticalFieldOfView()) {
-            // TODO: implement for Vfov
-        } else {
-            double tanHFov = Math.tan(Math.toRadians(getFieldOfView()) * 0.5f);
-            vMouse = new Vec3d(2*sceneX/sWidth-1, 2*sceneY/sWidth-sHeight/sWidth, 1);
-            vMouse.x *= tanHFov;
-            vMouse.y *= tanHFov;
-        }
-
-        Vec3d result = localToSceneDirection(vMouse, new Vec3d());
-        result.normalize();
-        return result;
-    }
-    
-    public Vec3d getPosition() {
-        return new Vec3d(getPosX(), getPosY(), getPosZ());
-    }
-
-    public Vec3d getTarget() {
-        return new Vec3d(getTargetX(), getTargetY(), getTargetZ());
-    }
-    
-    public Vec3d localToScene(Vec3d pt, Vec3d result) {
-        Point3D res = localToParentTransformProperty().get().transform(pt.x, pt.y, pt.z);
-        if (getParent() != null) {
-            res = getParent().localToSceneTransformProperty().get().transform(res);
-        }
-        result.set(res.getX(), res.getY(), res.getZ());
-        return result;
-    }
-    
-    public Vec3d localToSceneDirection(Vec3d dir, Vec3d result) {
-        localToScene(dir, result);
-        result.sub(localToScene(new Vec3d(0, 0, 0), new Vec3d()));
-        return result;
-    }
-    
-    public Vec3d getForward() {
-        Vec3d res = localToSceneDirection(FORWARD, new Vec3d());
-        res.normalize();
-        return res;
-    }
-
-    public Vec3d getUp() {
-        Vec3d res = localToSceneDirection(UP, new Vec3d());
-        res.normalize();
-        return res;
-    }
-
-    public Vec3d getRight() {
-        Vec3d res = localToSceneDirection(RIGHT, new Vec3d());
-        res.normalize();
-        return res;
-    }
-    
-    @Override
-    public String toString() {
-        return "camera3D.setPos(" + posX.get() + ", " + posY.get() + ", " 
-                + posZ.get() + ");\n"
-                + "camera3D.setTarget(" + targetX.get() + ", " 
-                + targetY.get() + ", " + targetZ.get() + ");\n"
-                + "camera3D.setUp(" + upX.get() + ", " + upY.get() + ", " 
-                + upZ.get() + ");";
-    }
-}
--- a/apps/toys/FX8-3DFeatures/src/fx83dfeatures/CameraController.java	Fri Aug 28 09:10:39 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,454 +0,0 @@
-/*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package fx83dfeatures;
-
-import com.sun.javafx.geom.Vec2d;
-import com.sun.javafx.geom.Vec3d;
-import javafx.animation.AnimationTimer;
-import javafx.beans.value.ChangeListener;
-import javafx.beans.value.ObservableValue;
-import javafx.event.EventHandler;
-import javafx.geometry.Point3D;
-import javafx.scene.Node;
-import javafx.scene.Scene;
-import javafx.scene.SubScene;
-import javafx.scene.input.KeyEvent;
-import javafx.scene.input.MouseEvent;
-import javafx.scene.transform.Rotate;
-
-/**
- * This is camera controller to use with new 3D API.
- *
- */
-public class CameraController {
-
-    private Camera3D camera;
-    private Node node;
-    private int up, down, left, right,
-            forward, back; // key pressed
-    private double initialSpeed = 5;
-    private double maxSpeed = 200;
-    private double speed = initialSpeed;
-    private double orbitSpeed = 1.0;
-    private double previousX, previousY;
-    private double yaw = 0.0022;
-    private double pitch = -0.0022;
-    private double maxPitch = 0.95;
-    private AnimationTimer moveTimer;
-    private Rotate rotateX;
-    private Rotate rotateY;
-
-    private void handleKeyEvent(KeyEvent t) {
-        if (t.getEventType() == KeyEvent.KEY_PRESSED) {
-            handleKeyEvent(t, true);
-        } else if (t.getEventType() == KeyEvent.KEY_RELEASED) {
-            handleKeyEvent(t, false);
-        }
-        // skip other event types
-    }
-    
-    private void handleMouseEvent(MouseEvent t) {
-        if (t.getEventType() == MouseEvent.MOUSE_PRESSED) {
-            handleMousePress(t);
-        } else if (t.getEventType() == MouseEvent.MOUSE_DRAGGED) {
-            Vec2d d = getDragDelta(t);
-            double speedModifier = getSpeedModifier(t);
-            switch (t.getButton()) {
-                case PRIMARY:
-                    // Alt + LMB = orbit
-                    handlePrimaryMouseDrag(t, d, speedModifier);
-                    break;
-                case MIDDLE:
-                    // Alt + MMB = pan/track
-                    handleMiddleMouseDrag(t, d, speedModifier);
-                    break;
-                case SECONDARY:
-                    // Alt + RMB = zoom
-                    handleSecondaryMouseDrag(t, d, speedModifier);
-                    break;
-                default:
-                    throw new AssertionError();
-            }
-        }
-    }
-
-    private void setEventHandlers(Scene scene) {
-        scene.addEventHandler(KeyEvent.ANY, k -> handleKeyEvent(k));
-        scene.addEventHandler(MouseEvent.ANY, m -> handleMouseEvent(m));
-    }
-
-    private void setEventHandlers(SubScene subScene) {
-        subScene.addEventHandler(KeyEvent.ANY, k -> handleKeyEvent(k));
-        subScene.addEventHandler(MouseEvent.ANY, m -> handleMouseEvent(m));
-    }
-
-    public CameraController(Camera3D camera) {
-        this.camera = camera;
-
-        new AnimationTimer() {
-            long now = 0;
-
-            @Override
-            public void handle(long l) {
-                if (now == 0) {
-                    now = l;
-                } else {
-                    double dt = (l - now) * 1e-9;
-                    now = l;
-                    update(dt);
-                }
-            }
-        }.start();
-    }
-
-    public CameraController(Camera3D camera, Scene scene) {
-        this(camera);
-        setEventHandlers(scene);
-    }
-
-    public CameraController(Camera3D camera, SubScene subScene) {
-        this(camera);
-        setEventHandlers(subScene);
-    }
-
-    private boolean isNotMoving() {
-        return forward - back == 0 && right - left == 0 && up - down == 0;
-    }
-
-    private void update(double dt) {
-        if (isNotMoving()) {
-            return;
-        }
-        Vec3d shiftForward = camera.getForward();
-        shiftForward.mul(forward - back);
-        Vec3d shiftRight = camera.getRight();
-        shiftRight.mul(right - left);
-        Vec3d shiftUp = camera.getUp();
-        shiftUp.mul(up - down);
-        Vec3d shift = new Vec3d(shiftForward);
-        shift.add(shiftRight);
-        shift.add(shiftUp);
-        shift.mul(speed * dt);
-        shiftCamera(shift);
-    }
-
-    private void handleKeyEvent(KeyEvent event, boolean state) {
-        int pressed = state ? 1 : 0;
-        boolean wasNotMoving = isNotMoving();
-        switch (event.getCode()) {
-            case I:
-                if (state) {
-                    System.out.println(camera);
-                }
-                break;
-            case Z:
-                if (state) {
-                    camera.setTarget(0.0, 0.0, 0.0);
-                }
-                break;
-            case W:
-            case NUMPAD8:
-            case UP:
-                this.forward = pressed;
-                break;
-            case A:
-            case Q:
-            case NUMPAD4:
-            case LEFT:
-                this.left = pressed;
-                break;
-            case S:
-            case MINUS:
-            case NUMPAD2:
-            case NUMPAD5:
-            case DOWN:
-                this.back = pressed;
-                break;
-            case D:
-            case E:
-            case NUMPAD6:
-            case RIGHT:
-                this.right = pressed;
-                break;
-            case R:
-            case T:
-            case NUMPAD9:
-            case PAGE_UP:
-                this.up = pressed;
-                break;
-            case G:
-            case NUMPAD3:
-            case PAGE_DOWN:
-                this.down = pressed;
-                break;
-            case DIGIT1:
-                speed = 5;
-                break;
-            case DIGIT2:
-                speed = 10;
-                break;
-            case DIGIT3:
-                speed = 20;
-                break;
-            case DIGIT4:
-                speed = 40;
-                break;
-            case DIGIT5:
-                speed = 60;
-                break;
-            case DIGIT6:
-                speed = 80;
-                break;
-            case DIGIT7:
-                speed = 100;
-                break;
-            case DIGIT8:
-                speed = 120;
-                break;
-            case DIGIT9:
-                speed = 140;
-                break;
-            case DIGIT0:
-                speed = 160;
-                break;
-            case O:
-                orbitSpeed = 1.0;
-                break;
-            case OPEN_BRACKET:
-                //camera.setMinZ(1.0);
-                break;
-            case CLOSE_BRACKET:
-                //camera.setMaxZ(10000.0);
-                break;
-        }
-        if (isNotMoving()) {
-            if (moveTimer != null) {
-                moveTimer.stop();
-                moveTimer = null;
-                speed = initialSpeed;
-            }
-        } else if (wasNotMoving) {
-            moveTimer = new AnimationTimer() {
-                long now = 0;
-
-                @Override
-                public void handle(long l) {
-                    if (now == 0) {
-                        now = l;
-                    } else {
-                        double age = (l - now) * 1e-9;
-                        if (age > 1.0) {
-                            speed = initialSpeed * Math.pow(2, age);
-                            if (speed > maxSpeed) {
-                                speed = maxSpeed;
-                            }
-                        }
-                    }
-                }
-            };
-            moveTimer.start();
-        }
-        event.consume();
-    }
-
-    private Vec2d getDragDelta(MouseEvent event) {
-        Vec2d res = new Vec2d();
-        res.x = event.getSceneX() - previousX;
-        res.y = event.getSceneY() - previousY;
-        previousX = event.getSceneX();
-        previousY = event.getSceneY();
-        return res;
-    }
-
-    private double getSpeedModifier(MouseEvent event) {
-        if (event.isShiftDown()) {
-            return 4.0;
-        } else if (event.isControlDown()) {
-            // We're going to use control for some other purpose
-            // than a speed modifier, at least for now
-            // return 0.25;
-            return 1.0;
-        } else {
-            return 1.0;
-        }
-    }
-
-    private void handleMousePress(MouseEvent event) {
-        previousX = event.getSceneX();
-        previousY = event.getSceneY();
-        event.consume();
-    }
-
-    private void handlePrimaryMouseDrag(MouseEvent event, Vec2d d, double localFactor) {
-        if (event.isAltDown()) {
-            orbit(d, localFactor);
-            event.consume();
-        } else if (node != null) {
-            rotateObject(d, localFactor);
-        }
-    }
-
-    private void handleMiddleMouseDrag(MouseEvent event, Vec2d d, double localFactor) {
-        if (event.isAltDown()) {
-            track(d, localFactor);
-            event.consume();
-        }
-    }
-
-    private void handleSecondaryMouseDrag(MouseEvent event, Vec2d d, double localFactor) {
-        if (event.isAltDown()) {
-            if (!event.isControlDown()) {
-                // zoom actually change distance to lookat target
-                zoom(d, localFactor);
-            } else {
-                // actually move camera forward/backward
-                move(d, localFactor);
-            }
-        } else {
-            rotate(d, localFactor);
-        }
-        event.consume();
-    }
-
-    private double getLookatDist() {
-        Vec3d target = camera.getTarget();
-        target.sub(camera.getPosition());
-        return target.length();
-    }
-
-    private void shiftCamera(Vec3d shift) {
-        Vec3d pos = camera.getPosition();
-        Vec3d target = camera.getTarget();
-        pos.add(shift);
-        target.add(shift);
-        camera.setPos(pos.x, pos.y, pos.z);
-        camera.setTarget(target.x, target.y, target.z);
-    }
-
-    static private double clamp(double val, double min, double max) {
-        return val > max ? max : val < min ? min : val;
-    }
-
-    // get direction vector from (asimut, height)
-    // 0 < asimut < 2
-    // -1 < height < 1
-    static private Vec3d globus(Vec2d ah) {
-        double ra = ah.x * Math.PI;
-        double rh = ah.y * Math.PI * 0.5;
-        double cosH = Math.cos(rh);
-        return new Vec3d(Math.sin(ra) * cosH, Math.sin(rh), Math.cos(ra) * cosH);
-    }
-
-    static private Vec2d antiGlobus(Vec3d globus) {
-        double rh = Math.asin(globus.y);
-        double ra = Math.atan2(globus.x, globus.z);
-        return new Vec2d(ra / Math.PI, rh * 2 / Math.PI);
-    }
-
-    private void orbit(Vec2d d, double speedFactor) {
-        Vec3d lookFromTarget = camera.getForward();
-        lookFromTarget.mul(-1.0); // look from target to pos
-        Vec2d ah = antiGlobus(lookFromTarget);
-        ah.x += d.x * yaw * speedFactor;
-        // -abs(pitch) - don't invert mouse when orbit?
-        ah.y -= d.y * Math.abs(pitch) * speedFactor;
-        ah.y = clamp(ah.y, -maxPitch, maxPitch);
-        lookFromTarget = globus(ah);
-        lookFromTarget.mul(getLookatDist());
-        Vec3d newPos = camera.getTarget();
-        newPos.add(lookFromTarget);
-        camera.setPos(newPos.x, newPos.y, newPos.z);
-    }
-
-    private void track(Vec2d d, double speedFactor) {
-        Vec3d shiftRight = camera.getRight();
-        shiftRight.mul(-d.x * 0.1 * orbitSpeed * speedFactor);
-        Vec3d shiftUp = camera.getUp();
-        shiftUp.mul(d.y * 0.1 * orbitSpeed * speedFactor);
-        shiftRight.add(shiftUp);
-        shiftCamera(shiftRight);
-    }
-
-    private void zoom(Vec2d d, double speedFactor) {
-        double dist = getLookatDist();
-        dist -= d.x * orbitSpeed * speedFactor;
-        dist += d.y * orbitSpeed * speedFactor;
-        if (dist < 0.1) {
-            dist = 0.1;
-        }
-        Vec3d lookFromTarget = camera.getForward();
-        lookFromTarget.mul(-1.0 * dist); // look from target to pos
-        Vec3d newPos = camera.getTarget();
-        newPos.add(lookFromTarget);
-        camera.setPos(newPos.x, newPos.y, newPos.z);
-    }
-
-    private void move(Vec2d d, double speedFactor) {
-        Vec3d shiftForward = camera.getForward();
-        shiftForward.mul(d.x * .5 * orbitSpeed * speedFactor);
-        shiftCamera(shiftForward);
-    }
-
-    private void rotate(Vec2d d, double speedFactor) {
-        Vec2d ah = antiGlobus(camera.getForward());
-        ah.x += d.x * yaw * speedFactor;
-        ah.y += d.y * pitch * speedFactor;
-        ah.y = clamp(ah.y, -maxPitch, maxPitch);
-        Vec3d lookat = globus(ah);
-        lookat.mul(getLookatDist());
-        Vec3d pos = camera.getPosition();
-        pos.add(lookat);
-        camera.setTarget(pos.x, pos.y, pos.z);
-    }
-
-    private void rotateObject(Vec2d d, double speedFactor) {
-        double angle = rotateY.getAngle();
-        angle += d.x * yaw * speedFactor * 180;
-        rotateY.setAngle(angle % 360); // just in case
-
-        angle = rotateX.getAngle();
-        angle += d.y * yaw * speedFactor * 180;
-        rotateX.setAngle(angle % 360); // just in case
-    }
-    
-    public void setObject(Node node) {
-        rotateX = new Rotate(0, new Point3D(1, 0, 0));
-        rotateY = new Rotate(0, new Point3D(0, 1, 0));
-        // explicitly add transforms to the front
-        // because max nodes are rotated during loading
-        node.getTransforms().add(0, rotateX);
-        node.getTransforms().add(1, rotateY);
-        
-        this.node = node;
-    }
-    
-    public void setInvertMouse(boolean invert) {
-        pitch = Math.abs(pitch) * (invert ? -1 : 1);
-    }
-
-    public boolean getInvertMouse() {
-        return pitch < 0;
-    }
-}
--- a/apps/toys/FX8-3DFeatures/src/fx83dfeatures/SpecularColorTestApp.java	Fri Aug 28 09:10:39 2015 -0700
+++ b/apps/toys/FX8-3DFeatures/src/fx83dfeatures/SpecularColorTestApp.java	Fri Aug 28 16:55:26 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,8 @@
  */
 package fx83dfeatures;
 
+import fx83dfeatures.utils3d.CameraController;
+import fx83dfeatures.utils3d.Camera3D;
 import java.util.ArrayList;
 import java.util.List;
 import javafx.application.Application;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/toys/FX8-3DFeatures/src/fx83dfeatures/utils3d/Camera3D.java	Fri Aug 28 16:55:26 2015 -0700
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package fx83dfeatures.utils3d;
+
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+import javafx.geometry.Point3D;
+import javafx.scene.PerspectiveCamera;
+import javafx.scene.transform.Affine;
+
+/**
+ * A movable 3D camera node
+ * The camera looks into positive Z direction
+ */
+public class Camera3D extends PerspectiveCamera {
+    public final Vec3d FORWARD = new Vec3d(0,0,1);
+    public final Vec3d UP = new Vec3d(0,-1,0);
+    public final Vec3d RIGHT = new Vec3d(1,0,0);
+
+    private final Affine transform = new Affine();
+
+    private final DoubleProperty upX = new SimpleDoubleProperty(0){
+        @Override protected void invalidated() { updateLookup(); }
+    };
+    public final double getUpX() { return upX.getValue(); }
+    public final void setUpX(double value) { upX.setValue(value); }
+    public final DoubleProperty upXModel() { return upX; }
+
+    private final DoubleProperty upY = new SimpleDoubleProperty(-1){
+        @Override protected void invalidated() { updateLookup(); }
+    };
+    public final double getUpY() { return upY.getValue(); }
+    public final void setUpY(double value) { upY.setValue(value); }
+    public final DoubleProperty upYModel() { return upY; }
+
+    private final DoubleProperty upZ = new SimpleDoubleProperty(0){
+        @Override protected void invalidated() { updateLookup(); }
+    };
+    public final double getUpZ() { return upZ.getValue(); }
+    public final void setUpZ(double value) { upZ.setValue(value); }
+    public final DoubleProperty upZModel() { return upZ; }
+
+    private final DoubleProperty targetX = new SimpleDoubleProperty(0){
+        @Override protected void invalidated() { updateLookup(); }
+    };
+    public final double getTargetX() { return targetX.getValue(); }
+    public final void setTargetX(double value) { targetX.setValue(value); }
+    public final DoubleProperty targetXModel() { return targetX; }
+
+    private final DoubleProperty targetY = new SimpleDoubleProperty(0){
+        @Override protected void invalidated() { updateLookup(); }
+    };
+    public final double getTargetY() { return targetY.getValue(); }
+    public final void setTargetY(double value) { targetY.setValue(value); }
+    public final DoubleProperty targetYModel() { return targetY; }
+
+    private final DoubleProperty targetZ = new SimpleDoubleProperty(1){
+        @Override protected void invalidated() { updateLookup(); }
+    };
+    public final double getTargetZ() { return targetZ.getValue(); }
+    public final void setTargetZ(double value) { targetZ.setValue(value); }
+    public final DoubleProperty targetZModel() { return targetZ; }
+
+    private final DoubleProperty posX = new SimpleDoubleProperty(0){
+        @Override protected void invalidated() { updateLookup(); }
+    };
+    public final double getPosX() { return posX.getValue(); }
+    public final void setPosX(double value) { posX.setValue(value); }
+    public final DoubleProperty posXModel() { return posX; }
+
+    private final DoubleProperty posY = new SimpleDoubleProperty(0){
+        @Override protected void invalidated() { updateLookup(); }
+    };
+    public final double getPosY() { return posY.getValue(); }
+    public final void setPosY(double value) { posY.setValue(value); }
+    public final DoubleProperty posYModel() { return posY; }
+
+    private final DoubleProperty posZ = new SimpleDoubleProperty(0){
+        @Override protected void invalidated() { updateLookup(); }
+    };
+    public final double getPosZ() { return posZ.getValue(); }
+    public final void setPosZ(double value) { posZ.setValue(value); }
+    public final DoubleProperty posZModel() { return posZ; }
+    
+    public Camera3D() {
+        super(true);
+        getTransforms().add(transform);
+        updateLookup();
+    }
+
+    private final Vec3f tm[] = new Vec3f[]{new Vec3f(),new Vec3f(),new Vec3f(),};
+    
+    private void updateLookup() {
+        Vec3f pos = new Vec3f((float)getPosX(), (float)getPosY(), (float)getPosZ());
+        Vec3f target = new Vec3f((float)getTargetX(), (float)getTargetY(), (float)getTargetZ());
+        Vec3f up = new Vec3f((float)getUpX(), (float)getUpY(), (float)getUpZ());
+        tm[2].sub(target, pos);         // z looks to the target
+        tm[1].set(-up.x, -up.y, -up.z); // y looks down
+        tm[0].cross(tm[1], tm[2]);      // x = y ^ z;
+        tm[1].cross(tm[2], tm[0]);      // y = z ^ x
+
+        for (int i=0; i!=3; ++i) {
+            tm[i].normalize();
+        }
+        //Vec3f pos, Vec3f tm[], Affine tma) {
+        transform.setMxx(tm[0].x); transform.setMxy(tm[1].x); transform.setMxz(tm[2].x);
+        transform.setMyx(tm[0].y); transform.setMyy(tm[1].y); transform.setMyz(tm[2].y);
+        transform.setMzx(tm[0].z); transform.setMzy(tm[1].z); transform.setMzz(tm[2].z);
+        transform.setTx (pos.x);   transform.setTy(pos.y);    transform.setTz(pos.z);
+    }
+
+    public Affine getTransform() {
+        return transform;
+    }
+
+    public void setPos(double x, double y, double z) {
+        setPosX(x);
+        setPosY(y);
+        setPosZ(z);
+    }
+    
+    public void setTarget(double x, double y, double z) {
+        setTargetX(x);
+        setTargetY(y);
+        setTargetZ(z);
+    }
+    
+    public void setUp(double x, double y, double z) {
+        setUpX(x);
+        setUpY(y);
+        setUpZ(z);
+    }
+    
+    /*
+     * returns 3D direction from the Camera position to the mouse
+     * in the Scene space 
+     */
+    
+    public Vec3d unProjectDirection(double sceneX, double sceneY, double sWidth, double sHeight) {
+        Vec3d vMouse = null;
+        
+        if (isVerticalFieldOfView()) {
+            // TODO: implement for Vfov
+        } else {
+            double tanHFov = Math.tan(Math.toRadians(getFieldOfView()) * 0.5f);
+            vMouse = new Vec3d(2*sceneX/sWidth-1, 2*sceneY/sWidth-sHeight/sWidth, 1);
+            vMouse.x *= tanHFov;
+            vMouse.y *= tanHFov;
+        }
+
+        Vec3d result = localToSceneDirection(vMouse, new Vec3d());
+        result.normalize();
+        return result;
+    }
+    
+    public Vec3d getPosition() {
+        return new Vec3d(getPosX(), getPosY(), getPosZ());
+    }
+
+    public Vec3d getTarget() {
+        return new Vec3d(getTargetX(), getTargetY(), getTargetZ());
+    }
+    
+    public Vec3d localToScene(Vec3d pt, Vec3d result) {
+        Point3D res = localToParentTransformProperty().get().transform(pt.x, pt.y, pt.z);
+        if (getParent() != null) {
+            res = getParent().localToSceneTransformProperty().get().transform(res);
+        }
+        result.set(res.getX(), res.getY(), res.getZ());
+        return result;
+    }
+    
+    public Vec3d localToSceneDirection(Vec3d dir, Vec3d result) {
+        localToScene(dir, result);
+        result.sub(localToScene(new Vec3d(0, 0, 0), new Vec3d()));
+        return result;
+    }
+    
+    public Vec3d getForward() {
+        Vec3d res = localToSceneDirection(FORWARD, new Vec3d());
+        res.normalize();
+        return res;
+    }
+
+    public Vec3d getUp() {
+        Vec3d res = localToSceneDirection(UP, new Vec3d());
+        res.normalize();
+        return res;
+    }
+
+    public Vec3d getRight() {
+        Vec3d res = localToSceneDirection(RIGHT, new Vec3d());
+        res.normalize();
+        return res;
+    }
+    
+    @Override
+    public String toString() {
+        return "camera3D.setPos(" + posX.get() + ", " + posY.get() + ", " 
+                + posZ.get() + ");\n"
+                + "camera3D.setTarget(" + targetX.get() + ", " 
+                + targetY.get() + ", " + targetZ.get() + ");\n"
+                + "camera3D.setUp(" + upX.get() + ", " + upY.get() + ", " 
+                + upZ.get() + ");";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/toys/FX8-3DFeatures/src/fx83dfeatures/utils3d/CameraController.java	Fri Aug 28 16:55:26 2015 -0700
@@ -0,0 +1,449 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package fx83dfeatures.utils3d;
+
+import javafx.animation.AnimationTimer;
+import javafx.geometry.Point3D;
+import javafx.scene.Node;
+import javafx.scene.Scene;
+import javafx.scene.SubScene;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.transform.Rotate;
+
+/**
+ * This is camera controller to use with new 3D API.
+ *
+ */
+public class CameraController {
+
+    private Camera3D camera;
+    private Node node;
+    private int up, down, left, right,
+            forward, back; // key pressed
+    private double initialSpeed = 5;
+    private double maxSpeed = 200;
+    private double speed = initialSpeed;
+    private double orbitSpeed = 1.0;
+    private double previousX, previousY;
+    private double yaw = 0.0022;
+    private double pitch = -0.0022;
+    private double maxPitch = 0.95;
+    private AnimationTimer moveTimer;
+    private Rotate rotateX;
+    private Rotate rotateY;
+
+    private void handleKeyEvent(KeyEvent t) {
+        if (t.getEventType() == KeyEvent.KEY_PRESSED) {
+            handleKeyEvent(t, true);
+        } else if (t.getEventType() == KeyEvent.KEY_RELEASED) {
+            handleKeyEvent(t, false);
+        }
+        // skip other event types
+    }
+    
+    private void handleMouseEvent(MouseEvent t) {
+        if (t.getEventType() == MouseEvent.MOUSE_PRESSED) {
+            handleMousePress(t);
+        } else if (t.getEventType() == MouseEvent.MOUSE_DRAGGED) {
+            Vec2d d = getDragDelta(t);
+            double speedModifier = getSpeedModifier(t);
+            switch (t.getButton()) {
+                case PRIMARY:
+                    // Alt + LMB = orbit
+                    handlePrimaryMouseDrag(t, d, speedModifier);
+                    break;
+                case MIDDLE:
+                    // Alt + MMB = pan/track
+                    handleMiddleMouseDrag(t, d, speedModifier);
+                    break;
+                case SECONDARY:
+                    // Alt + RMB = zoom
+                    handleSecondaryMouseDrag(t, d, speedModifier);
+                    break;
+                default:
+                    throw new AssertionError();
+            }
+        }
+    }
+
+    private void setEventHandlers(Scene scene) {
+        scene.addEventHandler(KeyEvent.ANY, k -> handleKeyEvent(k));
+        scene.addEventHandler(MouseEvent.ANY, m -> handleMouseEvent(m));
+    }
+
+    private void setEventHandlers(SubScene subScene) {
+        subScene.addEventHandler(KeyEvent.ANY, k -> handleKeyEvent(k));
+        subScene.addEventHandler(MouseEvent.ANY, m -> handleMouseEvent(m));
+    }
+
+    public CameraController(Camera3D camera) {
+        this.camera = camera;
+
+        new AnimationTimer() {
+            long now = 0;
+
+            @Override
+            public void handle(long l) {
+                if (now == 0) {
+                    now = l;
+                } else {
+                    double dt = (l - now) * 1e-9;
+                    now = l;
+                    update(dt);
+                }
+            }
+        }.start();
+    }
+
+    public CameraController(Camera3D camera, Scene scene) {
+        this(camera);
+        setEventHandlers(scene);
+    }
+
+    public CameraController(Camera3D camera, SubScene subScene) {
+        this(camera);
+        setEventHandlers(subScene);
+    }
+
+    private boolean isNotMoving() {
+        return forward - back == 0 && right - left == 0 && up - down == 0;
+    }
+
+    private void update(double dt) {
+        if (isNotMoving()) {
+            return;
+        }
+        Vec3d shiftForward = camera.getForward();
+        shiftForward.mul(forward - back);
+        Vec3d shiftRight = camera.getRight();
+        shiftRight.mul(right - left);
+        Vec3d shiftUp = camera.getUp();
+        shiftUp.mul(up - down);
+        Vec3d shift = new Vec3d(shiftForward);
+        shift.add(shiftRight);
+        shift.add(shiftUp);
+        shift.mul(speed * dt);
+        shiftCamera(shift);
+    }
+
+    private void handleKeyEvent(KeyEvent event, boolean state) {
+        int pressed = state ? 1 : 0;
+        boolean wasNotMoving = isNotMoving();
+        switch (event.getCode()) {
+            case I:
+                if (state) {
+                    System.out.println(camera);
+                }
+                break;
+            case Z:
+                if (state) {
+                    camera.setTarget(0.0, 0.0, 0.0);
+                }
+                break;
+            case W:
+            case NUMPAD8:
+            case UP:
+                this.forward = pressed;
+                break;
+            case A:
+            case Q:
+            case NUMPAD4:
+            case LEFT:
+                this.left = pressed;
+                break;
+            case S:
+            case MINUS:
+            case NUMPAD2:
+            case NUMPAD5:
+            case DOWN:
+                this.back = pressed;
+                break;
+            case D:
+            case E:
+            case NUMPAD6:
+            case RIGHT:
+                this.right = pressed;
+                break;
+            case R:
+            case T:
+            case NUMPAD9:
+            case PAGE_UP:
+                this.up = pressed;
+                break;
+            case G:
+            case NUMPAD3:
+            case PAGE_DOWN:
+                this.down = pressed;
+                break;
+            case DIGIT1:
+                speed = 5;
+                break;
+            case DIGIT2:
+                speed = 10;
+                break;
+            case DIGIT3:
+                speed = 20;
+                break;
+            case DIGIT4:
+                speed = 40;
+                break;
+            case DIGIT5:
+                speed = 60;
+                break;
+            case DIGIT6:
+                speed = 80;
+                break;
+            case DIGIT7:
+                speed = 100;
+                break;
+            case DIGIT8:
+                speed = 120;
+                break;
+            case DIGIT9:
+                speed = 140;
+                break;
+            case DIGIT0:
+                speed = 160;
+                break;
+            case O:
+                orbitSpeed = 1.0;
+                break;
+            case OPEN_BRACKET:
+                //camera.setMinZ(1.0);
+                break;
+            case CLOSE_BRACKET:
+                //camera.setMaxZ(10000.0);
+                break;
+        }
+        if (isNotMoving()) {
+            if (moveTimer != null) {
+                moveTimer.stop();
+                moveTimer = null;
+                speed = initialSpeed;
+            }
+        } else if (wasNotMoving) {
+            moveTimer = new AnimationTimer() {
+                long now = 0;
+
+                @Override
+                public void handle(long l) {
+                    if (now == 0) {
+                        now = l;
+                    } else {
+                        double age = (l - now) * 1e-9;
+                        if (age > 1.0) {
+                            speed = initialSpeed * Math.pow(2, age);
+                            if (speed > maxSpeed) {
+                                speed = maxSpeed;
+                            }
+                        }
+                    }
+                }
+            };
+            moveTimer.start();
+        }
+        event.consume();
+    }
+
+    private Vec2d getDragDelta(MouseEvent event) {
+        Vec2d res = new Vec2d();
+        res.x = event.getSceneX() - previousX;
+        res.y = event.getSceneY() - previousY;
+        previousX = event.getSceneX();
+        previousY = event.getSceneY();
+        return res;
+    }
+
+    private double getSpeedModifier(MouseEvent event) {
+        if (event.isShiftDown()) {
+            return 4.0;
+        } else if (event.isControlDown()) {
+            // We're going to use control for some other purpose
+            // than a speed modifier, at least for now
+            // return 0.25;
+            return 1.0;
+        } else {
+            return 1.0;
+        }
+    }
+
+    private void handleMousePress(MouseEvent event) {
+        previousX = event.getSceneX();
+        previousY = event.getSceneY();
+        event.consume();
+    }
+
+    private void handlePrimaryMouseDrag(MouseEvent event, Vec2d d, double localFactor) {
+        if (event.isAltDown()) {
+            orbit(d, localFactor);
+            event.consume();
+        } else if (node != null) {
+            rotateObject(d, localFactor);
+        }
+    }
+
+    private void handleMiddleMouseDrag(MouseEvent event, Vec2d d, double localFactor) {
+        if (event.isAltDown()) {
+            track(d, localFactor);
+            event.consume();
+        }
+    }
+
+    private void handleSecondaryMouseDrag(MouseEvent event, Vec2d d, double localFactor) {
+        if (event.isAltDown()) {
+            if (!event.isControlDown()) {
+                // zoom actually change distance to lookat target
+                zoom(d, localFactor);
+            } else {
+                // actually move camera forward/backward
+                move(d, localFactor);
+            }
+        } else {
+            rotate(d, localFactor);
+        }
+        event.consume();
+    }
+
+    private double getLookatDist() {
+        Vec3d target = camera.getTarget();
+        target.sub(camera.getPosition());
+        return target.length();
+    }
+
+    private void shiftCamera(Vec3d shift) {
+        Vec3d pos = camera.getPosition();
+        Vec3d target = camera.getTarget();
+        pos.add(shift);
+        target.add(shift);
+        camera.setPos(pos.x, pos.y, pos.z);
+        camera.setTarget(target.x, target.y, target.z);
+    }
+
+    static private double clamp(double val, double min, double max) {
+        return val > max ? max : val < min ? min : val;
+    }
+
+    // get direction vector from (asimut, height)
+    // 0 < asimut < 2
+    // -1 < height < 1
+    static private Vec3d globus(Vec2d ah) {
+        double ra = ah.x * Math.PI;
+        double rh = ah.y * Math.PI * 0.5;
+        double cosH = Math.cos(rh);
+        return new Vec3d(Math.sin(ra) * cosH, Math.sin(rh), Math.cos(ra) * cosH);
+    }
+
+    static private Vec2d antiGlobus(Vec3d globus) {
+        double rh = Math.asin(globus.y);
+        double ra = Math.atan2(globus.x, globus.z);
+        return new Vec2d(ra / Math.PI, rh * 2 / Math.PI);
+    }
+
+    private void orbit(Vec2d d, double speedFactor) {
+        Vec3d lookFromTarget = camera.getForward();
+        lookFromTarget.mul(-1.0); // look from target to pos
+        Vec2d ah = antiGlobus(lookFromTarget);
+        ah.x += d.x * yaw * speedFactor;
+        // -abs(pitch) - don't invert mouse when orbit?
+        ah.y -= d.y * Math.abs(pitch) * speedFactor;
+        ah.y = clamp(ah.y, -maxPitch, maxPitch);
+        lookFromTarget = globus(ah);
+        lookFromTarget.mul(getLookatDist());
+        Vec3d newPos = camera.getTarget();
+        newPos.add(lookFromTarget);
+        camera.setPos(newPos.x, newPos.y, newPos.z);
+    }
+
+    private void track(Vec2d d, double speedFactor) {
+        Vec3d shiftRight = camera.getRight();
+        shiftRight.mul(-d.x * 0.1 * orbitSpeed * speedFactor);
+        Vec3d shiftUp = camera.getUp();
+        shiftUp.mul(d.y * 0.1 * orbitSpeed * speedFactor);
+        shiftRight.add(shiftUp);
+        shiftCamera(shiftRight);
+    }
+
+    private void zoom(Vec2d d, double speedFactor) {
+        double dist = getLookatDist();
+        dist -= d.x * orbitSpeed * speedFactor;
+        dist += d.y * orbitSpeed * speedFactor;
+        if (dist < 0.1) {
+            dist = 0.1;
+        }
+        Vec3d lookFromTarget = camera.getForward();
+        lookFromTarget.mul(-1.0 * dist); // look from target to pos
+        Vec3d newPos = camera.getTarget();
+        newPos.add(lookFromTarget);
+        camera.setPos(newPos.x, newPos.y, newPos.z);
+    }
+
+    private void move(Vec2d d, double speedFactor) {
+        Vec3d shiftForward = camera.getForward();
+        shiftForward.mul(d.x * .5 * orbitSpeed * speedFactor);
+        shiftCamera(shiftForward);
+    }
+
+    private void rotate(Vec2d d, double speedFactor) {
+        Vec2d ah = antiGlobus(camera.getForward());
+        ah.x += d.x * yaw * speedFactor;
+        ah.y += d.y * pitch * speedFactor;
+        ah.y = clamp(ah.y, -maxPitch, maxPitch);
+        Vec3d lookat = globus(ah);
+        lookat.mul(getLookatDist());
+        Vec3d pos = camera.getPosition();
+        pos.add(lookat);
+        camera.setTarget(pos.x, pos.y, pos.z);
+    }
+
+    private void rotateObject(Vec2d d, double speedFactor) {
+        double angle = rotateY.getAngle();
+        angle += d.x * yaw * speedFactor * 180;
+        rotateY.setAngle(angle % 360); // just in case
+
+        angle = rotateX.getAngle();
+        angle += d.y * yaw * speedFactor * 180;
+        rotateX.setAngle(angle % 360); // just in case
+    }
+    
+    public void setObject(Node node) {
+        rotateX = new Rotate(0, new Point3D(1, 0, 0));
+        rotateY = new Rotate(0, new Point3D(0, 1, 0));
+        // explicitly add transforms to the front
+        // because max nodes are rotated during loading
+        node.getTransforms().add(0, rotateX);
+        node.getTransforms().add(1, rotateY);
+        
+        this.node = node;
+    }
+    
+    public void setInvertMouse(boolean invert) {
+        pitch = Math.abs(pitch) * (invert ? -1 : 1);
+    }
+
+    public boolean getInvertMouse() {
+        return pitch < 0;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/toys/FX8-3DFeatures/src/fx83dfeatures/utils3d/Vec2d.java	Fri Aug 28 16:55:26 2015 -0700
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package fx83dfeatures.utils3d;
+
+/**
+ * A 2-dimensional, double-precision, floating-point vector.
+ *
+ */
+public class Vec2d {
+    /**
+     * The x coordinate.
+     */
+    public double x;
+
+    /**
+     * The y coordinate.
+     */
+    public double y;
+
+    public Vec2d() { }
+
+    public Vec2d(double x, double y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    public Vec2d(Vec2d v) {
+        set(v);
+    }
+
+    public Vec2d(Vec2f v) {
+        set(v);
+    }
+
+    public void set(Vec2d v) {
+        this.x = v.x;
+        this.y = v.y;
+    }
+
+    public void set(Vec2f v) {
+        this.x = v.x;
+        this.y = v.y;
+    }
+    
+    public void set(double x, double y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    /**
+     * Returns the square of the distance between two points.
+     *
+     * @param x1 the X coordinate of the first specified point
+     * @param y1 the Y coordinate of the first specified point
+     * @param x2 the X coordinate of the second specified point
+     * @param y2 the Y coordinate of the second specified point
+     * @return the square of the distance between the two
+     * sets of specified coordinates.
+     */
+    public static double distanceSq(double x1, double y1, double x2, double y2) {
+        x1 -= x2;
+        y1 -= y2;
+        return (x1 * x1 + y1 * y1);
+    }
+
+    /**
+     * Returns the distance between two points.
+     *
+     * @param x1 the X coordinate of the first specified point
+     * @param y1 the Y coordinate of the first specified point
+     * @param x2 the X coordinate of the second specified point
+     * @param y2 the Y coordinate of the second specified point
+     * @return the distance between the two sets of specified
+     * coordinates.
+     */
+    public static double distance(double x1, double y1, double x2, double y2) {
+        x1 -= x2;
+        y1 -= y2;
+        return Math.sqrt(x1 * x1 + y1 * y1);
+    }
+
+    /**
+     * Returns the square of the distance from this
+     * <code>Vec2d</code> to a specified point.
+     *
+     * @param vx the X coordinate of the specified point to be measured
+     *           against this <code>Vec2d</code>
+     * @param vy the Y coordinate of the specified point to be measured
+     *           against this <code>Vec2d</code>
+     * @return the square of the distance between this
+     * <code>Vec2d</code> and the specified point.
+     */
+    public double distanceSq(double vx, double vy) {
+        vx -= x;
+        vy -= y;
+        return (vx * vx + vy * vy);
+    }
+
+    /**
+     * Returns the square of the distance from this
+     * <code>Vec2d</code> to a specified <code>Vec2d</code>.
+     *
+     * @param v the specified point to be measured
+     *           against this <code>Vec2d</code>
+     * @return the square of the distance between this
+     * <code>Vec2d</code> to a specified <code>Vec2d</code>.
+     */
+    public double distanceSq(Vec2d v) {
+        double vx = v.x - this.x;
+        double vy = v.y - this.y;
+        return (vx * vx + vy * vy);
+    }
+
+    /**
+     * Returns the distance from this <code>Vec2d</code> to
+     * a specified point.
+     *
+     * @param vx the X coordinate of the specified point to be measured
+     *           against this <code>Vec2d</code>
+     * @param vy the Y coordinate of the specified point to be measured
+     *           against this <code>Vec2d</code>
+     * @return the distance between this <code>Vec2d</code>
+     * and a specified point.
+     */
+    public double distance(double vx, double vy) {
+        vx -= x;
+        vy -= y;
+        return Math.sqrt(vx * vx + vy * vy);
+    }
+
+    /**
+     * Returns the distance from this <code>Vec2d</code> to a
+     * specified <code>Vec2d</code>.
+     *
+     * @param v the specified point to be measured
+     *           against this <code>Vec2d</code>
+     * @return the distance between this <code>Vec2d</code> and
+     * the specified <code>Vec2d</code>.
+     */
+    public double distance(Vec2d v) {
+        double vx = v.x - this.x;
+        double vy = v.y - this.y;
+        return Math.sqrt(vx * vx + vy * vy);
+    }
+
+    /**
+     * Returns the hashcode for this <code>Vec2d</code>.
+     * @return      a hash code for this <code>Vec2d</code>.
+     */
+    @Override
+    public int hashCode() {
+        long bits = 7L;
+        bits = 31L * bits + Double.doubleToLongBits(x);
+        bits = 31L * bits + Double.doubleToLongBits(y);
+        return (int) (bits ^ (bits >> 32));
+    }
+
+    /**
+     * Determines whether or not two 2D points or vectors are equal.
+     * Two instances of <code>Vec2d</code> are equal if the values of their
+     * <code>x</code> and <code>y</code> member fields, representing
+     * their position in the coordinate space, are the same.
+     * @param obj an object to be compared with this <code>Vec2d</code>
+     * @return <code>true</code> if the object to be compared is
+     *         an instance of <code>Vec2d</code> and has
+     *         the same values; <code>false</code> otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof Vec2d) {
+            Vec2d v = (Vec2d) obj;
+            return (x == v.x) && (y == v.y);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a <code>String</code> that represents the value
+     * of this <code>Vec2d</code>.
+     * @return a string representation of this <code>Vec2d</code>.
+     */
+    @Override
+    public String toString() {
+        return "Vec2d[" + x + ", " + y + "]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/toys/FX8-3DFeatures/src/fx83dfeatures/utils3d/Vec2f.java	Fri Aug 28 16:55:26 2015 -0700
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates.
+ * All rights reserved. Use is subject to license terms.
+ *
+ * This file is available and licensed under the following license:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the distribution.
+ *  - Neither the name of Oracle Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package fx83dfeatures.utils3d;
+
+/**
+ * A 2-dimensional, single-precision, floating-point vector.
+ */
+public class Vec2f {
+    /**
+     * The x coordinate.
+     */
+    public float x;
+
+    /**
+     * The y coordinate.
+     */
+    public float y;
+
+    public Vec2f() {
+    }
+
+    public Vec2f(float x, float y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    public Vec2f(Vec2f v) {
+        this.x = v.x;
+        this.y = v.y;
+    }
+
+
+    /**
+     * Sets the location of this <code>Vec2f</code> to the same
+     * coordinates as the specified <code>Vec2f</code> object.
+     *
+     * @param v the specified <code>Vec2f</code> to which to set
+     *          this <code>Vec2f</code>
+     */
+    public void set(Vec2f v) {
+        this.x = v.x;
+        this.y = v.y;
+    }
+
+    /**
+     * Sets the location of this <code>Vec2f</code> to the
+     * specified <code>float</code> coordinates.
+     *
+     * @param x the new X coordinate of this {@code Vec2f}
+     * @param y the new Y coordinate of this {@code Vec2f}
+     */
+    public void set(float x, float y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    /**
+     * Returns the square of the distance between two points.
+     *
+     * @param x1 the X coordinate of the first specified point
+     * @param y1 the Y coordinate of the first specified point
+     * @param x2 the X coordinate of the second specified point
+     * @param y2 the Y coordinate of the second specified point
+     * @return the square of the distance between the two
+     * sets of specified coordinates.
+     */
+    public static float distanceSq(float x1, float y1, float x2, float y2) {
+        x1 -= x2;
+        y1 -= y2;
+        return (x1 * x1 + y1 * y1);
+    }
+
+    /**
+     * Returns the distance between two points.
+     *
+     * @param x1 the X coordinate of the first specified point
+     * @param y1 the Y coordinate of the first specified point
+     * @param x2 the X coordinate of the second specified point
+     * @param y2 the Y coordinate of the second specified point
+     * @return the distance between the two sets of specified
+     * coordinates.
+     */
+    public static float distance(float x1, float y1, float x2, float y2) {
+        x1 -= x2;
+        y1 -= y2;
+        return (float) Math.sqrt(x1 * x1 + y1 * y1);
+    }
+
+    /**
+     * Returns the square of the distance from this
+     * <code>Vec2f</code> to a specified point.
+     *
+     * @param vx the X coordinate of the specified point to be measured
+     *           against this <code>Vec2f</code>
+     * @param vy the Y coordinate of the specified point to be measured
+     *           against this <code>Vec2f</code>
+     * @return the square of the distance between this
+     * <code>Vec2f</code> and the specified point.
+     */
+    public float distanceSq(float vx, float vy) {
+        vx -= x;
+        vy -= y;
+        return (vx * vx + vy * vy);
+    }
+
+    /**
+     * Returns the square of the distance from this
+     * <code>Vec2f</code> to a specified <code>Vec2f</code>.
+     *
+     * @param v the specified point to be measured
+     *          against this <code>Vec2f</code>
+     * @return the square of the distance between this
+     * <code>Vec2f</code> to a specified <code>Vec2f</code>.
+     */
+    public float distanceSq(Vec2f v) {
+        float vx = v.x - this.x;
+        float vy = v.y - this.y;
+        return (vx * vx + vy * vy);
+    }
+
+    /**
+     * Returns the distance from this <code>Vec2f</code> to
+     * a specified point.
+     *
+     * @param vx the X coordinate of the specified point to be measured
+     *           against this <code>Vec2f</code>
+     * @param vy the Y coordinate of the specified point to be measured
+     *           against this <code>Vec2f</code>
+     * @return the distance between this <code>Vec2f</code>
+     * and a specified point.
+     */
+    public float distance(float vx, float vy) {
+        vx -= x;
+        vy -= y;
+        return (float) Math.sqrt(vx * vx + vy * vy);
+    }
+
+    /**
+     * Returns the distance from this <code>Vec2f</code> to a
+     * specified <code>Vec2f</code>.
+     *
+     * @param v the specified point to be measured
+     *          against this <code>Vec2f</code>
+     * @return the distance between this <code>Vec2f</code> and
+     * the specified <code>Vec2f</code>.
+     */
+    public float distance(Vec2f v) {
+        float vx = v.x - this.x;
+        float vy = v.y - this.y;
+        return (float) Math.sqrt(vx * vx + vy * vy);
+    }
+
+    /**
+     * Returns the hashcode for this <code>Vec2f</code>.
+     *
+     * @return a hash code for this <code>Vec2f</code>.
+     */
+    @Override
+    public int hashCode() {
+        int bits = 7;
+        bits = 31 * bits + Float.floatToIntBits(x);
+        bits = 31 * bits + Float.floatToIntBits(y);
+        return bits;
+    }
+
+    /**
+     * Determines whether or not two 2D points or vectors are equal.
+     * Two instances of <code>Vec2f</code> are equal if the values of their
+     * <code>x</code> and <code>y</code> member fields, representing
+     * their position in the coordinate space, are the same.
+     *
+     * @param obj an object to be compared with this <code>Vec2f</code>
+     * @return <code>true</code> if the object to be compared is
+     * an instance of <code>Vec2f</code> and has
+     * the same values; <code>false</code> otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) return true;
+        if (obj instanceof Vec2f) {
+            Vec2f v = (Vec2f) obj;
+            return (x == v.x) && (y == v.y);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a <code>String</code> that represents the value
+     * of this <code>Vec2f</code>.
+     *
+     * @return a string representation of this <code>Vec2f</code>.
+     */
+    @Override
+    public String toString() {
+        return "Vec2f[" + x + ", " + y + "]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/toys/FX8-3DFeatures/src/fx83dfeatures/utils3d/Vec3d.java	Fri Aug 28 16:55:26 2015 -0700
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates.
+ * All rights reserved. Use is subject to license terms.
+ *
+ * This file is available and licensed under the following license:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the distribution.
+ *  - Neither the name of Oracle Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package fx83dfeatures.utils3d;
+
+/**
+ * A 3-dimensional, double-precision, floating-point vector.
+ */
+public class Vec3d {
+    /**
+     * The x coordinate.
+     */
+    public double x;
+
+    /**
+     * The y coordinate.
+     */
+    public double y;
+
+    /**
+     * The z coordinate.
+     */
+    public double z;
+
+    public Vec3d() {
+    }
+
+    public Vec3d(double x, double y, double z) {
+        this.x = x;
+        this.y = y;
+        this.z = z;
+    }
+
+    public Vec3d(Vec3d v) {
+        set(v);
+    }
+
+    public Vec3d(Vec3f v) {
+        set(v);
+    }
+
+    public void set(Vec3f v) {
+        this.x = v.x;
+        this.y = v.y;
+        this.z = v.z;
+    }
+
+    public void set(Vec3d v) {
+        this.x = v.x;
+        this.y = v.y;
+        this.z = v.z;
+    }
+
+    public void set(double x, double y, double z) {
+        this.x = x;
+        this.y = y;
+        this.z = z;
+    }
+
+    /**
+     * Multiplies this vector by the specified scalar value.
+     *
+     * @param scale the scalar value
+     */
+    public void mul(double scale) {
+        x *= scale;
+        y *= scale;
+        z *= scale;
+    }
+
+    /**
+     * Sets the value of this vector to the difference
+     * of vectors t1 and t2 (this = t1 - t2).
+     *
+     * @param t1 the first vector
+     * @param t2 the second vector
+     */
+    public void sub(Vec3f t1, Vec3f t2) {
+        this.x = t1.x - t2.x;
+        this.y = t1.y - t2.y;
+        this.z = t1.z - t2.z;
+    }
+
+    /**
+     * Sets the value of this vector to the difference
+     * of vectors t1 and t2 (this = t1 - t2).
+     *
+     * @param t1 the first vector
+     * @param t2 the second vector
+     */
+    public void sub(Vec3d t1, Vec3d t2) {
+        this.x = t1.x - t2.x;
+        this.y = t1.y - t2.y;
+        this.z = t1.z - t2.z;
+    }
+
+    /**
+     * Sets the value of this vector to the difference of
+     * itself and vector t1 (this = this - t1) .
+     *
+     * @param t1 the other vector
+     */
+    public void sub(Vec3d t1) {
+        this.x -= t1.x;
+        this.y -= t1.y;
+        this.z -= t1.z;
+    }
+
+    /**
+     * Sets the value of this vector to the sum
+     * of vectors t1 and t2 (this = t1 + t2).
+     *
+     * @param t1 the first vector
+     * @param t2 the second vector
+     */
+    public void add(Vec3d t1, Vec3d t2) {
+        this.x = t1.x + t2.x;
+        this.y = t1.y + t2.y;
+        this.z = t1.z + t2.z;
+    }
+
+    /**
+     * Sets the value of this vector to the sum of
+     * itself and vector t1 (this = this + t1) .
+     *
+     * @param t1 the other vector
+     */
+    public void add(Vec3d t1) {
+        this.x += t1.x;
+        this.y += t1.y;
+        this.z += t1.z;
+    }
+
+    /**
+     * Returns the length of this vector.
+     *
+     * @return the length of this vector
+     */
+    public double length() {
+        return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
+    }
+
+    /**
+     * Normalize this vector.
+     */
+    public void normalize() {
+        double norm = 1.0 / length();
+        this.x = this.x * norm;
+        this.y = this.y * norm;
+        this.z = this.z * norm;
+    }
+
+    /**
+     * Sets this vector to be the vector cross product of vectors v1 and v2.
+     *
+     * @param v1 the first vector
+     * @param v2 the second vector
+     */
+    public void cross(Vec3d v1, Vec3d v2) {
+        double tmpX;
+        double tmpY;
+
+        tmpX = v1.y * v2.z - v1.z * v2.y;
+        tmpY = v2.x * v1.z - v2.z * v1.x;
+        this.z = v1.x * v2.y - v1.y * v2.x;
+        this.x = tmpX;
+        this.y = tmpY;
+    }
+
+    /**
+     * Computes the dot product of this vector and vector v1.
+     *
+     * @param v1 the other vector
+     * @return the dot product of this vector and v1
+     */
+    public double dot(Vec3d v1) {
+        return this.x * v1.x + this.y * v1.y + this.z * v1.z;
+    }
+
+    /**
+     * Returns the hashcode for this <code>Vec3f</code>.
+     *
+     * @return a hash code for this <code>Vec3f</code>.
+     */
+    @Override
+    public int hashCode() {
+        long bits = 7L;
+        bits = 31L * bits + Double.doubleToLongBits(x);
+        bits = 31L * bits + Double.doubleToLongBits(y);
+        bits = 31L * bits + Double.doubleToLongBits(z);
+        return (int) (bits ^ (bits >> 32));
+    }
+
+    /**
+     * Determines whether or not two 3D points or vectors are equal.
+     * Two instances of <code>Vec3d</code> are equal if the values of their
+     * <code>x</code>, <code>y</code> and <code>z</code> member fields,
+     * representing their position in the coordinate space, are the same.
+     *
+     * @param obj an object to be compared with this <code>Vec3d</code>
+     * @return <code>true</code> if the object to be compared is
+     * an instance of <code>Vec3d</code> and has
+     * the same values; <code>false</code> otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof Vec3d) {
+            Vec3d v = (Vec3d) obj;
+            return (x == v.x) && (y == v.y) && (z == v.z);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a <code>String</code> that represents the value
+     * of this <code>Vec3f</code>.
+     *
+     * @return a string representation of this <code>Vec3f</code>.
+     */
+    @Override
+    public String toString() {
+        return "Vec3d[" + x + ", " + y + ", " + z + "]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/toys/FX8-3DFeatures/src/fx83dfeatures/utils3d/Vec3f.java	Fri Aug 28 16:55:26 2015 -0700
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates.
+ * All rights reserved. Use is subject to license terms.
+ *
+ * This file is available and licensed under the following license:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the distribution.
+ *  - Neither the name of Oracle Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package fx83dfeatures.utils3d;
+
+/**
+ * A 3-dimensional, single-precision, floating-point vector.
+ */
+public class Vec3f {
+    /**
+     * The x coordinate.
+     */
+    public float x;
+
+    /**
+     * The y coordinate.
+     */
+    public float y;
+
+    /**
+     * The z coordinate.
+     */
+    public float z;
+
+    public Vec3f() {
+    }
+
+    public Vec3f(float x, float y, float z) {
+        this.x = x;
+        this.y = y;
+        this.z = z;
+    }
+
+    public Vec3f(Vec3f v) {
+        this.x = v.x;
+        this.y = v.y;
+        this.z = v.z;
+    }
+
+    public void set(Vec3f v) {
+        this.x = v.x;
+        this.y = v.y;
+        this.z = v.z;
+    }
+
+    public void set(float x, float y, float z) {
+        this.x = x;
+        this.y = y;
+        this.z = z;
+    }
+
+    public final void mul(float s) {
+        this.x *= s;
+        this.y *= s;
+        this.z *= s;
+    }
+
+    /**
+     * Sets the value of this vector to the difference
+     * of vectors t1 and t2 (this = t1 - t2).
+     *
+     * @param t1 the first vector
+     * @param t2 the second vector
+     */
+    public void sub(Vec3f t1, Vec3f t2) {
+        this.x = t1.x - t2.x;
+        this.y = t1.y - t2.y;
+        this.z = t1.z - t2.z;
+    }
+
+    /**
+     * Sets the value of this vector to the difference of
+     * itself and vector t1 (this = this - t1) .
+     *
+     * @param t1 the other vector
+     */
+    public void sub(Vec3f t1) {
+        this.x -= t1.x;
+        this.y -= t1.y;
+        this.z -= t1.z;
+    }
+
+    /**
+     * Sets the value of this vector to the sum
+     * of vectors t1 and t2 (this = t1 + t2).
+     *
+     * @param t1 the first vector
+     * @param t2 the second vector
+     */
+    public void add(Vec3f t1, Vec3f t2) {
+        this.x = t1.x + t2.x;
+        this.y = t1.y + t2.y;
+        this.z = t1.z + t2.z;
+    }
+
+    /**
+     * Sets the value of this vector to the sum of
+     * itself and vector t1 (this = this + t1) .
+     *
+     * @param t1 the other vector
+     */
+    public void add(Vec3f t1) {
+        this.x += t1.x;
+        this.y += t1.y;
+        this.z += t1.z;
+    }
+
+    /**
+     * Returns the length of this vector.
+     *
+     * @return the length of this vector
+     */
+    public float length() {
+        return (float) Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
+    }
+
+    /**
+     * Normalize this vector.
+     */
+    public void normalize() {
+        float norm = 1.0f / length();
+        this.x = this.x * norm;
+        this.y = this.y * norm;
+        this.z = this.z * norm;
+    }
+
+    /**
+     * Sets this vector to be the vector cross product of vectors v1 and v2.
+     *
+     * @param v1 the first vector
+     * @param v2 the second vector
+     */
+    public void cross(Vec3f v1, Vec3f v2) {
+        float tmpX;
+        float tmpY;
+
+        tmpX = v1.y * v2.z - v1.z * v2.y;
+        tmpY = v2.x * v1.z - v2.z * v1.x;
+        this.z = v1.x * v2.y - v1.y * v2.x;
+        this.x = tmpX;
+        this.y = tmpY;
+    }
+
+    /**
+     * Computes the dot product of this vector and vector v1.
+     *
+     * @param v1 the other vector
+     * @return the dot product of this vector and v1
+     */
+    public float dot(Vec3f v1) {
+        return this.x * v1.x + this.y * v1.y + this.z * v1.z;
+    }
+
+    /**
+     * Returns the hashcode for this <code>Vec3f</code>.
+     *
+     * @return a hash code for this <code>Vec3f</code>.
+     */
+    @Override
+    public int hashCode() {
+        int bits = 7;
+        bits = 31 * bits + Float.floatToIntBits(x);
+        bits = 31 * bits + Float.floatToIntBits(y);
+        bits = 31 * bits + Float.floatToIntBits(z);
+        return bits;
+    }
+
+    /**
+     * Determines whether or not two 3D points or vectors are equal.
+     * Two instances of <code>Vec3f</code> are equal if the values of their
+     * <code>x</code>, <code>y</code> and <code>z</code> member fields,
+     * representing their position in the coordinate space, are the same.
+     *
+     * @param obj an object to be compared with this <code>Vec3f</code>
+     * @return <code>true</code> if the object to be compared is
+     * an instance of <code>Vec3f</code> and has
+     * the same values; <code>false</code> otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof Vec3f) {
+            Vec3f v = (Vec3f) obj;
+            return (x == v.x) && (y == v.y) && (z == v.z);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a <code>String</code> that represents the value
+     * of this <code>Vec3f</code>.
+     *
+     * @return a string representation of this <code>Vec3f</code>.
+     */
+    @Override
+    public String toString() {
+        return "Vec3f[" + x + ", " + y + ", " + z + "]";
+    }
+}
--- a/apps/toys/Hello/src/main/java/hello/BMPOutputStream.java	Fri Aug 28 09:10:39 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package hello;
-
-import java.io.*;
-
-/**
- * The class creates an OutputStream in BMP format from
- * integer array, width and height of the image.
- */
-
-public class BMPOutputStream extends FilterOutputStream{
-
-
-    BMPOutputStream(OutputStream out, int [] arr, int width, int height) {
-        super(out);
-        try {
-            int lineByteWidth = ((width * 3 + 3) >> 2) << 2;
-            out.write(0x42);
-            out.write(0x4d);
-            writeBMPInt(out, lineByteWidth * height + 0x36);
-            writeBMPInt(out, 0);
-            writeBMPInt(out, 0x36);
-            writeBMPInt(out, 0x28);
-            writeBMPInt(out, width);
-            writeBMPInt(out, height);
-            writeBMPShort(out, 0x01);
-            writeBMPShort(out, 0x18);
-            writeBMPInt(out, 0);
-            writeBMPInt(out, lineByteWidth * height);
-            writeBMPInt(out, 0xb13);
-            writeBMPInt(out, 0xb13);
-            writeBMPInt(out, 0);
-            writeBMPInt(out, 0);
-            out.flush();
-
-            int yIncrement = height;
-
-            byte[] line = new byte[lineByteWidth];
-
-            for (int i = yIncrement - 1; i >= 0; i--) {
-                java.util.Arrays.fill(line,(byte)0);
-                int pixelRowStart = i * width;
-                int byteOffsetInLine = 0;
-                for (int imgX = 0; imgX < width; imgX++) {
-                    int rgb = arr[pixelRowStart + imgX];
-                    line[byteOffsetInLine++] = (byte) (rgb & 0xff);
-                    line[byteOffsetInLine++] = (byte) ((rgb >> 8) & 0xff);
-                    line[byteOffsetInLine++] = (byte) ((rgb >> 16) & 0xff);
-                }
-                out.write(line);
-            }
-            out.flush();
-            out.close();
-
-        } catch (Exception e) {}
-    }
-
-    private static void writeBMPInt(OutputStream out, int i) throws IOException {
-        out.write(i & 0xff);
-        out.write((i >> 8) & 0xff);
-        out.write((i >> 16) & 0xff);
-        out.write(i >> 24);
-    }
-
-    private static void writeBMPShort(OutputStream out, int i) throws IOException {
-        out.write(i & 0xff);
-        out.write((i >> 8) & 0xff);
-    }
-}
--- a/apps/toys/Hello/src/main/java/hello/HelloFPS.java	Fri Aug 28 09:10:39 2015 -0700
+++ b/apps/toys/Hello/src/main/java/hello/HelloFPS.java	Fri Aug 28 16:55:26 2015 -0700
@@ -40,6 +40,7 @@
 
 import com.sun.javafx.perf.PerformanceTracker;
 
+// FIXME: Needs public performance tracker API else move to tests/manual
 public class HelloFPS extends Application {
 
     private static final Color colors[] = {
--- a/apps/toys/Hello/src/main/java/hello/HelloRectangle3D.java	Fri Aug 28 09:10:39 2015 -0700
+++ b/apps/toys/Hello/src/main/java/hello/HelloRectangle3D.java	Fri Aug 28 16:55:26 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,9 +26,7 @@
 package hello;
 
 import javafx.animation.Interpolator;
-import javafx.animation.KeyFrame;
 import javafx.animation.RotateTransition;
-import javafx.animation.Timeline;
 import javafx.application.Application;
 import javafx.scene.Group;
 import javafx.scene.PerspectiveCamera;
@@ -43,8 +41,6 @@
 import javafx.stage.Stage;
 import javafx.util.Duration;
 
-import com.sun.javafx.perf.PerformanceTracker;
-
 /**
  */
 public class HelloRectangle3D extends Application {
@@ -84,12 +80,6 @@
         tx.setInterpolator(Interpolator.LINEAR);
         tx.play();
 
-        PerformanceTracker tracker = PerformanceTracker.getSceneTracker(scene);
-        Timeline t = new Timeline(
-            new KeyFrame(Duration.seconds(1), event -> System.out.println("" + tracker.getAverageFPS() + " average fps, " + tracker.getInstantFPS() + " instant fps"))
-        );
-        t.setCycleCount(Timeline.INDEFINITE);
-        t.play();
     }
 
     private Rectangle rect(double x, double y, double width, double height, Color color) {
--- a/apps/toys/Hello/src/main/java/hello/HelloSanity.java	Fri Aug 28 09:10:39 2015 -0700
+++ b/apps/toys/Hello/src/main/java/hello/HelloSanity.java	Fri Aug 28 16:55:26 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,8 +36,6 @@
 import javafx.geometry.Pos;
 import javafx.geometry.Rectangle2D;
 
-import java.io.File;
-
 /**
  *  The application should be used by QA in order to test main
  *  FX functionality
@@ -78,16 +76,13 @@
         Button bEffs = new Button("Effects");
         bEffs.setOnAction(e -> builder.effectsTest(globalScene, mainBox));
 
-        Button bRobot = new Button("Robot");
-        bRobot.setOnAction(e -> builder.robotTest(globalScene, mainBox, primaryStage));
-
         Button bgestures = new Button("Gesture Actions");
         bgestures.setOnAction(e -> builder.GestureTest(globalScene, mainBox));
         
         Button bquit = new Button("Quit");
         bquit.setOnAction(e -> primaryStage.close());
         
-        mainBox.getChildren().addAll(welcome, bControls, bTabs, bWins, bRobot,
+        mainBox.getChildren().addAll(welcome, bControls, bTabs, bWins,
                                      bAnim, bEffs, bgestures, bquit);
         globalScene.setRoot(mainBox);
         globalScene.getStylesheets().add("hello/HelloSanityStyles.css");
--- a/apps/toys/Hello/src/main/java/hello/HelloTiger.java	Fri Aug 28 09:10:39 2015 -0700
+++ b/apps/toys/Hello/src/main/java/hello/HelloTiger.java	Fri Aug 28 16:55:26 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@
 
 package hello;
 
-import javafx.animation.AnimationTimer;
 import javafx.animation.FillTransition;
 import javafx.animation.RotateTransition;
 import javafx.application.Application;
@@ -35,7 +34,6 @@
 import javafx.scene.shape.Rectangle;
 import javafx.stage.Stage;
 import javafx.util.Duration;
-import com.sun.javafx.perf.PerformanceTracker;
 
 /**
  * Spins the tiger!
@@ -70,18 +68,6 @@
         rot.setToAngle(360);
         rot.play();
 
-        final PerformanceTracker tracker = PerformanceTracker.getSceneTracker(scene);
-        AnimationTimer trackerTimer = new AnimationTimer() {
-            long ticks = 0;
-            @Override
-            public void handle(long now) {
-                ticks++;
-                if (ticks % 60 == 0) {
-                    System.out.println(tracker.getInstantFPS());
-                }
-            }
-        };
-        trackerTimer.start();
     }
 
     public static void main(String[] args) {
--- a/apps/toys/Hello/src/main/java/hello/HelloTouch.java	Fri Aug 28 09:10:39 2015 -0700
+++ b/apps/toys/Hello/src/main/java/hello/HelloTouch.java	Fri Aug 28 16:55:26 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,15 +25,9 @@
 
 package hello;
 
-import javafx.beans.value.ChangeListener;
-import javafx.beans.value.ObservableValue;
-import javafx.beans.property.DoubleProperty;
-import javafx.event.Event;
 import javafx.event.EventHandler;
-import javafx.scene.Group;
 import javafx.scene.Scene;
 import javafx.scene.control.*;
-import javafx.scene.text.Text;
 import javafx.scene.text.Font;
 import javafx.scene.shape.Rectangle;
 import javafx.scene.layout.VBox;
@@ -44,11 +38,7 @@
 import javafx.stage.Stage;
 import javafx.stage.Screen;
 import javafx.application.Application;
-import javafx.geometry.Pos;
 import javafx.geometry.Point2D;
-import javafx.geometry.Insets;
-
-import com.sun.glass.ui.Robot;
 
 public class HelloTouch extends Application {
 
--- a/apps/toys/Hello/src/main/java/hello/TestBuilder.java	Fri Aug 28 09:10:39 2015 -0700
+++ b/apps/toys/Hello/src/main/java/hello/TestBuilder.java	Fri Aug 28 16:55:26 2015 -0700
@@ -25,9 +25,6 @@
 
 package hello;
 
-import java.io.*;
-import java.nio.Buffer;
-import java.nio.IntBuffer;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import javafx.animation.PathTransition;
@@ -45,8 +42,6 @@
 import javafx.event.Event;
 import javafx.event.EventHandler;
 import javafx.geometry.Insets;
-import javafx.geometry.Bounds;
-import javafx.geometry.BoundingBox;
 import javafx.geometry.Orientation;
 import javafx.geometry.Point3D;
 import javafx.geometry.Pos;
@@ -63,7 +58,6 @@
 import javafx.scene.input.KeyCode;
 import javafx.scene.input.KeyCodeCombination;
 import javafx.scene.input.KeyCombination;
-import javafx.scene.input.SwipeEvent;
 import javafx.scene.layout.*;
 import javafx.scene.paint.Color;
 import javafx.scene.shape.CubicCurveTo;
@@ -75,15 +69,12 @@
 import javafx.scene.text.FontWeight;
 import javafx.scene.text.Text;
 import javafx.scene.transform.Rotate;
-import javafx.animation.AnimationTimer;
 import javafx.stage.Modality;
 import javafx.stage.Popup;
 import javafx.stage.Stage;
 import javafx.util.Callback;
 import javafx.util.Duration;
-import com.sun.glass.events.KeyEvent;
-import com.sun.glass.ui.Robot;
-    
+
 /**
  * The class is a singleton, used by HelloSanity application 
  * for tests creation 
@@ -94,7 +85,6 @@
     //Variables used by "HelloMenu" section
     private CheckMenuItem showMessagesItem;
     private final Label sysMenuLabel = new Label("Using System Menu");
-    private Popup screenShot;
 
     //Variables used by "HelloComboBox" section
     private final ObservableList<String> strings = FXCollections.observableArrayList(
@@ -120,9 +110,6 @@
     private final static int column_disabled = 160;
     private final static int line_spacing = 30;
 
-    //Variable used by "RobotTest" section
-    private final Rectangle rec1 = new Rectangle(50, 50, 40, 160);
-
     private boolean playing = false;
     
     private static TestBuilder instance;
@@ -1517,391 +1504,6 @@
     }
 
     /**
-     * The method updates globalScene with robot tests
-     * @param globalScene the global Scene
-     * @param mainBox the Box to insert into
-     * @param robotStage the Robot Stage
-     */
-    public void robotTest(final Scene globalScene, final VBox mainBox,
-                          final Stage robotStage){
-
-        Label l = new Label("Robot features Demo");
-        Group lGroup = new Group(l);
-        lGroup.setLayoutX(400);
-        lGroup.setLayoutY(10);
-
-    	//Rectangle's coordinates
-        final int recX = 50;
-        final int recY = 50;
-
-        Group allGroup = new Group();
-        rec1.setFill(Color.RED);
-        Rectangle rec2 = new Rectangle(recX + 40, recY, 40, 160);
-        rec2.setFill(Color.BLUE);
-        Rectangle rec3 = new Rectangle(recX + 80, recY, 40, 160);
-        rec3.setFill(Color.YELLOW);
-        Rectangle rec4 = new Rectangle(recX + 120, recY, 40, 160);
-        rec4.setFill(Color.GREEN);
-
-        GridPane grid = new GridPane();
-        grid.setVgap(50);
-        grid.setHgap(20);
-        grid.setLayoutX(recX + 300);
-        grid.setLayoutY(recY + 50);
-
-        final TextField result1 = new TextField("Result");
-        result1.setEditable(false);
-        Button screenTestBtn = new Button("Robot Get Screen Capture Test");
-        screenTestBtn.setOnAction(new EventHandler<ActionEvent>() {
-            @Override public void handle(ActionEvent e) {
-               screenShot = robotScreenTest(result1, robotStage);
-            }
-        });
-
-        grid.setConstraints(screenTestBtn, 0, 0);
-        grid.getChildren().add(screenTestBtn);
-        grid.setConstraints(result1, 1, 0);
-        grid.getChildren().add(result1);
-
-        final TextField result2 = new TextField("Result");
-        result2.setEditable(false);
-        Button pixelTestBtn = new Button("Robot Get Pixel Color Test");
-        pixelTestBtn.setOnAction(new EventHandler<ActionEvent>() {
-            @Override public void handle(ActionEvent e) {
-               robotPixelTest(result2, robotStage);
-            }
-        });
-
-        grid.setConstraints(pixelTestBtn, 0, 1);
-        grid.getChildren().add(pixelTestBtn);
-        grid.setConstraints(result2, 1, 1);
-        grid.getChildren().add(result2);
-
-        //KeyPressRelesase
-        final TextField writeField = new TextField("");
-        Group writeFieldGroup = new Group(writeField);
-        writeFieldGroup.setLayoutX(recX);
-        writeFieldGroup.setLayoutY(recY + 200);
-
-        final TextField result3 = new TextField("Result");
-        result3.setEditable(false);
-
-        Button keyTestBtn = new Button("Robot Key Press/Release Test");
-        keyTestBtn.setOnAction(new EventHandler<ActionEvent>() {
-            @Override public void handle(ActionEvent e) {
-                robotKeyTest(writeField, result3);
-            }
-        });
-
-        grid.setConstraints(keyTestBtn, 0, 2);
-        grid.getChildren().add(keyTestBtn);
-        grid.setConstraints(result3, 1, 2);
-        grid.getChildren().add(result3);
-
-        //Mouse wheel
-        final ListView<String> sv = new ListView<String>();
-        ObservableList<String> items =FXCollections.observableArrayList (
-                    "a", "b", "c", "d", "e", "f", "g", "h", "i");
-        sv.setItems(items);
-        sv.setPrefWidth(100);
-        sv.setPrefHeight(100);
-
-        Group svGroup = new Group(sv);
-        svGroup.setLayoutX(recX);
-        svGroup.setLayoutY(recY + 250);
-
-        final TextField result4 = new TextField("Result");
-        result4.setEditable(false);
-
-        Button wheelTestBtn = new Button("Robot Mouse Press/Release/Wheel Test");
-        wheelTestBtn.setOnAction(new EventHandler<ActionEvent>() {
-            @Override public void handle(ActionEvent e) {
-                robotWheelTest(sv, result4, robotStage);
-            }
-        });
-
-        grid.setConstraints(wheelTestBtn, 0, 3);
-        grid.getChildren().add(wheelTestBtn);
-        grid.setConstraints(result4, 1, 3);
-        grid.getChildren().add(result4);
-
-        Button btn = new Button("Back");
-        btn.setOnAction(new EventHandler<ActionEvent>() {
-            @Override public void handle(ActionEvent e) {
-                if (screenShot.isShowing()) {
-                    screenShot.hide();
-                }
-                globalScene.setRoot(mainBox);
-            }
-        });
-        Group btnGroup = new Group(btn);
-        btnGroup.setLayoutX(450);
-        btnGroup.setLayoutY(450);
-
-        allGroup.getChildren().addAll(rec1, rec2, rec3, rec4, grid, lGroup, btnGroup,
-                                      writeFieldGroup, svGroup);
-        globalScene.setRoot(allGroup);
-    }
-
-
-   public void robotKeyTest(final TextField field, final TextField result) {
-		field.requestFocus();
-		new AnimationTimer() {
-			long startTime = System.nanoTime();
-			@Override 
-			public void handle(long now) {
-				if (now > startTime + 3000000000l){ 
-					stop(); 
-					field.setText("Failed");
-				} else if (field.isFocused()) {
-					stop();
-					Robot robot = com.sun.glass.ui.Application.GetApplication().createRobot();
-					robot.keyPress(KeyEvent.VK_T);
-					robot.keyRelease(KeyEvent.VK_T);
-					robot.keyPress(KeyEvent.VK_E);
-					robot.keyRelease(KeyEvent.VK_E);
-					robot.keyPress(KeyEvent.VK_S);
-					robot.keyRelease(KeyEvent.VK_S);
-					robot.keyPress(KeyEvent.VK_T);
-					robot.keyRelease(KeyEvent.VK_T);
-					robot.destroy();
-					new AnimationTimer() {
-						long startTime = System.nanoTime();
-						@Override
-						public void handle(long now) {
-							if (now > startTime + 3000000000l){ 
-								stop();
-								result.setText("Failed");
-							} else if ((field.getText()).equals("test")) { 
-								stop();
-								result.setText("Passed");
-							}
-						}
-					}.start();
-				}
-			}
-		}.start();
-	}
-
-    public void robotWheelTest(final ListView<String> lv, final TextField result,
-                                                            Stage currentStage){
-
-		//Caclulation of ListView minimal coordinates
-		Bounds bounds = lv.localToScreen(new BoundingBox(0, 0, 
-	        lv.getBoundsInParent().getWidth(),
-	        lv.getBoundsInParent().getHeight()));
-		int x = 10 + (int) bounds.getMinX();
-		int y = 10 + (int) bounds.getMinY();
-
-		final Robot robot =
-                    com.sun.glass.ui.Application.GetApplication().createRobot();
-        robot.mouseMove(x, y);
-        robot.mousePress(Robot.MOUSE_LEFT_BTN);
-        robot.mouseRelease(Robot.MOUSE_LEFT_BTN);
-
-		new AnimationTimer() {
-			long startTime = System.nanoTime();
-			@Override 
-			public void handle(long now) {
-				if (now > startTime + 3000000000l){ 
-					stop(); 
-					result.setText("Failed");
-				} else if (lv.isFocused()) {
-					stop();
-					robot.mouseWheel(-5);
-					robot.mousePress(Robot.MOUSE_LEFT_BTN);
-                    robot.mouseRelease(Robot.MOUSE_LEFT_BTN);
-                    robot.destroy();
-					new AnimationTimer() {
-						long startTime = System.nanoTime();
-						@Override
-						public void handle(long now) {
-							if (now > startTime + 3000000000l){ 
-								stop();
-								result.setText("Scroll Down Failed");
-							} else if (!lv.getSelectionModel().
-                                    selectedItemProperty().getValue().
-                                    equals("a")) {
-								        stop();
-								    result.setText("Scroll Down Passed");
-							}
-						}
-					}.start();
-				}
-			}
-		}.start();
-	}
-
-    public void robotPixelTest(final TextField result, Stage currentStage){
-
-	Bounds bounds = rec1.localToScreen(new BoundingBox(0, 0, 
-			rec1.getBoundsInParent().getWidth(),
-                        rec1.getBoundsInParent().getHeight()));
-	int x = 53 + (int) bounds.getMinX();
-	int y = 53 + (int) bounds.getMinY();
-	int answer = assertPixelEquals(x, y, Color.RED) +
-                     assertPixelEquals(x + 40, y, Color.BLUE) +
-                     assertPixelEquals(x + 80, y, Color.YELLOW) +
-                     assertPixelEquals(x + 120, y, Color.GREEN);
-    if (answer == 4) {
-        result.setText("Passed");
-    } else {
-        result.setText("Failed");
-    }
-
-    }
-
-    static int colorToRGB(Color c) {
-        int r = (int) Math.round(c.getRed() * 255.0);
-        int g = (int) Math.round(c.getGreen() * 255.0);
-        int b = (int) Math.round(c.getBlue() * 255.0);
-        return 0xff000000 | (r << 16) | (g << 8) | b;
-    }
-
-    public int assertPixelEquals(int x, int y, Color expected){
-
-        Robot robot = com.sun.glass.ui.Application.GetApplication().createRobot();
-        int pixel = robot.getPixelColor(x, y);
-        robot.destroy();
-        int expectedPixel = colorToRGB(expected);
-        if (checkColor(pixel, expected)) {
-            return 1;
-        } else {
-            System.out.println("Expected color 0x" + Integer.toHexString(expectedPixel) +
-                    " at " + x + "," + y + " but found 0x" + Integer.toHexString(pixel));
-        }
-        return 0;
-    }
-
-    private boolean checkColor(int value, Color expected) {
-
-        double tolerance = 0.07;
-        double ered = expected.getRed();
-        double egrn = expected.getGreen();
-        double eblu = expected.getBlue();
-
-        double vred = ((value & 0xff0000) >> 16) / 255.0;
-        double vgrn = ((value & 0x00ff00) >> 8) / 255.0;
-        double vblu = ((value & 0x0000ff)) / 255.0;
-
-        double dred = Math.abs(ered - vred);
-        double dgrn = Math.abs(egrn - vgrn);
-        double dblu = Math.abs(eblu - vblu);
-
-        if (dred <= tolerance && dgrn <= tolerance && dblu <= tolerance) {
-            return true;
-        }
-
-        return false;
-    }
-       
-    public Popup robotScreenTest(final TextField result, Stage stage){
-	
-        Bounds bounds = rec1.localToScreen(new BoundingBox(0, 0,
-                rec1.getBoundsInParent().getWidth(),
-                rec1.getBoundsInParent().getHeight()));
-
-        int x = 50 + (int) bounds.getMinX();
-        int y = 50 + (int) bounds.getMinY();
-        int[] intArr = null;
-        boolean correct = true;
-        Robot robot = com.sun.glass.ui.Application.GetApplication().createRobot();
-        int width = 160;
-        int height = 160;
-        final Buffer buff = robot.getScreenCapture(x, y, width, height).getPixels();
-        if ((buff instanceof IntBuffer)&&(buff.hasArray())) {
-            intArr =((IntBuffer) buff).array();
-        }
-
-        String filename= "scrCapture.bmp";
-        File file = new File(filename);
-        try {
-            if (!file.exists()) {
-                file.createNewFile();
-            }
-            BMPOutputStream bmp = new BMPOutputStream(new FileOutputStream(filename), intArr, width, height);
-        } catch (Exception e) {}
-
-
-        for (int i = width; i <= height*(height-1); i += width) {
-            for (int j = 1; j <= 38; j ++){
-                if (!checkColor(intArr[j+i],Color.RED)) {
-                    System.out.println(" pixel("+j+","+(i/width)+") "+
-                            Integer.toHexString(intArr[j+i])+" != "+
-                            Integer.toHexString(colorToRGB(Color.RED)));
-                    correct = false;
-                }
-             }
-            for (int j = 41; j <= 78; j ++){
-                if (!checkColor(intArr[j+i],Color.BLUE)) {
-                    System.out.println(" pixel("+j+","+(i/width)+") "+
-                            Integer.toHexString(intArr[j+i])+" != "+
-                            Integer.toHexString(colorToRGB(Color.BLUE)));
-                    correct = false;
-                }
-             }
-            for (int j = 81; j <= 118; j ++){
-                if (!checkColor(intArr[j+i],Color.YELLOW)) {
-                    System.out.println(" pixel("+j+","+(i/width)+") "+
-                            Integer.toHexString(intArr[j+i])+" != "+
-                            Integer.toHexString(colorToRGB(Color.YELLOW)));
-                    correct = false;
-                }
-             }
-            for (int j = 121; j <= 158; j ++){
-                if (!checkColor(intArr[j+i],Color.GREEN)) {
-                    System.out.println(" pixel("+j+","+(i/width)+") "+
-                            Integer.toHexString(intArr[j+i])+" != "+
-                            Integer.toHexString(colorToRGB(Color.GREEN)));
-                    correct = false;
-                }
-            }
-        }
-        robot.destroy();
-        if (correct) {
-            result.setText("Passed");
-        } else {
-            result.setText("Failed");
-        }
-        return showImage(stage, width, height, result);
-    }
-
-    private Popup showImage(Stage stage, int width, int height, TextField tf) {
-
-        int frame = 70;
-        Rectangle rec = new Rectangle(width + frame, height + frame);
-        FileInputStream os = null;
-        final File file = new File("scrCapture.bmp");
-        try {
-            os = new FileInputStream(file);
-        } catch (Exception e) {}
-
-        final Popup popup = new Popup();
-        ImageView iv = new ImageView(new Image(os));
-        iv.setLayoutX(frame/2);
-        iv.setLayoutY(frame/2);
-
-        rec.setFill(Color.WHITE);
-        rec.setStroke(Color.BLACK);
-        Button exit = new Button("x");
-        exit.setOnAction(new EventHandler<ActionEvent>() {
-            @Override public void handle(ActionEvent e) {
-                if (file.exists()&&tf.getText().equals("Passed")) {
-                    file.deleteOnExit();
-                }
-                popup.hide();
-            }
-        });
-        exit.setLayoutX(width + frame/2);
-        Pane popupPane = new Pane(rec, iv, exit);
-        popup.setX(stage.getX() + 550);
-        popup.setY(stage.getY() + 430);
-        popup.getContent().addAll(popupPane);
-        popup.show(stage);
-        return popup;
-    }
-
-    /**
      * The method updates globalScene with rectangle that should be 
      * swiped, scrolled, zoomed or rotated (touch only)
      * @param globalScene the global Scene
--- a/apps/toys/Industrial/src/industrial/Controller.java	Fri Aug 28 09:10:39 2015 -0700
+++ b/apps/toys/Industrial/src/industrial/Controller.java	Fri Aug 28 16:55:26 2015 -0700
@@ -24,7 +24,8 @@
  */
 package industrial;
 
-import com.sun.javafx.perf.PerformanceTracker;
+// FIXME: Needs public performance tracker API else remove this FPS feature
+//import com.sun.javafx.perf.PerformanceTracker;
 import javafx.animation.KeyFrame;
 import javafx.animation.Timeline;
 import javafx.collections.ObservableList;
@@ -55,16 +56,15 @@
         10.0, // high
     };
 
-    PerformanceTracker tracker;
+// FIXME: Needs public performance tracker API else remove this FPS feature
+//    PerformanceTracker tracker;
     Model model;
 
     public Controller(
-            Model model,
-            PerformanceTracker tracker
-    ) {
+            Model model /* , PerformanceTracker tracker */ ) {
 
         this.model = model;
-        this.tracker = tracker;
+//        this.tracker = tracker;
 
         tankVolume = 25.0;
     }
@@ -140,8 +140,9 @@
                 seconds+=Industrial.historyInterval;
                 lastDataPoint = currtime;
 
-                int fpsValue = (int) Math.round(tracker.getAverageFPS());
-                model.getFPSProperty().set(fpsValue);
+// FIXME: Needs public performance tracker API else remove this FPS feature
+//                int fpsValue = (int) Math.round(tracker.getAverageFPS());
+//                model.getFPSProperty().set(fpsValue);
             }
         } else {
             lastDataPoint = currtime;
--- a/apps/toys/Industrial/src/industrial/Industrial.java	Fri Aug 28 09:10:39 2015 -0700
+++ b/apps/toys/Industrial/src/industrial/Industrial.java	Fri Aug 28 16:55:26 2015 -0700
@@ -29,7 +29,7 @@
  Add emergency button
  Add help text ?
  */
-import com.sun.javafx.perf.PerformanceTracker;
+//import com.sun.javafx.perf.PerformanceTracker;
 import javafx.animation.KeyFrame;
 import javafx.animation.Timeline;
 import javafx.application.Application;
@@ -87,8 +87,9 @@
     Group chartFillGroup;
     Group chartFlowGroup;
     Group helpGroup;
-
-    PerformanceTracker tracker;
+    
+// FIXME: Needs public performance tracker API else remove this FPS feature
+//    PerformanceTracker tracker;
 
     static final int layoutSizeX = 1280;
     static final int layoutSizeY = 720;
@@ -215,10 +216,11 @@
         rateB.setTranslateY(430);
 
         //****************************
-        fps = new Text("??? fps");
-        fps.setFont(new Font(25));
-        fps.setLayoutX(10);
-        fps.setLayoutY(40);
+// FIXME: Needs public performance tracker API else remove this FPS feature
+//        fps = new Text("??? fps");
+//        fps.setFont(new Font(25));
+//        fps.setLayoutX(10);
+//        fps.setLayoutY(40);
 
         //****************************
         lowWater = new Slider(0, 90, 10);
@@ -389,7 +391,6 @@
         //****************************
         Group root = new Group(
                 backdrop,
-                fps,
                 pipeIn.getGroup(),
                 pumpGroup,
                 nameP, flowRateP, rateP,
@@ -415,16 +416,14 @@
         System.out.println("Screen size is " + primaryScreenBounds);
         Scene scene = new Scene(root, layoutSizeX, layoutSizeY);
 
-        tracker = PerformanceTracker.getSceneTracker(scene);
+// FIXME: Needs public performance tracker API else remove this FPS feature
+//        tracker = PerformanceTracker.getSceneTracker(scene);
 
-        controller = new Controller(
-                model,
-                tracker
-        );
+        controller = new Controller(model /*, tracker */);
 
-        model.getFPSProperty().addListener((ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
-            fps.setText("" + newValue.intValue() + " fps");
-        });
+//        model.getFPSProperty().addListener((ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
+//            fps.setText("" + newValue.intValue() + " fps");
+//        });
 
         rateP.valueProperty().bindBidirectional(model.getValveFlowRateProperty(Model.PUMP));
         rateA.valueProperty().bindBidirectional(model.getValveFlowRateProperty(Model.VALVE_A));
--- a/apps/toys/Industrial/src/industrial/Model.java	Fri Aug 28 09:10:39 2015 -0700
+++ b/apps/toys/Industrial/src/industrial/Model.java	Fri Aug 28 16:55:26 2015 -0700
@@ -38,18 +38,19 @@
  */
 public class Model {
 
-    private final IntegerProperty fpsProp = new IntegerPropertyBase(0) {
-
-        @Override
-        public Object getBean() {
-            return Model.this;
-        }
-
-        @Override
-        public String getName() {
-            return "FPS";
-        }
-    };
+// FIXME: Needs public performance tracker API else remove this FPS feature
+//    private final IntegerProperty fpsProp = new IntegerPropertyBase(0) {
+//
+//        @Override
+//        public Object getBean() {
+//            return Model.this;
+//        }
+//
+//        @Override
+//        public String getName() {
+//            return "FPS";
+//        }
+//    };
 
     static final int PUMP = 0;
     static final int VALVE_A = 1;
@@ -234,9 +235,10 @@
         return valveFlowRates.get(which);
     }
 
-    public IntegerProperty getFPSProperty() {
-        return fpsProp;
-    }
+// FIXME: Needs public performance tracker API else remove this FPS feature
+//    public IntegerProperty getFPSProperty() {
+//        return fpsProp;
+//    }
 
     public XYChart.Series getFlowRateHistory(int which) {
         if (which > valveFlowRatesHistory.size()) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/manual/Robot/build.xml	Fri Aug 28 16:55:26 2015 -0700
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See commented blocks below for -->
+<!-- some examples of how to customize the build. -->
+<!-- (If you delete it and reopen the project it will be recreated.) -->
+<!-- By default, only the Clean and Build commands use this build script. -->
+<!-- Commands such as Run, Debug, and Test only use this build script if -->
+<!-- the Compile on Save feature is turned off for the project. -->
+<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
+<!-- in the project's Project Properties dialog box.-->
+<project name="RobotTest" default="default" basedir=".">
+    <description>Builds, tests, and runs the project RobotTest.</description>
+    <import file="nbproject/build-impl.xml"/>
+    <!--
+
+    There exist several targets which are by default empty and which can be 
+    used for execution of your tasks. These targets are usually executed 
+    before and after some main targets. They are: 
+
+      -pre-init:                 called before initialization of project properties
+      -post-init:                called after initialization of project properties
+      -pre-compile:              called before javac compilation
+      -post-compile:             called after javac compilation
+      -pre-compile-single:       called before javac compilation of single file
+      -post-compile-single:      called after javac compilation of single file
+      -pre-compile-test:         called before javac compilation of JUnit tests
+      -post-compile-test:        called after javac compilation of JUnit tests
+      -pre-compile-test-single:  called before javac compilation of single JUnit test
+      -post-compile-test-single: called after javac compilation of single JUunit test
+      -pre-jar:                  called before JAR building
+      -post-jar:                 called after JAR building
+      -post-clean:               called after cleaning build products
+
+    (Targets beginning with '-' are not intended to be called on their own.)
+
+    Example of inserting an obfuscator after compilation could look like this:
+
+        <target name="-post-compile">
+            <obfuscate>
+                <fileset dir="${build.classes.dir}"/>
+            </obfuscate>
+        </target>
+
+    For list of available properties check the imported 
+    nbproject/build-impl.xml file. 
+
+
+    Another way to customize the build is by overriding existing main targets.
+    The targets of interest are: 
+
+      -init-macrodef-javac:     defines macro for javac compilation
+      -init-macrodef-junit:     defines macro for junit execution
+      -init-macrodef-debug:     defines macro for class debugging
+      -init-macrodef-java:      defines macro for class execution
+      -do-jar:                  JAR building
+      run:                      execution of project 
+      -javadoc-build:           Javadoc generation
+      test-report:              JUnit report generation
+
+    An example of overriding the target for project execution could look like this:
+
+        <target name="run" depends="RobotTest-impl.jar">
+            <exec dir="bin" executable="launcher.exe">
+                <arg file="${dist.jar}"/>
+            </exec>
+        </target>
+
+    Notice that the overridden target depends on the jar target and not only on 
+    the compile target as the regular run target does. Again, for a list of available 
+    properties which you can use, check the target you are overriding in the
+    nbproject/build-impl.xml file. 
+
+    -->
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/manual/Robot/manifest.mf	Fri Aug 28 16:55:26 2015 -0700
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+X-COMMENT: Main-Class will be added automatically by build
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/manual/Robot/nbproject/build-impl.xml	Fri Aug 28 16:55:26 2015 -0700
@@ -0,0 +1,1431 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+
+For the purpose of easier reading the script
+is divided into following sections:
+
+  - initialization
+  - compilation
+  - jar
+  - execution
+  - debugging
+  - javadoc
+  - test compilation
+  - test execution
+  - test debugging
+  - applet
+  - cleanup
+
+        -->
+<project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="RobotTest-impl">
+    <fail message="Please build using Ant 1.8.0 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.8.0"/>
+            </not>
+        </condition>
+    </fail>
+    <target depends="test,jar,javadoc" description="Build and test whole project." name="default"/>
+    <!-- 
+                ======================
+                INITIALIZATION SECTION 
+                ======================
+            -->
+    <target name="-pre-init">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="-pre-init" name="-init-private">
+        <property file="nbproject/private/config.properties"/>
+        <property file="nbproject/private/configs/${config}.properties"/>
+        <property file="nbproject/private/private.properties"/>
+    </target>
+    <target depends="-pre-init,-init-private" name="-init-user">
+        <property file="${user.properties.file}"/>
+        <!-- The two properties below are usually overridden -->
+        <!-- by the active platform. Just a fallback. -->
+        <property name="default.javac.source" value="1.4"/>
+        <property name="default.javac.target" value="1.4"/>
+    </target>
+    <target depends="-pre-init,-init-private,-init-user" name="-init-project">
+        <property file="nbproject/configs/${config}.properties"/>
+        <property file="nbproject/project.properties"/>
+    </target>
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" name="-do-init">
+        <j2seproject1:property name="platform.home" value="platforms.${platform.active}.home"/>
+        <j2seproject1:property name="platform.bootcp" value="platforms.${platform.active}.bootclasspath"/>
+        <j2seproject1:property name="platform.compiler" value="platforms.${platform.active}.compile"/>
+        <j2seproject1:property name="platform.javac.tmp" value="platforms.${platform.active}.javac"/>
+        <condition property="platform.javac" value="${platform.home}/bin/javac">
+            <equals arg1="${platform.javac.tmp}" arg2="$${platforms.${platform.active}.javac}"/>
+        </condition>
+        <property name="platform.javac" value="${platform.javac.tmp}"/>
+        <j2seproject1:property name="platform.java.tmp" value="platforms.${platform.active}.java"/>
+        <condition property="platform.java" value="${platform.home}/bin/java">
+            <equals arg1="${platform.java.tmp}" arg2="$${platforms.${platform.active}.java}"/>
+        </condition>
+        <property name="platform.java" value="${platform.java.tmp}"/>
+        <j2seproject1:property name="platform.javadoc.tmp" value="platforms.${platform.active}.javadoc"/>
+        <condition property="platform.javadoc" value="${platform.home}/bin/javadoc">
+            <equals arg1="${platform.javadoc.tmp}" arg2="$${platforms.${platform.active}.javadoc}"/>
+        </condition>
+        <property name="platform.javadoc" value="${platform.javadoc.tmp}"/>
+        <condition property="platform.invalid" value="true">
+            <or>
+                <contains string="${platform.javac}" substring="$${platforms."/>
+                <contains string="${platform.java}" substring="$${platforms."/>
+                <contains string="${platform.javadoc}" substring="$${platforms."/>
+            </or>
+        </condition>
+        <fail unless="platform.home">Must set platform.home</fail>
+        <fail unless="platform.bootcp">Must set platform.bootcp</fail>
+        <fail unless="platform.java">Must set platform.java</fail>
+        <fail unless="platform.javac">Must set platform.javac</fail>
+        <fail if="platform.invalid">
+ The J2SE Platform is not correctly set up.
+ Your active platform is: ${platform.active}, but the corresponding property "platforms.${platform.active}.home" is not found in the project's properties files. 
+ Either open the project in the IDE and setup the Platform with the same name or add it manually.
+ For example like this:
+     ant -Duser.properties.file=&lt;path_to_property_file&gt; jar (where you put the property "platforms.${platform.active}.home" in a .properties file)
+  or ant -Dplatforms.${platform.active}.home=&lt;path_to_JDK_home&gt; jar (where no properties file is used) 
+  </fail>
+        <available file="${manifest.file}" property="manifest.available"/>
+        <condition property="splashscreen.available">
+            <and>
+                <not>
+                    <equals arg1="${application.splash}" arg2="" trim="true"/>
+                </not>
+                <available file="${application.splash}"/>
+            </and>
+        </condition>
+        <condition property="main.class.available">
+            <and>
+                <isset property="main.class"/>
+                <not>
+                    <equals arg1="${main.class}" arg2="" trim="true"/>
+                </not>
+            </and>
+        </condition>
+        <condition property="profile.available">
+            <and>
+                <isset property="javac.profile"/>
+                <length length="0" string="${javac.profile}" when="greater"/>
+                <matches pattern="1\.[89](\..*)?" string="${javac.source}"/>
+            </and>
+        </condition>
+        <condition property="do.archive">
+            <or>
+                <not>
+                    <istrue value="${jar.archive.disabled}"/>
+                </not>
+                <istrue value="${not.archive.disabled}"/>
+            </or>
+        </condition>
+        <condition property="do.mkdist">
+            <and>
+                <isset property="do.archive"/>
+                <isset property="libs.CopyLibs.classpath"/>
+                <not>
+                    <istrue value="${mkdist.disabled}"/>
+                </not>
+            </and>
+        </condition>
+        <condition property="do.archive+manifest.available">
+            <and>
+                <isset property="manifest.available"/>
+                <istrue value="${do.archive}"/>
+            </and>
+        </condition>
+        <condition property="do.archive+main.class.available">
+            <and>
+                <isset property="main.class.available"/>
+                <istrue value="${do.archive}"/>
+            </and>
+        </condition>
+        <condition property="do.archive+splashscreen.available">
+            <and>
+                <isset property="splashscreen.available"/>
+                <istrue value="${do.archive}"/>
+            </and>
+        </condition>
+        <condition property="do.archive+profile.available">
+            <and>
+                <isset property="profile.available"/>
+                <istrue value="${do.archive}"/>
+            </and>
+        </condition>
+        <condition property="have.tests">
+            <or/>
+        </condition>
+        <condition property="have.sources">
+            <or>
+                <available file="${src.dir}"/>
+            </or>
+        </condition>
+        <condition property="netbeans.home+have.tests">
+            <and>
+                <isset property="netbeans.home"/>
+                <isset property="have.tests"/>
+            </and>
+        </condition>
+        <condition property="no.javadoc.preview">
+            <and>
+                <isset property="javadoc.preview"/>
+                <isfalse value="${javadoc.preview}"/>
+            </and>
+        </condition>
+        <property name="run.jvmargs" value=""/>
+        <property name="run.jvmargs.ide" value=""/>
+        <property name="javac.compilerargs" value=""/>
+        <property name="work.dir" value="${basedir}"/>
+        <condition property="no.deps">
+            <and>
+                <istrue value="${no.dependencies}"/>
+            </and>
+        </condition>
+        <property name="javac.debug" value="true"/>
+        <property name="javadoc.preview" value="true"/>
+        <property name="application.args" value=""/>
+        <property name="source.encoding" value="${file.encoding}"/>
+        <property name="runtime.encoding" value="${source.encoding}"/>
+        <condition property="javadoc.encoding.used" value="${javadoc.encoding}">
+            <and>
+                <isset property="javadoc.encoding"/>
+                <not>
+                    <equals arg1="${javadoc.encoding}" arg2=""/>
+                </not>
+            </and>
+        </condition>
+        <property name="javadoc.encoding.used" value="${source.encoding}"/>
+        <property name="includes" value="**"/>
+        <property name="excludes" value=""/>
+        <property name="do.depend" value="false"/>
+        <condition property="do.depend.true">
+            <istrue value="${do.depend}"/>
+        </condition>
+        <path id="endorsed.classpath.path" path="${endorsed.classpath}"/>
+        <condition else="" property="endorsed.classpath.cmd.line.arg" value="-Xbootclasspath/p:'${toString:endorsed.classpath.path}'">
+            <and>
+                <isset property="endorsed.classpath"/>
+                <not>
+                    <equals arg1="${endorsed.classpath}" arg2="" trim="true"/>
+                </not>
+            </and>
+        </condition>
+        <condition else="" property="javac.profile.cmd.line.arg" value="-profile ${javac.profile}">
+            <isset property="profile.available"/>
+        </condition>
+        <property name="jar.index" value="false"/>
+        <property name="jar.index.metainf" value="${jar.index}"/>
+        <property name="copylibs.rebase" value="true"/>
+        <available file="${meta.inf.dir}/persistence.xml" property="has.persistence.xml"/>
+        <condition property="junit.available">
+            <or>
+                <available classname="org.junit.Test" classpath="${run.test.classpath}"/>
+                <available classname="junit.framework.Test" classpath="${run.test.classpath}"/>
+            </or>
+        </condition>
+        <condition property="testng.available">
+            <available classname="org.testng.annotations.Test" classpath="${run.test.classpath}"/>
+        </condition>
+        <condition property="junit+testng.available">
+            <and>
+                <istrue value="${junit.available}"/>
+                <istrue value="${testng.available}"/>
+            </and>
+        </condition>
+        <condition else="testng" property="testng.mode" value="mixed">
+            <istrue value="${junit+testng.available}"/>
+        </condition>
+        <condition else="" property="testng.debug.mode" value="-mixed">
+            <istrue value="${junit+testng.available}"/>
+        </condition>
+    </target>
+    <target name="-post-init">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init" name="-init-check">
+        <fail unless="src.dir">Must set src.dir</fail>
+        <fail unless="build.dir">Must set build.dir</fail>
+        <fail unless="dist.dir">Must set dist.dir</fail>
+        <fail unless="build.classes.dir">Must set build.classes.dir</fail>
+        <fail unless="dist.javadoc.dir">Must set dist.javadoc.dir</fail>
+        <fail unless="build.test.classes.dir">Must set build.test.classes.dir</fail>
+        <fail unless="build.test.results.dir">Must set build.test.results.dir</fail>
+        <fail unless="build.classes.excludes">Must set build.classes.excludes</fail>
+        <fail unless="dist.jar">Must set dist.jar</fail>
+    </target>
+    <target name="-init-macrodef-property">
+        <macrodef name="property" uri="http://www.netbeans.org/ns/j2se-project/1">
+            <attribute name="name"/>
+            <attribute name="value"/>
+            <sequential>
+                <property name="@{name}" value="${@{value}}"/>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-macrodef-javac-with-processors">
+        <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${src.dir}" name="srcdir"/>
+            <attribute default="${build.classes.dir}" name="destdir"/>
+            <attribute default="${javac.classpath}" name="classpath"/>
+            <attribute default="${javac.processorpath}" name="processorpath"/>
+            <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="${javac.debug}" name="debug"/>
+            <attribute default="${empty.dir}" name="sourcepath"/>
+            <attribute default="${empty.dir}" name="gensrcdir"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property location="${build.dir}/empty" name="empty.dir"/>
+                <mkdir dir="${empty.dir}"/>
+                <mkdir dir="@{apgeneratedsrcdir}"/>
+                <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" executable="${platform.javac}" fork="yes" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
+                    <src>
+                        <dirset dir="@{gensrcdir}" erroronmissingdir="false">
+                            <include name="*"/>
+                        </dirset>
+                    </src>
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <compilerarg line="${javac.profile.cmd.line.arg}"/>
+                    <compilerarg line="${javac.compilerargs}"/>
+                    <compilerarg value="-processorpath"/>
+                    <compilerarg path="@{processorpath}:${empty.dir}"/>
+                    <compilerarg line="${ap.processors.internal}"/>
+                    <compilerarg line="${annotation.processing.processor.options}"/>
+                    <compilerarg value="-s"/>
+                    <compilerarg path="@{apgeneratedsrcdir}"/>
+                    <compilerarg line="${ap.proc.none.internal}"/>
+                    <customize/>
+                </javac>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-ap-cmdline-properties" name="-init-macrodef-javac-without-processors" unless="ap.supported.internal">
+        <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${src.dir}" name="srcdir"/>
+            <attribute default="${build.classes.dir}" name="destdir"/>
+            <attribute default="${javac.classpath}" name="classpath"/>
+            <attribute default="${javac.processorpath}" name="processorpath"/>
+            <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="${javac.debug}" name="debug"/>
+            <attribute default="${empty.dir}" name="sourcepath"/>
+            <attribute default="${empty.dir}" name="gensrcdir"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property location="${build.dir}/empty" name="empty.dir"/>
+                <mkdir dir="${empty.dir}"/>
+                <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" executable="${platform.javac}" fork="yes" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
+                    <src>
+                        <dirset dir="@{gensrcdir}" erroronmissingdir="false">
+                            <include name="*"/>
+                        </dirset>
+                    </src>
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <compilerarg line="${javac.profile.cmd.line.arg}"/>
+                    <compilerarg line="${javac.compilerargs}"/>
+                    <customize/>
+                </javac>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-javac-with-processors,-init-macrodef-javac-without-processors" name="-init-macrodef-javac">
+        <macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${src.dir}" name="srcdir"/>
+            <attribute default="${build.classes.dir}" name="destdir"/>
+            <attribute default="${javac.classpath}" name="classpath"/>
+            <sequential>
+                <depend cache="${build.dir}/depcache" destdir="@{destdir}" excludes="${excludes}" includes="${includes}" srcdir="@{srcdir}">
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                </depend>
+            </sequential>
+        </macrodef>
+        <macrodef name="force-recompile" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${build.classes.dir}" name="destdir"/>
+            <sequential>
+                <fail unless="javac.includes">Must set javac.includes</fail>
+                <pathconvert pathsep="${line.separator}" property="javac.includes.binary">
+                    <path>
+                        <filelist dir="@{destdir}" files="${javac.includes}"/>
+                    </path>
+                    <globmapper from="*.java" to="*.class"/>
+                </pathconvert>
+                <tempfile deleteonexit="true" property="javac.includesfile.binary"/>
+                <echo file="${javac.includesfile.binary}" message="${javac.includes.binary}"/>
+                <delete>
+                    <files includesfile="${javac.includesfile.binary}"/>
+                </delete>
+                <delete>
+                    <fileset file="${javac.includesfile.binary}"/>
+                </delete>
+            </sequential>
+        </macrodef>
+    </target>
+    <target if="${junit.available}" name="-init-macrodef-junit-init">
+        <condition else="false" property="nb.junit.batch" value="true">
+            <and>
+                <istrue value="${junit.available}"/>
+                <not>
+                    <isset property="test.method"/>
+                </not>
+            </and>
+        </condition>
+        <condition else="false" property="nb.junit.single" value="true">
+            <and>
+                <istrue value="${junit.available}"/>
+                <isset property="test.method"/>
+            </and>
+        </condition>
+    </target>
+    <target name="-init-test-properties">
+        <property name="test.binaryincludes" value="&lt;nothing&gt;"/>
+        <property name="test.binarytestincludes" value=""/>
+        <property name="test.binaryexcludes" value=""/>
+    </target>
+    <target if="${nb.junit.single}" name="-init-macrodef-junit-single" unless="${nb.junit.batch}">
+        <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property name="junit.forkmode" value="perTest"/>
+                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" jvm="${platform.java}" showoutput="true" tempdir="${build.dir}">
+                    <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/>
+                    <syspropertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <formatter type="brief" usefile="false"/>
+                    <formatter type="xml"/>
+                    <jvmarg value="-ea"/>
+                    <customize/>
+                </junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-test-properties" if="${nb.junit.batch}" name="-init-macrodef-junit-batch" unless="${nb.junit.single}">
+        <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property name="junit.forkmode" value="perTest"/>
+                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" jvm="${platform.java}" showoutput="true" tempdir="${build.dir}">
+                    <batchtest todir="${build.test.results.dir}">
+                        <fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}">
+                            <filename name="${test.binarytestincludes}"/>
+                        </fileset>
+                    </batchtest>
+                    <syspropertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <formatter type="brief" usefile="false"/>
+                    <formatter type="xml"/>
+                    <jvmarg value="-ea"/>
+                    <customize/>
+                </junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit-init,-init-macrodef-junit-single, -init-macrodef-junit-batch" if="${junit.available}" name="-init-macrodef-junit"/>
+    <target if="${testng.available}" name="-init-macrodef-testng">
+        <macrodef name="testng" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <condition else="" property="testng.methods.arg" value="@{testincludes}.@{testmethods}">
+                    <isset property="test.method"/>
+                </condition>
+                <union id="test.set"/>
+                <taskdef classname="org.testng.TestNGAntTask" classpath="${run.test.classpath}" name="testng"/>
+                <testng classfilesetref="test.set" failureProperty="tests.failed" jvm="${platform.java}" listeners="org.testng.reporters.VerboseReporter" methods="${testng.methods.arg}" mode="${testng.mode}" outputdir="${build.test.results.dir}" suitename="RobotTest" testname="TestNG tests" workingDir="${work.dir}">
+                    <xmlfileset dir="${build.test.classes.dir}" includes="@{testincludes}"/>
+                    <propertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </propertyset>
+                    <customize/>
+                </testng>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-macrodef-test-impl">
+        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <echo>No tests executed.</echo>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit" if="${junit.available}" name="-init-macrodef-junit-impl">
+        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <j2seproject3:junit excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize/>
+                </j2seproject3:junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-testng" if="${testng.available}" name="-init-macrodef-testng-impl">
+        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <j2seproject3:testng excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize/>
+                </j2seproject3:testng>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-test-impl,-init-macrodef-junit-impl,-init-macrodef-testng-impl" name="-init-macrodef-test">
+        <macrodef name="test" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <sequential>
+                <j2seproject3:test-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize>
+                        <classpath>
+                            <path path="${run.test.classpath}"/>
+                        </classpath>
+                        <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                        <jvmarg line="${run.jvmargs}"/>
+                        <jvmarg line="${run.jvmargs.ide}"/>
+                    </customize>
+                </j2seproject3:test-impl>
+            </sequential>
+        </macrodef>
+    </target>
+    <target if="${junit.available}" name="-init-macrodef-junit-debug" unless="${nb.junit.batch}">
+        <macrodef name="junit-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property name="junit.forkmode" value="perTest"/>
+                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" jvm="${platform.java}" showoutput="true" tempdir="${build.dir}">
+                    <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/>
+                    <syspropertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <formatter type="brief" usefile="false"/>
+                    <formatter type="xml"/>
+                    <jvmarg value="-ea"/>
+                    <jvmarg line="${debug-args-line}"/>
+                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
+                    <customize/>
+                </junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-test-properties" if="${nb.junit.batch}" name="-init-macrodef-junit-debug-batch">
+        <macrodef name="junit-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property name="junit.forkmode" value="perTest"/>
+                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" jvm="${platform.java}" showoutput="true" tempdir="${build.dir}">
+                    <batchtest todir="${build.test.results.dir}">
+                        <fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}">
+                            <filename name="${test.binarytestincludes}"/>
+                        </fileset>
+                    </batchtest>
+                    <syspropertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <formatter type="brief" usefile="false"/>
+                    <formatter type="xml"/>
+                    <jvmarg value="-ea"/>
+                    <jvmarg line="${debug-args-line}"/>
+                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
+                    <customize/>
+                </junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit-debug,-init-macrodef-junit-debug-batch" if="${junit.available}" name="-init-macrodef-junit-debug-impl">
+        <macrodef name="test-debug-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <j2seproject3:junit-debug excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize/>
+                </j2seproject3:junit-debug>
+            </sequential>
+        </macrodef>
+    </target>
+    <target if="${testng.available}" name="-init-macrodef-testng-debug">
+        <macrodef name="testng-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <element name="customize2" optional="true"/>
+            <sequential>
+                <condition else="-testclass @{testClass}" property="test.class.or.method" value="-methods @{testClass}.@{testMethod}">
+                    <isset property="test.method"/>
+                </condition>
+                <condition else="-suitename RobotTest -testname @{testClass} ${test.class.or.method}" property="testng.cmd.args" value="@{testClass}">
+                    <matches pattern=".*\.xml" string="@{testClass}"/>
+                </condition>
+                <delete dir="${build.test.results.dir}" quiet="true"/>
+                <mkdir dir="${build.test.results.dir}"/>
+                <j2seproject3:debug classname="org.testng.TestNG" classpath="${debug.test.classpath}">
+                    <customize>
+                        <customize2/>
+                        <jvmarg value="-ea"/>
+                        <arg line="${testng.debug.mode}"/>
+                        <arg line="-d ${build.test.results.dir}"/>
+                        <arg line="-listener org.testng.reporters.VerboseReporter"/>
+                        <arg line="${testng.cmd.args}"/>
+                    </customize>
+                </j2seproject3:debug>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-testng-debug" if="${testng.available}" name="-init-macrodef-testng-debug-impl">
+        <macrodef name="testng-debug-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <element implicit="true" name="customize2" optional="true"/>
+            <sequential>
+                <j2seproject3:testng-debug testClass="@{testClass}" testMethod="@{testMethod}">
+                    <customize2/>
+                </j2seproject3:testng-debug>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit-debug-impl" if="${junit.available}" name="-init-macrodef-test-debug-junit">
+        <macrodef name="test-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <sequential>
+                <j2seproject3:test-debug-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize>
+                        <classpath>
+                            <path path="${run.test.classpath}"/>
+                        </classpath>
+                        <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                        <jvmarg line="${run.jvmargs}"/>
+                        <jvmarg line="${run.jvmargs.ide}"/>
+                    </customize>
+                </j2seproject3:test-debug-impl>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-testng-debug-impl" if="${testng.available}" name="-init-macrodef-test-debug-testng">
+        <macrodef name="test-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <sequential>
+                <j2seproject3:testng-debug-impl testClass="@{testClass}" testMethod="@{testMethod}">
+                    <customize2>
+                        <syspropertyset>
+                            <propertyref prefix="test-sys-prop."/>
+                            <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                        </syspropertyset>
+                    </customize2>
+                </j2seproject3:testng-debug-impl>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-test-debug-junit,-init-macrodef-test-debug-testng" name="-init-macrodef-test-debug"/>
+    <!--
+                pre NB7.2 profiling section; consider it deprecated
+            -->
+    <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile, -profile-init-check" if="profiler.info.jvmargs.agent" name="profile-init"/>
+    <target if="profiler.info.jvmargs.agent" name="-profile-pre-init">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target if="profiler.info.jvmargs.agent" name="-profile-post-init">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target if="profiler.info.jvmargs.agent" name="-profile-init-macrodef-profile">
+        <macrodef name="resolve">
+            <attribute name="name"/>
+            <attribute name="value"/>
+            <sequential>
+                <property name="@{name}" value="${env.@{value}}"/>
+            </sequential>
+        </macrodef>
+        <macrodef name="profile">
+            <attribute default="${main.class}" name="classname"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property environment="env"/>
+                <resolve name="profiler.current.path" value="${profiler.info.pathvar}"/>
+                <java classname="@{classname}" dir="${profiler.info.dir}" fork="true" jvm="${profiler.info.jvm}">
+                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <jvmarg value="${profiler.info.jvmargs.agent}"/>
+                    <jvmarg line="${profiler.info.jvmargs}"/>
+                    <env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>
+                    <arg line="${application.args}"/>
+                    <classpath>
+                        <path path="${run.classpath}"/>
+                    </classpath>
+                    <syspropertyset>
+                        <propertyref prefix="run-sys-prop."/>
+                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <customize/>
+                </java>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile" if="profiler.info.jvmargs.agent" name="-profile-init-check">
+        <fail unless="profiler.info.jvm">Must set JVM to use for profiling in profiler.info.jvm</fail>
+        <fail unless="profiler.info.jvmargs.agent">Must set profiler agent JVM arguments in profiler.info.jvmargs.agent</fail>
+    </target>
+    <!--
+                end of pre NB7.2 profiling section
+            -->
+    <target depends="-init-debug-args" name="-init-macrodef-nbjpda">
+        <macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/j2se-project/1">
+            <attribute default="${main.class}" name="name"/>
+            <attribute default="${debug.classpath}" name="classpath"/>
+            <attribute default="" name="stopclassname"/>
+            <sequential>
+                <nbjpdastart addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}" transport="${debug-transport}">
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <bootclasspath>
+                        <path path="${platform.bootcp}"/>
+                    </bootclasspath>
+                </nbjpdastart>
+            </sequential>
+        </macrodef>
+        <macrodef name="nbjpdareload" uri="http://www.netbeans.org/ns/j2se-project/1">
+            <attribute default="${build.classes.dir}" name="dir"/>
+            <sequential>
+                <nbjpdareload>
+                    <fileset dir="@{dir}" includes="${fix.classes}">
+                        <include name="${fix.includes}*.class"/>
+                    </fileset>
+                </nbjpdareload>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-debug-args">
+        <exec executable="${platform.java}" outputproperty="version-output">
+            <arg value="-version"/>
+        </exec>
+        <condition property="have-jdk-older-than-1.4">
+            <or>
+                <contains string="${version-output}" substring="java version &quot;1.0"/>
+                <contains string="${version-output}" substring="java version &quot;1.1"/>
+                <contains string="${version-output}" substring="java version &quot;1.2"/>
+                <contains string="${version-output}" substring="java version &quot;1.3"/>
+            </or>
+        </condition>
+        <condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none">
+            <istrue value="${have-jdk-older-than-1.4}"/>
+        </condition>
+        <condition else="dt_socket" property="debug-transport-by-os" value="dt_shmem">
+            <os family="windows"/>
+        </condition>
+        <condition else="${debug-transport-by-os}" property="debug-transport" value="${debug.transport}">
+            <isset property="debug.transport"/>
+        </condition>
+    </target>
+    <target depends="-init-debug-args" name="-init-macrodef-debug">
+        <macrodef name="debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${main.class}" name="classname"/>
+            <attribute default="${debug.classpath}" name="classpath"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <java classname="@{classname}" dir="${work.dir}" fork="true" jvm="${platform.java}">
+                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <jvmarg line="${debug-args-line}"/>
+                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
+                    <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
+                    <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
+                    <jvmarg line="${run.jvmargs}"/>
+                    <jvmarg line="${run.jvmargs.ide}"/>
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <syspropertyset>
+                        <propertyref prefix="run-sys-prop."/>
+                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <customize/>
+                </java>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-macrodef-java">
+        <macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
+            <attribute default="${main.class}" name="classname"/>
+            <attribute default="${run.classpath}" name="classpath"/>
+            <attribute default="jvm" name="jvm"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <java classname="@{classname}" dir="${work.dir}" fork="true" jvm="${platform.java}">
+                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
+                    <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
+                    <jvmarg line="${run.jvmargs}"/>
+                    <jvmarg line="${run.jvmargs.ide}"/>
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <syspropertyset>
+                        <propertyref prefix="run-sys-prop."/>
+                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <customize/>
+                </java>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-macrodef-copylibs">
+        <macrodef name="copylibs" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${manifest.file}" name="manifest"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
+                <pathconvert property="run.classpath.without.build.classes.dir">
+                    <path path="${run.classpath}"/>
+                    <map from="${build.classes.dir.resolved}" to=""/>
+                </pathconvert>
+                <pathconvert pathsep=" " property="jar.classpath">
+                    <path path="${run.classpath.without.build.classes.dir}"/>
+                    <chainedmapper>
+                        <flattenmapper/>
+                        <filtermapper>
+                            <replacestring from=" " to="%20"/>
+                        </filtermapper>
+                        <globmapper from="*" to="lib/*"/>
+                    </chainedmapper>
+                </pathconvert>
+                <taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
+                <copylibs compress="${jar.compress}" excludeFromCopy="${copylibs.excludes}" index="${jar.index}" indexMetaInf="${jar.index.metainf}" jarfile="${dist.jar}" manifest="@{manifest}" rebase="${copylibs.rebase}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
+                    <fileset dir="${build.classes.dir}" excludes="${dist.archive.excludes}"/>
+                    <manifest>
+                        <attribute name="Class-Path" value="${jar.classpath}"/>
+                        <customize/>
+                    </manifest>
+                </copylibs>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-presetdef-jar">
+        <presetdef name="jar" uri="http://www.netbeans.org/ns/j2se-project/1">
+            <jar compress="${jar.compress}" index="${jar.index}" jarfile="${dist.jar}">
+                <j2seproject1:fileset dir="${build.classes.dir}" excludes="${dist.archive.excludes}"/>
+            </jar>
+        </presetdef>
+    </target>
+    <target name="-init-ap-cmdline-properties">
+        <property name="annotation.processing.enabled" value="true"/>
+        <property name="annotation.processing.processors.list" value=""/>
+        <property name="annotation.processing.processor.options" value=""/>
+        <property name="annotation.processing.run.all.processors" value="true"/>
+        <property name="javac.processorpath" value="${javac.classpath}"/>
+        <property name="javac.test.processorpath" value="${javac.test.classpath}"/>
+        <condition property="ap.supported.internal" value="true">
+            <not>
+                <matches pattern="1\.[0-5](\..*)?" string="${javac.source}"/>
+            </not>
+        </condition>
+    </target>
+    <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-ap-cmdline-supported">
+        <condition else="" property="ap.processors.internal" value="-processor ${annotation.processing.processors.list}">
+            <isfalse value="${annotation.processing.run.all.processors}"/>
+        </condition>
+        <condition else="" property="ap.proc.none.internal" value="-proc:none">
+            <isfalse value="${annotation.processing.enabled}"/>
+        </condition>
+    </target>
+    <target depends="-init-ap-cmdline-properties,-init-ap-cmdline-supported" name="-init-ap-cmdline">
+        <property name="ap.cmd.line.internal" value=""/>
+    </target>
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-test,-init-macrodef-test-debug,-init-macrodef-nbjpda,-init-macrodef-debug,-init-macrodef-java,-init-presetdef-jar,-init-ap-cmdline" name="init"/>
+    <!--
+                ===================
+                COMPILATION SECTION
+                ===================
+            -->
+    <target name="-deps-jar-init" unless="built-jar.properties">
+        <property location="${build.dir}/built-jar.properties" name="built-jar.properties"/>
+        <delete file="${built-jar.properties}" quiet="true"/>
+    </target>
+    <target if="already.built.jar.${basedir}" name="-warn-already-built-jar">
+        <echo level="warn" message="Cycle detected: RobotTest was already built"/>
+    </target>
+    <target depends="init,-deps-jar-init" name="deps-jar" unless="no.deps">
+        <mkdir dir="${build.dir}"/>
+        <touch file="${built-jar.properties}" verbose="false"/>
+        <property file="${built-jar.properties}" prefix="already.built.jar."/>
+        <antcall target="-warn-already-built-jar"/>
+        <propertyfile file="${built-jar.properties}">
+            <entry key="${basedir}" value=""/>
+        </propertyfile>
+    </target>
+    <target depends="init,-check-automatic-build,-clean-after-automatic-build" name="-verify-automatic-build"/>
+    <target depends="init" name="-check-automatic-build">
+        <available file="${build.classes.dir}/.netbeans_automatic_build" property="netbeans.automatic.build"/>
+    </target>
+    <target depends="init" if="netbeans.automatic.build" name="-clean-after-automatic-build">
+        <antcall target="clean"/>
+    </target>
+    <target depends="init,deps-jar" name="-pre-pre-compile">
+        <mkdir dir="${build.classes.dir}"/>
+    </target>
+    <target name="-pre-compile">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target if="do.depend.true" name="-compile-depend">
+        <pathconvert property="build.generated.subdirs">
+            <dirset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+                <include name="*"/>
+            </dirset>
+        </pathconvert>
+        <j2seproject3:depend srcdir="${src.dir}:${build.generated.subdirs}"/>
+    </target>
+    <target depends="init,deps-jar,-pre-pre-compile,-pre-compile, -copy-persistence-xml,-compile-depend" if="have.sources" name="-do-compile">
+        <j2seproject3:javac gensrcdir="${build.generated.sources.dir}"/>
+        <copy todir="${build.classes.dir}">
+            <fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
+        </copy>
+    </target>
+    <target if="has.persistence.xml" name="-copy-persistence-xml">
+        <mkdir dir="${build.classes.dir}/META-INF"/>
+        <copy todir="${build.classes.dir}/META-INF">
+            <fileset dir="${meta.inf.dir}" includes="persistence.xml orm.xml"/>
+        </copy>
+    </target>
+    <target name="-post-compile">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>
+    <target name="-pre-compile-single">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
+        <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
+        <j2seproject3:force-recompile/>
+        <j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}" sourcepath="${src.dir}"/>
+    </target>
+    <target name="-post-compile-single">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>
+    <!--
+                ====================
+                JAR BUILDING SECTION
+                ====================
+            -->
+    <target depends="init" name="-pre-pre-jar">
+        <dirname file="${dist.jar}" property="dist.jar.dir"/>
+        <mkdir dir="${dist.jar.dir}"/>
+    </target>
+    <target name="-pre-jar">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init" if="do.archive" name="-do-jar-create-manifest" unless="manifest.available">
+        <tempfile deleteonexit="true" destdir="${build.dir}" property="tmp.manifest.file"/>
+        <touch file="${tmp.manifest.file}" verbose="false"/>
+    </target>
+    <target depends="init" if="do.archive+manifest.available" name="-do-jar-copy-manifest">
+        <tempfile deleteonexit="true" destdir="${build.dir}" property="tmp.manifest.file"/>
+        <copy file="${manifest.file}" tofile="${tmp.manifest.file}"/>
+    </target>
+    <target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+main.class.available" name="-do-jar-set-mainclass">
+        <manifest file="${tmp.manifest.file}" mode="update">
+            <attribute name="Main-Class" value="${main.class}"/>
+        </manifest>
+    </target>
+    <target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+profile.available" name="-do-jar-set-profile">
+        <manifest file="${tmp.manifest.file}" mode="update">
+            <attribute name="Profile" value="${javac.profile}"/>
+        </manifest>
+    </target>
+    <target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+splashscreen.available" name="-do-jar-set-splashscreen">
+        <basename file="${application.splash}" property="splashscreen.basename"/>
+        <mkdir dir="${build.classes.dir}/META-INF"/>
+        <copy failonerror="false" file="${application.splash}" todir="${build.classes.dir}/META-INF"/>
+        <manifest file="${tmp.manifest.file}" mode="update">
+            <attribute name="SplashScreen-Image" value="META-INF/${splashscreen.basename}"/>
+        </manifest>
+    </target>
+    <target depends="init,-init-macrodef-copylibs,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen" if="do.mkdist" name="-do-jar-copylibs">
+        <j2seproject3:copylibs manifest="${tmp.manifest.file}"/>
+        <echo level="info">To run this application from the command line without Ant, try:</echo>
+        <property location="${dist.jar}" name="dist.jar.resolved"/>
+        <echo level="info">${platform.java} -jar "${dist.jar.resolved}"</echo>
+    </target>
+    <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen" if="do.archive" name="-do-jar-jar" unless="do.mkdist">
+        <j2seproject1:jar manifest="${tmp.manifest.file}"/>
+        <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
+        <property location="${dist.jar}" name="dist.jar.resolved"/>
+        <pathconvert property="run.classpath.with.dist.jar">
+            <path path="${run.classpath}"/>
+            <map from="${build.classes.dir.resolved}" to="${dist.jar.resolved}"/>
+        </pathconvert>
+        <condition else="" property="jar.usage.message" value="To run this application from the command line without Ant, try:${line.separator}${platform.java} -cp ${run.classpath.with.dist.jar} ${main.class}">
+            <isset property="main.class.available"/>
+        </condition>
+        <condition else="debug" property="jar.usage.level" value="info">
+            <isset property="main.class.available"/>
+        </condition>
+        <echo level="${jar.usage.level}" message="${jar.usage.message}"/>
+    </target>
+    <target depends="-do-jar-copylibs" if="do.archive" name="-do-jar-delete-manifest">
+        <delete>
+            <fileset file="${tmp.manifest.file}"/>
+        </delete>
+    </target>
+    <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen,-do-jar-jar,-do-jar-delete-manifest" name="-do-jar-without-libraries"/>
+    <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen,-do-jar-copylibs,-do-jar-delete-manifest" name="-do-jar-with-libraries"/>
+    <target name="-post-jar">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,compile,-pre-jar,-do-jar-without-libraries,-do-jar-with-libraries,-post-jar" name="-do-jar"/>
+    <target depends="init,compile,-pre-jar,-do-jar,-post-jar" description="Build JAR." name="jar"/>
+    <!--
+                =================
+                EXECUTION SECTION
+                =================
+            -->
+    <target depends="init,compile" description="Run a main class." name="run">
+        <j2seproject1:java>
+            <customize>
+                <arg line="${application.args}"/>
+            </customize>
+        </j2seproject1:java>
+    </target>
+    <target name="-do-not-recompile">
+        <property name="javac.includes.binary" value=""/>
+    </target>
+    <target depends="init,compile-single" name="run-single">
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+        <j2seproject1:java classname="${run.class}"/>
+    </target>
+    <target depends="init,compile-test-single" name="run-test-with-main">
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+        <j2seproject1:java classname="${run.class}" classpath="${run.test.classpath}"/>
+    </target>
+    <!--
+                =================
+                DEBUGGING SECTION
+                =================
+            -->
+    <target depends="init" if="netbeans.home" name="-debug-start-debugger">
+        <j2seproject1:nbjpdastart name="${debug.class}"/>
+    </target>
+    <target depends="init" if="netbeans.home" name="-debug-start-debugger-main-test">
+        <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${debug.class}"/>
+    </target>
+    <target depends="init,compile" name="-debug-start-debuggee">
+        <j2seproject3:debug>
+            <customize>
+                <arg line="${application.args}"/>
+            </customize>
+        </j2seproject3:debug>
+    </target>
+    <target depends="init,compile,-debug-start-debugger,-debug-start-debuggee" description="Debug project in IDE." if="netbeans.home" name="debug"/>
+    <target depends="init" if="netbeans.home" name="-debug-start-debugger-stepinto">
+        <j2seproject1:nbjpdastart stopclassname="${main.class}"/>
+    </target>
+    <target depends="init,compile,-debug-start-debugger-stepinto,-debug-start-debuggee" if="netbeans.home" name="debug-stepinto"/>
+    <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-single">
+        <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
+        <j2seproject3:debug classname="${debug.class}"/>
+    </target>
+    <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single"/>
+    <target depends="init,compile-test-single" if="netbeans.home" name="-debug-start-debuggee-main-test">
+        <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
+        <j2seproject3:debug classname="${debug.class}" classpath="${debug.test.classpath}"/>
+    </target>
+    <target depends="init,compile-test-single,-debug-start-debugger-main-test,-debug-start-debuggee-main-test" if="netbeans.home" name="debug-test-with-main"/>
+    <target depends="init" name="-pre-debug-fix">
+        <fail unless="fix.includes">Must set fix.includes</fail>
+        <property name="javac.includes" value="${fix.includes}.java"/>
+    </target>
+    <target depends="init,-pre-debug-fix,compile-single" if="netbeans.home" name="-do-debug-fix">
+        <j2seproject1:nbjpdareload/>
+    </target>
+    <target depends="init,-pre-debug-fix,-do-debug-fix" if="netbeans.home" name="debug-fix"/>
+    <!--
+                =================
+                PROFILING SECTION
+                =================
+            -->
+    <!--
+                pre NB7.2 profiler integration
+            -->
+    <target depends="profile-init,compile" description="Profile a project in the IDE." if="profiler.info.jvmargs.agent" name="-profile-pre72">
+        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
+        <nbprofiledirect>
+            <classpath>
+                <path path="${run.classpath}"/>
+            </classpath>
+        </nbprofiledirect>
+        <profile/>
+    </target>
+    <target depends="profile-init,compile-single" description="Profile a selected class in the IDE." if="profiler.info.jvmargs.agent" name="-profile-single-pre72">
+        <fail unless="profile.class">Must select one file in the IDE or set profile.class</fail>
+        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
+        <nbprofiledirect>
+            <classpath>
+                <path path="${run.classpath}"/>
+            </classpath>
+        </nbprofiledirect>
+        <profile classname="${profile.class}"/>
+    </target>
+    <target depends="profile-init,compile-single" if="profiler.info.jvmargs.agent" name="-profile-applet-pre72">
+        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
+        <nbprofiledirect>
+            <classpath>
+                <path path="${run.classpath}"/>
+            </classpath>
+        </nbprofiledirect>
+        <profile classname="sun.applet.AppletViewer">
+            <customize>
+                <arg value="${applet.url}"/>
+            </customize>
+        </profile>
+    </target>
+    <target depends="profile-init,compile-test-single" if="profiler.info.jvmargs.agent" name="-profile-test-single-pre72">
+        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
+        <nbprofiledirect>
+            <classpath>
+                <path path="${run.test.classpath}"/>
+            </classpath>
+        </nbprofiledirect>
+        <junit dir="${profiler.info.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" jvm="${profiler.info.jvm}" showoutput="true">
+            <env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>
+            <jvmarg value="${profiler.info.jvmargs.agent}"/>
+            <jvmarg line="${profiler.info.jvmargs}"/>
+            <test name="${profile.class}"/>
+            <classpath>
+                <path path="${run.test.classpath}"/>
+            </classpath>
+            <syspropertyset>
+                <propertyref prefix="test-sys-prop."/>
+                <mapper from="test-sys-prop.*" to="*" type="glob"/>
+            </syspropertyset>
+            <formatter type="brief" usefile="false"/>
+            <formatter type="xml"/>
+        </junit>
+    </target>
+    <!--
+                end of pre NB72 profiling section
+            -->
+    <target if="netbeans.home" name="-profile-check">
+        <condition property="profiler.configured">
+            <or>
+                <contains casesensitive="true" string="${run.jvmargs.ide}" substring="-agentpath:"/>
+                <contains casesensitive="true" string="${run.jvmargs.ide}" substring="-javaagent:"/>
+            </or>
+        </condition>
+    </target>
+    <target depends="-profile-check,-profile-pre72" description="Profile a project in the IDE." if="profiler.configured" name="profile" unless="profiler.info.jvmargs.agent">
+        <startprofiler/>
+        <antcall target="run"/>
+    </target>
+    <target depends="-profile-check,-profile-single-pre72" description="Profile a selected class in the IDE." if="profiler.configured" name="profile-single" unless="profiler.info.jvmargs.agent">
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+        <startprofiler/>
+        <antcall target="run-single"/>
+    </target>
+    <target depends="-profile-test-single-pre72" description="Profile a selected test in the IDE." name="profile-test-single"/>
+    <target depends="-profile-check" description="Profile a selected test in the IDE." if="profiler.configured" name="profile-test" unless="profiler.info.jvmargs">
+        <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
+        <startprofiler/>
+        <antcall target="test-single"/>
+    </target>
+    <target depends="-profile-check" description="Profile a selected class in the IDE." if="profiler.configured" name="profile-test-with-main">
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+        <startprofiler/>
+        <antcal target="run-test-with-main"/>
+    </target>
+    <target depends="-profile-check,-profile-applet-pre72" if="profiler.configured" name="profile-applet" unless="profiler.info.jvmargs.agent">
+        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
+        <startprofiler/>
+        <antcall target="run-applet"/>
+    </target>
+    <!--
+                ===============
+                JAVADOC SECTION
+                ===============
+            -->
+    <target depends="init" if="have.sources" name="-javadoc-build">
+        <mkdir dir="${dist.javadoc.dir}"/>
+        <condition else="" property="javadoc.endorsed.classpath.cmd.line.arg" value="-J${endorsed.classpath.cmd.line.arg}">
+            <and>
+                <isset property="endorsed.classpath.cmd.line.arg"/>
+                <not>
+                    <equals arg1="${endorsed.classpath.cmd.line.arg}" arg2=""/>
+                </not>
+            </and>
+        </condition>
+        <exec executable="${platform.java}" failonerror="false" outputproperty="platform.version.output">
+            <arg value="-version"/>
+        </exec>
+        <condition else="" property="bug5101868workaround" value="*.java">
+            <matches multiline="true" pattern="1\.[56](\..*)?" string="${platform.version.output}"/>
+        </condition>
+        <javadoc additionalparam="-J-Dfile.encoding=${file.encoding} ${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" executable="${platform.javadoc}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">
+            <classpath>
+                <path path="${javac.classpath}"/>
+            </classpath>
+            <fileset dir="${src.dir}" excludes="${bug5101868workaround},${excludes}" includes="${includes}">
+                <filename name="**/*.java"/>
+            </fileset>
+            <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+                <include name="**/*.java"/>
+                <exclude name="*.java"/>
+            </fileset>
+            <arg line="${javadoc.endorsed.classpath.cmd.line.arg}"/>
+        </javadoc>
+        <copy todir="${dist.javadoc.dir}">
+            <fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
+                <filename name="**/doc-files/**"/>
+            </fileset>
+            <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+                <include name="**/doc-files/**"/>
+            </fileset>
+        </copy>
+    </target>
+    <target depends="init,-javadoc-build" if="netbeans.home" name="-javadoc-browse" unless="no.javadoc.preview">
+        <nbbrowse file="${dist.javadoc.dir}/index.html"/>
+    </target>
+    <target depends="init,-javadoc-build,-javadoc-browse" description="Build Javadoc." name="javadoc"/>
+    <!--
+                =========================
+                TEST COMPILATION SECTION
+                =========================
+            -->
+    <target depends="init,compile" if="have.tests" name="-pre-pre-compile-test">
+        <mkdir dir="${build.test.classes.dir}"/>
+    </target>
+    <target name="-pre-compile-test">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target if="do.depend.true" name="-compile-test-depend">
+        <j2seproject3:depend classpath="${javac.test.classpath}" destdir="${build.test.classes.dir}" srcdir=""/>
+    </target>
+    <target depends="init,deps-jar,compile,-pre-pre-compile-test,-pre-compile-test,-compile-test-depend" if="have.tests" name="-do-compile-test">
+        <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" processorpath="${javac.test.processorpath}" srcdir=""/>
+        <copy todir="${build.test.classes.dir}"/>
+    </target>
+    <target name="-post-compile-test">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-do-compile-test,-post-compile-test" name="compile-test"/>
+    <target name="-pre-compile-test-single">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-jar,compile,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">
+        <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
+        <j2seproject3:force-recompile destdir="${build.test.classes.dir}"/>
+        <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}" processorpath="${javac.test.processorpath}" sourcepath="" srcdir=""/>
+        <copy todir="${build.test.classes.dir}"/>
+    </target>
+    <target name="-post-compile-test-single">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single" name="compile-test-single"/>
+    <!--
+                =======================
+                TEST EXECUTION SECTION
+                =======================
+            -->
+    <target depends="init" if="have.tests" name="-pre-test-run">
+        <mkdir dir="${build.test.results.dir}"/>
+    </target>
+    <target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">
+        <j2seproject3:test includes="${includes}" testincludes="**/*Test.java"/>
+    </target>
+    <target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
+        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
+    </target>
+    <target depends="init" if="have.tests" name="test-report"/>
+    <target depends="init" if="netbeans.home+have.tests" name="-test-browse"/>
+    <target depends="init,compile-test,-pre-test-run,-do-test-run,test-report,-post-test-run,-test-browse" description="Run unit tests." name="test"/>
+    <target depends="init" if="have.tests" name="-pre-test-run-single">
+        <mkdir dir="${build.test.results.dir}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single">
+        <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
+        <j2seproject3:test excludes="" includes="${test.includes}" testincludes="${test.includes}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">
+        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single-method">
+        <fail unless="test.class">Must select some files in the IDE or set test.class</fail>
+        <fail unless="test.method">Must select some method in the IDE or set test.method</fail>
+        <j2seproject3:test excludes="" includes="${javac.includes}" testincludes="${test.class}" testmethods="${test.method}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method" if="have.tests" name="-post-test-run-single-method">
+        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method,-post-test-run-single-method" description="Run single unit test." name="test-single-method"/>
+    <!--
+                =======================
+                TEST DEBUGGING SECTION
+                =======================
+            -->
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-debug-start-debuggee-test">
+        <fail unless="test.class">Must select one file in the IDE or set test.class</fail>
+        <j2seproject3:test-debug excludes="" includes="${javac.includes}" testClass="${test.class}" testincludes="${javac.includes}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-debug-start-debuggee-test-method">
+        <fail unless="test.class">Must select one file in the IDE or set test.class</fail>
+        <fail unless="test.method">Must select some method in the IDE or set test.method</fail>
+        <j2seproject3:test-debug excludes="" includes="${javac.includes}" testClass="${test.class}" testMethod="${test.method}" testincludes="${test.class}" testmethods="${test.method}"/>
+    </target>
+    <target depends="init,compile-test" if="netbeans.home+have.tests" name="-debug-start-debugger-test">
+        <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${test.class}"/>
+    </target>
+    <target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>
+    <target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test-method" name="debug-test-method"/>
+    <target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">
+        <j2seproject1:nbjpdareload dir="${build.test.classes.dir}"/>
+    </target>
+    <target depends="init,-pre-debug-fix,-do-debug-fix-test" if="netbeans.home" name="debug-fix-test"/>
+    <!--
+                =========================
+                APPLET EXECUTION SECTION
+                =========================
+            -->
+    <target depends="init,compile-single" name="run-applet">
+        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
+        <j2seproject1:java classname="sun.applet.AppletViewer">
+            <customize>
+                <arg value="${applet.url}"/>
+            </customize>
+        </j2seproject1:java>
+    </target>
+    <!--
+                =========================
+                APPLET DEBUGGING  SECTION
+                =========================
+            -->
+    <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-applet">
+        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
+        <j2seproject3:debug classname="sun.applet.AppletViewer">
+            <customize>
+                <arg value="${applet.url}"/>
+            </customize>
+        </j2seproject3:debug>
+    </target>
+    <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-applet" if="netbeans.home" name="debug-applet"/>
+    <!--
+                ===============
+                CLEANUP SECTION
+                ===============
+            -->
+    <target name="-deps-clean-init" unless="built-clean.properties">
+        <property location="${build.dir}/built-clean.properties" name="built-clean.properties"/>
+        <delete file="${built-clean.properties}" quiet="true"/>
+    </target>
+    <target if="already.built.clean.${basedir}" name="-warn-already-built-clean">
+        <echo level="warn" message="Cycle detected: RobotTest was already built"/>
+    </target>
+    <target depends="init,-deps-clean-init" name="deps-clean" unless="no.deps">
+        <mkdir dir="${build.dir}"/>
+        <touch file="${built-clean.properties}" verbose="false"/>
+        <property file="${built-clean.properties}" prefix="already.built.clean."/>
+        <antcall target="-warn-already-built-clean"/>
+        <propertyfile file="${built-clean.properties}">
+            <entry key="${basedir}" value=""/>
+        </propertyfile>
+    </target>
+    <target depends="init" name="-do-clean">
+        <delete dir="${build.dir}"/>
+        <delete dir="${dist.dir}" followsymlinks="false" includeemptydirs="true"/>
+    </target>
+    <target name="-post-clean">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-clean,-do-clean,-post-clean" description="Clean build products." name="clean"/>
+    <target name="-check-call-dep">
+        <property file="${call.built.properties}" prefix="already.built."/>
+        <condition property="should.call.dep">
+            <and>
+                <not>
+                    <isset property="already.built.${call.subproject}"/>
+                </not>
+                <available file="${call.script}"/>
+            </and>
+        </condition>
+    </target>
+    <target depends="-check-call-dep" if="should.call.dep" name="-maybe-call-dep">
+        <ant antfile="${call.script}" inheritall="false" target="${call.target}">
+            <propertyset>
+                <propertyref prefix="transfer."/>
+                <mapper from="transfer.*" to="*" type="glob"/>
+            </propertyset>
+        </ant>
+    </target>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/manual/Robot/nbproject/genfiles.properties	Fri Aug 28 16:55:26 2015 -0700
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=65fbcabf
+build.xml.script.CRC32=fb12e8ad
+build.xml.stylesheet.CRC32=8064a381@1.75.2.48
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=65fbcabf
+nbproject/build-impl.xml.script.CRC32=b571bedd
+nbproject/build-impl.xml.stylesheet.CRC32=876e7a8f@1.75.2.48
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/manual/Robot/nbproject/project.properties	Fri Aug 28 16:55:26 2015 -0700
@@ -0,0 +1,73 @@
+annotation.processing.enabled=true
+annotation.processing.enabled.in.editor=false
+annotation.processing.processors.list=
+annotation.processing.run.all.processors=true
+annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
+application.title=RobotTest
+application.vendor=ckyang
+build.classes.dir=${build.dir}/classes
+build.classes.excludes=**/*.java,**/*.form
+# This directory is removed when the project is cleaned:
+build.dir=build
+build.generated.dir=${build.dir}/generated
+build.generated.sources.dir=${build.dir}/generated-sources
+# Only compile against the classpath explicitly listed here:
+build.sysclasspath=ignore
+build.test.classes.dir=${build.dir}/test/classes
+build.test.results.dir=${build.dir}/test/results
+# Uncomment to specify the preferred debugger connection transport:
+#debug.transport=dt_socket
+debug.classpath=\
+    ${run.classpath}
+debug.test.classpath=\
+    ${run.test.classpath}
+# Files in build.classes.dir which should be excluded from distribution jar
+dist.archive.excludes=
+# This directory is removed when the project is cleaned:
+dist.dir=dist
+dist.jar=${dist.dir}/RobotTest.jar
+dist.javadoc.dir=${dist.dir}/javadoc
+endorsed.classpath=
+excludes=
+file.reference.jfxrt.jar=../../../../artifacts/sdk/rt/lib/ext/jfxrt.jar
+file.reference.Robot-src=src
+includes=**
+jar.compress=false
+javac.classpath=\
+    ${file.reference.jfxrt.jar}
+# Space-separated list of extra javac options
+javac.compilerargs=
+javac.deprecation=false
+javac.processorpath=\
+    ${javac.classpath}
+javac.source=1.8
+javac.target=1.8
+javac.test.classpath=\
+    ${javac.classpath}:\
+    ${build.classes.dir}
+javac.test.processorpath=\
+    ${javac.test.classpath}
+javadoc.additionalparam=
+javadoc.author=false
+javadoc.encoding=${source.encoding}
+javadoc.noindex=false
+javadoc.nonavbar=false
+javadoc.notree=false
+javadoc.private=false
+javadoc.splitindex=true
+javadoc.use=true
+javadoc.version=false
+javadoc.windowtitle=
+main.class=robottest.RobotTest
+manifest.file=manifest.mf
+meta.inf.dir=${src.dir}/META-INF
+mkdist.disabled=false
+platform.active=JDK_1.8
+run.classpath=\
+    ${javac.classpath}:\
+    ${build.classes.dir}
+run.test.classpath=\
+    ${javac.test.classpath}:\
+    ${build.test.classes.dir}
+source.encoding=UTF-8
+src.dir=${file.reference.Robot-src}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/manual/Robot/nbproject/project.xml	Fri Aug 28 16:55:26 2015 -0700
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.java.j2seproject</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/j2se-project/3">
+            <name>RobotTest</name>
+            <explicit-platform explicit-source-supported="true"/>
+            <source-roots>
+                <root id="src.dir"/>
+            </source-roots>
+            <test-roots/>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/manual/Robot/src/robottest/BMPOutputStream.java	Fri Aug 28 16:55:26 2015 -0700
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package robottest;
+
+import java.io.*;
+
+/**
+ * The class creates an OutputStream in BMP format from
+ * integer array, width and height of the image.
+ */
+
+public class BMPOutputStream extends FilterOutputStream{
+
+
+    BMPOutputStream(OutputStream out, int [] arr, int width, int height) {
+        super(out);
+        try {
+            int lineByteWidth = ((width * 3 + 3) >> 2) << 2;
+            out.write(0x42);
+            out.write(0x4d);
+            writeBMPInt(out, lineByteWidth * height + 0x36);
+            writeBMPInt(out, 0);
+            writeBMPInt(out, 0x36);
+            writeBMPInt(out, 0x28);
+            writeBMPInt(out, width);
+            writeBMPInt(out, height);
+            writeBMPShort(out, 0x01);
+            writeBMPShort(out, 0x18);
+            writeBMPInt(out, 0);
+            writeBMPInt(out, lineByteWidth * height);
+            writeBMPInt(out, 0xb13);
+            writeBMPInt(out, 0xb13);
+            writeBMPInt(out, 0);
+            writeBMPInt(out, 0);
+            out.flush();
+
+            int yIncrement = height;
+
+            byte[] line = new byte[lineByteWidth];
+
+            for (int i = yIncrement - 1; i >= 0; i--) {
+                java.util.Arrays.fill(line,(byte)0);
+                int pixelRowStart = i * width;
+                int byteOffsetInLine = 0;
+                for (int imgX = 0; imgX < width; imgX++) {
+                    int rgb = arr[pixelRowStart + imgX];
+                    line[byteOffsetInLine++] = (byte) (rgb & 0xff);
+                    line[byteOffsetInLine++] = (byte) ((rgb >> 8) & 0xff);
+                    line[byteOffsetInLine++] = (byte) ((rgb >> 16) & 0xff);
+                }
+                out.write(line);
+            }
+            out.flush();
+            out.close();
+
+        } catch (Exception e) {}
+    }
+
+    private static void writeBMPInt(OutputStream out, int i) throws IOException {
+        out.write(i & 0xff);
+        out.write((i >> 8) & 0xff);
+        out.write((i >> 16) & 0xff);
+        out.write(i >> 24);
+    }
+
+    private static void writeBMPShort(OutputStream out, int i) throws IOException {
+        out.write(i & 0xff);
+        out.write((i >> 8) & 0xff);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/manual/Robot/src/robottest/RobotBuilder.java	Fri Aug 28 16:55:26 2015 -0700
@@ -0,0 +1,458 @@
+/*
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package robottest;
+
+import com.sun.glass.events.KeyEvent;
+import com.sun.glass.ui.Robot;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.nio.Buffer;
+import java.nio.IntBuffer;
+import javafx.animation.AnimationTimer;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.geometry.BoundingBox;
+import javafx.geometry.Bounds;
+import javafx.scene.Group;
+import javafx.scene.Scene;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.control.ListView;
+import javafx.scene.control.TextField;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.Pane;
+import javafx.scene.layout.VBox;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Rectangle;
+import javafx.stage.Popup;
+import javafx.stage.Stage;
+
+
+public class RobotBuilder {
+
+    //Variable used by "RobotTest" section
+    private final Rectangle rec1 = new Rectangle(50, 50, 40, 160);
+    private Popup screenShot;
+
+    private static RobotBuilder instance;
+
+//    protected TestRobot {}
+
+    public static RobotBuilder getInstance() {
+        if (instance==null)
+                 instance = new RobotBuilder();
+        return instance;
+    }
+
+    /**
+     * The method updates globalScene with robot tests
+     * @param globalScene the global Scene
+     * @param mainBox the Box to insert into
+     * @param robotStage the Robot Stage
+     */
+    void robotTest(final Scene globalScene, final VBox mainBox,
+                          final Stage robotStage){
+
+        Label l = new Label("Robot features Demo");
+        Group lGroup = new Group(l);
+        lGroup.setLayoutX(400);
+        lGroup.setLayoutY(10);
+
+    	//Rectangle's coordinates
+        final int recX = 50;
+        final int recY = 50;
+
+        Group allGroup = new Group();
+        rec1.setFill(Color.RED);
+        Rectangle rec2 = new Rectangle(recX + 40, recY, 40, 160);
+        rec2.setFill(Color.BLUE);
+        Rectangle rec3 = new Rectangle(recX + 80, recY, 40, 160);
+        rec3.setFill(Color.YELLOW);
+        Rectangle rec4 = new Rectangle(recX + 120, recY, 40, 160);
+        rec4.setFill(Color.GREEN);
+
+        GridPane grid = new GridPane();
+        grid.setVgap(50);
+        grid.setHgap(20);
+        grid.setLayoutX(recX + 300);
+        grid.setLayoutY(recY + 50);
+
+        final TextField result1 = new TextField("Result");
+        result1.setEditable(false);
+        Button screenTestBtn = new Button("Robot Get Screen Capture Test");
+        screenTestBtn.setOnAction(new EventHandler<ActionEvent>() {
+            @Override public void handle(ActionEvent e) {
+               screenShot = robotScreenTest(result1, robotStage);
+            }
+        });
+
+        grid.setConstraints(screenTestBtn, 0, 0);
+        grid.getChildren().add(screenTestBtn);
+        grid.setConstraints(result1, 1, 0);
+        grid.getChildren().add(result1);
+
+        final TextField result2 = new TextField("Result");
+        result2.setEditable(false);
+        Button pixelTestBtn = new Button("Robot Get Pixel Color Test");
+        pixelTestBtn.setOnAction(new EventHandler<ActionEvent>() {
+            @Override public void handle(ActionEvent e) {
+               robotPixelTest(result2, robotStage);
+            }
+        });
+
+        grid.setConstraints(pixelTestBtn, 0, 1);
+        grid.getChildren().add(pixelTestBtn);
+        grid.setConstraints(result2, 1, 1);
+        grid.getChildren().add(result2);
+
+        //KeyPressRelesase
+        final TextField writeField = new TextField("");
+        Group writeFieldGroup = new Group(writeField);
+        writeFieldGroup.setLayoutX(recX);
+        writeFieldGroup.setLayoutY(recY + 200);
+
+        final TextField result3 = new TextField("Result");
+        result3.setEditable(false);
+
+        Button keyTestBtn = new Button("Robot Key Press/Release Test");
+        keyTestBtn.setOnAction(new EventHandler<ActionEvent>() {
+            @Override public void handle(ActionEvent e) {
+                robotKeyTest(writeField, result3);
+            }
+        });
+
+        grid.setConstraints(keyTestBtn, 0, 2);
+        grid.getChildren().add(keyTestBtn);
+        grid.setConstraints(result3, 1, 2);
+        grid.getChildren().add(result3);
+
+        //Mouse wheel
+        final ListView<String> sv = new ListView<String>();
+        ObservableList<String> items =FXCollections.observableArrayList (
+                    "a", "b", "c", "d", "e", "f", "g", "h", "i");
+        sv.setItems(items);
+        sv.setPrefWidth(100);
+        sv.setPrefHeight(100);
+
+        Group svGroup = new Group(sv);
+        svGroup.setLayoutX(recX);
+        svGroup.setLayoutY(recY + 250);
+
+        final TextField result4 = new TextField("Result");
+        result4.setEditable(false);
+
+        Button wheelTestBtn = new Button("Robot Mouse Press/Release/Wheel Test");
+        wheelTestBtn.setOnAction(new EventHandler<ActionEvent>() {
+            @Override public void handle(ActionEvent e) {
+                robotWheelTest(sv, result4, robotStage);
+            }
+        });
+
+        grid.setConstraints(wheelTestBtn, 0, 3);
+        grid.getChildren().add(wheelTestBtn);
+        grid.setConstraints(result4, 1, 3);
+        grid.getChildren().add(result4);
+
+        Button btn = new Button("Back");
+        btn.setOnAction(new EventHandler<ActionEvent>() {
+            @Override public void handle(ActionEvent e) {
+                if ((screenShot != null) && (screenShot.isShowing())) {
+                    screenShot.hide();
+                }
+                globalScene.setRoot(mainBox);
+            }
+        });
+        Group btnGroup = new Group(btn);
+        btnGroup.setLayoutX(450);
+        btnGroup.setLayoutY(450);
+
+        allGroup.getChildren().addAll(rec1, rec2, rec3, rec4, grid, lGroup, btnGroup,
+                                      writeFieldGroup, svGroup);
+        globalScene.setRoot(allGroup);
+    }
+
+
+   public void robotKeyTest(final TextField field, final TextField result) {
+		field.requestFocus();
+		new AnimationTimer() {
+			long startTime = System.nanoTime();
+			@Override 
+			public void handle(long now) {
+				if (now > startTime + 3000000000l){ 
+					stop(); 
+					field.setText("Failed");
+				} else if (field.isFocused()) {
+					stop();
+					Robot robot = com.sun.glass.ui.Application.GetApplication().createRobot();
+					robot.keyPress(KeyEvent.VK_T);
+					robot.keyRelease(KeyEvent.VK_T);
+					robot.keyPress(KeyEvent.VK_E);
+					robot.keyRelease(KeyEvent.VK_E);
+					robot.keyPress(KeyEvent.VK_S);
+					robot.keyRelease(KeyEvent.VK_S);
+					robot.keyPress(KeyEvent.VK_T);
+					robot.keyRelease(KeyEvent.VK_T);
+					robot.destroy();
+					new AnimationTimer() {
+						long startTime = System.nanoTime();
+						@Override
+						public void handle(long now) {
+							if (now > startTime + 3000000000l){ 
+								stop();
+								result.setText("Failed");
+							} else if ((field.getText()).equals("test")) { 
+								stop();
+								result.setText("Passed");
+							}
+						}
+					}.start();
+				}
+			}
+		}.start();
+	}
+
+    public void robotWheelTest(final ListView<String> lv, final TextField result,
+                                                            Stage currentStage){
+
+		//Caclulation of ListView minimal coordinates
+		Bounds bounds = lv.localToScreen(new BoundingBox(0, 0, 
+	        lv.getBoundsInParent().getWidth(),
+	        lv.getBoundsInParent().getHeight()));
+		int x = 10 + (int) bounds.getMinX();
+		int y = 10 + (int) bounds.getMinY();
+
+		final Robot robot =
+                    com.sun.glass.ui.Application.GetApplication().createRobot();
+        robot.mouseMove(x, y);
+        robot.mousePress(Robot.MOUSE_LEFT_BTN);
+        robot.mouseRelease(Robot.MOUSE_LEFT_BTN);
+
+		new AnimationTimer() {
+			long startTime = System.nanoTime();
+			@Override 
+			public void handle(long now) {
+				if (now > startTime + 3000000000l){ 
+					stop(); 
+					result.setText("Failed");
+				} else if (lv.isFocused()) {
+					stop();
+					robot.mouseWheel(-5);
+					robot.mousePress(Robot.MOUSE_LEFT_BTN);
+                    robot.mouseRelease(Robot.MOUSE_LEFT_BTN);
+                    robot.destroy();
+					new AnimationTimer() {
+						long startTime = System.nanoTime();
+						@Override
+						public void handle(long now) {
+							if (now > startTime + 3000000000l){ 
+								stop();
+								result.setText("Scroll Down Failed");
+							} else if (!lv.getSelectionModel().
+                                    selectedItemProperty().getValue().
+                                    equals("a")) {
+								        stop();
+								    result.setText("Scroll Down Passed");
+							}
+						}
+					}.start();
+				}
+			}
+		}.start();
+	}
+
+    public void robotPixelTest(final TextField result, Stage currentStage){
+
+	Bounds bounds = rec1.localToScreen(new BoundingBox(0, 0, 
+			rec1.getBoundsInParent().getWidth(),
+                        rec1.getBoundsInParent().getHeight()));
+	int x = 53 + (int) bounds.getMinX();
+	int y = 53 + (int) bounds.getMinY();
+	int answer = assertPixelEquals(x, y, Color.RED) +
+                     assertPixelEquals(x + 40, y, Color.BLUE) +
+                     assertPixelEquals(x + 80, y, Color.YELLOW) +
+                     assertPixelEquals(x + 120, y, Color.GREEN);
+    if (answer == 4) {
+        result.setText("Passed");
+    } else {
+        result.setText("Failed");
+    }
+
+    }
+
+    static int colorToRGB(Color c) {
+        int r = (int) Math.round(c.getRed() * 255.0);
+        int g = (int) Math.round(c.getGreen() * 255.0);
+        int b = (int) Math.round(c.getBlue() * 255.0);
+        return 0xff000000 | (r << 16) | (g << 8) | b;
+    }
+
+    public int assertPixelEquals(int x, int y, Color expected){
+
+        Robot robot = com.sun.glass.ui.Application.GetApplication().createRobot();
+        int pixel = robot.getPixelColor(x, y);
+        robot.destroy();
+        int expectedPixel = colorToRGB(expected);
+        if (checkColor(pixel, expected)) {
+            return 1;
+        } else {
+            System.out.println("Expected color 0x" + Integer.toHexString(expectedPixel) +
+                    " at " + x + "," + y + " but found 0x" + Integer.toHexString(pixel));
+        }
+        return 0;
+    }
+
+    private boolean checkColor(int value, Color expected) {
+
+        double tolerance = 0.07;
+        double ered = expected.getRed();
+        double egrn = expected.getGreen();
+        double eblu = expected.getBlue();
+
+        double vred = ((value & 0xff0000) >> 16) / 255.0;
+        double vgrn = ((value & 0x00ff00) >> 8) / 255.0;
+        double vblu = ((value & 0x0000ff)) / 255.0;
+
+        double dred = Math.abs(ered - vred);
+        double dgrn = Math.abs(egrn - vgrn);
+        double dblu = Math.abs(eblu - vblu);
+
+        if (dred <= tolerance && dgrn <= tolerance && dblu <= tolerance) {
+            return true;
+        }
+
+        return false;
+    }
+       
+    public Popup robotScreenTest(final TextField result, Stage stage){
+	
+        Bounds bounds = rec1.localToScreen(new BoundingBox(0, 0,
+                rec1.getBoundsInParent().getWidth(),
+                rec1.getBoundsInParent().getHeight()));
+
+        int x = 50 + (int) bounds.getMinX();
+        int y = 50 + (int) bounds.getMinY();
+        int[] intArr = null;
+        boolean correct = true;
+        Robot robot = com.sun.glass.ui.Application.GetApplication().createRobot();
+        int width = 160;
+        int height = 160;
+        final Buffer buff = robot.getScreenCapture(x, y, width, height).getPixels();
+        if ((buff instanceof IntBuffer)&&(buff.hasArray())) {
+            intArr =((IntBuffer) buff).array();
+        }
+
+        String filename= "scrCapture.bmp";
+        File file = new File(filename);
+        try {
+            if (!file.exists()) {
+                file.createNewFile();
+            }
+            BMPOutputStream bmp = new BMPOutputStream(new FileOutputStream(filename), intArr, width, height);
+        } catch (Exception e) {}
+
+
+        for (int i = width; i <= height*(height-1); i += width) {
+            for (int j = 1; j <= 38; j ++){
+                if (!checkColor(intArr[j+i],Color.RED)) {
+                    System.out.println(" pixel("+j+","+(i/width)+") "+
+                            Integer.toHexString(intArr[j+i])+" != "+
+                            Integer.toHexString(colorToRGB(Color.RED)));
+                    correct = false;
+                }
+             }
+            for (int j = 41; j <= 78; j ++){
+                if (!checkColor(intArr[j+i],Color.BLUE)) {
+                    System.out.println(" pixel("+j+","+(i/width)+") "+
+                            Integer.toHexString(intArr[j+i])+" != "+
+                            Integer.toHexString(colorToRGB(Color.BLUE)));
+                    correct = false;
+                }
+             }
+            for (int j = 81; j <= 118; j ++){
+                if (!checkColor(intArr[j+i],Color.YELLOW)) {
+                    System.out.println(" pixel("+j+","+(i/width)+") "+
+                            Integer.toHexString(intArr[j+i])+" != "+
+                            Integer.toHexString(colorToRGB(Color.YELLOW)));
+                    correct = false;
+                }
+             }
+            for (int j = 121; j <= 158; j ++){
+                if (!checkColor(intArr[j+i],Color.GREEN)) {
+                    System.out.println(" pixel("+j+","+(i/width)+") "+
+                            Integer.toHexString(intArr[j+i])+" != "+
+                            Integer.toHexString(colorToRGB(Color.GREEN)));
+                    correct = false;
+                }
+            }
+        }
+        robot.destroy();
+        if (correct) {
+            result.setText("Passed");
+        } else {
+            result.setText("Failed");
+        }
+        return showImage(stage, width, height, result);
+    }
+
+    private Popup showImage(Stage stage, int width, int height, TextField tf) {
+
+        int frame = 70;
+        Rectangle rec = new Rectangle(width + frame, height + frame);
+        FileInputStream os = null;
+        final File file = new File("scrCapture.bmp");
+        try {
+            os = new FileInputStream(file);
+        } catch (Exception e) {}
+
+        final Popup popup = new Popup();
+        ImageView iv = new ImageView(new Image(os));
+        iv.setLayoutX(frame/2);
+        iv.setLayoutY(frame/2);
+
+        rec.setFill(Color.WHITE);
+        rec.setStroke(Color.BLACK);
+        Button exit = new Button("x");
+        exit.setOnAction(new EventHandler<ActionEvent>() {
+            @Override public void handle(ActionEvent e) {
+                if (file.exists()&&tf.getText().equals("Passed")) {
+                    file.deleteOnExit();
+                }
+                popup.hide();
+            }
+        });
+        exit.setLayoutX(width + frame/2);
+        Pane popupPane = new Pane(rec, iv, exit);
+        popup.setX(stage.getX() + 550);
+        popup.setY(stage.getY() + 430);
+        popup.getContent().addAll(popupPane);
+        popup.show(stage);
+        return popup;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/manual/Robot/src/robottest/RobotTest.java	Fri Aug 28 16:55:26 2015 -0700
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package robottest;
+
+import javafx.scene.Group;
+import javafx.scene.Scene;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.layout.VBox;
+import javafx.stage.Stage;
+import javafx.stage.Screen;
+import javafx.application.Application;
+import javafx.geometry.Pos;
+import javafx.geometry.Rectangle2D;
+
+/**
+ *  The application should be used by QA in order to test main
+ *  FX functionality
+ */
+public class RobotTest extends Application {
+
+    public static void main(String[] args) {
+        launch(args);
+    }
+    
+    //@Override
+    public void start(final Stage primaryStage) {
+
+        Screen screen = Screen.getPrimary();
+        Rectangle2D bounds = screen.getVisualBounds();
+
+        primaryStage.setX(0);
+        primaryStage.setY(0);
+        final VBox mainBox = new VBox(30);
+        mainBox.setAlignment(Pos.CENTER);
+        final Scene globalScene = new Scene(new Group(),bounds.getWidth(), bounds.getHeight());
+        final RobotBuilder builder = RobotBuilder.getInstance();
+
+        Label welcome = new Label("Welcome to Robot Test");
+
+        Button bRobot = new Button("Robot");
+        bRobot.setOnAction(e -> builder.robotTest(globalScene, mainBox, primaryStage));
+        
+        Button bquit = new Button("Quit");
+        bquit.setOnAction(e -> primaryStage.close());
+        
+        mainBox.getChildren().addAll(welcome, bRobot, bquit);
+        globalScene.setRoot(mainBox);
+        globalScene.getStylesheets().add("robottest/RobotTestStyles.css");
+        primaryStage.setScene(globalScene);
+        primaryStage.show();
+    }
+
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/manual/Robot/src/robottest/RobotTestStyles.css	Fri Aug 28 16:55:26 2015 -0700
@@ -0,0 +1,64 @@
+    /*
+        Font configuration for HelloSanity sample
+    */
+    
+    .button {
+    -fx-font-size: 18px;
+    }
+
+    .label {
+    -fx-font-size: 18px;
+    }
+
+    .text-field {
+    -fx-font-size: 18px;
+    }
+
+    .radio-button {
+    -fx-font-size: 18px;
+    }
+
+    .check-box {
+    -fx-font-size: 18px;
+    }
+    
+    .slider {
+    -fx-font-size: 18px;
+    }
+
+    .scroll-pane {
+    -fx-font-size: 18px;
+    }
+
+    .list-view {
+    -fx-font-size: 18px;
+    }
+
+    .menu-bar {
+    -fx-font-size: 18px;
+    }
+
+    .menu {
+    -fx-font-size: 18px;
+    }
+
+    .combo-box {
+    -fx-font-size: 18px;
+    }
+
+    .menu-item {
+    -fx-font-size: 18px;
+    }
+
+    .menu-button {
+    -fx-font-size: 18px;
+    }
+
+    .split-menu-button {
+    -fx-font-size: 18px;
+    }
+
+
+
+
+